Induction principle for le
Question
For the inductive type nat, the generated induction principle uses the constructors O and S in its statement:
But for le, the generated statement does not uses the constructors le_n and le_S:
However it is possible to state and prove an induction principle following the same shape as the one for nat:
forall (n : nat) (P : forall m : nat, n <= m -> Prop), P n (le_n n) -> (forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)) -> forall (m : nat) (p : n <= m), P m pforall (n : nat) (P : forall m : nat, n <= m -> Prop), P n (le_n n) -> (forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)) -> forall (m : nat) (p : n <= m), P m pH: forall (n : nat) (P : forall m : nat, n <= m -> Prop), P n (le_n n) -> (forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)) -> forall (m : nat) (p : n <= m), P m pforall (n : nat) (P : forall m : nat, n <= m -> Prop), P n (le_n n) -> (forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)) -> forall (m : nat) (p : n <= m), P m pH: forall (n : nat) (P : forall m : nat, n <= m -> Prop), P n (le_n n) -> (forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)) -> forall (m : nat) (p : n <= m), P m p
n: nat
P: forall m : nat, n <= m -> Prop
H0: P n (le_n n)
H1: forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)
m: nat
p: n <= mP m pH: forall (n : nat) (P : forall m : nat, n <= m -> Prop), P n (le_n n) -> (forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)) -> forall (m : nat) (p : n <= m), P m p
n: nat
P: forall m : nat, n <= m -> Prop
H0: P n (le_n n)
H1: forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)P n (le_n n)H: forall (n : nat) (P : forall m : nat, n <= m -> Prop), P n (le_n n) -> (forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)) -> forall (m : nat) (p : n <= m), P m p
n: nat
P: forall m : nat, n <= m -> Prop
H0: P n (le_n n)
H1: forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)
m: nat
p: n <= mP (S m) (le_S n m p)apply H0.H: forall (n : nat) (P : forall m : nat, n <= m -> Prop), P n (le_n n) -> (forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)) -> forall (m : nat) (p : n <= m), P m p
n: nat
P: forall m : nat, n <= m -> Prop
H0: P n (le_n n)
H1: forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)P n (le_n n)H: forall (n : nat) (P : forall m : nat, n <= m -> Prop), P n (le_n n) -> (forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)) -> forall (m : nat) (p : n <= m), P m p
n: nat
P: forall m : nat, n <= m -> Prop
H0: P n (le_n n)
H1: forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)
m: nat
p: n <= mP (S m) (le_S n m p)H: forall (n : nat) (P : forall m : nat, n <= m -> Prop), P n (le_n n) -> (forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)) -> forall (m : nat) (p : n <= m), P m p
n: nat
P: forall m : nat, n <= m -> Prop
H0: P n (le_n n)
H1: forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)
m: nat
p: n <= mP n (le_n n)H: forall (n : nat) (P : forall m : nat, n <= m -> Prop), P n (le_n n) -> (forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)) -> forall (m : nat) (p : n <= m), P m p
n: nat
P: forall m : nat, n <= m -> Prop
H0: P n (le_n n)
H1: forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)
m: nat
p: n <= mforall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)apply H1. Qed.H: forall (n : nat) (P : forall m : nat, n <= m -> Prop), P n (le_n n) -> (forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)) -> forall (m : nat) (p : n <= m), P m p
n: nat
P: forall m : nat, n <= m -> Prop
H0: P n (le_n n)
H1: forall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)
m: nat
p: n <= mforall (m : nat) (p : n <= m), P m p -> P (S m) (le_S n m p)
I guess the generated one is more convenient. But how does Coq chooses the shape for its generated induction principle? If there is any rule, I cannot find them in the reference manual. What about other proof assistants such as Agda?
Answer
You can manually generate an induction principle for an inductive type by using the command Scheme (see the documentation).
The command comes in two flavours:
Scheme scheme := Induction for Sort Prop generates the standard induction scheme.
Scheme scheme := Minimality for Sort Prop generates a simplified induction scheme more suited to inductive predicates.
If you define an inductive type in Type, the generated induction principle is of the first kind. If you define an inductive type in Prop (i.e. an inductive predicate), the generated induction principle is of the second kind.
To obtain the induction principle that you want in the case of le, you can define it in Type:
Inductive le (n : nat) : nat -> Type := | le_n : le n n | le_S : forall m : nat, le n m -> le n (S m).
or you can manually ask Coq to generate the expected induction principle:
Inductive le (n : nat) : nat -> Prop := | le_n : le n n | le_S : forall m : nat, le n m -> le n (S m).Scheme le_ind2 := Induction for le Sort Prop.