@@ -200,6 +200,9 @@ lemma remE ['a 'b] (m : ('a, 'b) fmap) x y :
200200 (rem m x).[y] = if y = x then None else m.[y].
201201proof. by rewrite /rem /"_.[_]" rem_valE SmtMap.get_setE. qed.
202202
203+ lemma rem_set (m: (' a, ' b) fmap) x: x \i n m => (rem m x).[x <- oget m.[x]] = m.
204+ proof. move => x_in; apply fmap_eqP => y; rewrite get_setE remE /#. qed.
205+
203206(* -------------------------------------------------------------------- *)
204207lemma mem_rem [' a ' b] (m : (' a, ' b) fmap) x y :
205208 y \i n (rem m x) <=> (y \i n m /\ y <> x).
@@ -529,6 +532,44 @@ lemma mem_fdom_rem ['a 'b] (m : ('a, 'b) fmap) x y :
529532 y \in fdom (rem m x) <=> (y \in fdom m /\ y <> x).
530533proof. by rewrite fdom_rem in_fsetD1. qed.
531534
535+ (* ==================================================================== *)
536+ op offset (s: ' a fset): (' a, unit) fmap =
537+ ofmap (offun (fun e => if e \in s then Some () else None)).
538+
539+ lemma mem_offset (s: ' a fset) x: x \i n (offset s) <=> x \i n s.
540+ proof.
541+ rewrite /dom getE ofmapK.
542+ - move: (FSet.finite_mem s).
543+ apply/eq_ind/fun_ext => y.
544+ rewrite offunE /#.
545+ rewrite offunE /#.
546+ qed.
547+
548+ lemma offset_get s (e: ' a): (offset s).[e] = if e \in s then Some () else None.
549+ proof.
550+ rewrite getE /ofset ofmapK.
551+ - move: (FSet.finite_mem s).
552+ apply/eq_ind/fun_ext => y.
553+ rewrite offunE /#.
554+ rewrite offunE /#.
555+ qed.
556+
557+ lemma offsetK: cancel offset fdom<:' a, unit>.
558+ proof. move => s; rewrite fsetP => x; by rewrite mem_fdom mem_offset. qed.
559+
560+ (* ==================================================================== *)
561+ op offsetmap (f: ' a -> ' b) (s: ' a fset) : (' a, ' b) fmap =
562+ map (fun x y => f x) (offset s).
563+
564+ lemma offsetmapT (s: ' a fset) (f: ' a -> ' b) e: e \i n s => (offsetmap f s).[e] = Some (f e).
565+ proof. by move => e_in; rewrite /offsetmap mapE offset_get e_in. qed.
566+
567+ lemma offsetmapN (s: ' a fset) (f: ' a -> ' b) e: e \notin s => (offsetmap f s).[e] = None.
568+ proof. by move => e_in; rewrite /offsetmap mapE offset_get e_in. qed.
569+
570+ lemma mem_offsetmap s (f: ' a -> ' b) e: e \in offsetmap f s <=> e \in s.
571+ proof. by rewrite /offsetmap mem_map mem_offset. qed.
572+
532573(* ==================================================================== *)
533574op [opaque] frng ['a 'b] (m : (' a, ' b) fmap) = oflist (to_seq (rng m)).
534575lemma frngE (m : (' a, ' b) fmap): frng m = oflist (to_seq (rng m)).
@@ -741,6 +782,16 @@ lemma fsize_set (m : ('a, 'b) fmap) k v :
741782 fsize m.[k <- v] = b2i (k \n otin m) + fsize m.
742783proof. by rewrite /fsize fdom_set fcardU1 mem_fdom. qed.
743784
785+ lemma fsize0_empty (m: (' a, ' b) fmap): fsize m = 0 => m = empty.
786+ proof.
787+ move: m; apply fmapW => [//| /= m k v].
788+ rewrite mem_fdom fsize_set =>->_/=.
789+ smt(ge0_fsize).
790+ qed.
791+
792+ lemma fsize_map m (f: ' a -> ' b -> ' c): fsize (map f m) = fsize m.
793+ proof. by rewrite /fsize fdom_map. qed.
794+
744795(* ==================================================================== *)
745796
746797(* f-collisions (i.e. collisions under some function f) *)
0 commit comments