Merge branch 'mailmap' into 'master'
[why3.git] / examples / vstte10_aqueue.mlw
blob72d79151141f8b4f02ccb2175c53b046ef764bd9
1 (*
2    VSTTE'10 competition http://www.macs.hw.ac.uk/vstte10/Competition.html
3    Problem 5: amortized queue
5    Author: Jean-Christophe Filliatre (CNRS)
6    Tool:   Why3 (see http://why3.lri.fr/)
7 *)
9 module AmortizedQueue
11   use int.Int
12   use option.Option
13   use list.ListRich
15   type queue 'a = { front: list 'a; lenf: int;
16                     rear : list 'a; lenr: int; }
17     invariant { length front = lenf >= length rear = lenr }
18     by { front = Nil; lenf = 0; rear = Nil; lenr = 0 }
20   function sequence (q: queue 'a) : list 'a =
21     q.front ++ reverse q.rear
23   let constant empty : queue 'a =
24     { front = Nil; lenf = 0; rear = Nil; lenr = 0 }
25     ensures { sequence result = Nil }
27   let head (q: queue 'a) : 'a
28     requires { sequence q <> Nil }
29     ensures  { hd (sequence q) = Some result }
30   = let Cons x _ = q.front in x
32   let create (f: list 'a) (lf: int) (r: list 'a) (lr: int) : queue 'a
33     requires { lf = length f /\ lr = length r }
34     ensures  { sequence result = f ++ reverse r }
35   = if lf >= lr then
36       { front = f; lenf = lf; rear = r; lenr = lr }
37     else
38       let f = f ++ reverse r in
39       { front = f; lenf = lf + lr; rear = Nil; lenr = 0 }
41   let tail (q: queue 'a) : queue 'a
42     requires { sequence q <> Nil }
43     ensures  { tl (sequence q) = Some (sequence result) }
44   = let Cons _ r = q.front in
45     create r (q.lenf - 1) q.rear q.lenr
47   let enqueue (x: 'a) (q: queue 'a) : queue 'a
48     ensures { sequence result = sequence q ++ Cons x Nil }
49   = create q.front q.lenf (Cons x q.rear) (q.lenr + 1)
51 end