Dyck words example completed (thanks to Martin)

parent 87fe8329
(** Checking that a word is a Dyck word
Authors: Martin Clochard (École Normale Supérieure)
Jean-Christophe Filliâtre (CNRS)
*)
theory Dyck theory Dyck
use export list.List use export list.List
...@@ -19,12 +25,6 @@ theory Dyck ...@@ -19,12 +25,6 @@ theory Dyck
lemma dyck_word_first: lemma dyck_word_first:
forall w: word. dyck w -> forall w: word. dyck w ->
match w with Nil -> true | Cons c _ -> c = L end match w with Nil -> true | Cons c _ -> c = L end
(*(* Concatenation of dyck words is a dyck word. *)
lemma dyck_concat : forall w1 w2:word. dyck w1 -> dyck w2 -> dyck (w1 ++ w2)
lemma dyck_decomp:
forall w1 w2: word. dyck (w1 ++ w2) -> dyck w1 -> dyck w2*)
end end
...@@ -38,10 +38,10 @@ module Check ...@@ -38,10 +38,10 @@ module Check
(* A fall of a word is a decomposition p ++ s with p a dyck word (* A fall of a word is a decomposition p ++ s with p a dyck word
and s a word not starting by L. *) and s a word not starting by L. *)
predicate fall (p s:word) = dyck p /\ predicate fall (p s: word) = dyck p /\
match s with Cons L _ -> false | _ -> true end match s with Cons L _ -> false | _ -> true end
let rec lemma same_prefix (p s s2:word) : unit let rec lemma same_prefix (p s s2: word) : unit
requires { p ++ s = p ++ s2 } requires { p ++ s = p ++ s2 }
ensures { s = s2 } ensures { s = s2 }
variant { p } variant { p }
...@@ -49,27 +49,31 @@ module Check ...@@ -49,27 +49,31 @@ module Check
(* Compute the fall decomposition, if it exists. As a side-effect, (* Compute the fall decomposition, if it exists. As a side-effect,
prove its unicity. *) prove its unicity. *)
let rec is_dyck_rec (ghost p:ref word) (w: word) : word let rec is_dyck_rec (ghost p: ref word) (w: word) : word
ensures { w = !p ++ result && fall !p result && ensures { w = !p ++ result && fall !p result &&
(forall p2 s: word. w = p2 ++ s /\ fall p2 s -> p2 = !p && s = result) } (forall p2 s: word. w = p2 ++ s /\ fall p2 s -> p2 = !p && s = result) }
writes { p } writes { p }
raises { Failure -> (forall p s:word. w = p ++ s -> not fall p s) } raises { Failure -> forall p s: word. w = p ++ s -> not fall p s }
variant { length w } variant { length w }
= =
match w with match w with
| Cons L w0 -> let ghost p0 = ref Nil in | Cons L w0 ->
let ghost p0 = ref Nil in
match is_dyck_rec p0 w0 with match is_dyck_rec p0 w0 with
| Cons _ w1 -> assert { forall p s p1 p2:word. | Cons _ w1 ->
dyck p /\ w = p ++ s /\ dyck p1 /\ dyck p2 /\ assert { forall p s p1 p2: word.
p = Cons L (p1 ++ Cons R p2) -> dyck p /\ w = p ++ s /\ dyck p1 /\ dyck p2 /\
w0 = p1 ++ (Cons R (p2 ++ s)) && p1 = !p0 && w1 = p2 ++ s }; p = Cons L (p1 ++ Cons R p2) ->
w0 = p1 ++ (Cons R (p2 ++ s)) && p1 = !p0 && w1 = p2 ++ s };
let ghost p1 = ref Nil in let ghost p1 = ref Nil in
let w = is_dyck_rec p1 w1 in let w = is_dyck_rec p1 w1 in
p := Cons L (!p0 ++ Cons R !p1); p := Cons L (!p0 ++ Cons R !p1);
w w
| _ -> raise Failure | _ ->
raise Failure
end end
| _ -> p := Nil; w | _ ->
p := Nil; w
end end
let is_dyck (w: word) : bool let is_dyck (w: word) : bool
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment