如何将 do 策略应用于序列
How to apply do tactic to a sequence
深入研究 test_nostutter_1
excersize 我找到了一种无需重复即可解决该问题的方法:
Example test_nostutter_1: nostutter [3;1;4;1;5;6].
Proof.
constructor 3.
(* This will apply the tactics to the 2-nd subgoal *)
2: {apply eqb_neq. auto. }
constructor 3.
2: {apply eqb_neq. auto. }
constructor 3.
2: {apply eqb_neq. auto. }
constructor 3.
2: {apply eqb_neq. auto. }
constructor 2.
Qed.
我决定更多地使用它,在 coq 参考手册中我发现 do tactical 可以多次循环一个策略。
do num expr
expr is evaluated to v which must be a tactic value. This tactic value v is applied num times. Supposing num > 1, after the first
application of v, v is applied, at least once, to the generated
subgoals and so on. It fails if the application of v fails before the
num applications have been completed.
所以我尝试了这个:
do 4 constructor 3; 2: {apply eqb_neq. auto. }
可惜失败了。只有这个有效:
do 1 constructor 3.
是否可以使用 do 使其工作?
回答
行中有几个问题
do 4 constructor 3; 2: {apply eqb_neq. auto. }
首先,不能在链运算符;
后面使用2:
或{}
。您可以使用的最接近的是 sequence with local application tac; [tac1 | tac2]
。由于我们只想在第二个分支上做一些事情,我们可以在这里省略 tac1
。
此外,您不能在战术中使用句点。句点标记语句的结尾,但整个 do
表达式是单个语句。您应该始终使用序列运算符 ;
来链接多个策略。
最后,do n tac; tac
的工作方式类似于 (do n tac); tac
。您可以用括号将策略表达式括起来,例如do n (tac; tac)
改变行为。
所以这个应该可以工作:
do 4 (constructor 3; [ | apply eqb_neq; auto ]).
题外话
我们可以通过多种方式简化线路。
auto
可以给出额外的定理来自动化。任何可以用 apply eqb_neq; auto
解决的目标也可以用 auto using eqb_neq
. 解决
do 4 (constructor 3; [ | auto using eqb_neq ]).
auto
策略永远不会失败,因此它可以安全地用于两个分支。
do 4 (constructor 3; auto using eqb_neq).
repeat
重复直到出现问题或没有更多的子目标。以下将重复,直到第三个构造函数不再适用。
repeat (constructor 3; auto using eqb_neq).
- 我们可以让 Coq 选择应用哪个构造函数。这样就可以完成(或接近完成)证明了。
repeat (constructor; auto using eqb_neq).
- 我们还可以通过
auto
使用 Hint Constructors
命令使 nostutter
的构造函数自动化。现在我们可以 auto
整件事了。 (您可以将提示命令放在 nostutter
的定义之后,然后您就可以 auto
它无处不在。)
Hint Constructors nostutter.
auto using eqb_neq.
(* if the above fails, the following increases the search depth so it should succeed. *)
auto 6 using eqb_neq.
- 实际上,定理
eqb_neq
已经为 auto
注册了。所以我们可以:
auto 6.
深入研究 test_nostutter_1
excersize 我找到了一种无需重复即可解决该问题的方法:
Example test_nostutter_1: nostutter [3;1;4;1;5;6].
Proof.
constructor 3.
(* This will apply the tactics to the 2-nd subgoal *)
2: {apply eqb_neq. auto. }
constructor 3.
2: {apply eqb_neq. auto. }
constructor 3.
2: {apply eqb_neq. auto. }
constructor 3.
2: {apply eqb_neq. auto. }
constructor 2.
Qed.
我决定更多地使用它,在 coq 参考手册中我发现 do tactical 可以多次循环一个策略。
do num expr
expr is evaluated to v which must be a tactic value. This tactic value v is applied num times. Supposing num > 1, after the first application of v, v is applied, at least once, to the generated subgoals and so on. It fails if the application of v fails before the num applications have been completed.
所以我尝试了这个:
do 4 constructor 3; 2: {apply eqb_neq. auto. }
可惜失败了。只有这个有效:
do 1 constructor 3.
是否可以使用 do 使其工作?
回答
行中有几个问题
do 4 constructor 3; 2: {apply eqb_neq. auto. }
首先,不能在链运算符;
后面使用2:
或{}
。您可以使用的最接近的是 sequence with local application tac; [tac1 | tac2]
。由于我们只想在第二个分支上做一些事情,我们可以在这里省略 tac1
。
此外,您不能在战术中使用句点。句点标记语句的结尾,但整个 do
表达式是单个语句。您应该始终使用序列运算符 ;
来链接多个策略。
最后,do n tac; tac
的工作方式类似于 (do n tac); tac
。您可以用括号将策略表达式括起来,例如do n (tac; tac)
改变行为。
所以这个应该可以工作:
do 4 (constructor 3; [ | apply eqb_neq; auto ]).
题外话
我们可以通过多种方式简化线路。
auto
可以给出额外的定理来自动化。任何可以用apply eqb_neq; auto
解决的目标也可以用auto using eqb_neq
. 解决
do 4 (constructor 3; [ | auto using eqb_neq ]).
auto
策略永远不会失败,因此它可以安全地用于两个分支。
do 4 (constructor 3; auto using eqb_neq).
repeat
重复直到出现问题或没有更多的子目标。以下将重复,直到第三个构造函数不再适用。
repeat (constructor 3; auto using eqb_neq).
- 我们可以让 Coq 选择应用哪个构造函数。这样就可以完成(或接近完成)证明了。
repeat (constructor; auto using eqb_neq).
- 我们还可以通过
auto
使用Hint Constructors
命令使nostutter
的构造函数自动化。现在我们可以auto
整件事了。 (您可以将提示命令放在nostutter
的定义之后,然后您就可以auto
它无处不在。)
Hint Constructors nostutter.
auto using eqb_neq.
(* if the above fails, the following increases the search depth so it should succeed. *)
auto 6 using eqb_neq.
- 实际上,定理
eqb_neq
已经为auto
注册了。所以我们可以:
auto 6.