(** Earlier, the Peano-like recursor was built and proved in a way due to
    Conor McBride, see "The view from the left" *)

Inductive PeanoView : positive -> Type :=
| PeanoOne : PeanoView 1
| PeanoSucc : forall p, PeanoView p -> PeanoView (succ p).(** Earlier, the Peano-like recursor was built and proved in a way due to
    Conor McBride, see "The view from the left" *)

Inductive PeanoView : positive -> Type :=
| PeanoOne : PeanoView 1
| PeanoSucc : forall p, PeanoView p -> PeanoView (succ p).(** Earlier, the Peano-like recursor was built and proved in a way due to
    Conor McBride, see "The view from the left" *)

Inductive PeanoView : positive -> Type :=
| PeanoOne : PeanoView 1
| PeanoSucc : forall p, PeanoView p -> PeanoView (succ p).Fixpoint peanoView_xO p (q:PeanoView p) : PeanoView (p~0) :=
  match q in PeanoView x return PeanoView (x~0) with
    | PeanoOne => PeanoSucc _ PeanoOne
    | PeanoSucc _ q => PeanoSucc _ (PeanoSucc _ (peanoView_xO _ q))
  end.Fixpoint peanoView_xI p (q:PeanoView p) : PeanoView (p~1) :=
  match q in PeanoView x return PeanoView (x~1) with
    | PeanoOne => PeanoSucc _ (PeanoSucc _ PeanoOne)
    | PeanoSucc _ q => PeanoSucc _ (PeanoSucc _ (peanoView_xI _ q))
  end.Fixpoint peanoView p : PeanoView p :=
  match p return PeanoView p with
    | 1 => PeanoOne
    | p~0 => peanoView_xO p (peanoView p)
    | p~1 => peanoView_xI p (peanoView p)
  end.Definition PeanoView_iter (P:positive->Type)
  (a:P 1) (f:forall p, P p -> P (succ p)) :=
  (fix iter p (q:PeanoView p) : P p :=
    match q in PeanoView p return P p with
      | PeanoOne => a
      | PeanoSucc _ q => f _ (iter _ q)
    end).

(* Specifications: *)
Theorem eq_dep_eq_positive : forall (P:positive->Type) (p:positive) (x y:P p), eq_dep positive P p x p y -> x = y.
Theorem PeanoViewUnique : forall p (q q':PeanoView p), q = q'.
Lemma peano_equiv (P:positive->Type) (a:P 1) (f:forall p, P p -> P (succ p)) p : PeanoView_iter P a f p (peanoView p) = peano_rect P a f p.
Lemma mul_1_l p : 1 * p = p.
Lemma mul_1_r p : p * 1 = p.
Lemma mul_xO_r p q : p * q~0 = (p * q)~0.
Lemma mul_xI_r p q : p * q~1 = p + (p * q)~0.
Theorem mul_comm p q : p * q = q * p.
Theorem mul_add_distr_l p q r : p * (q + r) = p * q + p * r.
Theorem mul_add_distr_r p q r : (p + q) * r = p * r + q * r.
Theorem mul_assoc p q r : p * (q * r) = p * q * r.
Lemma mul_succ_l p q : (succ p) * q = q + p * q.
Lemma mul_succ_r p q : p * (succ q) = p + p * q.
Lemma mul_xI_mul_xO_discr p q r : p~1 * r <> q~0 * r.
Lemma mul_xO_discr p q : p~0 * q <> q.
Theorem mul_reg_r p q r : p * r = q * r -> p = q.
Theorem mul_reg_l p q r : r * p = r * q -> p = q.
Lemma mul_cancel_r p q r : p * r = q * r <-> p = q.
Lemma mul_cancel_l p q r : r * p = r * q <-> p = q.
Lemma mul_eq_1_l p q : p * q = 1 -> p = 1.
Lemma mul_eq_1_r p q : p * q = 1 -> q = 1.