在证明过程中如何将单个统一变量转化为目标

时间:2018-11-30 00:35:13

标签: coq

我想以交互方式构造一个存在变量。我无法使用Grab Existential Variables,因为在完成目标之前,我需要填写存在的内容。

最小的珍贵 这是一个最小的示例(因为它很简单,它具有其他解决方案,但它说明了我的问题)

Context (A:Type).
Parameter P Q: A -> Prop.
Definition filter: forall {a}, P a -> A:= fun a Pa=> a.
Lemma my_lemma:
  forall a b, Q b -> (Q b -> P a) ->
         exists a (H: P a), P (filter H).
  Proof.
  intros ?? H H0.
  do 2 eexists.

这时,有两种解决方案无法回答我的问题:(1)我可以先运行(eauto)然后再进行Grab Existential Variables,但假设eauto直到我实例化统一变量; (2)我可以只使用instantiate(1:= H0 H)(甚至是instantiate(1:= ltac:(eauto)))明确地通过证明项,但假设存在证明的证明是乏味的,我们希望以交互方式进行。

我们还能做什么?我们可以尝试使用cutassert,如下所示:

match goal with
      |[|- P (filter ?x)] =>
       match type of x with
       | ?T => assert (HH:T) by eauto
       end
      end.

但是HH不在统一变量的上下文中,因此无法实例化。

  instantiate(1:=HH). (* Instance is not well-typed in the environment of ?H. *)

据我所知,解决此问题的唯一方法是使用Show Existentials,查看变量的类型,手动复制它,将证明回滚到引入统一之前并构造变量那里。在示例中,它看起来像这样:

Lemma my_lemma:
  forall a b, Q b -> (Q b -> P a) ->
         exists a (H: P a), P (filter H).
Proof.
  intros ?? H H0.
  do 2 eexists.
  Show Existentials.  
  Restart. (* This command restores the proof editing process to the original goal. *)
  intros ?? H H0.
  assert (HH:P a) by eauto.
  eexists; exists HH.
  auto.
Qed.

很显然,我想避免此工作流程。那么,无论如何将存在变量变成子目标?

1 个答案:

答案 0 :(得分:1)

您最好的选择也许是避免首先将生存变量创建为evar。您无需手动构造变量即可;如果您可以确定它的创建位置,则可以使用unshelve t来包装令人反感的策略,从而将t创建的所有evar都转化为目标。可能很难做到的地方是,如果相关策略深入到某种自动化中并且难以识别或更改。