使用Ltac

时间:2017-07-29 13:03:30

标签: coq 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)假设x : nat在量化假设compare

内的某个地方被用作H的参数

b)还有一些其他类型为nat的假设 - 即y - 可用于专门化量化假设。

c)一旦我们将这两件事专门化为Hy

我尝试这样做:

 match goal with
 | [ X : nat, Y : nat
   , H : forall (z : nat), context [ compare X z ] |- _ ] => specialize (H Y)
 end.

但是这段代码至少有两件事是错误的:

  1. 似乎不允许在context下使用forall

  2. 我无法找出将X作为参数传递给compare的正确方法  在某种程度上,它被认为是作为一种假设而存在的东西。就像这样:

2 个答案:

答案 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.