Coq 如何漂亮地打印使用策略构造的术语?
Coq how to pretty-print a term constructed using tactics?
我是 Coq 的新手,正在做一些练习以更加熟悉它。
我的理解是,在 Coq 中证明一个命题 "really" 就是在 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.
首先,plus_comm
是不是类型的一部分。你得到一个术语 named 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.
附带说明:在这种情况下,您需要在 Proof.
部分之后添加 intros x y.
(或只是 intros.
)。
策略(以及将它们粘合在一起的方法)是一种称为 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
策略。
我是 Coq 的新手,正在做一些练习以更加熟悉它。
我的理解是,在 Coq 中证明一个命题 "really" 就是在 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.
首先,plus_comm
是不是类型的一部分。你得到一个术语 named 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.
附带说明:在这种情况下,您需要在 Proof.
部分之后添加 intros x y.
(或只是 intros.
)。
策略(以及将它们粘合在一起的方法)是一种称为 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
策略。