Skip to content

Commit 3877abe

Browse files
committed
fold over finite maps
1 parent dbb6b54 commit 3877abe

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

theories/datatypes/FMap.ec

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,3 +958,49 @@ proof. by apply fmap_eqP=> z; rewrite mergeE // !get_setE mergeE // /#. qed.
958958
lemma mem_pair_map (m1: ('a, 'b1)fmap) (m2: ('a, 'b2)fmap) x:
959959
(x \in pair_map m1 m2) = (x \in m1 /\ x \in m2).
960960
proof. by rewrite /dom mergeE // /#. qed.
961+
962+
(* -------------------------------------------------------------------- *)
963+
lemma fmap_ind (p : ('a, 'b) fmap -> bool):
964+
p empty
965+
=> (forall m k v, p (rem m k) => p m.[k <- v])
966+
=> forall m, p m.
967+
proof.
968+
move=> p_empty pS; elim/fmapW=> //.
969+
by move=> m k v; rewrite mem_fdom=> /rem_id {1}<- /pS ->.
970+
qed.
971+
972+
(* -------------------------------------------------------------------- *)
973+
op [opaque] fold (f : 'a -> 'b -> 'c -> 'c) z (m : ('a, 'b) fmap) =
974+
fold (fun x s=> f x (oget m.[x]) s) z (fdom m).
975+
976+
lemma foldE (f : 'a -> 'b -> 'c -> 'c) z m:
977+
fold f z m = fold (fun x s=> f x (oget m.[x]) s) z (fdom m).
978+
proof. by rewrite /fold. qed.
979+
980+
lemma fold0 (f : 'a -> 'b -> 'c -> 'c) z:
981+
fold f z empty = z.
982+
proof. by rewrite foldE fdom0 fold0. qed.
983+
984+
lemma fold1 (f : 'a -> 'b -> 'c -> 'c) z x y:
985+
fold f z empty.[x <- y] = f x y z.
986+
proof. by rewrite foldE fdom_set fdom0 fset0U fold1 /= get_set_sameE. qed.
987+
988+
lemma fold_set_neq (f : 'a -> 'b -> 'c -> 'c) z m x y:
989+
(forall a a' z,
990+
a \in m.[x <- y]
991+
=> a' \in m.[x <- y]
992+
=> f a (oget m.[x <- y].[a]) (f a' (oget m.[x <- y].[a']) z)
993+
= f a' (oget m.[x <- y].[a']) (f a (oget m.[x <- y].[a]) z))
994+
=> x \notin m
995+
=> fold f z m.[x <- y] = f x y (fold f z m).
996+
proof.
997+
move=> fCA x_notin_m; rewrite foldE fdom_set.
998+
rewrite (foldC_in x) /=.
999+
+ by move=> a a' b; smt(in_fsetU in_fset1 mem_set mem_fdom).
1000+
+ by move=> /=; rewrite in_fsetU in_fset1.
1001+
rewrite get_set_sameE fsetDK /oget /=.
1002+
rewrite -fdom_rem rem_id //.
1003+
congr; rewrite foldE; apply: eq_in_fold.
1004+
move=> a /mem_fdom a_in_m /=.
1005+
by rewrite get_set_neqE // -negP=> <<-.
1006+
qed.

theories/datatypes/FSet.ec

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,14 @@ lemma foldC (a : 'a) (f : 'a -> 'b -> 'b) (z : 'b) (A : 'a fset):
757757
fold f z A = f a (fold f z (A `\` fset1 a)).
758758
proof. by move=> f_commutative; apply: foldC_in=> + + + _ _. qed.
759759

760+
lemma eq_in_fold (f g : 'a -> 'b -> 'b) (z : 'b) (A : 'a fset):
761+
(forall a, a \in A => f a = g a) =>
762+
fold f z A = fold g z A.
763+
proof.
764+
move=> f_eq_in; rewrite !foldE.
765+
by apply: eq_in_foldr=> // x; rewrite -memE=> /f_eq_in.
766+
qed.
767+
760768
(* -------------------------------------------------------------------- *)
761769
762770
op rangeset (m n : int) = oflist (range m n).

0 commit comments

Comments
 (0)