2 module ResizableArraySpec
8 type rarray 'a = private {
9 ghost mutable length: int;
10 ghost mutable data: map int 'a
13 function ([]) (r: rarray 'a) (i: int) : 'a = Map.get r.data i
14 val function ([<-]) (r: rarray 'a) (i: int) (v: 'a) : rarray 'a
15 ensures { result.length = r.length }
16 ensures { result.data = Map.set r.data i v }
18 val make (len: int) (dummy: 'a) : rarray 'a
20 ensures { result.length = len }
21 ensures { result.data = Const.const dummy }
22 (* ensures { forall i: int. 0 <= i < len -> result[i] = dummy } *)
24 val ([]) (r: rarray 'a) (i: int) : 'a
25 requires { 0 <= i < r.length } ensures { result = r[i] }
27 val ([]<-) (r: rarray 'a) (i: int) (v: 'a) : unit writes {r}
28 requires { 0 <= i < r.length } ensures { r = (old r)[i <- v] }
30 val resize (r: rarray 'a) (len: int) : unit writes {r}
32 ensures { r.length = len }
33 ensures { forall i: int.
34 0 <= i < old r.length -> i < len -> r[i] = (old r)[i] }
36 val append (r1: rarray 'a) (r2: rarray 'a) : unit writes {r1}
37 ensures { r1.length = (old r1.length) + r2.length }
38 ensures { forall i: int. 0 <= i < r1.length ->
39 (i < old r1.length -> r1[i] = (old r1)[i]) /\
40 (old r1.length <= i -> r1[i] = r2[i - old r1.length]) }
44 module ResizableArrayImplem (* : ResizableArraySpec *)
51 { dummy: 'a; mutable length: int; mutable data: A.array 'a }
52 invariant { 0 <= length <= A.length data }
53 invariant { forall i: int. length <= i < A.length data ->
54 A.([]) data i = dummy }
55 by { dummy = any 'a; length = 0; data = A.make 0 (any 'a) }
57 function ([]) (r: rarray 'a) (i: int) : 'a = A.([]) r.data i
60 function make (len: int) (dummy: 'a) : rarray 'a =
61 { dummy = dummy; length = len; data = A.make len dummy }
64 let make (len: int) (dummy: 'a) : rarray 'a
66 ensures { result.dummy = dummy }
67 ensures { result.length = len }
68 ensures { forall i:int. 0 <= i < len -> A.([]) result.data i = dummy }
70 { dummy = dummy; length = len; data = A.make len dummy }
72 let ([]) (r: rarray 'a) (i: int) : 'a
73 requires { 0 <= i < r.length }
77 let ([]<-) (r: rarray 'a) (i: int) (v: 'a) : unit
78 requires { 0 <= i < r.length }
79 ensures { r.data.A.elts = A.Map.([<-]) (old r).data.A.elts i v }
83 let resize (r: rarray 'a) (len: int) : unit
85 ensures { r.length = len }
86 ensures { forall i: int.
87 0 <= i < old r.length -> i < len -> r[i] = (old r)[i] }
89 let n = A.length r.data in
91 let a = A.make (max len (2 * n)) r.dummy in
92 A.blit r.data 0 a 0 n;
95 A.fill r.data len (n - len) r.dummy
99 let append (r1: rarray 'a) (r2: rarray 'a) : unit
100 ensures { r1.length = old r1.length + r2.length }
101 ensures { forall i: int. 0 <= i < r1.length ->
102 (i < old r1.length -> r1[i] = (old r1)[i]) /\
103 (old r1.length <= i -> r1[i] = r2[i - old r1.length]) }
105 let n1 = length r1 in
106 resize r1 (length r1 + length r2);
107 A.blit r2.data 0 r1.data n1 (length r2)
109 (* sanity checks for WhyML typing system *)
112 let test_reset1 (r: rarray) =
113 let a = A.make 10 dummy in
115 A.([]) a 0 (* <-- we cannot access array a anymore *)
117 let test_reset2 (r: rarray) =
119 r.data <- A.make 10 dummy;
120 let x = A.([]) r.data 0 in (* <-- this is accepted *)
121 let y = A.([]) b 0 in (* <-- but we cannot access array b anymore *)
124 (* the same, using resize *)
125 let test_reset3 (r: rarray) =
128 let x = A.([]) r.data 0 in (* <-- this is accepted *)
129 let y = A.([]) c 0 in (* <-- but we cannot access array c anymore *)
138 use ResizableArrayImplem
142 assert { r.length = 10 };
145 assert { r[0] = 17 };
146 assert { r.length = 7 }
149 let r1 = make 10 0 in
151 let r2 = make 10 0 in
154 assert { r1.length = 20 };
155 assert { r1[0] = 17 };