Coq:我如何用可判定的道具创建一个bool?

时间:2015-10-02 14:25:13

标签: coq

我想将程序结构化为抽象模块,并编写使用抽象类型的函数。但我无法使用match来破坏抽象类型,所以我必须创建某种反转引理,但我也不能match。我试图将我的问题归结为:

首先创建一个可由Module Type类型使用的decidable

Require Import Decidable.

Module Type decType.
  Parameter T : Type.
  Axiom decT : forall (a b:T), decidable (a=b).
End decType.

以下是一个示例:nat是可判定的。但目的是编写plus等仅解决抽象类型。 (我已删除参数zeroSucc及其要求,以使此示例最小化。

Require Peano_dec.

Module nat_dec <: decType.
  Definition T := nat.
  Definition decT := Peano_dec.dec_eq_nat.
End nat_dec.

现在回答我的问题:我想在decType模块上编写参数化模块,其函数如果true则返回a=b,否则返回false。由于ab属于decType,因此这应该是可判定的(因此可计算,或?),但如何编写beq

Module decBool (M: decType).
  Import M.
  Definition beq (a b:T) : bool :=
    ???
  .

End decBool.

到目前为止,我的想法是我必须在decType模块类型中添加一个布尔函数,如下所示:

Module Type decType.
  Parameter T : Type.
  Axiom decT : forall (a b:T), decidable (a=b).
  Parameter decB : forall (a b:T), {a=b}+{a<>b}.
End decType.

然后在上面的decB模块中定义nat_dec

这是人们必须做的事情(即定义函数decB)?是不是可以使用抽象的事实,即类型是可判定的,而不通过返回bool的函数?

1 个答案:

答案 0 :(得分:4)

你不能写这个函数,因为Coq中的命题和计算对象是分开的(例如参见this answer)。

请注意,将decB参数添加到模块会导致decidable公理不必要,因为您可以使用{P} + {Q}派生P \/ Q

我想补充一些相关的说明。首先,我会避免使用Coq模块系统来执行除命名空间和编写不透明定义之外的任何操作。如果要编写参数化定义,最好使用相关记录,例如

Record eqType := {
  sort :> Type; 
  eqb : sort -> sort -> bool;
  eqbP : forall x y, eqb x y = true <-> x = y
}.

这基本上是Ssreflect采取的方法。您可以使用规范结构(如Ssreflect确实)或类型类来更轻松地使用这些相关记录。

其次,您可以编写显式的消除函数,以避免诉诸match。例如,nat_rect函数允许您使用高阶参数在nat上编写递归函数:

nat_rect : forall (T : nat -> Type),
             (* value for 0 *)
             T 0 ->
             (* body for recursive call *)
             (forall n, T n -> T (S n)) ->
             forall n, T n.

为每种感应数据类型自动定义这些功能。它们涉及依赖类型,但您也可以使用它们进行非依赖类型的递归。虽然这样效率有点低,但您也可以通过传递它们忽略递归调用值的函数(在上面的例子中,第二个函数参数的T n参数)来使用它们进行模式匹配。 p>