我是Coq的新手,正在做一些练习,以便更熟悉它。
我的理解是,在Coq“真正”中证明一个命题是在Gallina中写下一个类型,然后表明它是使用策略居住的,以确定的方式将术语组合在一起。
我想知道是否有办法获得实际术语的漂亮印刷表示,并删除所有策略。
在下面的示例中,最终生成了plus_comm (x y : N) : plus x y = plus y x
类型的匿名术语......我想。如果我想看一下,我该怎么办?从某种意义上说,我很好奇战术是什么“desugar”。
以下是有问题的代码,基本上是从YouTube https://www.youtube.com/watch?v=OaIn7g8BAIc上的教程逐字解读。
Inductive N : Type :=
| O : N
| S : N -> N
.
Fixpoint plus (x y : N) : N :=
match x with
| O => y
| S x' => S (plus x' y)
end.
Lemma plus_0 (x : N) : plus x O = x.
Proof.
induction x.
- simpl. reflexivity.
- simpl. rewrite IHx. reflexivity.
Qed.
Lemma plus_S (x y : N) : plus x (S y) = S(plus x y).
Proof.
induction x.
- simpl. reflexivity.
- simpl. rewrite IHx. reflexivity.
Qed.
Lemma plus_comm (x y : N) : plus x y = plus y x.
Proof.
induction x.
- simpl. rewrite plus_0. reflexivity.
- simpl. rewrite IHx. rewrite plus_S. reflexivity.
Qed.
答案 0 :(得分:2)
首先,plus_comm
不是类型的一部分。您得到一个名为 {/ em> plus_comm
的术语forall x y : N, plus x y = plus y x.
您可以使用以下命令进行检查
Check plus_comm.
因此,定义plus_comm
引理的另一种方法是
Lemma plus_comm : forall x y : N, plus x y = plus y x.
作为旁注:在这种情况下,您需要在intros x y.
部分之后添加intros.
(或仅Proof.
)。
战术(以及将它们粘合在一起的方法)是一种叫做Ltac的元语言,因为它们被用来产生另一种语言的术语,称为Gallina,它是Coq的规范语言。
例如,forall x y : N, plus x y = plus y x
是Gallina句子的实例以及plus
函数的主体。要获取附加到plus_comm
的术语,请使用Print
命令:
Print plus_comm.
plus_comm =
fun x y : N =>
N_ind (fun x0 : N => plus x0 y = plus y x0)
(eq_ind_r (fun n : N => y = n) eq_refl (plus_0 y))
(fun (x0 : N) (IHx : plus x0 y = plus y x0) =>
eq_ind_r (fun n : N => S n = plus y (S x0))
(eq_ind_r (fun n : N => S (plus y x0) = n) eq_refl (plus_S y x0))
IHx) x
: forall x y : N, plus x y = plus y x
这不是一个简单的阅读,但有了一些经验,你将能够理解它。
顺便说一句,这就是我们如何证明引理不使用策略:
Definition plus_comm : forall x y : N, plus x y = plus y x :=
fix IH (x y : N) :=
match x return plus x y = plus y x with
| O => eq_sym (plus_0 y)
| S x => eq_ind _ (fun p => S p = plus y (S x)) (eq_sym (plus_S y x)) _ (eq_sym (IH x y))
end.
要解释一些事情:fix
是定义递归函数的方法,eq_sym
用于将x = y
更改为y = x
,eq_ind
对应rewrite
战术。