2 (** {1 Decision of regular expression membership} *)
4 (** Decision algorithm based on residuals *)
10 val predicate eq (x y : char)
11 ensures { result <-> x = y }
13 clone regexp.Regexp with type char = char
18 let rec accepts_epsilon (r: regexp) : bool
20 ensures { result <-> mem empty r }
25 | Alt r1 r2 -> accepts_epsilon r1 || accepts_epsilon r2
26 | Concat r1 r2 -> accepts_epsilon r1 && accepts_epsilon r2
30 lemma inversion_mem_star_gen :
32 w' = cons c w /\ r' = Star r ->
34 exists w1 w2. w = w1 ++ w2 /\ mem (cons c w1) r /\ mem w2 r'
36 lemma inversion_mem_star :
37 forall c w r. mem (cons c w) (Star r) ->
38 exists w1 w2. w = w1 ++ w2 /\ mem (cons c w1) r /\ mem w2 (Star r)
40 (** `residual r c` denotes the set of words `w` such that `mem c.w r` *)
41 let rec residual (r: regexp) (c: char) : regexp
43 ensures { forall w. mem w result <-> mem (cons c w) r }
47 | Char c' -> if eq c c' then Epsilon else Empty
48 | Alt r1 r2 -> alt (residual r1 c) (residual r2 c)
50 let r1' = residual r1 c in
51 let r2' = residual r2 c in
52 if accepts_epsilon r1 then (
55 mem w (Alt (Concat r1' r2) r2') <->
58 alt (concat r1' r2) r2')
60 | Star r1 -> concat (residual r1 c) r
63 let decide_mem (w: word) (r: regexp) : bool
64 ensures { result <-> mem w r }
66 for i = 0 to length w - 1 do
67 invariant { mem w[i..] r' <-> mem w r }
68 r' <- residual r' w[i]
82 type ostring = abstract {
85 meta coercion function str
87 val ([]) (s: ostring) (i: int63) : char
88 requires { 0 <= i < length s }
89 ensures { result = get s i }
91 val partial length (s: ostring) : int63
92 ensures { result = length s >= 0 }
94 let partial decide (w: ostring) (r: regexp) : bool
95 ensures { result <-> mem w r }
97 for i = 0 to length w - 1 do
98 invariant { mem w[i..] r' <-> mem w r }
99 r' <- residual r' w[i]