Files
why3/bench/programs/good/recfun.mlw
DAILLER Sylvain f91bb58b89 Generalization of check_unused_vars to logic and program decl
Description:
- Choice was made to not add unused variables when there is no contract
  and no body (no pre/(x)post, and no body).
- For postcondition variable result, we only check variables that are not
  of unit type. And, we report a warning only if the variable is not present
  in all the ensures.
- For result variable, with several imbricated raise, it seems possible to
  have false positive with no location. Removing the no location case which
  seems unhelpful anyway
2019-08-20 15:48:44 +02:00

45 lines
1.2 KiB
Plaintext

module M
use int.Int
use ref.Ref
(** Recursive functions *)
(** 1. Pure function *)
let rec f1 (x:int) : int variant { x }
requires { x >= 0 } ensures { result = 0 }
= if x > 0 then (f1 (x-1)) else x
(** 2. With effects but no argument *)
val x : ref int
let rec f2 (_u:unit) : unit variant { !x }
requires { !x >= 0 } ensures { !x = 0 }
= if !x > 0 then begin x := !x - 1; f2 () end
(** 3. With effects and a pure argument *)
let rec f3 (a:int) : unit variant { a }
requires { a >= 0 } ensures { !x = old !x + a }
= if a > 0 then begin x := !x + 1; (f3 (a-1)) end
(** 4. With effects and a reference as argument *)
let rec f4 (a:ref int) : unit variant { !a }
requires { !a >= 0 } ensures { !x = old !x + old !a }
= if !a > 0 then begin x := !x + 1; a := !a - 1; f4 a end
(** 5. The acid test:
partial application of a recursive function with effects *)
let rec f5 (a b:ref int) variant { !a }
requires { !a >= 0 } ensures { result = old !a + old !b }
= if !a = 0 then !b else begin a := !a - 1; b := !b + 1; f5 a b end
let test_f5 () requires { !x >= 0 } ensures { result = old !x }
= let b = ref 0 in let f = f5 x in f b
end