0

I'm trying to proof that my function nonzeros' distribute over concat of list.

I wrote nonzeros' with a filter in this way:

Definition nonzeros' (l : list nat) : list nat := filter (fun x => match x with | O => false | _ => true end) l.

I've already proofed this 2 lemmas:

Lemma nonzeros'_remove_0 :
  forall (a b: list nat),
  nonzeros' (0 :: b) = nonzeros' b.
Proof.
  intros a b.
  unfold nonzeros'.
  simpl. 
  reflexivity.
Qed.

Lemma nonzeros'_not_remove_Sn :
  forall (a b: list nat) (n : nat),
  nonzeros' (S n :: b) = S n :: nonzeros' b.
Proof.
  intros a b n.
  unfold nonzeros'.
  simpl. 
  reflexivity.
Qed.

Now I have to proof the distribution over concat:

Lemma nonzero'_distribution_over_concat :
  forall (a b : list nat),
  nonzeros' (concat a b) = concat (nonzeros' a) (nonzeros' b).

In order to proof it I do the following:

Proof.
  intros a b.
  induction a as [| h t IHa].
  - 
    simpl. 
    reflexivity.
  - 
    simpl.
    destruct h.
    + rewrite nonzeros'_remove_0. rewrite nonzeros'_remove_0. rewrite IHa. reflexivity.

The problem is that after the tactics

rewrite nonzeros'_remove_0.

Coq create 2 subgoal:

______________________________________(1/2)
nonzeros' (concat t b) = concat (nonzeros' (0 :: t)) (nonzeros' b)
______________________________________(2/2)
list nat

The second subgoal is unexpected. Why does it appear?

Marco Mantovani
  • 111
  • 2
  • 7

1 Answers1

2

The lemma has an unused parameter a : list nat:

Lemma nonzeros'_remove_0 :
  forall (a b: list nat),
  nonzeros' (0 :: b) = nonzeros' b.

so to apply that lemma you need to provide such a list, and there is no way to tell which list it should be, other than by asking you via an extra goal. One could also develop automation to make an arbitrary choice here, but a better fix is to remove that unused parameter from the lemma in the first place.

Lemma nonzeros'_remove_0 :
  forall (b: list nat),
  nonzeros' (0 :: b) = nonzeros' b.
Li-yao Xia
  • 31,896
  • 2
  • 33
  • 56