coq - Coq Proof Assistant 中依赖类型的问题

标签 coq dependent-type

考虑以下简单的表达语言:

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/

相关文章:

coq - coq 中的多态相等

set - Coq:FSet 和 MSet 有什么区别?

coq - 定义产品类型的递归函数

dependent-type - 用于张量索引的 Idris 非平凡类型计算

haskell - 有效地抽象数据类型数量

pattern-matching - 关于依赖于其替代顺序的函数的证明

types - 在 Agda 中使用字符串作为键进行映射?

coq - 如何在 Coq 中重新排列新定义的关联术语?

pattern-matching - 在 Coq 的单个子句中模式匹配多个构造函数

dependent-type - 为什么 Idris 中的 Nat 数据类型以 0 而不是 1 开头?