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.
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)