Merge branch 'mailmap' into 'master'
[why3.git] / examples / fib_memo.mlw
blob04f96843700ae01db70634fc2305e4963b6c888f
1 (* Fibonacci function with memoisation *)
3 module FibMemo
5   use option.Option
6   use int.Int
7   use int.Fibonacci
8   use ref.Ref
9   use map.Map
11   type table = map int (option int)
13   predicate inv (t : table) =
14     forall x y : int. t[x] = Some y -> y = fib x
16   val table : ref table
18   val add (x:int) (y:int) : unit
19     writes  { table }
20     ensures { !table = (old !table)[x <- Some y] }
22   exception Not_found
24   val find (x:int) : int
25     ensures { !table[x] = Some result }
26     raises  { Not_found -> !table[x] = None }
28   let rec fibo n =
29     requires { 0 <= n /\ inv !table }
30     ensures  { result = fib n /\ inv !table }
31     variant  { 2*n }
32     if n <= 1 then
33       n
34     else
35       memo_fibo (n-1) + memo_fibo (n-2)
37   with memo_fibo n =
38     requires { 0 <= n /\ inv !table }
39     ensures  { result = fib n /\ inv !table }
40     variant  { 2*n+1 }
41     try  find n
42     with Not_found -> let fn = fibo n in add n fn; fn end
44 end