summaryrefslogtreecommitdiff
path: root/tests/hashmap
diff options
context:
space:
mode:
Diffstat (limited to 'tests/hashmap')
-rw-r--r--tests/hashmap/Hashmap.Properties.fst101
1 files changed, 51 insertions, 50 deletions
diff --git a/tests/hashmap/Hashmap.Properties.fst b/tests/hashmap/Hashmap.Properties.fst
index e7236189..aee5dbb7 100644
--- a/tests/hashmap/Hashmap.Properties.fst
+++ b/tests/hashmap/Hashmap.Properties.fst
@@ -293,13 +293,13 @@ type slots_s (t : Type0) = list (slot_s t)
/// High-level type for the hash-map, seen as a list of associative lists (one
/// list per slot)
-type hash_map_slots t = list (slot_s t)
+type hash_map_slots_s t = list (slot_s t)
/// High-level type for the hash-map, seen as a an associative list
type hash_map_s t = assoc_list t
/// Representation function for [hash_map_t] as a list of slots
-let hash_map_t_slots_v (#t : Type0) (hm : hash_map_t t) : hash_map_slots t =
+let hash_map_t_slots_v (#t : Type0) (hm : hash_map_t t) : hash_map_slots_s t =
map list_t_v hm.hash_map_slots
/// Representation function for [hash_map_t]
@@ -345,23 +345,23 @@ let slot_t_find_s (#t : Type0) (k : key) (slot : list_t t) : option t =
| Some (_, v) -> Some v
// This is a simpler version of the "find" function, which captures the essence
-// of what happens and operates on [hash_map_slots].
+// of what happens and operates on [hash_map_slots_s].
// TODO: useful?
-let hash_map_slots_find_s
- (#t : Type0) (hm : hash_map_slots t{length hm <= usize_max /\ length hm > 0})
+let hash_map_slots_s_find
+ (#t : Type0) (hm : hash_map_slots_s t{length hm <= usize_max /\ length hm > 0})
(k : key) : option t =
let i = hash_mod_key k (length hm) in
let slot = index hm i in
slot_find k slot
-let hash_map_slots_len_s
- (#t : Type0) (hm : hash_map_slots t{length hm <= usize_max /\ length hm > 0}) :
+let hash_map_slots_s_len
+ (#t : Type0) (hm : hash_map_slots_s t{length hm <= usize_max /\ length hm > 0}) :
nat =
length (flatten hm)
// Same as above, but operates on [hash_map_t]
// Note that we don't reuse the above function on purpose: converting to a
-// [hash_map_slots] then looking up an element is not the same as what we
+// [hash_map_slots_s] then looking up an element is not the same as what we
// wrote below.
let hash_map_t_find_s
(#t : Type0) (hm : hash_map_t t{length hm.hash_map_slots > 0}) (k : key) : option t =
@@ -411,7 +411,7 @@ type slot_t_inv_not_same_keys_f (#t : Type0) (i : usize) (slot : list_t t) =
/// Invariants for the slots
-let slot_inv
+let slot_s_inv
(#t : Type0) (len : usize{len > 0}) (i : usize) (slot : list (binding t)) : bool =
// All the bindings are in the proper slot
for_all (same_hash_mod_key len i) slot &&
@@ -470,10 +470,10 @@ let slot_t_inv_from_funs_lem
()
*)
-let slots_inv (#t : Type0) (slots : slots_s t{length slots <= usize_max}) : Type0 =
+let slots_s_inv (#t : Type0) (slots : slots_s t{length slots <= usize_max}) : Type0 =
forall(i:nat{i < length slots}).
{:pattern index slots i}
- slot_inv (length slots) i (index slots i)
+ slot_s_inv (length slots) i (index slots i)
let slots_t_inv (#t : Type0) (slots : slots_t t{length slots <= usize_max}) : Type0 =
forall(i:nat{i < length slots}).
@@ -504,10 +504,10 @@ let slots_t_from_fun
*)
// TODO: hash_map_slots -> hash_map_slots_s
-let hash_map_slots_inv (#t : Type0) (hm : hash_map_slots t) : Type0 =
+let hash_map_slots_s_inv (#t : Type0) (hm : hash_map_slots_s t) : Type0 =
length hm <= usize_max /\
length hm > 0 /\
- slots_inv hm
+ slots_s_inv hm
/// Base invariant for the hashmap (the complete invariant can be temporarily
/// broken between the moment we inserted an element and the moment we resize)
@@ -947,30 +947,30 @@ let rec slot_t_v_for_all_binding_neq_append_lem t key value ls b =
slot_t_v_for_all_binding_neq_append_lem t key value cls b
#pop-options
-val slot_inv_not_find_append_end_inv_lem
+val slot_s_inv_not_find_append_end_inv_lem
(t : Type0) (len : usize{len > 0}) (key : usize) (value : t) (ls : list (binding t)) :
Lemma
(requires (
- slot_inv len (hash_mod_key key len) ls /\
+ slot_s_inv len (hash_mod_key key len) ls /\
slot_find key ls == None))
(ensures (
let ls' = ls @ [(key,value)] in
- slot_inv len (hash_mod_key key len) ls' /\
+ slot_s_inv len (hash_mod_key key len) ls' /\
(slot_find key ls' == Some value) /\
(forall k'. k' <> key ==> slot_find k' ls' == slot_find k' ls)))
#push-options "--fuel 1"
-let rec slot_inv_not_find_append_end_inv_lem t len key value ls =
+let rec slot_s_inv_not_find_append_end_inv_lem t len key value ls =
match ls with
| [] -> ()
| (ck, cv) :: cls ->
- slot_inv_not_find_append_end_inv_lem t len key value cls;
+ slot_s_inv_not_find_append_end_inv_lem t len key value cls;
let h = hash_mod_key key len in
let ls' = ls @ [(key,value)] in
assert(for_all (same_hash_mod_key len h) ls');
slot_t_v_for_all_binding_neq_append_lem t key value cls (ck, cv);
assert(pairwise_rel binding_neq ls');
- assert(slot_inv len h ls')
+ assert(slot_s_inv len h ls')
#pop-options
/// [insert_in_list]: if the key is not in the map, appends a new bindings
@@ -978,20 +978,20 @@ val hash_map_insert_in_list_s_lem_append
(t : Type0) (len : usize{len > 0}) (key : usize) (value : t) (ls : list (binding t)) :
Lemma
(requires (
- slot_inv len (hash_mod_key key len) ls /\
+ slot_s_inv len (hash_mod_key key len) ls /\
slot_find key ls == None))
(ensures (
let ls' = hash_map_insert_in_list_s key value ls in
ls' == ls @ [(key,value)] /\
// The invariant is preserved
- slot_inv len (hash_mod_key key len) ls' /\
+ slot_s_inv len (hash_mod_key key len) ls' /\
// [key] maps to [value]
slot_find key ls' == Some value /\
// The other bindings are preserved
(forall k'. k' <> key ==> slot_find k' ls' == slot_find k' ls)))
let hash_map_insert_in_list_s_lem_append t len key value ls =
- slot_inv_not_find_append_end_inv_lem t len key value ls
+ slot_s_inv_not_find_append_end_inv_lem t len key value ls
/// [insert_in_list]: if the key is not in the map, appends a new bindings (quantifiers)
/// Rk.: we don't use this lemma.
@@ -1052,20 +1052,20 @@ let rec for_all_binding_neq_value_indep #t key v0 v1 ls =
| _ :: ls' -> for_all_binding_neq_value_indep #t key v0 v1 ls'
#pop-options
-val slot_inv_find_append_end_inv_lem
+val slot_s_inv_find_append_end_inv_lem
(t : Type0) (len : usize{len > 0}) (key : usize) (value : t) (ls : list (binding t)) :
Lemma
(requires (
- slot_inv len (hash_mod_key key len) ls /\
+ slot_s_inv len (hash_mod_key key len) ls /\
Some? (slot_find key ls)))
(ensures (
let ls' = find_update (same_key key) ls (key, value) in
- slot_inv len (hash_mod_key key len) ls' /\
+ slot_s_inv len (hash_mod_key key len) ls' /\
(slot_find key ls' == Some value) /\
(forall k'. k' <> key ==> slot_find k' ls' == slot_find k' ls)))
#push-options "--z3rlimit 50 --fuel 1"
-let rec slot_inv_find_append_end_inv_lem t len key value ls =
+let rec slot_s_inv_find_append_end_inv_lem t len key value ls =
match ls with
| [] -> ()
| (ck, cv) :: cls ->
@@ -1081,15 +1081,15 @@ let rec slot_inv_find_append_end_inv_lem t len key value ls =
for_all_binding_neq_value_indep key cv value cls;
assert(for_all (binding_neq (ck,value)) cls);
assert(pairwise_rel binding_neq ls');
- assert(slot_inv len (hash_mod_key key len) ls')
+ assert(slot_s_inv len (hash_mod_key key len) ls')
end
else
begin
- slot_inv_find_append_end_inv_lem t len key value cls;
+ slot_s_inv_find_append_end_inv_lem t len key value cls;
assert(for_all (same_hash_mod_key len h) ls');
slot_find_update_for_all_binding_neq_append_lem t key value cls (ck, cv);
assert(pairwise_rel binding_neq ls');
- assert(slot_inv len h ls')
+ assert(slot_s_inv len h ls')
end
#pop-options
@@ -1098,20 +1098,20 @@ val hash_map_insert_in_list_s_lem_update
(t : Type0) (len : usize{len > 0}) (key : usize) (value : t) (ls : list (binding t)) :
Lemma
(requires (
- slot_inv len (hash_mod_key key len) ls /\
+ slot_s_inv len (hash_mod_key key len) ls /\
Some? (slot_find key ls)))
(ensures (
let ls' = hash_map_insert_in_list_s key value ls in
ls' == find_update (same_key key) ls (key,value) /\
// The invariant is preserved
- slot_inv len (hash_mod_key key len) ls' /\
+ slot_s_inv len (hash_mod_key key len) ls' /\
// [key] maps to [value]
slot_find key ls' == Some value /\
// The other bindings are preserved
(forall k'. k' <> key ==> slot_find k' ls' == slot_find k' ls)))
let hash_map_insert_in_list_s_lem_update t len key value ls =
- slot_inv_find_append_end_inv_lem t len key value ls
+ slot_s_inv_find_append_end_inv_lem t len key value ls
/// [insert_in_list]: if the key is in the map, update the bindings
@@ -1146,11 +1146,11 @@ val hash_map_insert_in_list_s_lem
(t : Type0) (len : usize{len > 0}) (key : usize) (value : t) (ls : list (binding t)) :
Lemma
(requires (
- slot_inv len (hash_mod_key key len) ls))
+ slot_s_inv len (hash_mod_key key len) ls))
(ensures (
let ls' = hash_map_insert_in_list_s key value ls in
// The invariant is preserved
- slot_inv len (hash_mod_key key len) ls' /\
+ slot_s_inv len (hash_mod_key key len) ls' /\
// [key] maps to [value]
slot_find key ls' == Some value /\
// The other bindings are preserved
@@ -1203,16 +1203,16 @@ let hash_map_insert_in_list_back_lem t len key value ls =
(**** Refinement proof *)
/// Same strategy as for [insert_in_list]: we introduce a high-level version of
/// the function, and reason about it.
-/// We work on [hash_map_slots] (we use a higher-level view of the hash-map, but
+/// We work on [hash_map_slots_s] (we use a higher-level view of the hash-map, but
/// not too high).
let hash_map_insert_no_resize_s
- (#t : Type0) (hm : hash_map_slots t{length hm <= usize_max /\ length hm > 0})
+ (#t : Type0) (hm : hash_map_slots_s t{length hm <= usize_max /\ length hm > 0})
(key : usize) (value : t) :
- result (hash_map_slots t) =
+ result (hash_map_slots_s t) =
// Check if the table is saturated (too many entries, and we need to insert one)
let num_entries = length (flatten hm) in
- if None? (hash_map_slots_find_s hm key) && num_entries = usize_max then Fail
+ if None? (hash_map_slots_s_find hm key) && num_entries = usize_max then Fail
else
begin
let len = length hm in
@@ -1230,7 +1230,7 @@ val hash_map_insert_no_resize_fwd_back_lem
Lemma
(requires (
hash_map_t_inv self /\
- hash_map_slots_len_s (hash_map_t_slots_v self) = hash_map_t_len_s self))
+ hash_map_slots_s_len (hash_map_t_slots_v self) = hash_map_t_len_s self))
(ensures (
begin
match hash_map_insert_no_resize_fwd_back t self key value,
@@ -1239,7 +1239,7 @@ val hash_map_insert_no_resize_fwd_back_lem
| Fail, Fail -> True
| Return hm, Return hm_v ->
hash_map_t_slots_v hm == hm_v /\
- hash_map_slots_len_s hm_v = hash_map_t_len_s hm /\
+ hash_map_slots_s_len hm_v = hash_map_t_len_s hm /\
True
| _ -> False
end))
@@ -1287,7 +1287,7 @@ let hash_map_insert_no_resize_fwd_back_lem t self key value =
assert_norm(length [(key,value)] = 1);
assert(length (list_t_v l0) = length (list_t_v l) + 1);
length_flatten_update self_v hash_mod (list_t_v l0);
- assert(hash_map_slots_len_s hm_v = hash_map_t_len_s hm)
+ assert(hash_map_slots_s_len hm_v = hash_map_t_len_s hm)
end
end
end
@@ -1305,7 +1305,7 @@ let hash_map_insert_no_resize_fwd_back_lem t self key value =
assert(hm_v == list_update self_v hash_mod (list_t_v l0));
assert(length (list_t_v l0) = length (list_t_v l));
length_flatten_update self_v hash_mod (list_t_v l0);
- assert(hash_map_slots_len_s hm_v = hash_map_t_len_s hm)
+ assert(hash_map_slots_s_len hm_v = hash_map_t_len_s hm)
end
end
end
@@ -1317,18 +1317,18 @@ let hash_map_insert_no_resize_fwd_back_lem t self key value =
/// Lemmas about what happens if we call [find] after an insertion
val hash_map_insert_no_resize_s_get_same_lem
- (#t : Type0) (hm : hash_map_slots t)
+ (#t : Type0) (hm : hash_map_slots_s t)
(key : usize) (value : t) :
- Lemma (requires (hash_map_slots_inv hm))
+ Lemma (requires (hash_map_slots_s_inv hm))
(ensures (
match hash_map_insert_no_resize_s hm key value with
| Fail -> True
| Return hm' ->
- hash_map_slots_find_s hm' key == Some value))
+ hash_map_slots_s_find hm' key == Some value))
let hash_map_insert_no_resize_s_get_same_lem #t hm key value =
let num_entries = length (flatten hm) in
- if None? (hash_map_slots_find_s hm key) && num_entries = usize_max then ()
+ if None? (hash_map_slots_s_find hm key) && num_entries = usize_max then ()
else
begin
let hm' = Return?.v (hash_map_insert_no_resize_s hm key value) in
@@ -1339,18 +1339,18 @@ let hash_map_insert_no_resize_s_get_same_lem #t hm key value =
end
val hash_map_insert_no_resize_s_get_diff_lem
- (#t : Type0) (hm : hash_map_slots t)
+ (#t : Type0) (hm : hash_map_slots_s t)
(key : usize) (value : t) (key' : usize{key' <> key}) :
- Lemma (requires (hash_map_slots_inv hm))
+ Lemma (requires (hash_map_slots_s_inv hm))
(ensures (
match hash_map_insert_no_resize_s hm key value with
| Fail -> True
| Return hm' ->
- hash_map_slots_find_s hm' key' == hash_map_slots_find_s hm key'))
+ hash_map_slots_s_find hm' key' == hash_map_slots_s_find hm key'))
let hash_map_insert_no_resize_s_get_diff_lem #t hm key value key' =
let num_entries = length (flatten hm) in
- if None? (hash_map_slots_find_s hm key) && num_entries = usize_max then ()
+ if None? (hash_map_slots_s_find hm key) && num_entries = usize_max then ()
else
begin
let hm' = Return?.v (hash_map_insert_no_resize_s hm key value) in
@@ -1368,6 +1368,7 @@ let hash_map_insert_no_resize_s_get_diff_lem #t hm key value key' =
(*** remove_elements_from_list *)
+(*
type hash_map_slots_res (t : Type0) = res:result (hash_map_slots t){
match res with
| Fail -> True