aboutsummaryrefslogtreecommitdiff
path: root/src/Util/IterAssocOp.v
blob: 8629ae784b1f99ae1a6f11d2db343b5a2fdbe0c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Require Import Coq.Setoids.Setoid Coq.Classes.Morphisms Coq.Classes.Equivalence.
Require Import NArith BinPosDef.
Local Open Scope equiv_scope.

Generalizable All Variables.
Section IterAssocOp.
  Context `{Equivalence T}
          (op:T->T->T) {op_proper:Proper (equiv==>equiv==>equiv) op}
          (assoc: forall a b c, op a (op b c) === op (op a b) c)
          (neutral:T) (neutral_neutral : forall a, op a neutral === a).
  Existing Instance op_proper.

  Fixpoint nat_iter_op n a :=
    match n with
    | 0%nat => neutral
    | S n' => op a (nat_iter_op n' a)
    end.

  Definition N_iter_op n a :=
    match n with
    | 0%N => neutral
    | Npos p => Pos.iter_op op p a
    end.

  Lemma Pos_iter_op_succ : forall p a, Pos.iter_op op (Pos.succ p) a === op a (Pos.iter_op op p a).
  Proof.
   induction p; intros; simpl; rewrite ?assoc, ?IHp; reflexivity.
  Qed.

  Lemma N_iter_op_succ : forall n a, N_iter_op (N.succ n) a  === op a (N_iter_op n a).
  Proof.
    destruct n; simpl; intros; rewrite ?Pos_iter_op_succ, ?neutral_neutral; reflexivity.
  Qed.

  Lemma N_iter_op_is_nat_iter_op : forall n a, N_iter_op n a === nat_iter_op (N.to_nat n) a.
  Proof.
    induction n using N.peano_ind; intros; rewrite ?N2Nat.inj_succ, ?N_iter_op_succ, ?IHn; reflexivity.
  Qed.
End IterAssocOp.