Commit f82c19b3 authored by Mário Pereira's avatar Mário Pereira

cursor_examples.mlw moved to the gallery

parent c9b80a74
...@@ -42,7 +42,7 @@ end ...@@ -42,7 +42,7 @@ end
here we choose a list *) here we choose a list *)
module ListCursorImpl (* : IterableList *) module ListCursorImpl (* : ListCursor *)
use import int.Int use import int.Int
use import list.List use import list.List
...@@ -99,10 +99,10 @@ module ListCursorImpl (* : IterableList *) ...@@ -99,10 +99,10 @@ module ListCursorImpl (* : IterableList *)
= { visited = empty; collection = t; to_visit = t } = { visited = empty; collection = t; to_visit = t }
clone cursor.ListCursor with clone cursor.ListCursor with
type cursor = cursor, type cursor = cursor,
val create = create, val create = create,
val C.has_next = has_next, val C.has_next = has_next,
val C.next = next val C.next = next
end end
...@@ -116,19 +116,8 @@ module TestListCursor ...@@ -116,19 +116,8 @@ module TestListCursor
use import ref.Refint use import ref.Refint
use import seq.Seq use import seq.Seq
use import seq.OfList use import seq.OfList
use import cursor.ListCursor
let lemma aux2 (f g: int -> int) (a b c d: int) clone import cursor.ListCursor
requires { b - a = d - c }
requires { forall i. a <= i < b -> f i = g i }
ensures { S.sum f a b = S.sum g a b }
= ()
let lemma aux (s: seq int) (x: int)
ensures { let ss = cons x s in
S.sum (get ss) 0 (length ss) = x + S.sum (get s) 0 (length s) }
= let ss = cons x s in
assert { forall i. 0 <= i < length s -> get s i = get ss (i+1) }
lemma sum_of_list: forall l: list int. lemma sum_of_list: forall l: list int.
sum l = S.sum (get (of_list l)) 0 (length l) sum l = S.sum (get (of_list l)) 0 (length l)
...@@ -148,125 +137,126 @@ module TestListCursor ...@@ -148,125 +137,126 @@ module TestListCursor
end end
module TestListCursorLink
use import ListCursorImpl
clone import TestListCursor with
type ListCursor.cursor = cursor,
val ListCursor.C.next = next,
val ListCursor.C.has_next = has_next,
val ListCursor.create = create
end
(** {2 Iteration over a mutable collection} (** {2 Iteration over a mutable collection}
here we choose an array of integers *) here we choose an array of integers *)
(* module IntArrayCursor (\* : IterableList *\) *) module ArrayCursorImpl (* : ArrayCursor *)
(* use import int.Int *) use import int.Int
(* use import array.Array *) use import array.Array
(* use import list.List *) use import array.ToSeq
(* use import list.Reverse *) use import list.List
(* use import array.ToList *) use import list.Reverse
(* use import seq.Seq *) use import array.ToList
use import seq.Seq
(* type t 'a = array 'a *)
type cursor 'a = {
(* val ghost constant a : {array 'a} *) mutable ghost visited : seq 'a;
(* ensures { Array.length result = 0 } *) collection : seq 'a; (* FIXME : extraction of seq *)
mutable index : int; (** index of next element *)
(* type cursor 'a = { *) } invariant { 0 <= index <= length collection /\
(* mutable ghost visited: seq 'a; *) index = length visited /\
(* ghost collection: {t 'a}; *) forall i. 0 <= i < index -> collection[i] = visited[i] }
(* mutable index: int; (\** index of next element *\) *) by { visited = empty; collection = empty; index = 0 }
(* } invariant { 0 <= index <= Array.length collection /\ *)
(* index = length visited /\ *) predicate permitted (c: cursor 'a) =
(* forall i. 0 <= i < index -> *) length c.visited <= length c.collection /\
(* Array.([]) collection i = visited[i] } *) forall i. 0 <= i < length c.visited -> c.visited[i] = c.collection[i]
(* by { visited = empty; collection = a; index = 0 } *)
predicate complete (c: cursor 'a) =
(* clone import cursor.Cursor with *) length c.visited = length c.collection
(* type cursor = cursor, *)
(* type t = t *) let create (a: array 'a) : cursor 'a
ensures { result.visited = empty }
(* (\* predicate permitted (v: seq int) (t: t) = *\) *) ensures { result.index = 0 }
(* (\* length v <= length t /\ *\) *) ensures { result.collection = to_seq a }
(* (\* forall i. 0 <= i *\) *) = { visited = empty; collection = to_seq a; index = 0; }
(* (\* let create (t: t) : cursor *\) *) let has_next (c: cursor 'a) : bool
(* (\* ensures { result.done_ = Nil } *\) *) ensures { result <-> not (complete c) }
(* (\* ensures { coherent t result } *\) *) = c.index < length c.collection
(* (\* = *\) *)
(* (\* { done_ = Nil; to_do = to_list t 0 (length t); index = 0; } *\) *) let next (c: cursor 'a) : 'a
requires { not (complete c) }
(* (\* let has_next (t: t) (c: cursor) : bool *\) *) writes { c }
(* (\* requires { coherent t c } *\) *) ensures { c.visited = snoc (old c).visited result }
(* (\* ensures { result <-> c.to_do <> Nil } *\) *) ensures { c.index = (old c).index + 1 }
(* (\* = *\) *) = if c.index >= length c.collection then absurd
(* (\* c.index < length t *\) *) else begin let x = c.collection[c.index] in
c.visited <- snoc c.visited x;
(* (\* let rec lemma reverse_cons (a: array int) (l u: int) *\) *) c.index <- c.index + 1;
(* (\* requires { l <= u } *\) *) x end
(* (\* ensures { reverse (to_list a l (u+1)) = *\) *)
(* (\* Cons a[u] (reverse (to_list a l u)) } *\) *) clone cursor.ArrayCursor with
(* (\* variant { u - l } *\) *) type cursor = cursor,
(* (\* = if l < u then reverse_cons a (l+1) u *\) *) val C.next = next,
val C.has_next = has_next,
(* (\* let next (t: t) (c: cursor) : elt *\) *) val create = create
(* (\* requires { c.to_do <> Nil } *\) *)
(* (\* requires { coherent t c } *\) *) end
(* (\* writes { c } *\) *)
(* (\* ensures { match old c.to_do with *\) *) module TestArrayCursor
(* (\* | Nil -> false *\) *)
(* (\* | Cons x l -> result = x /\ c.done_ = Cons x (old c.done_) /\ *\) *) use import int.Int
(* (\* c.to_do = l end } *\) *) use import array.Array
(* (\* ensures { coherent t c } *\) *) use import array.ToSeq
(* (\* = *\) *) use import seq.Seq
(* (\* match c.to_do with *\) *) use import int.Sum
(* (\* | Nil -> absurd *\) *) use import ref.Refint
(* (\* | Cons x r -> c.to_do <- r; c.done_ <- Cons x c.done_ *\) *)
(* (\* end; *\) *) clone import cursor.ArrayCursor
(* (\* let x = t[c.index] in *\) *)
(* (\* c.index <- c.index + 1; *\) *) let array_sum (a: array int) : int
(* (\* x *\) *) ensures { result = sum (Array.([]) a) 0 (length a) }
= let s = ref 0 in
(* end *) let c = create a in
while C.has_next c do
(* module TestArrayCursor *) invariant { !s = sum (get c.visited) 0 (length c.visited) }
invariant { permitted c }
(* use import int.Int *) variant { length c.collection - length c.visited }
(* use list.Sum as L *) let x = C.next c in
(* use list.Length as LL *) s += x
(* use import array.Array *) done;
(* use import array.ArraySum *) !s
(* use import array.ToList *)
(* use import ref.Refint *) let harness1 () : unit
(* use import IntArrayCursor *) = let a = Array.make 42 0 in
let c = create a in
(* let rec lemma array_sum_array_to_list (a: array int) (l u: int) : unit *) let x = C.next c in
(* ensures { sum a l u = L.sum (to_list a l u) } variant { u-l } *) assert { x = 0 }
(* = if l < u then array_sum_array_to_list a (l+1) u *)
(*
(* let array_sum (a: array int) : int *) let harness2 () : unit
(* ensures { result = sum a 0 (length a) } *) = let a = Array.make 42 0 in
(* = *) let c = create a in
(* let s = ref 0 in *) a[1] <- 17;
(* let c = create a in *) let x = C.next c in
(* while has_next a c do *) assert { x = 0 }
(* invariant { sum a 0 (length a) = !s + L.sum c.to_do } *) *)
(* invariant { coherent a c } *)
(* variant { LL.length c.to_do } *) end
(* let x = next a c in *)
(* s += x *) module TestArrayCursorLink
(* done; *)
(* !s *) use import ArrayCursorImpl
(* let harness1 () : unit *) clone import TestArrayCursor with
(* = *) type ArrayCursor.cursor = cursor,
(* let a = Array.make 42 0 in *) val ArrayCursor.C.next = next,
(* let c = create a in *) val ArrayCursor.C.has_next = has_next,
(* let x = next a c in *) val ArrayCursor.create = create
(* assert { x = 0 } *)
end
(* (\* *) \ No newline at end of file
(* let harness2 () : unit *)
(* = *)
(* let a = Array.make 42 0 in *)
(* let c = create a in *)
(* a[1] <- 17; *)
(* let x = next a c in *)
(* assert { x = 0 } *)
(* *\) *)
(* end *)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE why3session PUBLIC "-//Why3//proof session v5//EN"
"http://why3.lri.fr/why3session.dtd">
<why3session shape_version="4">
<prover id="0" name="Alt-Ergo" version="1.30" timelimit="5" steplimit="0" memlimit="1000"/>
<file name="../cursor.mlw">
<theory name="TestCursor" sum="401d4ce6900374ae25d5039a681f2923">
<goal name="VC sum" expl="VC for sum">
<proof prover="0"><result status="valid" time="1.00" steps="461"/></proof>
</goal>
</theory>
<theory name="ListCursor" sum="98ec1f1e0527eca4c14a2ff349314fb9">
<goal name="VC cursor" expl="VC for cursor">
<proof prover="0"><result status="valid" time="0.01" steps="33"/></proof>
</goal>
<goal name="VC snoc_Cons" expl="VC for snoc_Cons">
<proof prover="0"><result status="valid" time="0.04" steps="99"/></proof>
</goal>
<goal name="VC next" expl="VC for next">
<proof prover="0"><result status="valid" time="0.23" steps="465"/></proof>
</goal>
<goal name="VC has_next" expl="VC for has_next">
<proof prover="0"><result status="valid" time="0.03" steps="66"/></proof>
</goal>
<goal name="VC create" expl="VC for create">
<proof prover="0"><result status="valid" time="0.02" steps="51"/></proof>
</goal>
<goal name="Cursor.VC create" expl="VC for create">
<proof prover="0"><result status="valid" time="0.01" steps="7"/></proof>
</goal>
<goal name="Cursor.VC next" expl="VC for next">
<proof prover="0"><result status="valid" time="0.02" steps="55"/></proof>
</goal>
<goal name="Cursor.VC has_next" expl="VC for has_next">
<proof prover="0"><result status="valid" time="0.01" steps="1"/></proof>
</goal>
</theory>
<theory name="TestListCursor" sum="912c61d8c8a3a20497d6a0b557c300d1">
<goal name="VC list_sum" expl="VC for list_sum">
<proof prover="0"><result status="valid" time="2.58" steps="1648"/></proof>
</goal>
</theory>
<theory name="IntArrayCursor" sum="4c9dca290af968fc2d686a13d791aecc">
<goal name="VC a" expl="VC for a">
<proof prover="0"><result status="valid" time="0.01" steps="1"/></proof>
</goal>
<goal name="VC cursor" expl="VC for cursor">
<proof prover="0"><result status="valid" time="0.01" steps="5"/></proof>
</goal>
</theory>
</file>
</why3session>
...@@ -339,15 +339,13 @@ module ToSeq ...@@ -339,15 +339,13 @@ module ToSeq
variant { u - l } variant { u - l }
= if u <= l then S.empty else S.cons a[l] (to_seq_sub a (l+1) u) = if u <= l then S.empty else S.cons a[l] (to_seq_sub a (l+1) u)
let rec lemma to_seq_length let rec lemma to_seq_length (a: array 'a) (l u: int)
(a: array 'a) (l u: int)
requires { 0 <= l <= u <= length a } requires { 0 <= l <= u <= length a }
variant { u - l } variant { u - l }
ensures { S.length (to_seq_sub a l u) = u - l } ensures { S.length (to_seq_sub a l u) = u - l }
= if l < u then to_seq_length a (l+1) u = if l < u then to_seq_length a (l+1) u
let rec lemma to_seq_nth let rec lemma to_seq_nth (a: array 'a) (l i u: int)
(a: array 'a) (l i u: int)
requires { 0 <= l <= i < u <= length a } requires { 0 <= l <= i < u <= length a }
variant { i - l } variant { i - l }
ensures { S.get (to_seq_sub a l u) (i - l) = a[i] } ensures { S.get (to_seq_sub a l u) (i - l) = a[i] }
......
...@@ -56,29 +56,30 @@ module ListCursor ...@@ -56,29 +56,30 @@ module ListCursor
end end
module CursorArray module ArrayCursor
use import array.Array use import array.Array
use import array.ToSeq
use import seq.Seq use import seq.Seq
use import seq.OfList use import seq.OfList
use import int.Int use import int.Int
type cursor 'a = private { type cursor 'a = private {
ghost mutable visited : seq 'a; ghost mutable visited : seq 'a;
ghost array : array 'a; ghost collection : seq 'a;
} }
predicate permitted (c: cursor 'a) = predicate permitted (c: cursor 'a) =
length c.visited <= Array.length c.array /\ length c.visited <= length c.collection /\
forall i. 0 <= i < length c.visited -> c.visited[i] = Array.([]) c.array i forall i. 0 <= i < length c.visited -> c.visited[i] = c.collection[i]
predicate complete (c: cursor 'a) = predicate complete (c: cursor 'a) =
length c.visited = Array.length c.array length c.visited = length c.collection
val create (a: array 'a) : cursor 'a val create (a: array 'a) : cursor 'a
ensures { permitted result } ensures { permitted result }
ensures { result.visited = empty } ensures { result.visited = empty }
ensures { result.array = a } ensures { result.collection = to_seq a }
clone import Cursor as C with clone import Cursor as C with
type cursor = cursor, type cursor = cursor,
......
...@@ -864,8 +864,8 @@ let clone_type_record cl s d s' d' = ...@@ -864,8 +864,8 @@ let clone_type_record cl s d s' d' =
let pj_str = pj.pv_vs.vs_name.id_string in let pj_str = pj.pv_vs.vs_name.id_string in
let pj_ity = clone_ity cl pj.pv_ity in let pj_ity = clone_ity cl pj.pv_ity in
let pj_ght = pj.pv_ghost in let pj_ght = pj.pv_ghost in
let rs' = try Hstr.find fields' pj_str let rs' = try Hstr.find fields' pj_str with Not_found ->
with Not_found -> raise (BadInstance id) in raise (BadInstance id) in
let pj' = fd_of_rs rs' in let pj' = fd_of_rs rs' in
let pj'_ity = pj'.pv_ity in let pj'_ity = pj'.pv_ity in
let pj'_ght = pj'.pv_ghost in let pj'_ght = pj'.pv_ghost in
......
...@@ -416,6 +416,13 @@ theory Sum ...@@ -416,6 +416,13 @@ theory Sum
forall f: int -> int, a b c: int. a <= b <= c -> forall f: int -> int, a b c: int. a <= b <= c ->
sum f a c = sum f a b + sum f b c sum f a c = sum f a b + sum f b c
let rec lemma shift_left (f g: int -> int) (a b c d: int)
requires { b - a = d - c }
requires { forall i. a <= i < b -> f i = g (c + i - a) }
variant { b - a }
ensures { sum f a b = sum g c d }
= if a < b then shift_left f g (a+1) b (c+1) d
end end
(** {2 Factorial function} *) (** {2 Factorial function} *)
......
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