Search code examples
coqssreflect

no error with assert (goal) but error with cut (goal)


I'm confused as to why assert and cut are behaving differently in this case. I am trying to prove this lemma with the ssreflect seq library.

Lemma subseq_add_both: forall{A: eqType} (L1 L2: seq A) (a: A),
    subseq L1 L2 -> subseq (a:: L1) (a :: L2).
Proof. intros.
       assert (subseq [:: a] (a:: L2)).

The above works fine. However,

Lemma subseq_add_both: forall{A: eqType} (L1 L2: seq A) (a: A),
    subseq L1 L2 -> subseq (a:: L1) (a :: L2).
Proof. intros.
       cut (subseq [:: a] (a:: L2)).

generates the error Error: Not a proposition or a type.

Why is this happening? I thought both assert and cut would take an arbitrary goal as argument, but this is evidently not the case. How are these two tactics different with regard to the goals they work on?

Thank you.


Solution

  • This is probably a bug. The issue is that subseq returns a boolean. You can use its result as a proposition because ssreflect declares is_true b := b = true as a coercion from bool to Prop. My guess is that cut does not apply this coercion and gets confused that it is getting a boolean instead of a proposition.

    You can solve the issue by putting the coercion explicitly:

    cut (is_true (subseq [:: a] (a:: L2))).
    

    However, since you are already using ssreflect, I would recommend using the have and suffices tactics instead of assert and cut. For instance,

    suffices : subseq [:: a] (a :: L2).
    

    gives you

    2 subgoals (ID 279)
      
      A : eqType
      L1, L2 : seq A
      a : A
      H : subseq L1 L2
      ============================
      subseq [:: a] (a :: L2) -> subseq (a :: L1) (a :: L2)
    
    subgoal 2 (ID 280) is:
     subseq [:: a] (a :: L2)