programs: no more optimization for singleton record types

parent fe31fcaf
......@@ -135,7 +135,8 @@ LIB_TRANSFORM = simplify_recursive_definition simplify_formula \
encoding_decorate encoding_bridge \
encoding_explicit encoding_guard encoding_sort \
encoding_instantiate simplify_array filter_trigger \
introduction abstraction close_epsilon lift_epsilon
introduction abstraction close_epsilon lift_epsilon \
eval_match
LIB_PRINTER = print_real alt_ergo why3 smt smt2 coq tptp simplify gappa cvc3
......
......@@ -3,7 +3,7 @@ module M
use import int.Int
use import module ref.Ref
parameter incr : x:ref int -> { } unit writes x { x = old x + 1 }
parameter incr : x:ref int -> { } unit writes x { !x = old !x + 1 }
parameter x : ref int
......@@ -17,14 +17,14 @@ let test_and_1 () =
{ result = 1 }
let test_and_2 () =
{ x <> 0 }
{ !x <> 0 }
if id_not_0 !x >= 1 && !x <= 1 then !x else 0+1
{ result = 1 }
let test_or_1 () =
{ }
if (incr x; !x > 0) || !x < 0 then 1 else 2
{ result = 1 -> x <> 0 }
{ result = 1 -> !x <> 0 }
let test_or_2 () =
{ }
......@@ -32,19 +32,19 @@ let test_or_2 () =
{ 0 <= result <= 1 }
let test_not_1 () =
{ }
{ }
if not (!x = 0) then x := 0
{ x = 0 }
{ !x = 0 }
let test_not_2 () =
{ x <= 0 }
while not (!x = 0) do invariant { x <= 0 } incr x done
{ x = 0 }
{ !x <= 0 }
while not (!x = 0) do invariant { !x <= 0 } incr x done
{ !x = 0 }
let test_all_1 () =
{ }
(!x >= 0 && not (!x = 0) || !x >= 1)
{ result=True <-> x>=1 }
{ result=True <-> !x>=1 }
(* from Cesar Munoz's CD3D *)
......@@ -58,13 +58,13 @@ parameter sq : x:int -> {} int { result = x*x }
let test_cd3d () =
{ true }
if !vx=0 && !vy=0 && sq !vx + sq !vy < sq d then 1 else 2
{ result=1 -> vx=0 and vy=0 }
{ result=1 -> !vx=0 and !vy=0 }
end
(*
Local Variables:
Local Variables:
compile-command: "unset LANG; make -C ../../.. bench/programs/good/booleans"
End:
End:
*)
......@@ -7,18 +7,24 @@ exception Break
let f (n : int) : int =
{ true }
let i = ref n in
let i = ref n in
try
while (!i > 0) do
invariant { true }
variant { i }
variant { !i }
if (!i <= 10) then raise Break;
i := !i - 1
done
with Break -> ()
end;
!i
{ result <= 10 }
{ result <= 10 }
end
(*
Local Variables:
compile-command: "unset LANG; make -C ../../.. bench/programs/good/exceptions"
End:
*)
......@@ -12,28 +12,28 @@ exception F int
let p2 () = {} raise (F 1) : unit { false } | F -> { result = 1 }
let p2a () =
let p2a () =
{} raise (F (raise E : int)) : unit { false } | E -> { true } | F -> { false }
(* composition of exceptions with other constructs *)
let p3 () =
let p3 () =
{} begin raise (F 1); raise (F 2) : unit end { false } | F -> { result = 1 }
let p4 () =
{}
let p4 () =
{}
(if True then raise (F 1) else raise (F 2)) : unit
{ false } | F -> { result = 1 }
let p5 () =
{}
{}
begin
if True then raise (F 1);
raise E : unit
end
{ false } | E -> { false } | F -> { result = 1 }
let p6 () =
let p6 () =
{}
begin
if False then raise (F 1);
......@@ -47,18 +47,18 @@ use import module ref.Ref
parameter x : ref int
let p7 () =
{} begin x := 1; raise E; x := 2 end { false } | E -> { x = 1 }
let p7 () =
{} begin x := 1; raise E; x := 2 end { false } | E -> { !x = 1 }
let p8 () =
let p8 () =
{}
begin x := 1; raise (F !x); x := 2 end
{ false } | F -> { x = 1 and result = 1 }
begin x := 1; raise (F !x); x := 2 end
{ false } | F -> { !x = 1 and result = 1 }
let p9 () =
let p9 () =
{}
(raise (F begin x := 1; !x end) : unit)
{ false } | F -> { x = 1 and result = 1 }
(raise (F begin x := 1; !x end) : unit)
{ false } | F -> { !x = 1 and result = 1 }
(* try / with *)
......@@ -66,39 +66,39 @@ let p10 () = {} (try raise E : int with E -> 0 end) { result = 0 }
let p11 () = {} (try raise (F 1) : int with F x -> x end) { result = 1 }
let p12 () =
let p12 () =
{}
try
try
begin raise E; raise (F 1); 1 end
with E -> 2
| F x -> 3
end
{ result = 2 }
let p13 () =
let p13 () =
{}
try
try
begin raise E; raise (F 1); x := 1 end
with E -> x := 2
| F _ -> x := 3
end
{ x = 2 }
{ !x = 2 }
let p13a () =
{}
try
(if !x = 1 then raise E)
(if !x = 1 then raise E)
(*{ true | E => x = 1 }*)
with E ->
x := 0
end
{ x <> 1 }
{ !x <> 1 }
exception E1
exception E1
exception E2
exception E3
let p14 () =
let p14 () =
{}
begin
if !x = 1 then raise E1;
......@@ -106,22 +106,22 @@ let p14 () =
if !x = 3 then raise E3;
raise E : unit
end
{ false } | E1 -> { x = 1 } | E2 -> { x = 2 } | E3 -> { x = 3 }
| E -> { x <> 1 and x <> 2 and x <> 3 }
{ false } | E1 -> { !x = 1 } | E2 -> { !x = 2 } | E3 -> { !x = 3 }
| E -> { !x <> 1 and !x <> 2 and !x <> 3 }
let p15 () =
{}
let p15 () =
{}
if !x = 0 then raise E else (x := 0; raise (F !x)) : unit
{ false } | E -> { x=0 } | F -> { result=0 }
{ false } | E -> { !x=0 } | F -> { result=0 }
let p16 () = {} if !x = 0 then (x:=1; raise E) { x<>0 } | E -> { x=1 }
let p16 () = {} if !x = 0 then (x:=1; raise E) { !x<>0 } | E -> { !x=1 }
let p17 () = {} (x := 0; (raise E; x := 1)) { false } | E -> { x=0 }
let p17 () = {} (x := 0; (raise E; x := 1)) { false } | E -> { !x=0 }
end
(*
Local Variables:
Local Variables:
compile-command: "unset LANG; make -C ../../.. bench/programs/good/exns"
End:
End:
*)
......@@ -7,10 +7,10 @@ use import module ref.Ref
let test1 () =
let x = ref 0 in
for i = 1 to 10 do
invariant { x = i-1 }
invariant { !x = i-1 }
x := !x + 1
done;
assert { x = 10 }
assert { !x = 10 }
(* we don't even enter *)
let test2 () =
......@@ -18,7 +18,7 @@ let test2 () =
for i = 2 to 1 do
x := 1
done;
assert { x = 0 }
assert { !x = 0 }
exception E
......@@ -50,17 +50,17 @@ let test4 x =
let test1d () =
let x = ref 11 in
for i = 10 downto 1 do
invariant { x = i+1 }
invariant { !x = i+1 }
x := !x - 1
done;
assert { x = 1 }
assert { !x = 1 }
let test2d () =
let x = ref 0 in
for i = 1 downto 2 do
x := 1
done;
assert { x = 0 }
assert { !x = 0 }
let test3d () =
{ }
......
......@@ -7,37 +7,37 @@ use import module ref.Ref
parameter i : ref int
let loop1 (u:unit) =
{ i <= 10 }
let loop1 (u:unit) =
{ !i <= 10 }
while !i < 10 do
invariant { i <= 10 } variant { 10 - i }
invariant { !i <= 10 } variant { 10 - !i }
i := !i + 1
done
{ i = 10 }
{ !i = 10 }
(** 2. The same loop, followed by a function call. *)
parameter x: ref int
let negate (u:unit) = {} x := - !x { x = - (old x) }
let negate (u:unit) = {} x := - !x { !x = - (old !x) }
let loop2 (u:unit) =
{ x <= 10 }
let loop2 (u:unit) =
{ !x <= 10 }
begin
while !x < 10 do invariant { x <= 10 } variant { 10 - x }
while !x < 10 do invariant { !x <= 10 } variant { 10 - !x }
x := !x + 1
done;
assert { x = 10 };
assert { !x = 10 };
if !x > 0 then (negate ());
assert { x = -10 }
assert { !x = -10 }
end
{}
end
(*
Local Variables:
Local Variables:
compile-command: "unset LANG; make -C ../../.. bench/programs/good/loops"
End:
End:
*)
......@@ -19,7 +19,7 @@ with is_odd x : bool variant {x} =
end
(*
Local Variables:
Local Variables:
compile-command: "unset LANG; make -C ../../.. bench/programs/good/mutual"
End:
End:
*)
......@@ -7,25 +7,25 @@ module M
parameter r : ref int
parameter f1 : y:int ->
{} unit writes r { q1 r (old r) y }
{} unit writes r { q1 !r (old !r) y }
let g1 () = {} f1 !r { q1 r (old r) (old r) }
let g1 () = {} f1 !r { q1 !r (old !r) (old !r) }
logic foo int : int
logic q int int int
parameter f : t:ref int -> x:int ->
{} unit writes t { q t (old t) x }
parameter f : t:ref int -> x:int ->
{} unit writes t { q !t (old !t) x }
let g (t:ref int) =
{}
f t (foo !t)
{ q t (old t) (foo (old t)) }
{ q !t (old !t) (foo (old !t)) }
end
(*
Local Variables:
Local Variables:
compile-command: "unset LANG; make -C ../../.. bench/programs/good/oldify"
End:
End:
*)
......@@ -11,13 +11,13 @@ parameter x : ref int
(* basic stuff: assignment, sequence and local variables *)
let p1 () = { q (x+1) } begin x := !x + 1 end { q x }
let p1 () = { q (!x+1) } begin x := !x + 1 end { q !x }
let p2 () = { q 7 } begin x := 3 + 4 end { q x }
let p2 () = { q 7 } begin x := 3 + 4 end { q !x }
let p3 () = {} begin x := !x + 1; x := !x + 2 end { x = (old x) + 3 }
let p3 () = {} begin x := !x + 1; x := !x + 2 end { !x = (old !x) + 3 }
let p4 () = {} begin x := 7; x := 2 * !x end { x = 14 }
let p4 () = {} begin x := 7; x := 2 * !x end { !x = 14 }
let p5 () = {} 3 + 4 { result = 7 }
......@@ -27,15 +27,15 @@ let p7 () = {} 3 + (let a = 4 in a + a) { result = 11 }
(* side effects in function arguments *)
let p8 () =
{ q (x+1) } 3 + begin x := !x + 1; !x end { q x and result = (old x) + 4 }
let p8 () =
{ q (!x+1) } 3 + begin x := !x + 1; !x end { q !x and result = (old !x) + 4 }
(* evaluation order (argument first) *)
let p9 () =
{} begin x := 1; 1 end + begin x := 2; 1 end { result = 2 and x = 2 }
let p9 () =
{} begin x := 1; 1 end + begin x := 2; 1 end { result = 2 and !x = 2 }
let p9a () = {} begin x := 1; 1 end + 1 { result = 2 and x = 1 }
let p9a () = {} begin x := 1; 1 end + 1 { result = 2 and !x = 1 }
(* function with a post-condition *)
......@@ -49,24 +49,24 @@ let p11a () = {} let a = (fsucc 1) in a + a { result = 4 }
(* function with a post-condition and side-effects *)
parameter incrx : unit -> { } unit writes x { x = (old x) + 1 }
parameter incrx : unit -> { } unit writes x { !x = (old !x) + 1 }
let p12 () = { x = 0 } incrx () { x = 1 }
let p12 () = { !x = 0 } incrx () { !x = 1 }
let p13 () = {} begin incrx (); incrx () end { x = (old x) + 2 }
let p13 () = {} begin incrx (); incrx () end { !x = (old !x) + 2 }
let p13a () = {} incrx (incrx ()) { x = (old x) + 2 }
let p13a () = {} incrx (incrx ()) { !x = (old !x) + 2 }
(* function with side-effects, result and post-condition *)
parameter incrx2 : unit -> { } int writes x { x = old x + 1 and result = x }
parameter incrx2 : unit -> { } int writes x { !x = old !x + 1 and result = !x }
let p14 () = { x = 0 } incrx2 () { result = 1 }
let p14 () = { !x = 0 } incrx2 () { result = 1 }
end
(*
Local Variables:
Local Variables:
compile-command: "unset LANG; make -C ../../.. bench/programs/good/po"
End:
End:
*)
......@@ -4,13 +4,13 @@ let f (x:'a) = {} x { result=x }
let p () =
{}
if f True then f 1 else f 2
if f True then f 1 else f 2
{ result = 1 }
end
(*
Local Variables:
Local Variables:
compile-command: "unset LANG; make -C ../../.. bench/programs/good/poly"
End:
End:
*)
......@@ -7,45 +7,45 @@ use import module ref.Ref
(** 1. Pure function *)
let rec f1 (x:int) : int variant { x } =
let rec f1 (x:int) : int variant { x } =
{ x >= 0 } (if x > 0 then (f1 (x-1)) else x) { result = 0 }
(** 2. With effects but no argument *)
parameter x : ref int
let rec f2 (u:unit) : unit variant { x } =
{ x >= 0 } (if !x > 0 then begin x := !x - 1; f2 () end) { x = 0 }
let rec f2 (u:unit) : unit variant { !x } =
{ !x >= 0 } (if !x > 0 then begin x := !x - 1; f2 () end) { !x = 0 }
(** 3. With effects and a pure argument *)
let rec f3 (a:int) : unit variant { a } =
{ a >= 0 }
{ a >= 0 }
if a > 0 then begin x := !x + 1; (f3 (a-1)) end
{ x = old x + a }
{ !x = old !x + a }
(** 4. With effects and a reference as argument *)
let rec f4 (a:ref int) : unit variant { a } =
{ a >= 0 }
let rec f4 (a:ref int) : unit variant { !a } =
{ !a >= 0 }
if !a > 0 then begin x := !x + 1; a := !a - 1; f4 a end
{ x = old x + old a }
{ !x = old !x + old !a }
(** 5. The acid test:
(** 5. The acid test:
partial application of a recursive function with effects *)
let rec f5 (a b:ref int) variant { a } =
{ a >= 0 }
if !a = 0 then !b else begin a := !a - 1; b := !b + 1; f5 a b end
{ result = old a + old b }
let rec f5 (a b:ref int) variant { !a } =
{ !a >= 0 }
if !a = 0 then !b else begin a := !a - 1; b := !b + 1; f5 a b end
{ result = old !a + old !b }
let test_f5 () =
{ x >= 0 } let f = f5 x in let b = ref 0 in f b { result = old x }
let test_f5 () =
{ !x >= 0 } let f = f5 x in let b = ref 0 in f b { result = old !x }
end
(*
Local Variables:
Local Variables:
compile-command: "unset LANG; make -C ../../.. bench/programs/good/recfun"
End:
End:
*)
......@@ -9,22 +9,22 @@ parameter b : ref int
parameter b1 : ref int
parameter b2 : ref int
let f () =
{} b := 1 - !b; !b { result = b and b = 1 - old b }
let f () =
{} b := 1 - !b; !b { result = !b and !b = 1 - old !b }
let k () =
{}
let k () =
{}
begin
b := 0;
b1 := (1 - (f ())) + (f ());
b2 := (f ()) * (1 - (f ()))
b2 := (f ()) * (1 - (f ()))
end
{ b1 = 0 and b2 = 1 }
{ !b1 = 0 and !b2 = 1 }
end
(*
Local Variables:
Local Variables:
compile-command: "unset LANG; make -C ../../.. bench/programs/good/see"
End:
End:
*)
......@@ -7,48 +7,48 @@ module M
parameter x : ref int
parameter set_and_test_zero :
v:int ->
{}
bool writes x
{ x = v and if result=True then x = 0 else x <> 0 }
parameter set_and_test_zero :
v:int ->
{}
bool writes x
{ !x = v and if result=True then !x = 0 else !x <> 0 }
let p () = {} if set_and_test_zero 0 then 1 else 2 { result = 1 }
parameter set_and_test_nzero :
v:int ->
{}
bool writes x
{ x = v and if result=True then x <> 0 else x = 0 }
let p2 (y:ref int) =
{ y >= 0 }
while set_and_test_nzero !y do
invariant { y >= 0 } variant { y }
y := !y - 1
done
{ y = 0 }
let p3 (y:ref int) =
{ y >= 0 }
while let b = set_and_test_nzero !y in b do
invariant { y >= 0 } variant { y }
y := !y - 1
done
{ y = 0 }
let p4 (y:ref int) =
{ y >= 1 }
while begin y := !y - 1; (set_and_test_nzero !y) end do
invariant { y >= 1 } variant { y }
parameter set_and_test_nzero :
v:int ->
{}
bool writes x
{ !x = v and if result=True then !x <> 0 else !x = 0 }
let p2 (y:ref int) =
{ !y >= 0 }
while set_and_test_nzero !y do
invariant { !y >= 0 } variant { !y }
y := !y - 1
done
{ !y = 0 }
let p3 (y:ref int) =
{ !y >= 0 }
while let b = set_and_test_nzero !y in b do
invariant { !y >= 0 } variant { !y }
y := !y - 1
done
{ !y = 0 }
let p4 (y:ref int) =
{ !y >= 1 }
while begin y := !y - 1; (set_and_test_nzero !y) end do
invariant { !y >= 1 } variant { !y }
()
done
{ y = 0 }
done
{ !y = 0 }
end
(*
Local Variables:
Local Variables:
compile-command: "unset LANG; make -C ../../.. bench/programs/good/set"
End:
End:
*)
......@@ -5,7 +5,7 @@ use import module ref.Ref
parameter x : ref int
parameter f : unit -> { } unit writes x { x = 1 - old x }
parameter f : unit -> { } unit writes x { !x = 1 - old !x }
let p () =
begin
......@@ -13,15 +13,15 @@ let p () =
let t = () in ();
(f ());
(f ());
assert { x = at x Init };
assert { !x = at !x Init };
()
end
end
(*
Local Variables:
Local Variables:
compile-command: "unset LANG; make -C ../../.. bench/programs/good/wpcalls"
End:
End:
*)
......@@ -152,11 +152,11 @@ theory map.Map
syntax type map "(Array %1 %2)"
meta "encoding : lskept" logic get
meta "encoding : lskept" logic set
meta "encoding : lskept" logic create_const
meta "encoding : lskept" logic const
syntax logic get "(select %1 %2)"
syntax logic set "(store %1 %2 %3)"
syntax logic create_const "(const[%t0] %1)"
syntax logic const "(const[%t0] %1)"
end
......
......@@ -2,13 +2,13 @@
(***
Algorithm 63
C. A. R. Hoare
C. A. R. Hoare
Elliott Brothers Ltd., Hertfordshire, England, U.K.
Communications of the ACM archive
Volume 4 , Issue 7 (July 1961) table of contents
Pages: 321 - 322
Pages: 321 - 322
***)
......@@ -19,20 +19,20 @@ module Algo63
use import module array.Array
use import module array.ArrayPermut
parameter partition :
parameter partition :
a : array int -> m:int -> n:int -> i:ref int -> j:ref int ->
{ m < n }
{ m < n }
unit writes a i j
{ m <= j and j < i and i <= n and permut_sub (old a) a m n and
{ m <= !j and !j < !i and !i <= n and permut_sub (old a) a m n and
exists x:int.
(forall r:int. m <= r <= j -> a[r] <= x) and
(forall r:int. j < r < i -> a[r] = x) and
(forall r:int. i <= r <= n -> a[r] >= x) }
(forall r:int. m <= r <= !j -> a[r] <= x) and
(forall r:int. !j < r < !i -> a[r] = x) and
(forall r:int. !i <= r <= n -> a[r] >= x) }
end
(*
Local Variables:
Local Variables:
compile-command: "unset LANG; make -C ../.. examples/programs/algo63.gui"
End:
End:
*)
(***
Algorithm 64
C. A. R. Hoare
C. A. R. Hoare
Elliott Brothers Ltd., Hertfordshire, England, U.K.
Communications of the ACM archive
Volume 4 , Issue 7 (July 1961) table of contents
Pages: 321 - 322
Pages: 321 - 322
***)