a variant of list reversal using sequences instead of lists

parent e8d1217c
......@@ -168,10 +168,178 @@ module InPlaceRev
end
(** Using sequences instead of lists *)
module InPlaceRevSeq
use import int.Int
use map.Map
use import seq.Seq
use import ref.Ref
predicate mem (x: 'a) (s: seq 'a) =
exists i. 0 <= i < length s /\ s[i] = x
predicate disjoint (s1: seq 'a) (s2: seq 'a) =
forall x:'a. not (mem x s1 /\ mem x s2)
predicate no_repet (s: seq 'a) =
forall i. 0 <= i < length s -> not (mem s[i] s[i+1 ..])
let rec ghost mem_decomp (x: 'a) (s: seq 'a) : (seq 'a, seq 'a)
requires { mem x s }
variant { length s }
returns { (s1,s2) -> s == s1 ++ cons x s2 }
= if length s = 0 then
absurd
else
let h = s[0] in
let t = s[1 .. ] in
if h = x then (empty, t)
else let (r1, r2) = mem_decomp x t in (cons h r1, r2)
type loc
function null: loc
type memory 'a = ref (Map.map loc 'a)
val acc (field: memory 'a) (l:loc) : 'a
requires { l <> null }
reads { field }
ensures { result = Map.get !field l }
val upd (field: memory 'a) (l: loc) (v: 'a) : unit
requires { l <> null }
writes { field }
ensures { !field = Map.set (old !field) l v }
type next = Map.map loc loc
predicate list_seg (next: next) (p: loc) (s: seq loc) (q: loc) =
let n = length s in
(forall i. 0 <= i < n -> s[i] <> null) /\
( (p = q /\ n = 0)
\/ (1 <= n /\ s[0] = p /\ Map.get next s[n-1] = q /\
forall i. 0 <= i < n-1 -> Map.get next s[i] = s[i+1]))
lemma list_seg_frame_ext:
forall next1 next2: next, p q r v: loc, pM: seq loc.
list_seg next1 p pM r ->
next2 = Map.set next1 q v ->
not (mem q pM) ->
list_seg next2 p pM r
lemma non_empty_seq:
forall s: seq 'a. length s > 0 ->
s == cons s[0] s[1 .. ]
let rec lemma list_seg_functional (next: next) (l1 l2: seq loc) (p: loc)
requires { list_seg next p l1 null }
requires { list_seg next p l2 null }
variant { length l1 }
ensures { l1 == l2 }
= if length l1 > 0 && length l2 > 0 then begin
assert { l1[0] = l2[0] = p };
list_seg_functional next l1[1 ..] l2[1 ..] (Map.get next p)
end
let rec lemma list_seg_tail (next: next) (l1: seq loc) (p q: loc)
requires { list_seg next p l1 q }
requires { length l1 > 0 }
variant { length l1 }
ensures { list_seg next (Map.get next p)l1[1 .. ] q }
= if length l1 > 1 then
list_seg_tail next l1[1 ..] (Map.get next p) q
let rec lemma list_seg_append (next: next) (p q r: loc) (pM qM: seq loc)
requires { list_seg next p pM q }
requires { list_seg next q qM r }
variant { length pM }
ensures { list_seg next p (pM ++ qM) r }
= if length pM > 0 then
list_seg_append next (Map.get next p) q r pM[1 .. ] qM
lemma seq_tail_append:
forall l1 l2: seq 'a.
length l1 > 0 -> (l1 ++ l2)[1 .. ] == l1[1 .. ] ++ l2
let rec lemma list_seg_prefix (next: next) (l1 l2: seq loc) (p q: loc)
requires { list_seg next p (l1 ++ cons q l2) null }
variant { length l1 }
ensures { list_seg next p l1 q }
= if length l1 > 0 then begin
list_seg_tail next (l1 ++ cons q l2) p null;
list_seg_prefix next l1[1 ..] l2 (Map.get next p) q
end
let rec lemma list_seg_sublistl (next: next) (l1 l2: seq loc) (p q: loc)
requires { list_seg next p (l1 ++ cons q l2) null }
variant { length l1 }
ensures { list_seg next q (cons q l2) null }
= assert { list_seg next p l1 q };
if length l1 > 0 then begin
list_seg_tail next l1 p q;
list_seg_sublistl next l1[1 ..] l2 (Map.get next p) q
end
lemma get_tail:
forall i: int, s: seq 'a. 0 <= i < length s - 1 -> s[1 .. ][i] = s[i+1]
lemma tail_suffix:
forall i: int, s: seq 'a. 0 <= i < length s -> s[1 .. ][i .. ] == s[i+1 ..]
let rec lemma list_seg_no_repet (next: next) (p: loc) (pM: seq loc)
requires { list_seg next p pM null }
variant { length pM }
ensures { no_repet pM }
= if length pM > 0 then begin
let h = pM[0] in
let t = pM[1 .. ] in
if mem h t then
(* absurd case *)
let (l1,l2) = mem_decomp h t in
list_seg_sublistl next (cons h l1) l2 p h;
list_seg_functional next pM (cons h l2) p;
assert { length pM > length (cons h l2) }
else begin
assert { not (mem pM[0] pM[0+1 .. ]) };
list_seg_no_repet next (Map.get next p) t;
assert { forall i. 1 <= i < length pM -> not (mem pM[i] pM[i+1 .. ]) }
end
end
val next : ref next
let app (l1 l2: loc) (ghost l1M l2M: seq loc) : loc
requires { list_seg !next l1 l1M null }
requires { list_seg !next l2 l2M null }
requires { disjoint l1M l2M }
ensures { list_seg !next result (l1M ++ l2M) null }
=
if l1 = null then l2 else
let p = ref l1 in
let ghost pM = ref l1M in
let ghost l1pM = ref (empty : seq loc) in
while acc next !p <> null do
invariant { !p <> null }
invariant { list_seg !next l1 !l1pM !p }
invariant { list_seg !next !p !pM null }
invariant { !l1pM ++ !pM == l1M }
invariant { disjoint !l1pM !pM }
variant { length !pM }
assert { length !pM > 0 };
let t = !pM[ 1 .. ] in
l1pM := !l1pM ++ cons !p empty;
pM := t;
p := acc next !p
done;
upd next !p l2;
assert { list_seg !next l1 !l1pM !p };
assert { list_seg !next !p (cons !p empty) l2 };
assert { list_seg !next l2 l2M null };
l1
end
(*
Local Variables:
......
......@@ -2,16 +2,19 @@
<!DOCTYPE why3session PUBLIC "-//Why3//proof session v5//EN"
"http://why3.lri.fr/why3session.dtd">
<why3session shape_version="4">
<prover id="0" name="CVC4" version="1.4" timelimit="5" memlimit="1000"/>
<prover id="0" name="CVC4" version="1.4" timelimit="10" memlimit="1000"/>
<prover id="1" name="Z3" version="4.3.1" timelimit="5" memlimit="1000"/>
<prover id="2" name="Alt-Ergo" version="0.95.2" timelimit="5" memlimit="1000"/>
<file name="../linked_list_rev.mlw" expanded="true">
<theory name="Disjoint" sum="9c582db93bf8e816b74d113c3748231e" expanded="true">
<prover id="3" name="Alt-Ergo" version="0.99.1" timelimit="10" memlimit="1000"/>
<prover id="4" name="Z3" version="4.3.3" timelimit="10" memlimit="1000"/>
<prover id="5" name="Z3" version="4.3.2" timelimit="10" memlimit="1000"/>
<file name="../linked_list_rev.mlw">
<theory name="Disjoint" sum="9c582db93bf8e816b74d113c3748231e">
<goal name="WP_parameter mem_decomp" expl="VC for mem_decomp">
<proof prover="2"><result status="valid" time="0.02" steps="54"/></proof>
</goal>
</theory>
<theory name="InPlaceRev" sum="6f1515477f42e0629a5741cced45aef5" expanded="true">
<theory name="InPlaceRev" sum="6f1515477f42e0629a5741cced45aef5">
<goal name="WP_parameter list_seg_frame_ext" expl="VC for list_seg_frame_ext">
<proof prover="2"><result status="valid" time="0.16" steps="278"/></proof>
</goal>
......@@ -19,7 +22,7 @@
<proof prover="2"><result status="valid" time="0.10" steps="326"/></proof>
</goal>
<goal name="WP_parameter list_seg_sublistl" expl="VC for list_seg_sublistl">
<proof prover="0"><result status="valid" time="0.29"/></proof>
<proof prover="0" timelimit="5"><result status="valid" time="0.29"/></proof>
</goal>
<goal name="WP_parameter list_seg_no_repet" expl="VC for list_seg_no_repet">
<proof prover="2"><result status="valid" time="0.72" steps="241"/></proof>
......@@ -27,8 +30,8 @@
<goal name="WP_parameter list_seg_append" expl="VC for list_seg_append">
<proof prover="2"><result status="valid" time="0.48" steps="712"/></proof>
</goal>
<goal name="WP_parameter app" expl="VC for app" expanded="true">
<transf name="split_goal_wp" expanded="true">
<goal name="WP_parameter app" expl="VC for app">
<transf name="split_goal_wp">
<goal name="WP_parameter app.1" expl="1. postcondition">
<proof prover="2"><result status="valid" time="0.03" steps="40"/></proof>
</goal>
......@@ -87,7 +90,276 @@
<proof prover="2"><result status="valid" time="0.65" steps="235"/></proof>
</goal>
<goal name="WP_parameter app.20" expl="20. postcondition">
<proof prover="0"><result status="valid" time="0.23"/></proof>
<proof prover="0" timelimit="5"><result status="valid" time="0.23"/></proof>
</goal>
</transf>
</goal>
</theory>
<theory name="InPlaceRevSeq" sum="068ee82c25a0ff944ca4fedde3b37f6b">
<goal name="WP_parameter mem_decomp" expl="VC for mem_decomp">
<transf name="split_goal_wp">
<goal name="WP_parameter mem_decomp.1" expl="1. unreachable point">
<proof prover="0"><result status="valid" time="0.03"/></proof>
<proof prover="3"><result status="valid" time="0.02" steps="5"/></proof>
</goal>
<goal name="WP_parameter mem_decomp.2" expl="2. postcondition">
<proof prover="3"><result status="valid" time="0.04" steps="42"/></proof>
</goal>
<goal name="WP_parameter mem_decomp.3" expl="3. variant decrease">
<proof prover="0"><result status="valid" time="0.03"/></proof>
<proof prover="3"><result status="valid" time="0.01" steps="13"/></proof>
</goal>
<goal name="WP_parameter mem_decomp.4" expl="4. precondition">
<transf name="inline_goal">
<goal name="WP_parameter mem_decomp.4.1" expl="1. precondition">
<proof prover="5"><result status="valid" time="3.64"/></proof>
</goal>
</transf>
</goal>
<goal name="WP_parameter mem_decomp.5" expl="5. postcondition">
<proof prover="5"><result status="valid" time="1.09"/></proof>
</goal>
</transf>
</goal>
<goal name="list_seg_frame_ext">
<proof prover="3"><result status="valid" time="0.02" steps="28"/></proof>
</goal>
<goal name="non_empty_seq">
<proof prover="3"><result status="valid" time="0.02" steps="22"/></proof>
</goal>
<goal name="WP_parameter list_seg_functional" expl="VC for list_seg_functional">
<transf name="split_goal_wp">
<goal name="WP_parameter list_seg_functional.1" expl="1. assertion">
<proof prover="3"><result status="valid" time="0.02" steps="13"/></proof>
</goal>
<goal name="WP_parameter list_seg_functional.2" expl="2. variant decrease">
<proof prover="4"><result status="valid" time="0.02"/></proof>
</goal>
<goal name="WP_parameter list_seg_functional.3" expl="3. precondition">
<proof prover="4"><result status="valid" time="0.33"/></proof>
</goal>
<goal name="WP_parameter list_seg_functional.4" expl="4. precondition">
<proof prover="4"><result status="valid" time="0.22"/></proof>
</goal>
<goal name="WP_parameter list_seg_functional.5" expl="5. postcondition">
<proof prover="5"><result status="valid" time="0.02"/></proof>
</goal>
<goal name="WP_parameter list_seg_functional.6" expl="6. postcondition">
<proof prover="3"><result status="valid" time="0.02" steps="26"/></proof>
</goal>
</transf>
</goal>
<goal name="WP_parameter list_seg_tail" expl="VC for list_seg_tail">
<transf name="split_goal_wp">
<goal name="WP_parameter list_seg_tail.1" expl="1. variant decrease">
<proof prover="3" timelimit="80"><result status="valid" time="0.01" steps="17"/></proof>
</goal>
<goal name="WP_parameter list_seg_tail.2" expl="2. precondition">
<proof prover="3" timelimit="80"><result status="valid" time="0.12" steps="192"/></proof>
</goal>
<goal name="WP_parameter list_seg_tail.3" expl="3. precondition">
<proof prover="3" timelimit="80"><result status="valid" time="0.03" steps="17"/></proof>
</goal>
<goal name="WP_parameter list_seg_tail.4" expl="4. postcondition">
<proof prover="3" timelimit="80"><result status="valid" time="0.02" steps="6"/></proof>
</goal>
<goal name="WP_parameter list_seg_tail.5" expl="5. postcondition">
<proof prover="3" timelimit="80"><result status="valid" time="0.04" steps="24"/></proof>
</goal>
</transf>
</goal>
<goal name="WP_parameter list_seg_append" expl="VC for list_seg_append">
<proof prover="5"><result status="valid" time="5.06"/></proof>
</goal>
<goal name="seq_tail_append">
<proof prover="3"><result status="valid" time="0.05" steps="52"/></proof>
</goal>
<goal name="WP_parameter list_seg_prefix" expl="VC for list_seg_prefix">
<transf name="split_goal_wp">
<goal name="WP_parameter list_seg_prefix.1" expl="1. precondition">
<proof prover="3"><result status="valid" time="0.03" steps="2"/></proof>
</goal>
<goal name="WP_parameter list_seg_prefix.2" expl="2. precondition">
<proof prover="3"><result status="valid" time="0.02" steps="8"/></proof>
</goal>
<goal name="WP_parameter list_seg_prefix.3" expl="3. variant decrease">
<proof prover="3"><result status="valid" time="0.06" steps="22"/></proof>
</goal>
<goal name="WP_parameter list_seg_prefix.4" expl="4. precondition">
<proof prover="3"><result status="valid" time="0.05" steps="60"/></proof>
</goal>
<goal name="WP_parameter list_seg_prefix.5" expl="5. postcondition">
<proof prover="5"><result status="valid" time="3.45"/></proof>
</goal>
<goal name="WP_parameter list_seg_prefix.6" expl="6. postcondition">
<proof prover="3"><result status="valid" time="2.09" steps="1137"/></proof>
<proof prover="5"><result status="valid" time="0.02"/></proof>
</goal>
</transf>
</goal>
<goal name="WP_parameter list_seg_sublistl" expl="VC for list_seg_sublistl">
<transf name="split_goal_wp">
<goal name="WP_parameter list_seg_sublistl.1" expl="1. assertion">
<proof prover="3"><result status="valid" time="0.02" steps="13"/></proof>
</goal>
<goal name="WP_parameter list_seg_sublistl.2" expl="2. precondition">
<proof prover="3"><result status="valid" time="0.02" steps="3"/></proof>
</goal>
<goal name="WP_parameter list_seg_sublistl.3" expl="3. precondition">
<proof prover="3"><result status="valid" time="0.03" steps="3"/></proof>
</goal>
<goal name="WP_parameter list_seg_sublistl.4" expl="4. variant decrease">
<proof prover="3" timelimit="25"><result status="valid" time="0.02" steps="69"/></proof>
</goal>
<goal name="WP_parameter list_seg_sublistl.5" expl="5. precondition">
<proof prover="5"><result status="valid" time="0.02"/></proof>
</goal>
<goal name="WP_parameter list_seg_sublistl.6" expl="6. postcondition">
<proof prover="3" timelimit="25"><result status="valid" time="0.02" steps="6"/></proof>
</goal>
<goal name="WP_parameter list_seg_sublistl.7" expl="7. postcondition">
<proof prover="3" timelimit="25"><result status="valid" time="0.44" steps="529"/></proof>
</goal>
</transf>
</goal>
<goal name="get_tail">
<proof prover="3"><result status="valid" time="0.03" steps="10"/></proof>
</goal>
<goal name="tail_suffix">
<proof prover="3"><result status="valid" time="0.03" steps="39"/></proof>
</goal>
<goal name="WP_parameter list_seg_no_repet" expl="VC for list_seg_no_repet">
<transf name="split_goal_wp">
<goal name="WP_parameter list_seg_no_repet.1" expl="1. precondition">
<proof prover="3"><result status="valid" time="0.02" steps="3"/></proof>
</goal>
<goal name="WP_parameter list_seg_no_repet.2" expl="2. precondition">
<transf name="introduce_premises">
<goal name="WP_parameter list_seg_no_repet.2.1" expl="1. precondition">
<proof prover="0"><result status="valid" time="0.10"/></proof>
</goal>
</transf>
</goal>
<goal name="WP_parameter list_seg_no_repet.3" expl="3. precondition">
<proof prover="3"><result status="valid" time="0.01" steps="6"/></proof>
</goal>
<goal name="WP_parameter list_seg_no_repet.4" expl="4. precondition">
<proof prover="3"><result status="valid" time="0.02" steps="18"/></proof>
</goal>
<goal name="WP_parameter list_seg_no_repet.5" expl="5. assertion">
<proof prover="3"><result status="valid" time="0.11" steps="74"/></proof>
</goal>
<goal name="WP_parameter list_seg_no_repet.6" expl="6. postcondition">
<proof prover="3"><result status="valid" time="0.02" steps="16"/></proof>
</goal>
<goal name="WP_parameter list_seg_no_repet.7" expl="7. assertion">
<proof prover="3" timelimit="70"><result status="valid" time="0.02" steps="3"/></proof>
</goal>
<goal name="WP_parameter list_seg_no_repet.8" expl="8. variant decrease">
<proof prover="3" timelimit="70"><result status="valid" time="0.04" steps="25"/></proof>
</goal>
<goal name="WP_parameter list_seg_no_repet.9" expl="9. precondition">
<proof prover="3" timelimit="70"><result status="valid" time="0.02" steps="5"/></proof>
</goal>
<goal name="WP_parameter list_seg_no_repet.10" expl="10. assertion">
<transf name="inline_trivial">
<goal name="WP_parameter list_seg_no_repet.10.1" expl="1. assertion">
<transf name="inline_goal">
<goal name="WP_parameter list_seg_no_repet.10.1.1" expl="1. assertion">
<proof prover="5"><result status="valid" time="0.04"/></proof>
</goal>
</transf>
</goal>
</transf>
</goal>
<goal name="WP_parameter list_seg_no_repet.11" expl="11. postcondition">
<proof prover="3" timelimit="70"><result status="valid" time="0.03" steps="12"/></proof>
</goal>
<goal name="WP_parameter list_seg_no_repet.12" expl="12. postcondition">
<proof prover="3"><result status="valid" time="0.03" steps="5"/></proof>
</goal>
</transf>
</goal>
<goal name="WP_parameter app" expl="VC for app">
<transf name="split_goal_wp">
<goal name="WP_parameter app.1" expl="1. postcondition">
<proof prover="3"><result status="valid" time="0.04" steps="106"/></proof>
</goal>
<goal name="WP_parameter app.2" expl="2. loop invariant init">
<proof prover="3"><result status="valid" time="0.03" steps="4"/></proof>
</goal>
<goal name="WP_parameter app.3" expl="3. loop invariant init">
<proof prover="3"><result status="valid" time="0.03" steps="14"/></proof>
</goal>
<goal name="WP_parameter app.4" expl="4. loop invariant init">
<proof prover="3"><result status="valid" time="0.02" steps="4"/></proof>
</goal>
<goal name="WP_parameter app.5" expl="5. loop invariant init">
<proof prover="3"><result status="valid" time="0.01" steps="23"/></proof>
</goal>
<goal name="WP_parameter app.6" expl="6. loop invariant init">
<proof prover="3"><result status="valid" time="0.02" steps="19"/></proof>
</goal>
<goal name="WP_parameter app.7" expl="7. precondition">
<proof prover="3"><result status="valid" time="0.02" steps="9"/></proof>
</goal>
<goal name="WP_parameter app.8" expl="8. assertion">
<proof prover="3"><result status="valid" time="0.02" steps="20"/></proof>
</goal>
<goal name="WP_parameter app.9" expl="9. precondition">
<proof prover="3"><result status="valid" time="0.02" steps="13"/></proof>
</goal>
<goal name="WP_parameter app.10" expl="10. loop invariant preservation">
<proof prover="3"><result status="valid" time="0.02" steps="14"/></proof>
</goal>
<goal name="WP_parameter app.11" expl="11. loop invariant preservation">
<proof prover="5"><result status="valid" time="0.10"/></proof>
</goal>
<goal name="WP_parameter app.12" expl="12. loop invariant preservation">
<proof prover="3"><result status="valid" time="0.02" steps="16"/></proof>
</goal>
<goal name="WP_parameter app.13" expl="13. loop invariant preservation">
<transf name="introduce_premises">
<goal name="WP_parameter app.13.1" expl="1. loop invariant preservation">
<transf name="inline_goal">
<goal name="WP_parameter app.13.1.1" expl="1. loop invariant preservation">
<transf name="split_goal_wp">
<goal name="WP_parameter app.13.1.1.1" expl="1. VC for app">
<proof prover="3"><result status="valid" time="0.14" steps="123"/></proof>
</goal>
<goal name="WP_parameter app.13.1.1.2" expl="2. VC for app">
<proof prover="5"><result status="valid" time="1.15"/></proof>
</goal>
</transf>
</goal>
</transf>
</goal>
</transf>
</goal>
<goal name="WP_parameter app.14" expl="14. loop invariant preservation">
<proof prover="5"><result status="valid" time="3.11"/></proof>
</goal>
<goal name="WP_parameter app.15" expl="15. loop variant decrease">
<proof prover="3"><result status="valid" time="1.08" steps="346"/></proof>
<proof prover="5"><result status="valid" time="0.02"/></proof>
</goal>
<goal name="WP_parameter app.16" expl="16. precondition">
<proof prover="3"><result status="valid" time="0.02" steps="10"/></proof>
<proof prover="5"><result status="valid" time="0.01"/></proof>
</goal>
<goal name="WP_parameter app.17" expl="17. assertion">
<proof prover="3"><result status="valid" time="0.23" steps="109"/></proof>
<proof prover="5"><result status="valid" time="0.02"/></proof>
</goal>
<goal name="WP_parameter app.18" expl="18. assertion">
<proof prover="3"><result status="valid" time="2.34" steps="613"/></proof>
<proof prover="5"><result status="valid" time="0.05"/></proof>
</goal>
<goal name="WP_parameter app.19" expl="19. assertion">
<proof prover="5"><result status="valid" time="0.08"/></proof>
</goal>
<goal name="WP_parameter app.20" expl="20. postcondition">
<proof prover="5"><result status="valid" time="0.51"/></proof>
</goal>
</transf>
</goal>
......
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