Skip to content

Commit 280d961

Browse files
initial definition of indexed regex
1 parent 17172a5 commit 280d961

File tree

6 files changed

+146
-12
lines changed

6 files changed

+146
-12
lines changed

Katydid.lean

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Katydid.Std.Ordering
2+
import Katydid.Std.Decidable
23
import Katydid.Std.OrderingThunk
34
import Katydid.Std.Lists
45
import Katydid.Std.Ltac
@@ -9,5 +10,6 @@ import Katydid.Example.SimpLibrary
910
import Katydid.Regex.Regex
1011
import Katydid.Regex.Language
1112
import Katydid.Regex.Commutes
13+
import Katydid.Regex.IndexedRegex
1214

1315
import Katydid.Expr.Desc

Katydid/Regex/IndexedRegex.lean

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import Katydid.Std.Decidable
2+
3+
import Katydid.Regex.Language
4+
5+
namespace IndexedRegex
6+
7+
open List
8+
9+
inductive Regex (α: Type): (List α -> Prop) -> Type where
10+
| emptyset : Regex α Language.emptyset
11+
| emptystr : Regex α Language.emptystr
12+
| char : (a: α) → Regex α (Language.char a)
13+
| or : Regex α x → Regex α y → Regex α (Language.or x y)
14+
| concat : Regex α x → Regex α y → Regex α (Language.concat x y)
15+
| star : Regex α x → Regex α (Language.star x)
16+
17+
def null (r: Regex α l): Decidable (Language.null l) :=
18+
match r with
19+
| Regex.emptyset => Decidable.isFalse (Language.not_null_if_emptyset)
20+
| Regex.emptystr => Decidable.isTrue (Language.null_if_emptystr)
21+
| Regex.char _ => Decidable.isFalse (Language.not_null_if_char)
22+
| Regex.or x y =>
23+
Decidable.map (symm Language.null_iff_or)
24+
(Decidable.or (null x) (null y))
25+
| Regex.concat x y =>
26+
Decidable.map (symm Language.null_iff_concat)
27+
(Decidable.and (null x) (null y))
28+
| Regex.star _ => Decidable.isTrue (Language.null_if_star)
29+
30+
def derive [DecidableEq α] (r: Regex α l) (a: α): Regex α (Language.derive l a) := by
31+
sorry

Katydid/Regex/Language.lean

+69-10
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,16 @@ def and {α: Type} (P : Lang α) (Q : Lang α) : Lang α :=
3030
fun w => P w /\ Q w
3131

3232
def concat {α: Type} (P : Lang α) (Q : Lang α) : Lang α :=
33-
fun (w : List α) =>
34-
∃ (x : List α) (y : List α), P x /\ Q y /\ w = (x ++ y)
33+
fun (xs : List α) =>
34+
∃ (ys : List α) (zs : List α), P ys /\ Q zs /\ xs = (ys ++ zs)
3535

3636
inductive All {α: Type} (P : α -> Prop) : (List α -> Prop) where
3737
| nil : All P []
3838
| cons : ∀ {x xs} (_px : P x) (_pxs : All P xs), All P (x :: xs)
3939

4040
def star {α: Type} (R : Lang α) : Lang α :=
41-
fun (w : List α) =>
42-
∃ (ws : List (List α)), All R ws /\ w = (List.flatten ws)
41+
fun (xs : List α) =>
42+
∃ (xss : List (List α)), All R xss /\ xs = (List.flatten xss)
4343

4444
-- attribute [simp] allows these definitions to be unfolded when using the simp tactic.
4545
attribute [simp] universal emptyset emptystr char onlyif or and concat star
@@ -116,6 +116,14 @@ def null_emptyset {α: Type}:
116116
@null α emptyset = False :=
117117
rfl
118118

119+
def null_iff_emptyset {α: Type}:
120+
@null α emptyset <-> False := by
121+
rw [null_emptyset]
122+
123+
def not_null_if_emptyset {α: Type}:
124+
@null α emptyset -> False :=
125+
null_iff_emptyset.mp
126+
119127
def null_universal {α: Type}:
120128
@null α universal = True :=
121129
rfl
@@ -126,6 +134,10 @@ def null_iff_emptystr {α: Type}:
126134
(fun _ => True.intro)
127135
(fun _ => rfl)
128136

137+
def null_if_emptystr {α: Type}:
138+
@null α emptystr :=
139+
rfl
140+
129141
def null_emptystr {α: Type}:
130142
@null α emptystr = True := by
131143
rw [null_iff_emptystr]
@@ -134,6 +146,10 @@ def null_iff_char {α: Type} {c: α}:
134146
null (char c) <-> False :=
135147
Iff.intro nofun nofun
136148

149+
def not_null_if_char {α: Type} {c: α}:
150+
null (char c) -> False :=
151+
nofun
152+
137153
def null_char {α: Type} {c: α}:
138154
null (char c) = False := by
139155
rw [null_iff_char]
@@ -142,6 +158,10 @@ def null_or {α: Type} {P Q: Lang α}:
142158
null (or P Q) = ((null P) \/ (null Q)) :=
143159
rfl
144160

161+
def null_iff_or {α: Type} {P Q: Lang α}:
162+
null (or P Q) <-> ((null P) \/ (null Q)) := by
163+
rw [null_or]
164+
145165
def null_and {α: Type} {P Q: Lang α}:
146166
null (and P Q) = ((null P) /\ (null Q)) :=
147167
rfl
@@ -170,6 +190,14 @@ def null_star {α: Type} {P: Lang α}:
170190
· intro l hl
171191
cases hl
172192

193+
def null_iff_star {α: Type} {P: Lang α}:
194+
null (star P) <-> True := by
195+
rw [null_star]
196+
197+
def null_if_star {α: Type} {P: Lang α}:
198+
null (star P) :=
199+
null_iff_star.mpr True.intro
200+
173201
def derive_emptyset {α: Type} {a: α}:
174202
(derive emptyset a) = emptyset :=
175203
rfl
@@ -293,17 +321,17 @@ inductive starplus {α: Type} (R: Lang α): Lang α where
293321
-> starplus R qs
294322
-> starplus R w
295323

296-
theorem star_is_starplus: ∀ {α: Type} (R: Lang α) (w: List α),
297-
star R w -> starplus R w := by
298-
intro α R w
324+
theorem star_is_starplus: ∀ {α: Type} (R: Lang α) (xs: List α),
325+
star R xs -> starplus R xs := by
326+
intro α R xs
299327
unfold star
300328
intro s
301329
match s with
302330
| Exists.intro ws (And.intro sl sr) =>
303331
clear s
304332
rw [sr]
305333
clear sr
306-
clear w
334+
clear xs
307335
induction ws with
308336
| nil =>
309337
simp
@@ -319,6 +347,37 @@ theorem star_is_starplus: ∀ {α: Type} (R: Lang α) (w: List α),
319347
· assumption
320348
· assumption
321349

350+
theorem starplus_is_star: ∀ {α: Type} (R: Lang α) (xs: List α),
351+
starplus R xs -> star R xs := by
352+
intro α R xs
353+
intro hs
354+
induction xs with
355+
| nil =>
356+
simp
357+
exists []
358+
apply And.intro ?_ (by simp)
359+
apply All.nil
360+
| cons x' xs' ih =>
361+
cases hs with
362+
| more ps qs _ xxspsqs Rps sRqs =>
363+
unfold star
364+
have hxs := list_split_cons (x' :: xs')
365+
cases hxs with
366+
| inl h =>
367+
contradiction
368+
| inr h =>
369+
cases h with
370+
| intro x h =>
371+
cases h with
372+
| intro xs h =>
373+
cases h with
374+
| intro ys h =>
375+
rw [h]
376+
have hys := list_split_flatten ys
377+
cases hys with
378+
| intro yss hyss =>
379+
sorry
380+
322381
inductive starcons {α: Type} (R: Lang α): Lang α where
323382
| zero: starcons R []
324383
| more: ∀ (p: α) (ps qs w: List α),
@@ -395,8 +454,8 @@ theorem star_is_starcons: ∀ {α: Type} (R: Lang α) (xs: List α),
395454
| intro h2l h2r =>
396455
sorry
397456

398-
def derive_iff_star {α: Type} {a: α} {P: Lang α} {w: List α}:
399-
(derive (star P) a) w <-> (concat (derive P a) (star P)) w := by
457+
def derive_iff_star {α: Type} {x: α} {R: Lang α} {xs: List α}:
458+
(derive (star R) x) xs <-> (concat (derive R x) (star R)) xs := by
400459
refine Iff.intro ?toFun ?invFun
401460
case toFun =>
402461
sorry

Katydid/Regex/Regex.lean

+2-2
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ def derive [DecidableEq α] (r: Regex α) (a: α): Regex α :=
9797
match r with
9898
| Regex.emptyset => Regex.emptyset
9999
| Regex.emptystr => Regex.emptyset
100-
| Regex.char c => Regex.onlyif (a == c) Regex.emptystr
100+
| Regex.char c => onlyif (a == c) Regex.emptystr
101101
| Regex.or x y => Regex.or (derive x a) (derive y a)
102102
| Regex.concat x y =>
103103
Regex.or
104104
(Regex.concat (derive x a) y)
105-
(Regex.onlyif (null x) (derive y a))
105+
(onlyif (null x) (derive y a))
106106
| Regex.star x =>
107107
Regex.concat (derive x a) (Regex.star x)

Katydid/Std/Decidable.lean

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
namespace Decidable
2+
3+
def or {α β: Prop} (a: Decidable α) (b: Decidable β): Decidable (α \/ β) :=
4+
match (a, b) with
5+
| (Decidable.isFalse a, Decidable.isFalse b) =>
6+
Decidable.isFalse (fun ab =>
7+
match ab with
8+
| Or.inl sa => a sa
9+
| Or.inr sb => b sb
10+
)
11+
| (Decidable.isTrue a, Decidable.isFalse _) =>
12+
Decidable.isTrue (Or.inl a)
13+
| (_, Decidable.isTrue b) =>
14+
Decidable.isTrue (Or.inr b)
15+
16+
def and {α β: Prop} (a : Decidable α) (b : Decidable β) : Decidable (α /\ β) :=
17+
match a with
18+
| isTrue ha =>
19+
match b with
20+
| isTrue hb => isTrue ⟨ha, hb⟩
21+
| isFalse hb => isFalse (fun h => hb (And.right h))
22+
| isFalse ha =>
23+
isFalse (fun h => ha (And.left h))
24+
25+
def map' {α β: Prop} (ab: α -> β) (ba: β -> α) (a: Decidable α): Decidable β :=
26+
match a with
27+
| Decidable.isTrue a =>
28+
Decidable.isTrue (ab a)
29+
| Decidable.isFalse nota =>
30+
Decidable.isFalse (nota ∘ ba)
31+
32+
def map {α β: Prop} (ab: α <-> β) (a: Decidable α): Decidable β :=
33+
map' ab.mp ab.mpr a

Katydid/Std/Lists.lean

+9
Original file line numberDiff line numberDiff line change
@@ -981,3 +981,12 @@ theorem list_split_cons {α: Type} (xs: List α):
981981
simp only [cons_append, cons.injEq, true_and]
982982
exists []
983983
exists ys
984+
985+
theorem list_split_flatten {α: Type} (zs: List α):
986+
∃ (zss: List (List α)), zs = zss.flatten :=
987+
match zs with
988+
| nil => by
989+
exists []
990+
| cons x ys => by
991+
exists [[x], ys]
992+
simp

0 commit comments

Comments
 (0)