-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathFunction.lean
78 lines (56 loc) · 2.74 KB
/
Function.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
-- An approximation of the Function module in the Agda standard library.
import Sadol.Tipe
-- A ↔ B = Inverse A B
-- record Inverse : Set (a ⊔ b ⊔ ℓ₁ ⊔ ℓ₂) where
-- field
-- to : A → B
-- from : B → A
-- to-cong : Congruent _≈₁_ _≈₂_ to
-- from-cong : Congruent _≈₂_ _≈₁_ from
-- inverse : Inverseᵇ _≈₁_ _≈₂_ to from
-- Congruent : (A → B) → Set _
-- Congruent f = ∀ {x y} → x ≈₁ y → f x ≈₂ f y
-- Inverseᵇ : (A → B) → (B → A) → Set _
-- Inverseᵇ f g = Inverseˡ f g × Inverseʳ f g
-- Inverseˡ : (A → B) → (B → A) → Set _
-- Inverseˡ f g = ∀ {x y} → y ≈₁ g x → f y ≈₂ x
-- Inverseʳ : (A → B) → (B → A) → Set _
-- Inverseʳ f g = ∀ {x y} → y ≈₂ f x → g y ≈₁ x
-- (_≈₁_ : Rel A ℓ₁) -- Equality over the domain
-- (_≈₂_ : Rel B ℓ₂) -- Equality over the codomain
-- Rel : Set a → (ℓ : Level) → Set (a ⊔ suc ℓ)
-- Rel A ℓ = REL A A ℓ
-- REL : Set a → Set b → (ℓ : Level) → Set (a ⊔ b ⊔ suc ℓ)
-- REL A B ℓ = A → B → Set ℓ
-- mk↔′ : ∀ (f : A → B) (f⁻¹ : B → A) → Inverseˡ f f⁻¹ → Inverseʳ f f⁻¹ → A ↔ B
-- If we look closely at mk↔′ it matches the Mathlib.Logic.Equiv.Defs
-- structure Equiv (α : Sort*) (β : Sort _) where
-- protected toFun : α → β
-- protected invFun : β → α
-- protected left_inv : LeftInverse invFun toFun
-- protected right_inv : RightInverse invFun toFun
def leftInverse {α β: Type u} (g : β → α) (f : α → β) : Type u :=
∀ x, g (f x) ≡ x
def rightInverse {α β: Type u} (g : β → α) (f : α → β) : Type u :=
leftInverse f g
structure TEquiv (α : Type u) (β : Type u) where
toFun : α → β
invFun : β → α
leftInv : leftInverse invFun toFun
rightInv : rightInverse invFun toFun
-- We consider the three definitions of equivalent (Equiv, TEquiv and Agda's Inverse) to be equivalent
infixr:25 " <=> " => TEquiv
-- ↔Eq.sym
def TEquiv.sym (e: A <=> B): B <=> A :=
⟨e.invFun, e.toFun, e.rightInv, e.leftInv⟩
-- Extensional (or “pointwise”) isomorphism relates predicates isomorphic on every argument: P ←→ Q = ∀ {w} → P w ↔ Q w
def ETEquiv (a b: List α -> Type u) := ∀ {w: List α}, (a w) <=> (b w)
infixr:25 " ⟷ " => ETEquiv
-- Note: We see that proofs that need ⟷ are typically proven using mk↔′
-- δ𝟏 : δ 𝟏 a ⟷ ∅
-- δ𝟏 = mk↔′ (λ ()) (λ ()) (λ ()) (λ ())
-- Lean struggles to synthesize w sometimes, for example
-- (δ' ε a) ⟷ ∅
-- results in the error: "don't know how to synthesize implicit argument 'w'"
-- Then we need to explicitly provide 'w', as such
-- ∀ (w: List α), (δ' ε a) w <=> ∅ w