Skip to content

Commit e40339d

Browse files
add derivative proves
These proves were originally copied from https://github.com/katydid/symbolic-automatic-derivatives/blob/main/Sadol/Calculus.lean and then rewritten in Prop instead of Type
1 parent ea2b650 commit e40339d

File tree

3 files changed

+147
-1
lines changed

3 files changed

+147
-1
lines changed

Katydid.lean

+1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ import Katydid.Example.SimpLibrary
88

99
import Katydid.Regex.Regex
1010
import Katydid.Regex.Language
11+
import Katydid.Regex.Calculus
1112

1213
import Katydid.Expr.Desc

Katydid/Regex/Calculus.lean

+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import Katydid.Regex.Language
2+
3+
namespace Calculus
4+
5+
open Language
6+
open List
7+
open Char
8+
open String
9+
10+
def null' (P: Lang α): Prop :=
11+
P []
12+
13+
def derive' (P: Lang α) (a: α): Lang α :=
14+
fun (w: List α) => P (a :: w)
15+
16+
def null {α: Type} (f: List α -> Prop): Prop :=
17+
f []
18+
19+
def derives {α: Type} (f: List α -> Prop) (u: List α): (List α -> Prop) :=
20+
λ v => f (u ++ v)
21+
22+
def derive {α: Type} (f: List α -> Prop) (a: α): (List α -> Prop) :=
23+
derives f [a]
24+
25+
attribute [simp] null derive derives
26+
27+
def derives_emptylist : derives f [] = f :=
28+
rfl
29+
30+
def derives_strings (f: List α -> Prop) (u v: List α): derives f (u ++ v) = derives (derives f u) v :=
31+
match u with
32+
| [] => rfl
33+
| (a :: u') => derives_strings (derive f a) u' v
34+
35+
def null_derives (f: List α -> Prop) (u: List α): (null ∘ derives f) u = f u := by
36+
simp
37+
38+
def derives_foldl (f: List α -> Prop) (u: List α): (derives f) u = (List.foldl derive f) u :=
39+
match u with
40+
| [] => rfl
41+
| (a :: as) => by sorry
42+
43+
def null_emptyset {α: Type}:
44+
@null α emptyset = False :=
45+
rfl
46+
47+
def null_universal {α: Type}:
48+
@null α universal = True :=
49+
rfl
50+
51+
def null_emptystr {α: Type}:
52+
@null α emptystr <-> True :=
53+
Iff.intro
54+
(fun _ => True.intro)
55+
(fun _ => rfl)
56+
57+
def null_char {α: Type} {c: α}:
58+
null (char c) <-> False :=
59+
Iff.intro nofun nofun
60+
61+
def null_or {α: Type} {P Q: Lang α}:
62+
null (or P Q) = ((null P) \/ (null Q)) := by
63+
rfl
64+
65+
def null_and {α: Type} {P Q: Lang α}:
66+
null (and P Q) = ((null P) /\ (null Q)) :=
67+
rfl
68+
69+
def null_concat {α: Type} {P Q: Lang α}:
70+
null (concat P Q) <-> ((null P) /\ (null Q)) := by
71+
refine Iff.intro ?toFun ?invFun
72+
case toFun =>
73+
intro ⟨x, y, hx, hy, hxy⟩
74+
simp at hxy
75+
simp [hxy] at hx hy
76+
exact ⟨hx, hy⟩
77+
case invFun =>
78+
exact fun ⟨x, y⟩ => ⟨[], [], x, y, rfl⟩
79+
80+
-- def null_star {α: Type} {P: Lang α}:
81+
-- null (star P) <-> (List (null P)) := by
82+
-- refine Iff.intro ?toFun ?invFun
83+
-- case toFun =>
84+
-- sorry
85+
-- case invFun =>
86+
-- sorry
87+
88+
def derive_emptyset {α: Type} {a: α}:
89+
(derive emptyset a) = emptyset :=
90+
rfl
91+
92+
def derive_universal {α: Type} {a: α}:
93+
(derive universal a) = universal :=
94+
rfl
95+
96+
def derive_emptystr {α: Type} {a: α} {w: List α}:
97+
(derive emptystr a) w <-> emptyset w :=
98+
Iff.intro nofun nofun
99+
100+
def derive_char {α: Type} {a: α} {c: α} {w: List α}:
101+
(derive (char c) a) w <-> (scalar (a = c) emptystr) w := by
102+
refine Iff.intro ?toFun ?invFun
103+
case toFun =>
104+
intro D
105+
cases D with | refl =>
106+
exact ⟨ rfl, rfl ⟩
107+
case invFun =>
108+
intro ⟨ H1 , H2 ⟩
109+
cases H1 with | refl =>
110+
cases H2 with | refl =>
111+
exact rfl
112+
113+
def derive_or {α: Type} {a: α} {P Q: Lang α}:
114+
(derive (or P Q) a) = (or (derive P a) (derive Q a)) :=
115+
rfl
116+
117+
def derive_and {α: Type} {a: α} {P Q: Lang α}:
118+
(derive (and P Q) a) = (and (derive P a) (derive Q a)) :=
119+
rfl
120+
121+
def derive_scalar {α: Type} {a: α} {s: Prop} {P: Lang α}:
122+
(derive (scalar s P) a) = (scalar s (derive P a)) :=
123+
rfl
124+
125+
def derive_concat {α: Type} {a: α} {P Q: Lang α} {w: List α}:
126+
(derive (concat P Q) a) w <-> (scalar (null P) (or (derive Q a) (concat (derive P a) Q))) w := by
127+
refine Iff.intro ?toFun ?invFun
128+
case toFun =>
129+
sorry
130+
case invFun =>
131+
sorry
132+
133+
-- def derive_star {α: Type} {a: α} {P: Lang α} {w: List α}:
134+
-- (derive (star P) a) w <-> (scalar (List (null P)) (concat (derive P a) (star P))) w := by
135+
-- refine Iff.intro ?toFun ?invFun
136+
-- case toFun =>
137+
-- sorry
138+
-- case invFun =>
139+
-- sorry

Katydid/Regex/Language.lean

+7-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ def emptystr {α: Type} : Lang α :=
1414
def char {α: Type} (a : α): Lang α :=
1515
fun w => w = [a]
1616

17+
-- scalar is used as an and to make derive char not require an if statement
18+
-- (derive (char c) a) w <-> (scalar (a = c) emptystr)
19+
def scalar {α: Type} (s : Prop) (P : Lang α) : Lang α :=
20+
fun w => s /\ P w
21+
1722
def or {α: Type} (P : Lang α) (Q : Lang α) : Lang α :=
1823
fun w => P w \/ Q w
1924

@@ -30,7 +35,7 @@ inductive All {α: Type} (P : α -> Prop) : (List α -> Prop) where
3035

3136
def star {α: Type} (P : Lang α) : Lang α :=
3237
fun (w : List α) =>
33-
∃ (ws : List (List α)), All P ws /\ w = (List.join ws)
38+
∃ (ws : List (List α)), All P ws /\ w = (List.flatten ws)
3439

3540
-- attribute [simp] allows these definitions to be unfolded when using the simp tactic.
3641
attribute [simp] universal emptyset emptystr char or and concat star
@@ -46,6 +51,7 @@ example: Lang Char := char 'b'
4651
example: Lang Char := (or (char 'a') emptyset)
4752
example: Lang Char := (and (char 'a') (char 'b'))
4853
example: Lang Nat := (and (char 1) (char 2))
54+
example: Lang Nat := (scalar True (char 2))
4955
example: Lang Nat := (concat (char 1) (char 2))
5056

5157
end Language

0 commit comments

Comments
 (0)