Coq中受限制的归纳类型定义

时间:2012-12-23 04:57:16

标签: coq

我想以某种方式限制允许构造函数在归纳定义中采用哪种输入。假设我想说如下定义二进制数:

Inductive bin : Type :=
  | O : bin
  | D : bin -> bin
  | S : bin -> bin.

这里的想法是D通过在末尾添加零来使非零数字加倍,并且S将数字作为最后一位数加零,并将最后一位数字变为1。这意味着以下是合法的数字:

S 0
D (S 0)
D (D (S 0))

虽然以下不是:

S (S 0)
D 0

有没有办法以干净的方式在归纳定义中强制执行此类限制?

2 个答案:

答案 0 :(得分:7)

您可以定义bin对谓词合法的含义,然后为遵守该谓词的bin子集指定名称。然后,您使用Program DefinitionProgram Fixpoint而不是DefinitionFixpoint编写函数。对于递归函数,您还需要一个度量来证明函数的参数减小,因为函数不再是结构递归的。

Require Import Coq.Program.Program.

Fixpoint Legal (b1 : bin) : Prop :=
  match b1 with
  | O       => True
  | D O     => False
  | D b2    => Legal b2
  | S (S _) => False
  | S b2    => Legal b2
  end.

Definition lbin : Type := {b1 : bin | Legal b1}.

Fixpoint to_un (b1 : bin) : nat :=
  match b1 with
  | O    => 0
  | D b2 => to_un b2 + to_un b2
  | S b2 => Coq.Init.Datatypes.S (to_un b2)
  end.

Program Definition zer (b1 : lbin) := O.

Program Fixpoint succ (b1 : lbin) {measure (to_un b1)} : lbin :=

但是this简单类型的方法可能会更容易。

答案 1 :(得分:1)

这可以通过归纳递归定义来完成 - 但遗憾的是Coq不支持这些定义。

从面向对象的编程角度来看,ODSbin的子类型,然后可以定义它们的构造函数类型,而无需求助于逻辑谓词,但Coq本身也不支持面向对象的编程。

然而,Coq确实有类型类。所以我可能做的是使bin成为类型类,并使每个构造函数成为一个单独的归纳类型,每个类型都有一个bin类型类的实例。我不确定类型类的方法是什么。

相关问题