One possible way to say that n m : nat
are adjacent even numbers in Coq is to define that relation inductively, beginning with 0 and 2.
Inductive adj_ev : nat -> nat -> Prop :=
| ae_0 : adj_ev 0 2
| ae_1 : forall ( n m : nat ), adj_ev n m -> adj_ev m ( S ( S m ) )
| ae_2 : forall ( n m : nat ), adj_ev n m -> adj_ev m n.
ae_0
states that 0 and 2 are adjacent even numbers. ae_1
states that if some n m : nat
are adjacent even numbers, so are m
and m + 2
. With these two constructors we can cover all pairs of adjacent even numbers up to infinity. But wait! This works for n
and m
if and only if n < m
. So we need the last constructor ae_2
that flips any given number pair in the relation.
Now that I've defined the relation, I want to do some sanity checks on it to make sure it works. For instance, I know that 1 and 3 are not adjacent even numbers, and I also know that adj_ev 1 3
can never be obtained from the way I defined adj_ev
. So I can surely prove that ~ ( adj_ev 1 3 )
, right?
Theorem test' : ~ ( adj_ev 1 3 ).
unfold not. intros H.
inversion H. inversion H0.
After a few inversions I quickly get stuck in an infinite loop. It's like I'm asking Coq, "How can n
and m
be adjacent and even?" Coq answers "well, perhaps m
and n
are adjacent and even..." Then I ask, "How are m
and n
adjacent and even?" Coq says "well, perhaps n
and m
are adjacent and even..." ad infinitum.
The general problem is that, when you have some inductively defined symmetrical relation R
, it is easy to show that R
holds where it really does hold, but difficult to show that it doesn't where it doesn't. Perhaps there is a better tactic than inversion
for extracting a contradiction in such cases, but I'm not sure what it might be.
Any thoughts?