2 (* Association lists. *)
4 (* Association with respect to an equivalence relation. *)
7 clone import key_type.KeyType as K
8 clone import relations_params.EquivalenceParam as Eq with type t = key
15 predicate appear (p:param 'a) (k:key 'a) (l:list (t 'a 'b)) =
16 exists x. mem x l /\ correct_for p k /\ Eq.rel p k (key x)
18 lemma appear_append : forall p:param 'a,k:key 'a,l r:list (t 'a 'b).
19 appear p k (l++r) <-> appear p k l \/ appear p k r
22 predicate correct (p:param 'a) (l:list (t 'a 'b)) =
23 forall x. mem x l -> let kx = key x in correct_for p kx
25 (* Unique occurence (a desirable property of an association list). *)
26 predicate unique (p:param 'a) (l:list (t 'a 'b)) = match l with
28 | Cons x q -> not appear p (key x) q /\ unique p q
31 (* functional update with equivalence classes. *)
32 function param_update (p:param 'a) (f:key 'a -> 'b)
33 (k:key 'a) (b:'b) : key 'a -> 'b = \k2.
34 if Eq.rel p k k2 then b else f k2
36 function const_none : 'a -> option 'b = \x.None
38 (* functional model of an association list. *)
39 function model (p:param 'a) (l:list (t 'a 'b)) : key 'a -> option (t 'a 'b) =
42 | Cons d q -> param_update p (model p q) (key d) (Some d)
45 (* A key is bound iff it occurs in the association lists. *)
46 let rec lemma model_occurence (p:param 'a) (k:key 'a)
47 (l:list (t 'a 'b)) : unit
48 requires { correct p l }
49 requires { correct_for p k }
50 ensures { appear p k l <-> match model p l k with None -> false
51 | Some _ -> true end }
52 ensures { not appear p k l <-> model p l k = None }
54 = match l with Cons _ q -> model_occurence p k q | _ -> () end
56 (* A key is bound to a value with an equivalent key. *)
57 let rec lemma model_link (p:param 'a) (k:key 'a) (l:list (t 'a 'b)) : unit
58 requires { correct p l }
59 requires { correct_for p k }
60 ensures { match model p l k with None -> true
61 | Some d -> Eq.rel p k (key d) end }
63 = match l with Cons _ q -> model_link p k q | _ -> () end
65 (* Two equivalent keys are bound to the same value. *)
66 let rec lemma model_equal (p:param 'a) (k1 k2:key 'a)
67 (l:list (t 'a 'b)) : unit
68 requires { correct p l }
69 requires { correct_for p k1 /\ correct_for p k2 }
70 requires { Eq.rel p k1 k2 }
71 ensures { model p l k1 = model p l k2 }
74 | Cons x q -> assert { correct_for p x.key };
79 (* If the list satisfies the uniqueness property,
80 then every value occuring in the list is the image of its key. *)
81 let rec lemma model_unique (p:param 'a) (k:key 'a) (l:list (t 'a 'b)) : unit
82 requires { correct p l }
83 requires { unique p l }
84 requires { correct_for p k }
85 ensures { forall d. mem d l -> model p l (key d) = Some d }
87 = match l with Cons _ q -> model_unique p k q | _ -> () end
89 (* Singleton association list. *)
90 let lemma model_singleton (p:param 'a) (k:key 'a) (d:t 'a 'b) : unit
91 requires { correct_for p d.key }
92 requires { correct_for p k }
93 ensures { model p (Cons d Nil) k = if rel p k d.key
98 (* Unique union of association list by concatenation. *)
99 let rec lemma model_concat (p:param 'a) (k:key 'a) (l r:list (t 'a 'b)) : unit
100 requires { correct p (l++r) /\ correct p l /\ correct p r }
101 requires { unique p (l++r) /\ unique p l /\ unique p r }
102 requires { correct_for p k }
103 ensures { match model p l k with None -> model p (l++r) k = model p r k
104 | s -> model p (l++r) k = s end }
105 ensures { match model p r k with None -> model p (l++r) k = model p l k
106 | s -> model p (l++r) k = s end }
107 ensures { model p (l++r) k = None <->
108 model p l k = None /\ model p r k = None }
109 ensures { model p l k = None \/ model p r k = None }
113 | Cons d q -> assert { rel p d.key k -> model p r k <> None ->
114 match model p r k with None -> false | _ -> not appear p k r && false end
122 (* Sorted (increasing) association list. *)
131 clone import key_type.KeyType as K
132 clone import preorder.FullParam as O with type t = key
133 clone export Assoc with namespace K = K,
134 type Eq.param = O.order,
135 predicate Eq.correct_for = O.correct_for,
136 predicate Eq.rel = O.eq,
137 (* Duplicates, there is no need to keep them as lemma. *)
141 clone sorted.Increasing as S with namespace K = K,
142 type O.param = O.order,
143 predicate O.correct_for = O.correct_for,
144 predicate O.rel = O.lt,
147 (* Sorted lists are correct association lists with unicity property. *)
148 let rec lemma increasing_unique_and_correct (o:order 'a)
149 (l:list (t 'a 'b)) : unit
150 requires { S.increasing o l }
151 ensures { correct o l }
152 ensures { unique o l }
154 = match l with Cons _ q -> increasing_unique_and_correct o q | _ -> () end
156 let lemma model_cut (o:order 'a) (k:key 'a) (l r:list (t 'a 'b)) : unit
157 requires { correct_for o k }
158 requires { S.increasing o r }
159 requires { S.increasing o l }
160 requires { S.majorate o k l }
161 requires { S.minorate o k r }
162 ensures { forall k2. correct_for o k2 /\ eq o k k2 ->
163 model o (l++r) k2 = None }
164 ensures { forall k2. correct_for o k2 /\ lt o k k2 ->
165 model o (l++r) k2 = model o r k2 }
166 ensures { forall k2. correct_for o k2 /\ le o k2 k ->
167 model o r k2 = None }
168 ensures { forall k2. correct_for o k2 /\ lt o k2 k ->
169 model o (l++r) k2 = model o l k2 }
170 ensures { forall k2. correct_for o k2 /\ le o k k2 ->
171 model o l k2 = None }
172 = assert { S.increasing o (l++r) };
173 assert { forall k2. correct_for o k2 /\ lt o k k2 ->
174 model o (l++r) k2 <> model o r k2 -> match model o r k2 with
175 | None -> match model o l k2 with
177 | Some d -> lt o d.key k && false
181 assert { forall k2. correct_for o k2 /\ lt o k2 k ->
182 model o (l++r) k2 <> model o l k2 -> match model o l k2 with
183 | None -> match model o r k2 with
185 | Some d -> lt o k d.key && false
190 let lemma model_split (o:order 'a) (d:t 'a 'b) (l r:list (t 'a 'b)) : unit
191 requires { correct_for o d.key }
192 requires { S.increasing o l }
193 requires { S.increasing o r }
194 requires { S.majorate o d.key l }
195 requires { S.minorate o d.key r }
196 ensures { forall k2. correct_for o k2 /\ eq o d.key k2 ->
197 model o (l++Cons d r) k2 = Some d }
198 ensures { forall k2. correct_for o k2 /\ lt o d.key k2 ->
199 model o (l++Cons d r) k2 = model o r k2 }
200 ensures { forall k2. correct_for o k2 /\ le o k2 d.key ->
201 model o r k2 = None }
202 ensures { forall k2. correct_for o k2 /\ lt o k2 d.key ->
203 model o (l++Cons d r) k2 = model o l k2 }
204 ensures { forall k2. correct_for o k2 /\ le o d.key k2 ->
205 model o l k2 = None }