考虑以下简单的表达语言:
Inductive Exp : Set :=
| EConst : nat -> Exp
| EVar : nat -> Exp
| EFun : nat -> list Exp -> Exp.
及其格式良好的谓词:
Definition Env := list nat.
Inductive WF (env : Env) : Exp -> Prop :=
| WFConst : forall n, WF env (EConst n)
| WFVar : forall n, In n env -> WF env (EVar n)
| WFFun : forall n es, In n env ->
Forall (WF env) es ->
WF env (EFun n es).
这基本上表明每个变量和函数符号都必须在环境中定义。现在,我想定义一个函数来说明 WF 谓词的可判定性:
Definition WFDec (env : Env) : forall e, {WF env e} + {~ WF env e}.
refine (fix wfdec e : {WF env e} + {~ WF env e} :=
match e as e' return e = e' -> {WF env e'} + {~ WF env e'} with
| EConst n => fun _ => left _ _
| EVar n => fun _ =>
match in_dec eq_nat_dec n env with
| left _ _ => left _ _
| right _ _ => right _ _
end
| EFun n es => fun _ =>
match in_dec eq_nat_dec n env with
| left _ _ => _
| right _ _ => right _ _
end
end (eq_refl e)) ; clear wfdec ; subst ; eauto.
问题在于如何声明 WF
谓词对于 EFun
情况下的表达式列表是否成立。我的明显猜测是:
...
match Forall_dec (WF env) wfdec es with
...
但是 Coq 拒绝了,认为递归调用 wfdec
格式不正确。我的问题是:是否可以在不改变表达式表示的情况下定义这种格式良好谓词的可判定性?
完整的工作代码如下gist .
最佳答案
问题在于,Forall_dec
在标准库中被定义为不透明(即使用 Qed
而不是 Defined
)。因此,Coq 不知道 wfdec
的使用是否有效。
解决您问题的直接方法是重新定义Forall_dec
,使其透明。您可以通过打印 Coq 生成的证明项并将其粘贴到源文件中来完成此操作。我添加了 gist这里有一个完整的解决方案。
不用说,这种方法会使代码变得臃肿、难以阅读和难以维护。正如 ejgallego 在他的回答中指出的那样,在这种情况下,最好的选择可能是定义一个决定 WF
的 bool 函数,并使用它而不是 WFDec
。正如他所说,他的方法的唯一问题是您需要将自己的归纳原理写入 Exp
中,以证明 bool 版本确实决定了归纳定义。 Adam Chlipala 的 CPDT 有 chapter关于归纳类型,给出了这种归纳原理的例子;只需寻找“嵌套归纳类型”。
关于coq - Coq Proof Assistant 中依赖类型的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43453365/