Commit d23e9cd8 authored by Andrei Paskevich's avatar Andrei Paskevich

use "return" in several examples

parent 923f35cc
......@@ -59,21 +59,17 @@ module AddListImp
use import SumList
use import ref.Ref
exception Break
let sum (l: list or_integer_float) : (int, real) =
returns { si, sf -> si = add_int l /\ sf = add_real l }
let si = ref 0 in
let sf = ref 0.0 in
let ll = ref l in
try
while True do
invariant { !si + add_int !ll = add_int l /\
!sf +. add_real !ll = add_real l
}
!sf +. add_real !ll = add_real l }
variant { !ll }
match !ll with
| Nil -> raise Break
| Nil -> return (!si, !sf)
| Cons (Integer n) t ->
si := !si + n; ll := t
| Cons (Real x) t ->
......@@ -81,8 +77,6 @@ let sum (l: list or_integer_float) : (int, real) =
end
done;
absurd
with Break -> (!si, !sf)
end
let main () =
......
......@@ -11,14 +11,13 @@ module BinarySearch
(* the code and its specification *)
exception Break int (* raised to exit the loop *)
exception Not_found (* raised to signal a search failure *)
let binary_search (a : array int) (v : int) : int
requires { forall i1 i2 : int. 0 <= i1 <= i2 < length a -> a[i1] <= a[i2] }
ensures { 0 <= result < length a /\ a[result] = v }
raises { Not_found -> forall i:int. 0 <= i < length a -> a[i] <> v }
= try
=
let l = ref 0 in
let u = ref (length a - 1) in
while !l <= !u do
......@@ -33,12 +32,9 @@ module BinarySearch
else if a[m] > v then
u := m - 1
else
raise (Break m)
return m
done;
raise Not_found
with Break i ->
i
end
end
......@@ -51,7 +47,6 @@ module BinarySearchAnyMidPoint
use import ref.Ref
use import array.Array
exception Break int (* raised to exit the loop *)
exception Not_found (* raised to signal a search failure *)
val midpoint (l:int) (u:int) : int
......@@ -61,7 +56,7 @@ module BinarySearchAnyMidPoint
requires { forall i1 i2 : int. 0 <= i1 <= i2 < length a -> a[i1] <= a[i2] }
ensures { 0 <= result < length a /\ a[result] = v }
raises { Not_found -> forall i:int. 0 <= i < length a -> a[i] <> v }
= try
=
let l = ref 0 in
let u = ref (length a - 1) in
while !l <= !u do
......@@ -75,12 +70,9 @@ module BinarySearchAnyMidPoint
else if a[m] > v then
u := m - 1
else
raise (Break m)
return m
done;
raise Not_found
with Break i ->
i
end
end
......@@ -95,7 +87,6 @@ module BinarySearchInt32
(* the code and its specification *)
exception Break int32 (* raised to exit the loop *)
exception Not_found (* raised to signal a search failure *)
let binary_search (a : array int32) (v : int32) : int32
......@@ -104,7 +95,7 @@ module BinarySearchInt32
ensures { 0 <= to_int result < to_int a.length /\ a[to_int result] = v }
raises { Not_found ->
forall i:int. 0 <= i < to_int a.length -> a[i] <> v }
= try
=
let l = ref (of_int 0) in
let u = ref (length a - of_int 1) in
while !l <= !u do
......@@ -119,12 +110,9 @@ module BinarySearchInt32
else if a[m] > v then
u := m - of_int 1
else
raise (Break m)
return m
done;
raise Not_found
with Break i ->
i
end
end
......
......@@ -21,8 +21,6 @@ module Decrease1
variant { j - i }
= if i < j then decrease1_induction a (i+1) j
exception Found
let search (a: array int)
requires { decrease1 a }
ensures {
......@@ -30,18 +28,14 @@ module Decrease1
\/ (0 <= result < length a /\ a[result] = 0 /\
forall j: int. 0 <= j < result -> a[j] <> 0) }
= let i = ref 0 in
try
while !i < length a do
invariant { 0 <= !i }
invariant { forall j: int. 0 <= j < !i -> j < length a -> a[j] <> 0 }
variant { length a - !i }
if a[!i] = 0 then raise Found;
if a[!i] = 0 then return !i;
if a[!i] > 0 then i := !i + a[!i] else i := !i + 1
done;
-1
with Found ->
!i
end
let rec search_rec (a: array int) (i : int)
requires { decrease1 a /\ 0 <= i }
......
......@@ -228,9 +228,6 @@ module NaturalMergesort
done;
!i
exception Break
exception Return
let natural_mergesort (a: array elt) : unit
ensures { sorted a }
ensures { permut_all (old a) a }
......@@ -238,14 +235,12 @@ module NaturalMergesort
if n >= 2 then
let tmp = Array.copy a in
let ghost first_run = ref 0 in
try
while true do
invariant { 0 <= !first_run <= n && sorted_sub a 0 !first_run }
invariant { permut_all (old a) a }
variant { n - !first_run }
label L in
let lo = ref 0 in
try
while !lo < n - 1 do
invariant { 0 <= !lo <= n }
invariant { !first_run at L <= !first_run <= n }
......@@ -254,7 +249,7 @@ module NaturalMergesort
invariant { permut_all (a at L) a }
variant { n - !lo }
let mid = find_run a !lo in
if mid = n then begin if !lo = 0 then raise Return; raise Break end;
if mid = n then begin if !lo = 0 then return; raise L end;
let hi = find_run a mid in
label M in
merge_using tmp a !lo mid hi;
......@@ -263,9 +258,7 @@ module NaturalMergesort
ghost if !lo = 0 then first_run := hi;
lo := hi;
done
with Break -> () end
done
with Return -> () end
(** an alternative implementation suggested by Martin Clochard,
......@@ -283,10 +276,9 @@ module NaturalMergesort
ensures { forall j: int. 0 <= j < lo -> a[j] = (old a)[j] }
variant { k }
= let n = length a in
if lo >= n-1 then n else
try
if lo >= n-1 then return n;
let mid = ref (find_run a lo) in
if !mid = n then raise Break;
if !mid = n then return n;
for i = 0 to k-1 do
invariant { lo + i < !mid < n }
invariant { sorted_sub a lo !mid }
......@@ -299,10 +291,9 @@ module NaturalMergesort
assert { permut_sub (a at M) a lo hi };
assert { permut_sub (a at M) a lo (length a) };
mid := hi;
if !mid = n then raise Break
if !mid = n then return n
done;
!mid
with Break -> n end
let natural_mergesort2 (a: array elt) : unit
ensures { sorted a }
......
......@@ -28,7 +28,6 @@ module Mjrty
use import array.NumOfEq
exception Not_found
exception Found
type candidate
......@@ -57,19 +56,15 @@ module Mjrty
decr k
done;
if !k = 0 then raise Not_found;
try
if 2 * !k > n then raise Found;
if 2 * !k > n then return !cand;
k := 0;
for i = 0 to n-1 do
invariant { !k = numof a !cand 0 i /\ 2 * !k <= n }
if eq a[i] !cand then begin
incr k;
if 2 * !k > n then raise Found
if 2 * !k > n then return !cand
end
done;
raise Not_found
with Found ->
!cand
end
end
......@@ -85,30 +85,26 @@ module PigeonHole
requires { n > m >= 0 }
variant { m }
ensures { not (injective f n m) }
= try
=
for i = 0 to n-1 do
invariant { forall k. 0 <= k < i -> f k <> m-1 }
if f i = m-1 then
begin
if f i = m-1 then begin
(* we have found index i such that f i = m-1 *)
for j = i+1 to n-1 do
invariant { forall k. i < k < j -> f k <> m-1 }
if f j = m-1 then raise Found
(* we know that f i = f j = m-1 hence we are done *)
if f j = m-1 then return
done;
(* we know that for all k <> i, f k <> m-1 *)
let g = shift f i in
assert { range g (n-1) (m-1) };
pigeon_hole (n-1) (m-1) g;
raise Found;
return
end
done;
(* we know that for all k, f k <> m-1 *)
assert { range f n (m-1) };
pigeon_hole n (m-1) f
with Found ->
(* we know that f i = f j = m-1 hence we are done *)
()
end
end
......@@ -343,10 +339,7 @@ module PatienceAbstract
let stack_i = s.stacks[i] in
let stack_i_size = s.stack_sizes[i] in
let top_stack_i = stack_i[stack_i_size - 1] in
if c <= s.values[top_stack_i] then
raise (Return i)
else
begin
if c <= s.values[top_stack_i] then raise (Return i);
assert { 0 <= top_stack_i < s.num_elts };
assert { let (is,ip) = s.positions[top_stack_i] in
0 <= is < s.num_stacks &&
......@@ -355,7 +348,6 @@ module PatienceAbstract
is = i /\ ip = stack_i_size - 1
};
pred := top_stack_i
end
done;
(* we add a new stack *)
let idx = s.num_elts in
......
......@@ -9,8 +9,6 @@ module Pigeonhole
use import set.Fset
use import ref.Ref
exception Exit
let rec below (n: int) : set int
requires { 0 <= n }
ensures { forall i. mem i result <-> 0 <= i < n }
......@@ -24,15 +22,13 @@ module Pigeonhole
ensures { exists i1, i2. 0 <= i1 < i2 < n /\ f i1 = f i2 }
=
let s = ref empty in
try
for i = 0 to n-1 do
invariant { cardinal !s = i }
invariant { forall x. mem x !s <-> (exists j. 0 <= j < i /\ x = f j) }
if mem (f i) !s then raise Exit;
if mem (f i) !s then return;
s := add (f i) !s
done;
let b = below m in assert { subset !s b };
absurd
with Exit -> () end
end
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