Coq:测试部分可转换性

Coq: Testing partial convertibilty

在以下示例中,合一(不出所料)不会推断规范结构:

Structure Pn := sr {gs: nat}.
Canonical Structure Pn_1: Pn := sr 1.
Canonical Structure Pn_2: Pn := sr 2.

Check ltac:(tryif unify 2 (gs _) then idtac "success" else idtac "fail"). (*fail*)
Check ltac:(tryif unify 2 (gs Pn_2) then idtac "success" else idtac "fail"). (*success*)

是否有可能使第一次统一成功,例如带 unify ... with ...?或者是否有更好的策略而不是 unify 来测试 2(gs _) 的部分可转换性?随意使用例如输入 类 而不是规范结构来使这项工作有效

规范结构的实例推断是在术语的头部调度的。数字 1 和 2 具有相同的头部 (S),导致重叠的实例破坏了推理。 (事实上​​ ,一旦您声明第二个实例,Coq 就会给出错误消息。)

一个解决方案是使用单独的定义,因为它们会改变术语的头部:

Record Pn := sr {gs: nat}.
Definition one := 1.
Definition two := 2.
Canonical Structure Pn_1 := sr one.
Canonical Structure Pn_2 := sr two. (* Now the error message goes away *)

(Georges Gonthier 和合作者甚至还 paper 展示了如何以这种方式对推理机制进行编程。)

至于 ltac,似乎 unify 单独对其参数进行类型检查,从而防止触发规范结构推断。我们可以通过将两个术语放在强制检查器统一它们的上下文中来解决这个问题。

Ltac check_instance t :=
  let p := constr:(eq_refl : t = gs _) in idtac.

现在这些工作:

Check ltac:(tryif check_instance one then idtac "success"
            else idtac "fail").
Check ltac:(tryif check_instance two then idtac "success" 
            else idtac "fail").

我怀疑使用 类 类型你应该能够避免推理问题,因为它不是在术语的开头调度的。