Definition semi_group_fold {A: Type} (default: A) (f: A -> A -> A) (l: list A): A :=
match l with
| nil => default
| a :: l0 => fold_left f l0 a
end.
Section ListFun1'.
Context {A: Type}.
Context {RA: relation A}.
Context {EqRA: Equivalence RA}.
Instance proper_semi_group_fold: forall (f: A -> A -> A) (default: A) {Proper_f: Proper (equiv ==> equiv ==> equiv) f}, Proper (Forall2 equiv ==> equiv) (semi_group_fold default f).

Lemma comm_semi_group_fold_perm: forall {f} {Proper_f: Proper (equiv ==> equiv ==> equiv) f} (default: A) l l',
(forall x y, f x y === f y x) ->
(forall x y z, f (f x y) z === f x (f y z)) ->
Permutation l l' ->
semi_group_fold default f l === semi_group_fold default f l'.