说我在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)假设x : nat
在量化假设compare
H
的参数
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.
但是这段代码至少有两件事是错误的:
似乎不允许在context
下使用forall
。
我无法找出将X
作为参数传递给compare
的正确方法
在某种程度上,它被认为是作为一种假设而存在的东西。就像这样:
答案 0 :(得分:2)
这不是你所要求的,但它有点接近:
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
的第二个参数是否与z
绑定的forall
匹配。
答案 1 :(得分:2)
如果要检查量化假设X
中是否出现H
,则在使用不包含X
的任何值实例化后,检查它是否出现在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.