Search code examples
coqtheorem-proving

Proving increasing iota in Coq


I am stuck on a goal.

Assume we have the following definition:

Fixpoint iota (n : nat) : list nat :=
  match n with
    | 0   => []
    | S k => iota k ++ [k]
  end.

And we want to prove:

Theorem t1 : forall n, In n (iota n) -> False.

So far, I have managed to the following:

Theorem t1 : forall n, In n (iota n) -> False.
Proof.
  intros.
  induction n.
    - cbn in H. contradiction.
    - cbn in H. apply app_split in H.
      Focus 2. unfold not. intros.
      unfold In in H0. destruct H0. assert (~(n = S n)) by now apply s_inj.
      contradiction.
      apply H0.
      apply IHn.

I used these two lemmas, proofs omitted:

Axiom app_split : forall A x (l l2 : list A), In x (l ++ l2) -> not (In x l2) -> In x l.
Axiom s_inj     : forall n, ~(n = S n).

However, I am completely stuck, I need to somehow show that: In n (iota n) assuming In (S n) (iota n).


Solution

  • As you've observed the fact that the n in In n and the one in iota n are in lockstep in your statement makes the induction hypothesis hard to invoke (if not completely useless).

    The trick here is to prove a more general statement than the one you are actually interested in which breaks this dependency between the two ns. I would suggest:

    Theorem t : forall n k, n <= k -> In k (iota n) -> False.
    

    from which you can derive t1 as a corollary:

    Corollary t1 : forall n, In n (iota n) -> False.
    intro n; apply (t n n); reflexivity.
    Qed.
    

    If you want to peek at the proof of t, you can have a look at this self-contained gist