Coq中的证据论证

时间:2013-12-10 21:40:45

标签: logic coq theorem-proving

我正在尝试在Coq中的弱指定类型上定义一个函数。具体来说,我有一个由一组递归构造函数归纳定义的类型,我想定义一个仅在使用这些构造的子集构造参数时定义的函数。

更具体地说,我有以下类型定义:

Inductive Example : Set :=
  | Example_cons0 : nat -> Example
  | Example_cons1 : Example -> Example
  .

现在,我有一个仅适用于地面情况的功能。 (以下定义显然不起作用,但意在暗示我的意图。)

Definition example (x:Example) : nat :=
  match x with
    | Example_cons0 n => n
  end.

理想情况下,我想告诉我,我的参数x是使用一般类型构造函数的子集构造的,在本例中是Example_cons0。我认为我可以通过定义一个谓词来说明这一事实,并将谓词的证明作为参数传递。例如:

Definition example_pred (x:Example) : Prop :=
  match x with
    | Example_cons0 _ => True
    | _ => False
  end.

然后(遵循Robin Green的建议),像

Definition example2 (x:Example) : example_pred x -> nat :=
  (use proof to define example2?)

不幸的是,我不确定如何做这件事。我甚至不确定这是在弱指定类型上定义受限函数的正确方法。

我们非常感谢任何指导,提示或建议! - 李

更新

根据jozefg的建议,示例函数可以定义为:

Definition example (x:Example) : example_pred x -> nat :=
  match x with
    | Example_cons0 n => fun _ => n
    | _               => fun proof => match proof with end 
  end.

详情请见他的评论。可以使用以下语法评估此函数,该语法还演示了如何在Coq中表示证明项:

Coq < Eval compute in Example.example (Example.Example_cons0 0) (I : Example.example_pred (Example.Example_cons0 0)).
    = 0
    : nat

2 个答案:

答案 0 :(得分:2)

以下是我将其作为简化示例编写的方法

考虑一个简单的数据类型

Inductive Foo :=
| Bar : nat -> Foo
| Baz.

现在我们定义一个有用的功能

Definition bar f :=
  match f with
    | Bar _ => True
    | Baz   => False
  end.

最后你要写的是什么:

Definition example f :=
  match f return bar f -> nat with
    | Bar n => fun _ => n
    | Baz   => fun p => match p with end
  end.

这种类型为forall f : Foo, bar f -> nat。这可以确保在example未提供Bar的情况下,用户必须提供虚假证明(不可能)。

这可以像这样调用

example (Bar n) I

但问题是,您可能需要手动证明​​某些术语是由Bar构建的,否则Coq应该如何知道?

答案 1 :(得分:1)

是的,你是对的。你想要:

Definition example2 (x:Example) (example_pred x) : nat :=

以及如何进一步取决于你想要证明什么。

您可能会发现通过使用Curry-Howard信函证明战术来制定定义很有帮助:

Definition example2 (x:Example) (example_pred x) : nat.
Proof.
  some proof
Defined.

另外,我想指出sigsigT类型通常用于将“弱指定类型”与谓词结合起来约束它们。