Files
why3/examples/dfa_example.mlw

90 lines
2.4 KiB
Plaintext
Raw Permalink Normal View History

2013-01-16 11:25:41 +01:00
module DfaExample
(** regular expressions on alphabet {0,1} *)
type char = Zero | One
clone regexp.Regexp with type char = char
2013-01-16 11:25:41 +01:00
(** mutable input stream *)
use option.Option
2024-03-20 18:13:00 +01:00
use seq.Seq
2013-01-16 11:25:41 +01:00
2024-03-20 18:13:00 +01:00
type stream = abstract { mutable state: seq char }
2013-01-16 11:25:41 +01:00
val input: stream
val get () : option char writes {input}
2024-03-20 18:13:00 +01:00
ensures {
if old input.state = empty then
old input.state = input.state = empty /\ result = None
else
input.state = (old input.state)[1..] /\
result = Some ((old input.state)[0]) }
2013-01-16 11:25:41 +01:00
(** 2-state DFA to recognize words ending with a 1, that is (0|1)*1
--------- 1 -------->
+- state 1 state 2-------+
| ^ <-------- 0 --------- ^ |
+-0--/ \----- 1 --+
*)
2014-02-03 14:38:59 +01:00
constant r0 : regexp = Star (Alt (Char Zero) (Char One))
constant r1 : regexp = Concat r0 (Char One)
2013-01-16 11:25:41 +01:00
constant r2 : regexp = Alt Epsilon r1
2024-03-20 18:13:00 +01:00
lemma empty_notin_r1: not (mem empty r1)
2013-01-16 11:25:41 +01:00
2024-03-20 18:13:00 +01:00
let rec lemma all_in_r0 (w: word)
variant { length w }
2014-02-03 14:38:59 +01:00
ensures { mem w r0 }
2024-03-20 18:13:00 +01:00
= if w = empty then ()
else (
assert { w = (cons w[0] empty) ++ w[1..] };
all_in_r0 w[1..])
2014-02-03 14:38:59 +01:00
2015-10-22 15:30:14 +02:00
lemma words_in_r1_end_with_one:
2024-03-20 18:13:00 +01:00
forall w: word.
mem w r1 <-> exists w': word. w = w' ++ cons One empty
2013-01-16 11:25:41 +01:00
2024-03-20 18:13:00 +01:00
lemma words_in_r1_suffix_in_r1:
forall c c': char. forall w: word.
mem (cons c (cons c' w)) r1 -> mem (cons c' w) r1
2015-10-22 15:30:14 +02:00
2024-03-20 18:13:00 +01:00
lemma zero_w_in_r1: forall w: word. mem w r1 <-> mem (cons Zero w) r1
lemma zero_w_in_r2: forall w: word. mem w r1 <-> mem (cons Zero w) r2
let lemma one_w_in_r1 (w: word)
ensures { mem w r2 <-> mem (cons One w) r1 }
= if length w = 0 then ()
else (
let c = w[0] in
let r = w[1..] in
2015-10-22 15:30:14 +02:00
assert { mem w r2 -> mem w r1 };
2024-03-20 18:13:00 +01:00
assert { mem (cons One (cons c r)) r1 -> mem w r1 }
)
2013-01-16 11:25:41 +01:00
2024-03-20 18:13:00 +01:00
lemma one_w_in_r2: forall w: word. mem w r2 <-> mem (cons One w) r2
2013-01-16 11:25:41 +01:00
let rec astate1 () : bool
2014-02-03 14:38:59 +01:00
variant { length input.state }
2024-03-20 18:13:00 +01:00
ensures { result <-> input.state = empty /\ mem (old input.state) r1 }
= match get () with
| None -> false
2013-01-16 11:25:41 +01:00
| Some Zero -> astate1 ()
| Some One -> astate2 ()
end
with astate2 () : bool
2014-02-03 14:38:59 +01:00
variant { length input.state }
2024-03-20 18:13:00 +01:00
ensures { result <-> input.state = empty /\ mem (old input.state) r2 }
= match get () with
| None -> true
2013-01-16 11:25:41 +01:00
| Some Zero -> astate1 ()
| Some One -> astate2 ()
end
end