I understood destruct
as it breaks an inductive definition into its constructors. I recently saw case_eq
and I couldn't understand what it does differently?
1 subgoals
n : nat
k : nat
m : M.t nat
H : match M.find (elt:=nat) n m with
| Some _ => true
| None => false
end = true
______________________________________(1/1)
cc n (M.add k k m) = true
In the above context, if I do destruct M.find n m
it breaks H into true and false whereas case_eq (M.find n m)
leaves H intact and adds separate proposition M.find (elt:=nat) n m = Some v
, which I can rewrite to get same effect as destruct.
Can someone please explain me the difference between the two tactics and when which one should be used?
The first basic tactic in the family of
destruct
andcase_eq
is calledcase
. This tactic modifies only the conclusion. When you typecase A
andA
has a typeT
which is inductive, the system replacesA
in the goal's conclusion by instances of all the constructors of typeT
, adding universal quantifications for the arguments of these constructors, if needed. This creates as many goals as there are constructors in typeT
. The formulaA
disappears from the goal and if there is any information aboutA
in an hypothesis, the link between this information and all the new constructors that replace it in the conclusion gets lost. In spite of this,case
is an important primitive tactic.Loosing the link between information in the hypotheses and instances of
A
in the conclusion is a big problem in practice, so developers came up with two solutions:case_eq
anddestruct
.Personnally, when writing the Coq'Art book, I proposed that we write a simple tactic on top of
case
that keeps a link betweenA
and the various constructor instances in the form of an equality. This is the tactic now calledcase_eq
. It does the same thing ascase
but adds an extra implication in the goal, where the premise of the implication is an equality of the formA = ...
and where...
is an instance of each constructor.At about the same time, the tactic
destruct
was proposed. Instead of limiting the effect of replacement in the goal's conclusion,destruct
replaces all instances ofA
appearing in the hypotheses with instances of constructors of typeT
. In a sense, this is cleaner because it avoids relying on the extra concept of equality, but it is still incomplete because the expressionA
may be a compound expressionf B
, and ifB
appears in the hypothesis but notf B
the link betweenA
andB
will still be lost.Illustration
Gives the two goals
and
the extra equality is very useful here.
In this question I suggested that the developer use
case_eq (a == b)
when(a == b)
has typebool
because this type is inductive and not very informative (constructors have no argument). But when(a == b)
has type{a = b}+{a <> b}
(which is the case for thestring_dec
function) the constructors have arguments that are proofs of interesting properties and the extra universal quantification for the arguments of the constructors are enough to give the relevant information, in this casea = b
in a first goal anda <> b
in a second goal.