在尝试创建循环遍历可变长度参数列表的Ltac定义时,我在Coq 8.4pl2上遇到以下意外行为.有谁可以向我解释一下?
Ltac ltac_loop X :=
match X with
| 0 => idtac "done"
| _ => (fun Y => idtac "hello"; ltac_loop Y)
end.
Goal True.
ltac_loop 0. (* prints "done" as expected *)
ltac_loop 1 0. (* prints "hello" then "done" as expected *)
ltac_loop 1 1 0. (* unexpectedly yields "Error: Illegal tactic application." *)
Run Code Online (Sandbox Code Playgroud)
让我们扩展最后的调用ltac_loop以查看发生了什么:
ltac_loop 1 1 0
-> (fun Y => idtac "hello"; ltac_loop Y) 1 0
-> (idtac "hello"; ltac_loop 1) 0
Run Code Online (Sandbox Code Playgroud)
在那里,您可以看到问题:您试图将不是函数的内容应用于自变量,从而导致看到错误。解决方案是以连续传递方式重写策略:
Ltac ltac_loop_aux k X :=
match X with
| 0 => k
| _ => (fun Y => ltac_loop_aux ltac:(idtac "hello"; k) Y)
end.
Ltac ltac_loop X := ltac_loop_aux ltac:(idtac "done") X.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
604 次 |
| 最近记录: |