123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- (* SPDX-License-Identifier: GPL-2.0 or GPL-3.0
- Copyright © 2019 Ariadne Devos *)
- Require Import Coq.Lists.List.
- Require Import Coq.Lists.SetoidList.
- Require Import Coq.Classes.Equivalence.
- Require Import Coq.Classes.Morphisms.
- Require Import Coq.Relations.Relations.
- (* Fold a vector (by addition, multiplication ...) (represented as a list),
- with some lemma's for simplification. Assumes an identity element,
- commutativity and associativity.
- The fold function (badly named all, all_morphism), is modulo any
- equivalence relation (eqv, equiv) as long as the specified operator
- respects it (op, op_morphism). *)
- Section vector_fold.
- Variable A : Set.
- Variable eqv : A -> A -> Prop.
- Hypothesis equiv : Equivalence eqv.
- Variable op : A -> A -> A.
- Variable op_morphism : Proper (eqv ==> eqv ==> eqv) op.
- Variable identity : A.
- Hypothesis op_comm : forall x y, eqv (op x y) (op y x).
- Hypothesis op_assoc : forall x y z, eqv (op (op x y) z) (op x (op y z)).
- Hypothesis op_comm_identity_r : forall x, eqv (op x identity) x.
- Lemma op_comm_identity_l : forall x, eqv (op identity x) x.
- Proof. intro x. rewrite op_comm. apply op_comm_identity_r. Qed.
- Local Open Scope list_scope.
- (* TODO: not a good name.
- Combine all x in l by op with neutral element identity.
- (E.g., theta, sigma) *)
- (* TODO: perhaps allow non-commutative operators, in which
- case a choice must be made between fold_left and fold_right. *)
-
- Definition all l : A := fold_right op identity l.
- (* Depends: A eqv equiv op op_morphism identity *)
- Add Morphism all with
- signature (eqlistA eqv ==> eqv) as all_morphism.
- Proof.
- intros x y P.
- unfold all.
- exact (fold_right_eqlistA equiv identity op_morphism P).
- Qed.
- Theorem all_nil : eqv (all nil) identity.
- Proof. cbn. reflexivity. Qed.
- Theorem all_peel a l : eqv (op a (all l)) (all (a :: l)).
- Proof.
- unfold all.
- cbn.
- reflexivity.
- Qed.
- Theorem all_merge l m : eqv (op (all l) (all m)) (all (l ++ m)).
- Proof.
- induction l.
- + rewrite all_nil.
- apply op_comm_identity_l.
- + rewrite <- app_comm_cons.
- repeat rewrite <- all_peel.
- rewrite op_assoc.
- eapply op_morphism.
- - reflexivity.
- - assumption.
- Qed.
- Theorem all_identity_l0 l : eqv (all (identity :: l)) (all l).
- Proof.
- rewrite <- all_peel.
- rewrite op_comm_identity_l.
- reflexivity.
- Qed.
- Theorem all_identity_l1 l : eqv (all ((identity :: nil) ++ l)) (all l).
- Proof.
- rewrite <- all_merge.
- rewrite all_identity_l0.
- rewrite all_nil.
- rewrite op_comm_identity_l.
- reflexivity.
- Qed.
- Theorem all_identity_r l : eqv (all (l ++ (identity :: nil))) (all l).
- Proof.
- rewrite <- all_merge.
- rewrite all_identity_l0.
- rewrite all_nil.
- rewrite op_comm_identity_r.
- reflexivity.
- Qed.
- End vector_fold.
|