我正在阅读Mike Nahas's introductory Coq tutorial,其中说:
" ex_intro"的论据是:
- 谓词
- 证人
- 证人与证人的证明
我看了the definition:
Inductive ex (A:Type) (P:A -> Prop) : Prop :=
ex_intro : forall x:A, P x -> ex (A:=A) P.
我在解析它时遇到了问题。表达式forall x:A, P x -> ex (A:=A) P
的哪些部分对应于这三个参数(谓词,见证和证明)?
答案 0 :(得分:11)
要理解迈克的意思,最好启动Coq解释器并查询ex_intro
的类型:
Check ex_intro.
然后你应该看到:
ex_intro
: forall (A : Type) (P : A -> Prop) (x : A), P x -> exists x, P x
这表示ex_intro
不仅需要3个参数,还需要4个参数:
A
; P : A -> Prop
; x : A
;和P x
,声称x
是有效的证人。如果您将所有这些内容合并在一起,就会获得exists x : A, P x
的证明。例如,@ex_intro nat (fun n => n = 3) 3 eq_refl
是exists n, n = 3
的证明。
因此,ex_intro
的实际类型与您在定义中读取的类型之间的差异在于前者包括标题中给出的所有参数 - 在本例中为{{1} }和A
。
答案 1 :(得分:1)
是的,那些归纳类型定义可能难以阅读。
第一部分是:
Inductive ex (A:Type) (P:A -> Prop) : Prop :=
这是与类型本身相关联的内容。因此,只要您看到ex
,就会有A
和P
,ex
的类型为Prop
。暂时跳过A
,让我们关注作为谓词的P
。因此,如果我们使用作为我们的示例"存在一个自然数字,它是{",P
可能是is_prime
,其中is_prime
采用nat
(自然数)作为参数,如果nat
是素数,则可以存在证据。
在此示例中,A
为nat
。在教程中,A
没有被提及,因为Coq总能推断它。给定谓词,Coq可以通过查看谓词的参数类型来获得A
的类型。
总结到这里,在我们的示例中,类型将是ex nat is_prime
。这说明存在一个素数的nat,但它没有说哪个nat。当我们构建ex nat is_prime
时,我们需要说出哪一个 - 我们需要一个"见证"。这导致我们进入构造函数定义:
ex_intro : forall x:A, P x -> ex (A:=A) P.
构造函数名为ex_intro
。这里有些棘手的是构造函数具有该类型的所有参数。因此,在我们到达ex_intro
之后列出的那些之前,我们必须包含类型的A
和P
。
在这些参数出现之后列出ex_intro
:x
(见证人)和P x
之后的参数,这是谓词为证人所持有的证据。使用我们的示例,x
可能为2,P x
将证明(is_prime 2)
。
构造函数需要指定它正在构造的类型ex
的参数。这就是箭头(->
)之后发生的事情。这些不必与调用构造函数时使用的参数匹配,但它们通常会这样做。为了实现这一点,论证A
不被推断 - 它被明确传递。 (A:=A)
表示A
中的参数ex
应该等于构造函数调用中的A
。同样,P
的参数ex
从调用构造函数设置为P
。
因此,如果我们的proof_that_2_is_prime
类型为(prime 2)
,我们可以调用ex_intro is_prime 2 proof_that_2_is_prime
,它的类型为ex nat is_prime
。我们证明存在一个自然数是素数。
直接回答您的问题:在表达式forall x:A, P x -> ex (A:=A)
中,x:A
是证人,P x
证明证人是真的。表达式不包含谓词,因为它是类型参数的一部分,必须将其传递给构造函数ex_intro
。教程的参数列表不包括A
,因为是由Coq推断的。
我希望你理解为什么我认为这个讨论对我的教程来说太详细了!谢谢你的问题。