diff --git a/Katydid.lean b/Katydid.lean index 54a9a28..be122df 100644 --- a/Katydid.lean +++ b/Katydid.lean @@ -11,6 +11,7 @@ import Katydid.Expr.Desc import Katydid.Expr.Regex import Katydid.Conal.Decidability +import Katydid.Conal.Function import Katydid.Conal.Language import Katydid.Conal.Calculus import Katydid.Conal.Examples diff --git a/Katydid/Conal/Calculus.lean b/Katydid/Conal/Calculus.lean index e0ed088..67def88 100644 --- a/Katydid/Conal/Calculus.lean +++ b/Katydid/Conal/Calculus.lean @@ -1,6 +1,7 @@ -- A translation to Lean from Agda -- https://github.com/conal/paper-2021-language-derivatives/blob/main/Calculus.lagda +import Katydid.Conal.Function import Katydid.Conal.Language import Mathlib.Logic.Equiv.Defs -- ≃ import Katydid.Std.Tipe @@ -236,12 +237,16 @@ def derivative_universal: -- δ𝟏 : Ξ΄ 𝟏 a ⟷ βˆ… -- δ𝟏 = mk↔′ (Ξ» ()) (Ξ» ()) (Ξ» ()) (Ξ» ()) --- TODO: Redo this definition to do extensional isomorphism: `⟷` properly -def derivative_emptyStr: - βˆ€ (a: Ξ±), - (Ξ΄' Ξ΅ a) ≑ βˆ… := by - -- TODO - sorry +def derivative_emptyStr: βˆ€ (w: List Ξ±), (Ξ΄' Ξ΅ a) w <=> βˆ… w := by + intro w + constructor + Β· intro D + simp at D + cases D + next D => + contradiction + Β· intro E + contradiction -- Ξ΄` : Ξ΄ (` c) a ⟷ (a ≑ c) Β· 𝟏 -- Ξ΄` = mk↔′ diff --git a/Katydid/Conal/Function.lean b/Katydid/Conal/Function.lean new file mode 100644 index 0000000..ee7d4da --- /dev/null +++ b/Katydid/Conal/Function.lean @@ -0,0 +1,85 @@ +-- An approximation of the Function module in the Agda standard library. + +import Katydid.Std.Tipe + +-- A ↔ B = Inverse A B + +-- mk↔′ : βˆ€ (f : A β†’ B) (f⁻¹ : B β†’ A) β†’ InverseΛ‘ f f⁻¹ β†’ InverseΚ³ f f⁻¹ β†’ 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 β„“ + +def Congruent (f: A -> B): Type := + βˆ€ {x y}, x ≑ y -> f x ≑ f y + +def Inverse (f: A -> B) (g: B -> A): Type := + βˆ€ {x y}, y ≑ g x -> f y ≑ x + +inductive Inverses (f: A -> B) (g: B -> A): Type (u + 1) where + | mk + (congF : Congruent f) + (congG : Congruent g) + (inverseL : Inverse f g) + (inverseR : Inverse g f): Inverses f g + +-- Lean has Bi-implication +-- If and only if, or logical bi-implication. `a ↔ b` means that `a` implies `b` and vice versa. By `propext`, this implies that `a` and `b` are equal and hence any expression involving `a` is equivalent to the corresponding expression with `b` instead. +-- structure Iff (a b : Prop) : Prop where + -- If `a β†’ b` and `b β†’ a` then `a` and `b` are equivalent. -/ + -- intro :: + -- Modus ponens for if and only if. If `a ↔ b` and `a`, then `b`. -/ + -- mp : a β†’ b + -- Modus ponens for if and only if, reversed. If `a ↔ b` and `b`, then `a`. -/ + -- mpr : b β†’ a + +-- We use this weaker form of Inverses, but redefine it work Type + +structure TIff (a b: Type u): Type (u + 1) where + intro :: + mp : a β†’ b + mpr : b β†’ a + +infixr:100 " <=> " => TIff + +-- Extensional (or β€œpointwise”) isomorphism relates predicates isomorphic on every argument: P ←→ Q = βˆ€ {w} β†’ P w ↔ Q w + +def EIff {w: List Ξ±} (a b: List Ξ± -> Type u) := (a w) <=> (b w) + +-- blackslash <--> +infixr:100 " ⟷ " => EIff + +-- 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 diff --git a/Katydid/Conal/Symbolic.lean b/Katydid/Conal/Symbolic.lean index d161829..2dcb2b1 100644 --- a/Katydid/Conal/Symbolic.lean +++ b/Katydid/Conal/Symbolic.lean @@ -2,18 +2,30 @@ -- https://github.com/conal/paper-2021-language-derivatives/blob/main/Symbolic.lagda import Katydid.Conal.Decidability +import Katydid.Conal.Function import Katydid.Conal.Language variable {P Q : dLang Ξ±} variable {s : Type u} inductive Lang : (List Ξ± -> Type u) -> Type (u + 1) where + -- βˆ… : Lang β—‡.βˆ… | emptySet : Lang dLang.emptyset - | universal : Lang (fun _ => PUnit) + -- 𝒰 : Lang β—‡.𝒰 + | universal : Lang dLang.universal + -- 𝟏 : Lang β—‡.𝟏 | emptyStr : Lang dLang.emptystr + -- ` : (a : A) β†’ Lang (β—‡.` a) | char {a: Type u}: (a: Ξ±) -> Lang (dLang.char a) + -- _βˆͺ_ : Lang P β†’ Lang Q β†’ Lang (P β—‡.βˆͺ Q) | or : Lang P -> Lang Q -> Lang (dLang.or P Q) + -- _∩_ : Lang P β†’ Lang Q β†’ Lang (P β—‡.∩ Q) | and : Lang P -> Lang Q -> Lang (dLang.and P Q) + -- _Β·_ : Dec s β†’ Lang P β†’ Lang (s β—‡.Β· P) | scalar {s: Type u}: (Dec s) -> Lang P -> Lang (dLang.scalar s P) + -- _⋆_ : Lang P β†’ Lang Q β†’ Lang (P β—‡.⋆ Q) | concat : Lang P -> Lang Q -> Lang (dLang.concat P Q) + -- _β˜† : Lang P β†’ Lang (P β—‡.β˜†) | star : Lang P -> Lang (dLang.star P) + -- _β—‚_ : (Q ⟷ P) β†’ Lang P β†’ Lang Q + | iso: (Q ⟷ P) -> Lang P -> Lang Q