将 `forall` 下的表达式上下文与 Ltac 匹配
Matching expression context under `forall` with Ltac
假设我在 Coq 中有以下定义:
Inductive Compare := Lt | Eq | Gt.
Fixpoint compare (x y : nat) : Compare :=
match x, y with
| 0, 0 => Eq
| 0, S _ => Lt
| S _, 0 => Gt
| S x', S y' => compare x' y'
end.
现在考虑这个引理:
Lemma foo : forall (x: nat),
(forall z, match compare x z with
| Lt => False
| Eq => False
| Gt => False
end) -> nat -> False.
Proof.
intros x H y.
此时证明状态如下所示:
x : nat
H : forall z : nat,
match compare x z with
| Lt => False
| Eq => False
| Gt => False
end
y : nat
============================
False
我想编写 Ltac match goal
来检测:
a) 在量化假设 H
的某处,有一个假设 x : nat
用作 compare
的参数
b) 并且还有其他一些类型为 nat
的假设 - 即 y
- 可用于专门化量化假设。
c) 一旦我们有了这两件事,就可以将 H
专门化为 y
我试过这样做:
match goal with
| [ X : nat, Y : nat
, H : forall (z : nat), context [ compare X z ] |- _ ] => specialize (H Y)
end.
但是这段代码至少有两处错误:
在 forall
下使用 context
似乎是不允许的。
我想不出将 X
作为参数传递给 compare
的正确方法
在某种程度上,它被认为是作为 hypothesis.doing 存在的东西,它像这样:
这并不能完全满足您的要求,但有点接近:
match goal with
| [ X : nat, Y : nat, H : context[compare ?a _] |- _ ] =>
match type of H with
| forall (z: nat), _ =>
match a with
| X => specialize (H Y)
end
end
end.
但是,这不会检查 compare
的第二个参数是否与 forall
绑定的 z
相匹配。
如果要检查X
是否出现在量化假设H
中,只要检查它在用任何不包含[=12的值实例化后出现在H中就可以了=].例如,您可以将 H
实例化为 Y
,只需将 H
的应用程序编写为 Y
的函数即可。这是我的建议:
match goal with | X : nat, H : _, Y : nat |- _ =>
match type of (H Y) with | context[X] => specialize (H Y) end
end.
这个 Ltac 文本确实检查了 H 是一个函数。如果您想更精确地说明 H
确实应该是通用量化(或产品类型),那么您可以检查 (H Y)
的类型是否也包含 Y
,如在以下片段中:
match goal with | X : nat, H : _, Y : nat |- _ =>
match type of (H Y) with | context[X] =>
match type of (H Y) with | context [Y] => specialize (H Y) end
end
end.
假设我在 Coq 中有以下定义:
Inductive Compare := Lt | Eq | Gt.
Fixpoint compare (x y : nat) : Compare :=
match x, y with
| 0, 0 => Eq
| 0, S _ => Lt
| S _, 0 => Gt
| S x', S y' => compare x' y'
end.
现在考虑这个引理:
Lemma foo : forall (x: nat),
(forall z, match compare x z with
| Lt => False
| Eq => False
| Gt => False
end) -> nat -> False.
Proof.
intros x H y.
此时证明状态如下所示:
x : nat
H : forall z : nat,
match compare x z with
| Lt => False
| Eq => False
| Gt => False
end
y : nat
============================
False
我想编写 Ltac match goal
来检测:
a) 在量化假设 H
x : nat
用作 compare
的参数
b) 并且还有其他一些类型为 nat
的假设 - 即 y
- 可用于专门化量化假设。
c) 一旦我们有了这两件事,就可以将 H
专门化为 y
我试过这样做:
match goal with
| [ X : nat, Y : nat
, H : forall (z : nat), context [ compare X z ] |- _ ] => specialize (H Y)
end.
但是这段代码至少有两处错误:
在
forall
下使用context
似乎是不允许的。我想不出将
X
作为参数传递给compare
的正确方法 在某种程度上,它被认为是作为 hypothesis.doing 存在的东西,它像这样:
这并不能完全满足您的要求,但有点接近:
match goal with
| [ X : nat, Y : nat, H : context[compare ?a _] |- _ ] =>
match type of H with
| forall (z: nat), _ =>
match a with
| X => specialize (H Y)
end
end
end.
但是,这不会检查 compare
的第二个参数是否与 forall
绑定的 z
相匹配。
如果要检查X
是否出现在量化假设H
中,只要检查它在用任何不包含[=12的值实例化后出现在H中就可以了=].例如,您可以将 H
实例化为 Y
,只需将 H
的应用程序编写为 Y
的函数即可。这是我的建议:
match goal with | X : nat, H : _, Y : nat |- _ =>
match type of (H Y) with | context[X] => specialize (H Y) end
end.
这个 Ltac 文本确实检查了 H 是一个函数。如果您想更精确地说明 H
确实应该是通用量化(或产品类型),那么您可以检查 (H Y)
的类型是否也包含 Y
,如在以下片段中:
match goal with | X : nat, H : _, Y : nat |- _ =>
match type of (H Y) with | context[X] =>
match type of (H Y) with | context [Y] => specialize (H Y) end
end
end.