Induction over relations
Question
I'm trying to prove the following toy theorem about the ordering of the naturals:
Inductive Le : nat -> nat -> Prop := | le_n : forall n, Le n n | le_S : forall n m, Le n m -> Le n (S m).forall n m : nat, Le (S n) m -> Le n m
On paper, this is a simple induction on Le (S n) m. In particular, the base case of le_n is trivial.
In Coq though, beginning my proof with induction gives me the following:
forall n m : nat, Le (S n) m -> Le n mn, m: nat
H: Le (S n) mLe n mn, n0: natLe n n0n, n0, m: nat
H: Le n0 m
IHLe: Le n mLe n (S m)
How should I proceed instead?
Answer (Vinz)
This is due to a limitation of Coq, when using induction on term that are not made only of variables. By doing your induction, Coq forgets about the fact that the first argument was a S of some n.
You can do the following instead:
forall X m : nat,
Le X m -> forall n : nat, X = S n -> Le n m
I think there is a dependent induction somewhere that could save you this intermediate lemma but I can't recall where.
Answer (Zimm i48)
Similar to @Vinz suggestion, but without changing the statement you are proving:
forall n m : nat, Le (S n) m -> Le n mforall n m : nat, Le (S n) m -> Le n mn, m: nat
H: Le (S n) mLe n mn, m, p: nat
Heqp: p = S n
H: Le p mLe n mn: natLe n (S n)n, m: nat
IHLe: S n = S n -> Le n m
H: Le (S n) mLe n (S m)do 2 constructor.n: natLe n (S n)n, m: nat
IHLe: S n = S n -> Le n m
H: Le (S n) mLe n (S m)now apply IHLe. Qed.n, m: nat
IHLe: S n = S n -> Le n m
H: Le (S n) mLe n m
Using the remember tactic will introduce an equality in your context which will avoid losing this critical information.
Answer (Anton Trunov)
This is happening because Coq treats differently indices and parameters (see the accepted answer to this question for a very nice explanation). Your Le relation uses indices only, whereas the standard definition makes the first argument a parameter:
I can recommend reading this blog post by James Wilcox. Here is a relevant excerpt:
When Coq performs a case analysis, it first abstracts over all indices. You may have seen this manifest as a loss of information when using destruct on predicates
So you can either (1) change your Le relation so it would use a parameter, or (2) use the remember tactic as was suggested by @Zimm i48, or (3) use the dependent induction tactic mentioned by @Vinz:
Require Import Coq.Program.Equality. (* for `dependent induction` *) Inductive Le : nat -> nat -> Prop := | le_n : forall n, Le n n | le_S : forall n m, Le n m -> Le n (S m).forall n m : nat, Le (S n) m -> Le n mforall n m : nat, Le (S n) m -> Le n mdependent induction H; auto. Qed.n, m: nat
H: Le (S n) mLe n m