当在Coq中使用自己的可判定性时,Eval计算是不完整的

时间:2015-02-12 13:16:29

标签: coq

Eval compute命令并不总是评估为简单表达式。 考虑一下代码:

Require Import Coq.Lists.List.
Require Import Coq.Arith.Peano_dec.
Import ListNotations.

Inductive I : Set := a : nat -> I | b : nat -> nat -> I.

Lemma I_eq_dec : forall x y : I, {x = y}+{x <> y}.
Proof.
  repeat decide equality.
Qed.

并且,如果我执行以下命令:

Eval compute in (if (In_dec eq_nat_dec 10 [3;4;5]) then 1 else 2).

Coq告诉我结果是2。但是,当我执行以下表达式时:

Eval compute in (if (In_dec I_eq_dec (a 2) [(a 1);(a 2)]) then 1 else 2).

我得到一个长表达式,其中In-predicate似乎展开,但没有给出结果。

在上一个1行中,我需要更改哪些内容才能获得答案Eval compute

2 个答案:

答案 0 :(得分:5)

在Coq中,有两个用于校对脚本的终结器命令:QedDefined。它们之间的区别在于前者创建不透明术语,即使Eval compute也无法展开。后者创建透明术语,然后可以像往常一样展开。因此,您只需将Defined放在Qed.

的位置即可
Require Import Coq.Lists.List.
Require Import Coq.Arith.Peano_dec.
Import ListNotations.

Inductive I : Set := a : nat -> I | b : nat -> nat -> I.

Lemma I_eq_dec : forall x y : I, {x = y}+{x <> y}.
Proof.
  repeat decide equality.
Defined.

Eval compute in (if (In_dec I_eq_dec (a 2) [(a 1);(a 2)]) then 1 else 2).

我个人觉得sumbool类型{A} + {B}对于表达可判定的命题并不是很好,正是因为证明和计算太纠结在一起了;特别是,证明会影响术语的减少方式。我发现最好遵循Ssreflect样式,单独的证明和计算,并通过特殊谓词将它们联系起来:

Inductive reflect (P : Prop) : bool -> Set :=
  | ReflectT of P : reflect P true
  | ReflectF of ~ P : reflect P false.

这给了一个方便的方法来说明如果某个属性为true,则布尔计算返回true。 Ssreflect支持在计算布尔视图和逻辑视图之间方便地切换。

答案 1 :(得分:1)

如果您想评估您的证明,您需要使它们透明。您可以使用Defined命令完成它们。 Qed命令使它们不透明,这意味着它会丢弃它们的计算内容。