Coq 让我来定义:
Definition teenagers : Set := { x : nat | x >= 13 /\ x <= 19 }.
还有:
Variable Julia:teenagers.
但不是:
Example minus_20 : forall x:teenagers, x<20.
或:
Example Julia_fact1 : Julia > 12.
这是因为Julia(类型青少年)无法与12( nat )进行比较。
问:我应该如何告知Coq Julia的支持类型是 nat ,这样我才能写出有关她的任何有用信息?
Q':我对青少年的定义似乎是死路一条;它更具说明性而非建设性,我似乎失去了 nat 的归纳属性。我怎样才能出现其居民?如果没有办法,我仍然可以坚持 nat 并使用 Prop 和函数。 (新手在这里,用Pierce's SF进行不到一周的自学习。)
答案 0 :(得分:3)
您在teenagers
中使用的模式是&#34; subType&#34;的实例。图案。如您所知,{ x : nat | P x }
与nat
不同。目前,Coq几乎没有提供有效处理这类类型的支持,但是如果你限制为&#34;表现良好&#34;类P
,您实际上可以以合理的方式工作。 [这应该真的成为一个Coq FAQ BTW]
从长远来看,您可能希望对此模式使用特殊支持。 math-comp库subType
接口提供了这种支持的一个很好的例子。
描述此界面超出了您的原始问题,因此我将以一些评论结束:
在minus_20
示例中,您希望使用青少年数据类型的第一个投影。试试forall x : teenagers, proj1_sig x < 20
。如果您将投影声明为Coercion
:
Require Import Omega.
Definition teenagers : Set :=
{ x : nat | x >= 13 /\ x <= 19 }.
Coercion teen_to_nat := fun x : teenagers => proj1_sig x.
Implicit Type t : teenagers.
Lemma u t : t < 20.
Proof. now destruct t; simpl; omega. Qed.
正如您所正确观察到的,{ x : T | P x }
在Coq中与x
不同。原则上,您不能将类型为T
的对象的推理转移到类型为{ x : T | P x }
的对象,因为您还必须另外推理类型为P x
的对象。但对于广泛的P
类,您可以证明teen_to_nat
投影是单射的,即:
forall t1 t2, teen_to_nat t1 = teen_to_nat t2 -> t1 = t2.
然后,可以将对基本类型的推理转移到子类型。另见:Inductive subset of an inductive set in Coq
[edit]:我在math-comp中添加了几个典型的子类型示例,因为我认为它们很好地说明了这个概念:
n.-tuples
。长度为n的列表在math-comp中表示为一对列表加上大小证明,即n.-tuple T = { s : seq T | size s == n}
。感谢injectivity和coertions,你可以使用所有常规列表函数而不是元组,它们工作正常。'I_n = { x : nat | x < n }
的工作方式几乎与自然数相同,但有一个界限。