Search code examples
coqproof

Coq - proving something which has already been defined?


Taking the very straightforward proof of "the sum of two naturals is odd if one of them is even and the other odd":

Require Import Arith.
Require Import Coq.omega.Omega.

Definition even (n: nat) := exists k, n = 2 * k.
Definition odd  (n: nat) := exists k, n = 2 * k + 1.

Lemma sum_odd_even : forall n m, odd (n + m) -> odd n /\ even m \/ even n /\ odd m.
Proof.
  intros n. intros m. left.
  destruct H. firstorder.

The state at the end of this block of code is:

2 subgoals
n, m, x : nat
H : n + m = 2 * x + 1
______________________________________(1/2)
odd n
______________________________________(2/2)
even m

To my understanding, it is telling me that I need to prove to it that I have an odd number n and an even number m through the hypothesis? Even though I have already stated than n is odd and m is even? How do I proceed from here?

UPDATE:

After a bit of fidgeting around (in light of the comments), I guess I would have to do something like this?

Lemma even_or_odd: forall (n: nat), even n \/ odd n.
Proof.
  induction n as [|n IHn].
  (* Base Case *)
  left. unfold even. exists 0. firstorder.
  (* step case *)
  destruct IHn as [IHeven | IHodd].
  right. unfold even in IHeven. destruct IHeven as [k Heq].
  unfold odd. exists k. firstorder.
  left. unfold odd in IHodd. destruct IHodd as [k Heq].
  unfold even. exists (k + 1). firstorder.
Qed.

Which means that now:

Lemma sum_odd : forall n m, odd (n + m) -> odd n /\ even m \/ even n /\ odd m.
Proof.
  intros n. intros m. left. destruct H. firstorder.
  pose proof (even_or_odd n). pose proof (even_or_odd m).

Result:

    2 subgoals
n, m, x : nat
H : n + m = 2 * x + 1
H0 : even n \/ odd n
H1 : even m \/ odd m
______________________________________(1/2)
odd n
______________________________________(2/2)
even m

Intuitively, all that I have done is saying that every number is either even or odd. Now I have to tell coq that my odd and even numbers are indeed odd and even (I guess?).

UPDATE 2:

As an aside, the problem is solvable with just firstorder:

Lemma sum_odd : forall n m, odd (n + m) -> odd n /\ even m \/ even n /\ odd m.
Proof.
  intros n. intros m. firstorder.
  pose proof (even_or_odd n). pose proof (even_or_odd m).
  destruct H0 as [Even_n | Odd_n]. destruct H1 as [Even_m | Odd_m].
  exfalso. firstorder.
  right. auto.
  destruct H1. left. auto.
  exfalso. firstorder.
Qed.

Solution

  • Your use of left is still incorrect and keeps you from completing the proof. You apply it to the following goal:

    odd (n + m) -> odd n /\ even m \/ even n /\ odd m
    

    and it gives:

    H : odd (n + m)
    ______________________________________(1/1)
    odd n /\ even m
    

    You are committing to proving that if n + m is odd, then n is odd and m is even. But this is not true: n might be odd and m might be even. Only apply left or right once you have enough information in the context to be sure which one you want to prove.

    So let's restart without left:

    Lemma sum_odd : forall n m, odd (n + m) -> odd n /\ even m \/ even n /\ odd m.
    Proof.
      intros n. intros m. firstorder.
      pose proof (even_or_odd n). pose proof (even_or_odd m).
    

    At this point we are at:

    H : n + m = 2 * x + 1
    H0 : even n \/ odd n
    H1 : even m \/ odd m
    ______________________________________(1/1)
    odd n /\ even m \/ even n /\ odd m
    

    Now you want to prove something from disjunctions. In order to prove something of the form A \/ B -> C in Coq's constructive logic, you must prove both A -> C and B -> C. You do this by case analysis on the A \/ B (using destruct or other tactics). In this case we have two disjunctions to decompose:

      destruct H0 as [Even_n | Odd_n], H1 as [Even_m | Odd_m].
    

    This gives four cases. I'll show you the first two, the last two are symmetric.

    Fist case:

    H : n + m = 2 * x + 1
    Even_n : even n
    Even_m : even m
    ______________________________________(1/1)
    odd n /\ even m \/ even n /\ odd m
    

    The assumptions are contradictory: If both n and m are even, then H cannot hold. We can prove this as follows:

      - exfalso. destruct Even_n, Even_m. omega.
    

    (Step through this to understand what happens!) The exfalso is not really necessary, but it's good documentation that we are doing a proof by showing that the assumptions contradict.

    Second case:

    H : n + m = 2 * x + 1
    Even_n : even n
    Odd_m : odd m
    ______________________________________(1/1)
    odd n /\ even m \/ even n /\ odd m
    

    Now, knowing assumptions that apply in this case, we can commit to the right disjunct. This is why your left kept you from making progress!

      - right.
    

    All that remains to be proved is:

    Even_n : even n
    Odd_m : odd m
    ______________________________________(1/1)
    even n /\ odd m
    

    And auto can handle this.