723723(* -------------------------------------------------------------------- *)
724724op [opaque] fold (f : ' a -> ' b -> ' b) (z : ' b) (A : ' a fset) : 'b =
725725 foldr f z (elems A).
726+
726727lemma foldE (f : ' a -> ' b -> ' b) z A: fold f z A = foldr f z (elems A).
727728proof. by rewrite/fold. qed.
728729
@@ -733,20 +734,29 @@ lemma fold1 (f : 'a -> 'b -> 'b) (z : 'b) (a : 'a):
733734 fold f z (fset1 a) = f a z.
734735proof. by rewrite foldE elems_fset1. qed.
735736
736- lemma foldC (a : ' a) (f : ' a -> ' b -> ' b) (z : ' b) (A : ' a fset):
737- (forall a a' b, f a (f a' b) = f a' (f a b)) =>
738- mem A a =>
737+ lemma foldC_in (a : ' a) (f : ' a -> ' b -> ' b) (z : ' b) (A : ' a fset):
738+ (forall a a' b, a \i n A => a ' \in A => f a (f a' b) = f a' (f a b)) =>
739+ a \in A =>
739740 fold f z A = f a (fold f z (A `\` fset1 a)).
740741proof.
741- move=> f_commutative a_in_A; rewrite !foldE (foldr_rem a)// 1:-memE//.
742- congr; apply/foldr_perm=> // .
743- rewrite setDE rem_filter 1 :uniq_elems// .
744- have ->: predC (mem (fset1 a)) = predC1 a (* FIXME: views *)
745- by apply/fun_ext=> x; rewrite /predC /predC1 in_fset1.
746- rewrite -{1 }(undup_id (filter (predC1 a) (elems A))) 2 :oflistK// .
747- by apply/filter_uniq/uniq_elems.
742+ move=> f_commutative a_in_A; rewrite !foldE (foldr_rem_in a) // .
743+ + by move=> z0 x y; rewrite -!memE; exact:f_commutative.
744+ + by rewrite -memE.
745+ congr; apply/foldr_perm_in=> // .
746+ + move=> z0 x y /mem_rem + /mem_rem; rewrite -!memE; exact:f_commutative.
747+ rewrite setDE rem_filter 1 :uniq_elems// .
748+ have ->: predC (mem (fset1 a)) = predC1 a (* FIXME: views *)
749+ by apply/fun_ext=> x; rewrite /predC /predC1 in_fset1.
750+ rewrite -{1 }(undup_id (filter (predC1 a) (elems A))) 2 :oflistK// .
751+ by apply/filter_uniq/uniq_elems.
748752qed.
749753
754+ lemma foldC (a : ' a) (f : ' a -> ' b -> ' b) (z : ' b) (A : ' a fset):
755+ (forall a a' b, f a (f a' b) = f a' (f a b)) =>
756+ a \in A =>
757+ fold f z A = f a (fold f z (A `\` fset1 a)).
758+ proof. by move=> f_commutative; apply: foldC_in=> + + + _ _. qed.
759+
750760(* -------------------------------------------------------------------- *)
751761
752762op rangeset (m n : int ) = oflist (range m n).
0 commit comments