Skip to content

Commit 10fdf3b

Browse files
dwrenshakim-em
andcommitted
feat: port Logic/Relator (#385)
Port logic/relator.lean and add comments in the places where the linter demands them. Compare to the mathlib3 version: https://github.com/leanprover-community/mathlib/blob/7362d50a80c3e7f7a1fb5adb1c0b6ba593db103d/src/logic/relator.lean Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
1 parent 9ce9121 commit 10fdf3b

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import Mathlib.Logic.Equiv.LocalEquiv
6161
import Mathlib.Logic.Equiv.MfldSimpsAttr
6262
import Mathlib.Logic.Function.Basic
6363
import Mathlib.Logic.Nonempty
64+
import Mathlib.Logic.Relator
6465
import Mathlib.Mathport.Attributes
6566
import Mathlib.Mathport.Rename
6667
import Mathlib.Mathport.SpecialNames

Mathlib/Logic/Relator.lean

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/-
2+
Copyright (c) 2017 Johannes Hölzl. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Johannes Hölzl
5+
-/
6+
7+
import Mathlib.Logic.Basic
8+
9+
/-!
10+
# Relator for functions, pairs, sums, and lists.
11+
-/
12+
13+
namespace Relator
14+
universe u₁ u₂ v₁ v₂
15+
16+
/- TODO(johoelzl):
17+
* should we introduce relators of datatypes as recursive function or as inductive
18+
predicate? For now we stick to the recursor approach.
19+
* relation lift for datatypes, Π, Σ, set, and subtype types
20+
* proof composition and identity laws
21+
* implement method to derive relators from datatype
22+
-/
23+
24+
section
25+
26+
variable {α : Sort u₁} {β : Sort u₂} {γ : Sort v₁} {δ : Sort v₂}
27+
variable (R : α → β → Prop) (S : γ → δ → Prop)
28+
29+
/-- The binary relations `R : α → β → Prop` and `S : γ → δ → Prop` induce a binary
30+
relation on functions `LiftFun : (f : α → γ) (g : β → δ) : Prop'. -/
31+
def LiftFun (f : α → γ) (g : β → δ) : Prop :=
32+
∀⦃a b⦄, R a b → S (f a) (g b)
33+
34+
/-- `(R ⇒ S) f g` means `LiftFun R S f g`. -/
35+
infixr:40 " ⇒ " => LiftFun
36+
37+
end
38+
39+
section
40+
41+
variable {α : Type u₁} {β : Type u₂} (R : α → β → Prop)
42+
43+
/-- A relation is "right total" if every element appears on the right. -/
44+
def RightTotal : Prop := ∀ b, ∃ a, R a b
45+
46+
/-- A relation is "left total" if every element appears on the left. -/
47+
def LeftTotal : Prop := ∀ a, ∃ b, R a b
48+
49+
/-- A relation is "bi-total" if it is both right total and left total. -/
50+
def BiTotal : Prop := LeftTotal R ∧ RightTotal R
51+
52+
/-- A relation is "left unique" if every element on the right is paired with at
53+
most one element on the left. -/
54+
def LeftUnique : Prop := ∀ ⦃a b c⦄, R a c → R b c → a = b
55+
56+
/-- A relation is "right unique" if every element on the left is paired with at
57+
most one element on the right. -/
58+
def RightUnique : Prop := ∀ ⦃a b c⦄, R a b → R a c → b = c
59+
60+
/-- A relation is "bi-unique" if it is both left unique and right unique. -/
61+
def BiUnique : Prop := LeftUnique R ∧ RightUnique R
62+
63+
variable {R}
64+
65+
lemma RightTotal.rel_forall (h : RightTotal R) :
66+
((R ⇒ (· → ·)) ⇒ (· → ·)) (λ p => ∀i, p i) (λ q => ∀i, q i) :=
67+
λ _ _ Hrel H b => Exists.elim (h b) (λ _ Rab => Hrel Rab (H _))
68+
69+
lemma LeftTotal.rel_exists (h : LeftTotal R) :
70+
((R ⇒ (· → ·)) ⇒ (· → ·)) (λ p => ∃i, p i) (λ q => ∃i, q i) :=
71+
λ _ _ Hrel ⟨a, pa⟩ => (h a).imp $ λ _ Rab => Hrel Rab pa
72+
73+
lemma BiTotal.rel_forall (h : BiTotal R) :
74+
((R ⇒ Iff) ⇒ Iff) (λ p => ∀i, p i) (λ q => ∀i, q i) :=
75+
λ _ _ Hrel =>
76+
⟨λ H b => Exists.elim (h.right b) (λ _ Rab => (Hrel Rab).mp (H _)),
77+
λ H a => Exists.elim (h.left a) (λ _ Rab => (Hrel Rab).mpr (H _))⟩
78+
79+
lemma BiTotal.rel_exists (h : BiTotal R) :
80+
((R ⇒ Iff) ⇒ Iff) (λ p => ∃i, p i) (λ q => ∃i, q i) :=
81+
λ _ _ Hrel =>
82+
⟨λ ⟨a, pa⟩ => (h.left a).imp $ λ _ Rab => (Hrel Rab).1 pa,
83+
λ ⟨b, qb⟩ => (h.right b).imp $ λ _ Rab => (Hrel Rab).2 qb⟩
84+
85+
lemma left_unique_of_rel_eq {eq' : β → β → Prop} (he : (R ⇒ (R ⇒ Iff)) Eq eq') :
86+
LeftUnique R :=
87+
λ a b c (ac : R a c) (bc : R b c) => (he ac bc).mpr ((he bc bc).mp rfl)
88+
89+
end
90+
91+
lemma rel_imp : (Iff ⇒ (Iff ⇒ Iff)) (· → ·) (· → ·) :=
92+
λ _ _ h _ _ l => imp_congr h l
93+
94+
lemma rel_not : (Iff ⇒ Iff) Not Not :=
95+
λ _ _ h => not_congr h
96+
97+
lemma bi_total_eq {α : Type u₁} : Relator.BiTotal (@Eq α) :=
98+
{ left := λ a => ⟨a, rfl⟩, right := λ a => ⟨a, rfl⟩ }
99+
100+
variable {α : Type _} {β : Type _} {γ : Type _} {δ : Type _}
101+
variable {r : α → β → Prop} {p : β → γ → Prop} {q : γ → δ → Prop}
102+
103+
lemma LeftUnique.flip (h : LeftUnique r) : RightUnique (flip r) :=
104+
λ _ _ _ h₁ h₂ => h h₁ h₂
105+
106+
lemma rel_and : ((·↔·) ⇒ (·↔·) ⇒ (·↔·)) (·∧·) (·∧·) :=
107+
λ _ _ h₁ _ _ h₂ => and_congr h₁ h₂
108+
109+
lemma rel_or : ((·↔·) ⇒ (·↔·) ⇒ (·↔·)) (·∨·) (·∨·) :=
110+
λ _ _ h₁ _ _ h₂ => or_congr h₁ h₂
111+
112+
lemma rel_iff : ((·↔·) ⇒ (·↔·) ⇒ (·↔·)) (·↔·) (·↔·) :=
113+
λ _ _ h₁ _ _ h₂ => iff_congr h₁ h₂
114+
115+
lemma rel_eq {r : α → β → Prop} (hr : BiUnique r) : (r ⇒ r ⇒ (·↔·)) (·=·) (·=·) :=
116+
λ _ _ h₁ _ _ h₂ => ⟨λ h => hr.right h₁ $ h.symm ▸ h₂, λ h => hr.left h₁ $ h.symm ▸ h₂⟩
117+
118+
end Relator

0 commit comments

Comments
 (0)