Induction over a type containing pairs - coq/coq GitHub Wiki
This Coq-club thread discusses how to do induction over types such as
Inductive foo : nat * nat -> Prop :=
| foo1 : forall i j k, i = j + k -> foo (i, j)
| foo2 : forall i j k, foo (i, j + k) -> foo (i, j).
Naively applying induction will forget the structure of foo's argument.
Doing induction on a term that does not contain only variables (there is a pair and a sum in (n, m+p)
). The first way to go is to reshape your hypothesis on which you do induction so it contains only variables. Example:
Require Import Omega.
Inductive foo : nat * nat -> Prop :=
| foo1 : forall i j k, i = j + k -> foo (i, j)
| foo2 : forall i j k, foo (i, j + k) -> foo (i, j).
Lemma bar : forall n m p, foo (n, m + p) -> m <= n.
intros n m p H.
assert (Haux: forall u, foo u -> forall p, u = (n, m + p) -> m <= n).
intros u Hu; elim Hu; intros i j k.
intros Eq1 p1 Eq2; injection Eq2; intros; omega.
intros _ Hrec p1 Eq2; apply Hrec with (p1 + k).
apply f_equal2 with (f := @pair nat nat); injection Eq2; intros; omega.
apply Haux with (1 := H) (p := p); trivial.
Qed.
The second way to go is to reshape your conclusion so it explicitly exhibits the dependancy with the term that is not a variable in your case (n, m + p)
. Example:
Lemma bar1 : forall n m p, foo (n, m + p) -> m <= n.
intros n m p H.
replace m with ((m + p) - p); try omega.
change ((fun x => (snd x - p <= fst x)) (n, m + p)).
elim H; simpl; intros; omega.
Qed.