如何在假设中将具体变量更改为存在量化变量?

时间:2015-09-04 16:46:01

标签: coq

说我有这样的假设:

FooProp a b

我想将这个假设改为这种形式:

exists a, FooProp a b

我该怎么做?

我知道我可以做assert (exists a, FooProp a b) by eauto但我正试图找到一种解决方案,不要求我明确写出整个假设;这对于自动化是不利的,并且当假设是不平凡的时候通常是头痛的。理想情况下,我想指定intro_exists a in H1或其他内容;它真的应该那么简单。

编辑:为什么?因为我有这样的引理:

Lemma find_instr_in: 
  forall c i,
   In i c <-> (exists z : Z, find_instr z c = Some i).

这样的假设:

H1: find_instr z c = Some i

我正试图像这样重写:

rewrite <- find_instr_in in H1

哪个失败,错误为Found no subterm matching "exists z, ..." ...。但是,如果我assert (exists z, find_instr z c = Some i) by eauto.首先重写有效。

1 个答案:

答案 0 :(得分:3)

这样的事情怎么样:

Ltac intro_exists' a H :=
  pattern a in H; apply ex_intro in H.

Tactic Notation "intro_exists" ident(a) "in" ident(H) := intro_exists' a H.

Section daryl.
  Variable A B : Type.
  Variable FooProp : A -> B -> Prop.

  Goal forall a b, FooProp a b -> False.
    intros.
    intro_exists a in H.
  Admitted.
End daryl.

关键是pattern策略,它找到一个术语的出现并将它们抽象为应用于参数的函数。因此,pattern a会将H的类型从FooProp a b转换为(fun x => FooProp x b) a。在那之后,Coq可以在你申请ex_intro时弄清楚你的意思。

修改 所有这一切,在你具体的情况下,我实际上会推荐一种不同的方法,就是不要这样说出你的引理。相反,将它分成两个引理是方便的,每个方向一个。向前方向是相同的,但向后方向​​应重新如下

forall c i z, 
  find_instr z c = Some i -> In i c.

如果你这样做,那么重写就会成功,而不需要引入存在主义。