Fold.v 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. (* SPDX-License-Identifier: GPL-2.0 or GPL-3.0
  2. Copyright © 2019 Ariadne Devos *)
  3. Require Import Coq.Lists.List.
  4. Require Import Coq.Lists.SetoidList.
  5. Require Import Coq.Classes.Equivalence.
  6. Require Import Coq.Classes.Morphisms.
  7. Require Import Coq.Relations.Relations.
  8. (* Fold a vector (by addition, multiplication ...) (represented as a list),
  9. with some lemma's for simplification. Assumes an identity element,
  10. commutativity and associativity.
  11. The fold function (badly named all, all_morphism), is modulo any
  12. equivalence relation (eqv, equiv) as long as the specified operator
  13. respects it (op, op_morphism). *)
  14. Section vector_fold.
  15. Variable A : Set.
  16. Variable eqv : A -> A -> Prop.
  17. Hypothesis equiv : Equivalence eqv.
  18. Variable op : A -> A -> A.
  19. Variable op_morphism : Proper (eqv ==> eqv ==> eqv) op.
  20. Variable identity : A.
  21. Hypothesis op_comm : forall x y, eqv (op x y) (op y x).
  22. Hypothesis op_assoc : forall x y z, eqv (op (op x y) z) (op x (op y z)).
  23. Hypothesis op_comm_identity_r : forall x, eqv (op x identity) x.
  24. Lemma op_comm_identity_l : forall x, eqv (op identity x) x.
  25. Proof. intro x. rewrite op_comm. apply op_comm_identity_r. Qed.
  26. Local Open Scope list_scope.
  27. (* TODO: not a good name.
  28. Combine all x in l by op with neutral element identity.
  29. (E.g., theta, sigma) *)
  30. (* TODO: perhaps allow non-commutative operators, in which
  31. case a choice must be made between fold_left and fold_right. *)
  32. Definition all l : A := fold_right op identity l.
  33. (* Depends: A eqv equiv op op_morphism identity *)
  34. Add Morphism all with
  35. signature (eqlistA eqv ==> eqv) as all_morphism.
  36. Proof.
  37. intros x y P.
  38. unfold all.
  39. exact (fold_right_eqlistA equiv identity op_morphism P).
  40. Qed.
  41. Theorem all_nil : eqv (all nil) identity.
  42. Proof. cbn. reflexivity. Qed.
  43. Theorem all_peel a l : eqv (op a (all l)) (all (a :: l)).
  44. Proof.
  45. unfold all.
  46. cbn.
  47. reflexivity.
  48. Qed.
  49. Theorem all_merge l m : eqv (op (all l) (all m)) (all (l ++ m)).
  50. Proof.
  51. induction l.
  52. + rewrite all_nil.
  53. apply op_comm_identity_l.
  54. + rewrite <- app_comm_cons.
  55. repeat rewrite <- all_peel.
  56. rewrite op_assoc.
  57. eapply op_morphism.
  58. - reflexivity.
  59. - assumption.
  60. Qed.
  61. Theorem all_identity_l0 l : eqv (all (identity :: l)) (all l).
  62. Proof.
  63. rewrite <- all_peel.
  64. rewrite op_comm_identity_l.
  65. reflexivity.
  66. Qed.
  67. Theorem all_identity_l1 l : eqv (all ((identity :: nil) ++ l)) (all l).
  68. Proof.
  69. rewrite <- all_merge.
  70. rewrite all_identity_l0.
  71. rewrite all_nil.
  72. rewrite op_comm_identity_l.
  73. reflexivity.
  74. Qed.
  75. Theorem all_identity_r l : eqv (all (l ++ (identity :: nil))) (all l).
  76. Proof.
  77. rewrite <- all_merge.
  78. rewrite all_identity_l0.
  79. rewrite all_nil.
  80. rewrite op_comm_identity_r.
  81. reflexivity.
  82. Qed.
  83. End vector_fold.