4 (** regular expressions on alphabet {0,1} *)
8 clone regexp.Regexp with type char = char
10 (** mutable input stream *)
15 type stream = abstract { mutable state: seq char }
19 val get () : option char writes {input}
21 if old input.state = empty then
22 old input.state = input.state = empty /\ result = None
24 input.state = (old input.state)[1..] /\
25 result = Some ((old input.state)[0]) }
27 (** 2-state DFA to recognize words ending with a 1, that is (0|1)*1
30 +- state 1 state 2-------+
31 | ^ <-------- 0 --------- ^ |
35 constant r0 : regexp = Star (Alt (Char Zero) (Char One))
36 constant r1 : regexp = Concat r0 (Char One)
37 constant r2 : regexp = Alt Epsilon r1
39 lemma empty_notin_r1: not (mem empty r1)
41 let rec lemma all_in_r0 (w: word)
44 = if w = empty then ()
46 assert { w = (cons w[0] empty) ++ w[1..] };
49 lemma words_in_r1_end_with_one:
51 mem w r1 <-> exists w': word. w = w' ++ cons One empty
53 lemma words_in_r1_suffix_in_r1:
54 forall c c': char. forall w: word.
55 mem (cons c (cons c' w)) r1 -> mem (cons c' w) r1
57 lemma zero_w_in_r1: forall w: word. mem w r1 <-> mem (cons Zero w) r1
58 lemma zero_w_in_r2: forall w: word. mem w r1 <-> mem (cons Zero w) r2
59 let lemma one_w_in_r1 (w: word)
60 ensures { mem w r2 <-> mem (cons One w) r1 }
61 = if length w = 0 then ()
65 assert { mem w r2 -> mem w r1 };
66 assert { mem (cons One (cons c r)) r1 -> mem w r1 }
69 lemma one_w_in_r2: forall w: word. mem w r2 <-> mem (cons One w) r2
71 let rec astate1 () : bool
72 variant { length input.state }
73 ensures { result <-> input.state = empty /\ mem (old input.state) r1 }
76 | Some Zero -> astate1 ()
77 | Some One -> astate2 ()
80 with astate2 () : bool
81 variant { length input.state }
82 ensures { result <-> input.state = empty /\ mem (old input.state) r2 }
85 | Some Zero -> astate1 ()
86 | Some One -> astate2 ()