Coq中模块自变量的专业化

时间:2019-02-15 05:33:13

标签: coq

我有一个模块,我需要专门说明其参数之一。我想使用自然数代替任意的UsualDecidableTypeFull。如何在Coq中获得这种行为?

我定义了一些模块:

Module PRO2PRE_mod
(SetVars FuncSymb PredSymb PropSymb: UsualDecidableTypeFull).
(* ... *)
End PRO2PRE_mod.

然后我专门化了PropSymb的最后一个参数。

Require Import Arith.PeanoNat.
Module m2 : UsualDecidableTypeFull.
Definition t:=nat.
Definition eq := @eq nat.
Definition eq_refl:=@eq_refl nat.
Definition eq_sym:=@eq_sym nat.
Definition eq_trans:=@eq_trans nat.
Definition eq_equiv:Equivalence eq := Nat.eq_equiv.
Definition eq_dec := Nat.eq_dec.
Definition eqb:=Nat.eqb.
Definition eqb_eq:=Nat.eqb_eq.
End m2.

该模块需要PropVars的特殊化:

Module SWAP_mod
(SetVars FuncSymb PredSymb : UsualDecidableTypeFull).

Module PRE := PRO2PRE_mod SetVars FuncSymb PredSymb m2.
Import PRE.

Theorem test : m2.t.
try exact 0. (* ERROR HERE! *)
Abort.
End SWAP_mod.

如何在最后一个模块中使用关于自然数的定理? (我想我对使用模块一无所知...也许我们需要以某种方式将'm2.t'类型强制为'nat'类型?)

1 个答案:

答案 0 :(得分:2)

实际上,在: UsualDecidableTypeFull的定义中使用m2完全隐藏了m2的实现细节。从外部看,m2.t是未知类型。

有时候,这正是您想要的。例如,您可能希望抽象化模块中定义的类型,以便用户在不使用您在模块中赋予他们的功能的情况下无法操纵该类型的值。因此,您可以确保它们不会破坏某些不变性。

但是,对于您的情况,您需要记住m2.t实际上是nat,您至少有以下两个选择:

  • 使用Module m2 <: UsualDecidableTypeFull使接口透明。使用此功能时,Coq只会验证模块的定义是否符合签名,而不会隐藏模块的内容。

  • 如果您仍然想隐藏模块的一部分,也可以使用

    Module m2 : UsualDecidableTypeFull with Definition t := nat.
    

    在这种情况下,从外面看,m2.t被称为nat,但是m的其他字段被屏蔽。例如,m2.eqb的正文被隐藏。