如何弄清楚" ="在coq中表示不同类型

时间:2017-10-05 14:45:26

标签: coq

给定Coq中的类型(如List),我如何计算出相等符号" ="意思是那种类型?我应该键入哪些命令来确定定义?

1 个答案:

答案 0 :(得分:4)

等号只是eq谓词的特殊中缀语法。也许令人惊讶的是,它的定义方式与每种类型相同,我们甚至可以让Coq为我们打印出来:

Print eq.
(* Answer: *)
Inductive eq (A : Type) (x : A) : Prop :=
| eq_refl : eq x x.

这个定义非常小,可能很难理解发生了什么。粗略地说,它表明显示两个表达式相同的最基本方法是 reflexivity - 也就是说,当它们完全相同时。例如,我们可以使用eq_refl来证明5 = 5[4] = [4]

Check eq_refl : 5 = 5.
Check eq_refl : [4] = [4].

这个定义还有很多东西比满足于眼睛。首先,Coq认为任何两个等同于简化的表达式都是相等的。在这些情况下,我们可以使用eq_refl来表明它们也是相同的。例如:

Check eq_refl : 2 + 2 = 4.

这是有效的,因为Coq知道自然数上加法的定义,并且能够机械地简化表达式2 + 2,直到它到达4

此外,上述定义告诉我们如何使用相等来证明其他事实。由于归纳类型在Coq中的工作方式,我们可以显示以下结果:

eq_elim : 
  forall (A : Type) (x y : A),
    x = y ->
    forall (P : A -> Prop), P x -> P y

释义,当两件事情相等时,任何持有第一件事的事实也都属于第二件事。当你调用rewrite策略时,这个原理大致是Coq在引擎盖下使用的原理。

最后,平等以有趣的方式与其他类型相互作用。你问list的等式定义是什么。我们可以证明以下引理是有效的:

forall A (x1 x2 : A) (l1 l2 : list A),
  x1 :: l1 = x2 :: l2 -> x1 = x2 /\ l1 = l2

forall A (x : A) (l : list A),
  x :: l <> nil.

用语言说:

  1. 如果两个非空列表相等,则它们的头部和尾部相等;

  2. 非空列表与nil不同。

  3. 更一般地说,如果T是归纳类型,我们可以证明:

    1. 如果两个以相同构造函数开头的表达式相等,则它们的参数相等(即构造函数是 injective );以及

    2. 以不同构造函数开头的两个表达式总是不同的(也就是说,不同的构造函数不相交)。

    3. 严格地说,这些事实并不是平等定义的一部分,而是归纳类型在Coq中起作用的方式的结果。不幸的是,对于Coq中的其他类型,它也不起作用;特别是,Coq中函数相等的概念并不是很有用,除非你愿意在理论中添加额外的公理。