如何调试比赛目标分支中的战术失败?
How to debug tactic failure in a match goal branch?
假设我在 match goal
分支的主体中有一些复杂的策略,这些策略很容易以我可能需要调试的方式出错。如果某些策略失败,是否有办法从分支获取“真实”错误消息,而不是简单地获取“错误:没有匹配目标的匹配子句”?
以这种假策略为例,其中 apply A, B, C
有几次出错的机会。我今天一直在用有点类似的真实战术战斗。
Ltac three_applications :=
match goal with
| [
A : (* something reasonable *),
B : (* something reasonable *),
C : (* something reasonable *)
|- _ ] =>
idtac A B C;
assert (F: (* something reasonable *))
by apply A, B, C;
solve [discriminate F]
end.
提前致谢!
最简单的方法是使用 lazymatch goal
,但它具有不同的语义,但正如我所见,您只匹配一种形状,这对您来说可能没问题。
想法是 match goal
可能会回溯:如果你有
match goal with
| n : nat |- _ => destruct n ; reflexivity
| |- nat => exact 0
end.
它会首先尝试在你的假设中找到一些 n : nat
,从最近的开始,然后尝试策略 destruct n ; reflexivity
。如果失败,它将尝试找到另一个自然数。如果它们都失败了,那么它将查找目标是否与第二个子句匹配,如果匹配则执行 exact 0
。
如果再次失败,它将再次回溯并得出结论 No matching clauses for match goal
.
另一方面,
lazymatch goal with
| n : nat |- _ => destruct n ; reflexivity
| |- nat => exact 0
end.
会找到第一个匹配的分支,然后应用该策略,如果失败,则在lazymatch
中不回溯,并给出相应分支中策略的错误。
请注意,当我找不到回溯的用例时,我总是会使用 lazymatch
,而不仅仅是为了调试目的。
如果 lazymatch
在语义上不等同于您的 match
并且需要涉及回溯那么它会更难,但实际上,使用 idtac A B C
可以帮助您了解哪个在启动错误之前选择它的分支。
有时,写作
Fail three_applications.
而不仅仅是
three_applications.
会有所帮助,因为 Fail
通常会保留您在命令中进行的打印,即使它最终失败了。
了解分支后,只需手动应用您的策略即可。
假设我在 match goal
分支的主体中有一些复杂的策略,这些策略很容易以我可能需要调试的方式出错。如果某些策略失败,是否有办法从分支获取“真实”错误消息,而不是简单地获取“错误:没有匹配目标的匹配子句”?
以这种假策略为例,其中 apply A, B, C
有几次出错的机会。我今天一直在用有点类似的真实战术战斗。
Ltac three_applications :=
match goal with
| [
A : (* something reasonable *),
B : (* something reasonable *),
C : (* something reasonable *)
|- _ ] =>
idtac A B C;
assert (F: (* something reasonable *))
by apply A, B, C;
solve [discriminate F]
end.
提前致谢!
最简单的方法是使用 lazymatch goal
,但它具有不同的语义,但正如我所见,您只匹配一种形状,这对您来说可能没问题。
想法是 match goal
可能会回溯:如果你有
match goal with
| n : nat |- _ => destruct n ; reflexivity
| |- nat => exact 0
end.
它会首先尝试在你的假设中找到一些 n : nat
,从最近的开始,然后尝试策略 destruct n ; reflexivity
。如果失败,它将尝试找到另一个自然数。如果它们都失败了,那么它将查找目标是否与第二个子句匹配,如果匹配则执行 exact 0
。
如果再次失败,它将再次回溯并得出结论 No matching clauses for match goal
.
另一方面,
lazymatch goal with
| n : nat |- _ => destruct n ; reflexivity
| |- nat => exact 0
end.
会找到第一个匹配的分支,然后应用该策略,如果失败,则在lazymatch
中不回溯,并给出相应分支中策略的错误。
请注意,当我找不到回溯的用例时,我总是会使用 lazymatch
,而不仅仅是为了调试目的。
如果 lazymatch
在语义上不等同于您的 match
并且需要涉及回溯那么它会更难,但实际上,使用 idtac A B C
可以帮助您了解哪个在启动错误之前选择它的分支。
有时,写作
Fail three_applications.
而不仅仅是
three_applications.
会有所帮助,因为 Fail
通常会保留您在命令中进行的打印,即使它最终失败了。
了解分支后,只需手动应用您的策略即可。