I was trying out mutual induction in Coq, the first type I defined was
Inductive IsEven : nat -> Prop :=
| EvenO : IsEven O
| EvenS n : IsOdd n -> IsEven (S n)
with IsOdd : nat -> Prop :=
| OddS n : IsEven n -> IsOdd (S n).
I now wanted to prove that the sum of even numbers is even. I was able to do this using a Fixpoint and pattern matching:
Fixpoint even_plus_even (n m : nat) (evenn : IsEven n) (evenm : IsEven m) : IsEven (n + m) :=
match evenn with
| EvenO => evenm
| EvenS n' oddn' => EvenS (n' + m) (odd_plus_even n' m oddn' evenm)
end
with odd_plus_even (n m : nat) (oddn : IsOdd n) (evenm : IsEven m) : IsOdd (n + m) :=
match oddn with
| OddS n' evenn' => OddS (n' + m) (even_plus_even n' m evenn' evenm)
end.
This defines both even_plus_even
and odd_plus_even
. I would now like to prove this using tactics in a more terse way (preferably without using many predefined lemmas to keep the code as self-contained as possible) but I haven't gotten very far.
Specifically, is it possible to prove both even_plus_even
and odd_plus_even
using only one Lemma like we can with the Fixpoint?
Edit: Thank you very much for your answers, the Lemma ... with ...
syntax was exactly what I was looking for. In fact
Lemma even_plus_even2 (n m : nat) (evenn : IsEven n) (evenm : IsEven m) : IsEven (n + m)
with odd_plus_even2 (n m : nat) (oddn : IsOdd n) (evenm : IsEven m) : IsOdd (n + m).
Proof.
induction evenn; simpl. assumption. constructor. auto.
induction oddn; simpl. constructor. auto.
Defined.
generates exactly the same proof term as the Fixpoint
in my originial question.
fix
tactic, so your life won't be much better. My point of view, your are using the wrong Coq tool for your problem. Inductive definitions are extremely powerful theoretical tools, whereasodd
/even
are simple functions that are better defined as functionsnat -> bool
and even justeven n = ~ odd n
, as done in math-comp for example. – ejgallego