(** All operations are well-defined (trivial here since eq is Leibniz) *)

Definition eq_equiv : Equivalence (@eq nat) := eq_equivalence.#[global] Program Instance succ_wd : Proper (eq==>eq) S.#[global] Program Instance pred_wd : Proper (eq==>eq) pred.#[global] Program Instance add_wd : Proper (eq==>eq==>eq) plus.#[global] Program Instance sub_wd : Proper (eq==>eq==>eq) minus.#[global] Program Instance mul_wd : Proper (eq==>eq==>eq) mult.#[global] Program Instance pow_wd : Proper (eq==>eq==>eq) pow.#[global] Program Instance div_wd : Proper (eq==>eq==>eq) div.#[global] Program Instance mod_wd : Proper (eq==>eq==>eq) modulo.#[global] Program Instance lt_wd : Proper (eq==>eq==>iff) lt.#[global] Program Instance testbit_wd : Proper (eq==>eq==>eq) testbit.

Theorem bi_induction : forall A : nat -> Prop, Proper (eq==>iff) A -> A 0 -> (forall n : nat, A n <-> A (S n)) -> forall n : nat, A n.