Transferring proof from Z to N in Coq
Question
Is there a way in Coq in to prove a statement for integer numbers and the transfer statement in a semi-automatic way to naturals?
For a concrete example, take the following lemma:
forall a b c : nat, a > 0 -> a * b = a * c -> b = c
The statement is actually true in Z. In this case, it is easier to prove, because one can use subtraction to get a * (b - c) = 0 and then simplify a. But subtraction for naturals is capped, hence this would not work.
Assume I can prove this for integers. Is there some tactic that one could use to derive the statement for naturals as well?
Answer
One solution is a tactic called zify that automatically turns a goal manipulating naturals into a goal manipulating integers (e.g., by inserting appropriate calls to Z.of_nat). This tactic is internally called by lia, but does not seem to be well documented. It is at least mentioned here.
In your case, this would give the following.
Require Import ZArith. (* The lemma stated in Z. *)forall a b c : Z, (a > 0)%Z -> (a * b)%Z = (a * c)%Z -> b = c(* your favorite proof of this result *) Admitted. (* The lemma stated in nat. *)forall a b c : Z, (a > 0)%Z -> (a * b)%Z = (a * c)%Z -> b = cforall a b c : nat, a > 0 -> a * b = a * c -> b = cforall a b c : nat, a > 0 -> a * b = a * c -> b = ca, b, c: nat
H: a > 0
H0: a * b = a * cb = ceauto using cancellation. Qed.a, b, c: nat
H0: (Z.of_nat a * Z.of_nat b)%Z = (Z.of_nat a * Z.of_nat c)%Z
H: (Z.of_nat a > 0)%Z
cstr: (0 <= Z.of_nat a)%Z
cstr0: (0 <= Z.of_nat b)%Z
cstr1: (0 <= Z.of_nat c)%Z
__sat: (0 <= Z.of_nat a * Z.of_nat c)%Z
__sat0: (0 <= Z.of_nat a * Z.of_nat b)%ZZ.of_nat b = Z.of_nat c