Skip to content

Commit 9da4a38

Browse files
committed
fold over finite maps
1 parent e00908b commit 9da4a38

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
@@ -907,3 +907,49 @@ proof. by apply fmap_eqP=> z; rewrite mergeE // !get_setE mergeE // /#. qed.
907907
lemma mem_pair_map (m1: ('a, 'b1)fmap) (m2: ('a, 'b2)fmap) x:
908908
(x \in pair_map m1 m2) = (x \in m1 /\ x \in m2).
909909
proof. by rewrite /dom mergeE // /#. qed.
910+
911+
(* -------------------------------------------------------------------- *)
912+
lemma fmap_ind (p : ('a, 'b) fmap -> bool):
913+
p empty
914+
=> (forall m k v, p (rem m k) => p m.[k <- v])
915+
=> forall m, p m.
916+
proof.
917+
move=> p_empty pS; elim/fmapW=> //.
918+
by move=> m k v; rewrite mem_fdom=> /rem_id {1}<- /pS ->.
919+
qed.
920+
921+
(* -------------------------------------------------------------------- *)
922+
op [opaque] fold (f : 'a -> 'b -> 'c -> 'c) z (m : ('a, 'b) fmap) =
923+
fold (fun x s=> f x (oget m.[x]) s) z (fdom m).
924+
925+
lemma foldE (f : 'a -> 'b -> 'c -> 'c) z m:
926+
fold f z m = fold (fun x s=> f x (oget m.[x]) s) z (fdom m).
927+
proof. by rewrite /fold. qed.
928+
929+
lemma fold0 (f : 'a -> 'b -> 'c -> 'c) z:
930+
fold f z empty = z.
931+
proof. by rewrite foldE fdom0 fold0. qed.
932+
933+
lemma fold1 (f : 'a -> 'b -> 'c -> 'c) z x y:
934+
fold f z empty.[x <- y] = f x y z.
935+
proof. by rewrite foldE fdom_set fdom0 fset0U fold1 /= get_set_sameE. qed.
936+
937+
lemma fold_set_neq (f : 'a -> 'b -> 'c -> 'c) z m x y:
938+
(forall a a' z,
939+
a \in m.[x <- y]
940+
=> a' \in m.[x <- y]
941+
=> f a (oget m.[x <- y].[a]) (f a' (oget m.[x <- y].[a']) z)
942+
= f a' (oget m.[x <- y].[a']) (f a (oget m.[x <- y].[a]) z))
943+
=> x \notin m
944+
=> fold f z m.[x <- y] = f x y (fold f z m).
945+
proof.
946+
move=> fCA x_notin_m; rewrite foldE fdom_set.
947+
rewrite (foldC_in x) /=.
948+
+ by move=> a a' b; smt(in_fsetU in_fset1 mem_set mem_fdom).
949+
+ by move=> /=; rewrite in_fsetU in_fset1.
950+
rewrite get_set_sameE fsetDK /oget /=.
951+
rewrite -fdom_rem rem_id //.
952+
congr; rewrite foldE; apply: eq_in_fold.
953+
move=> a /mem_fdom a_in_m /=.
954+
by rewrite get_set_neqE // -negP=> <<-.
955+
qed.

theories/datatypes/FSet.ec

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

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

0 commit comments

Comments
 (0)