121 lines
3.2 KiB
Coq
121 lines
3.2 KiB
Coq
Require Import String.
|
||
Open Scope string.
|
||
Declare Scope re_scope.
|
||
Delimit Scope re_scope with re.
|
||
(* dot, plus, question mark, ranges of repetitions, ^, $ *)
|
||
Definition char := string.
|
||
Inductive re : Type :=
|
||
| Atom : char -> re
|
||
(*| Star : re -> re*)
|
||
| Concat : re -> re -> re
|
||
| Alt : re -> re -> re
|
||
| Epsilon : re
|
||
| Dot : re.
|
||
(*
|
||
Definition Plus (a:re) : re := Alt a Epsilon.
|
||
Definition Optional (a:re) : re := Concat a a.
|
||
Fixpoint exactly_n (n:nat) (a:re) : re :=
|
||
match n with
|
||
| O => Epsilon
|
||
| S n' => Concat a (exactly_n n' a)
|
||
end.
|
||
Definition atleast_n (n:nat) (a:re) : re :=
|
||
Concat (exactly_n n a) (Star a).
|
||
Fixpoint atmost_n (n:nat) (a:re) : re :=
|
||
match n with
|
||
| O => Epsilon
|
||
| S n' => Alt (atmost_n n' a) (exactly_n n a)
|
||
end.
|
||
|
||
Definition exactly_ij (start stop:nat) (a:re) : re :=
|
||
Concat (exactly_n start a) (atmost_n (stop-start-1) a).
|
||
|
||
Infix ";" := Concat (at level 50) : re_scope.
|
||
Infix "│" := Alt (at level 50) : re_scope.
|
||
Notation "'۰'" := Dot (at level 30) : re_scope.
|
||
Notation "'ε'" := Epsilon (at level 30) : re_scope.
|
||
Notation " a '𐊛'" := (Plus a) (at level 50) : re_scope.
|
||
Notation " a '٭'" := (Star a) (at level 50) : re_scope.
|
||
|
||
Notation " '❴' count '❵' a " := (exactly_n count a)
|
||
(at level 80, count at next level) : signal_scope.
|
||
Notation " a '❴' count '❵' " := (exactly_n count a)
|
||
(at level 80, count at next level) : signal_scope.
|
||
Notation " a '❨' ':' stop '❩' " := (atmost_n stop a)
|
||
(at level 80) : signal_scope.
|
||
Notation " a '❲' start ':' stop '❳' " :=
|
||
(exactly_ij start stop a)
|
||
(at level 80, start at next level) : signal_scope.
|
||
|
||
Check (Dot │ ε)%re.
|
||
Fail Check (Dot❴2❵)%re.
|
||
Fail Check (❴2❵ Dot)%re.
|
||
*)
|
||
|
||
(* Indexing starts from zero. Empty string on invalid index. *)
|
||
Definition stridx (i:nat) (s:string) : char :=
|
||
String.substring i 1 s.
|
||
Definition strdrop (n:nat) (s:string) : string :=
|
||
String.substring n ((String.length s)-1) s.
|
||
Search (nat -> string -> string).
|
||
|
||
Fixpoint reDenote (r:re) : string -> Prop :=
|
||
match r with
|
||
| Atom ch => fun s:string => stridx 0 s = ch
|
||
| Epsilon => fun s:string => True (* TODO *)
|
||
| Dot => fun s:string => stridx 0 s = stridx 0 s
|
||
| Concat r1 r2 => fun s:string =>
|
||
((reDenote r1) s) /\ ((reDenote r2) (strdrop 1 s))
|
||
| Alt r1 r2 => fun s:string =>
|
||
((reDenote r1) s) \/ ((reDenote r2) s)
|
||
end.
|
||
Compute (reDenote (Alt (Atom "a") (Atom "b"))) "a".
|
||
|
||
(*
|
||
Infix ":-" := (Concat) (at level 50) : re_scope.
|
||
Infix "‖" := (Alt) (at level 51) : re_scope. (* and has less precedence *)
|
||
Compute ((Atom "a") :- (Atom "b"))%re.
|
||
Compute ((Atom "h") :- (Atom "e") :- (Atom "l"))%re.
|
||
*)
|
||
Compute
|
||
(reDenote (Concat (Concat (Concat (Concat (Atom "h") (Atom "e")) Dot) Dot) (Atom "o"))) "hello".
|
||
|
||
|
||
Goal
|
||
(reDenote (Alt (Atom "a") (Atom "b"))) "a".
|
||
Proof.
|
||
simpl.
|
||
unfold stridx.
|
||
simpl.
|
||
auto.
|
||
Qed.
|
||
|
||
Goal
|
||
(reDenote (Concat (Atom "a") (Atom "b"))) "ab".
|
||
Proof.
|
||
simpl.
|
||
unfold stridx.
|
||
simpl.
|
||
auto.
|
||
Qed.
|
||
|
||
|
||
Goal
|
||
(reDenote (Concat (Concat (Concat (Concat (Atom "h") (Atom "e")) Dot) Dot) (Atom "o"))) "hello".
|
||
Proof.
|
||
simpl.
|
||
split.
|
||
split.
|
||
split.
|
||
split.
|
||
unfold stridx.
|
||
now simpl.
|
||
unfold strdrop.
|
||
unfold stridx.
|
||
now simpl.
|
||
now simpl.
|
||
now simpl.
|
||
unfold strdrop.
|
||
unfold stridx.
|
||
simpl.
|