Coq 有没有像在*中应用lem这样的东西?

Coq 有没有像在*中应用lem这样的东西?,coq,Coq,是否有任何方法可以调用在H中应用lem以获得每个可能的H,比如在*中重写lem Axiom P Q : nat -> Prop. Axiom lem : forall (n : nat), P n -> Q n. Goal P O -> P (S O) -> True. intros. apply lem in H. apply lem in H0. 我找不到任何内置的东西,但可以用Ltac编写这样的策略 首先是特例 Axiom P Q : nat -> Pr

是否有任何方法可以调用
在H中应用lem
以获得每个可能的H,比如
在*
中重写lem

Axiom P Q : nat -> Prop.
Axiom lem : forall (n : nat), P n -> Q n.
Goal P O -> P (S O) -> True.
  intros. apply lem in H. apply lem in H0.

我找不到任何内置的东西,但可以用Ltac编写这样的策略

首先是特例

Axiom P Q : nat -> Prop.
Axiom lem : forall (n : nat), P n -> Q n.
Goal P O -> P (S O) -> True.
  intros.
  repeat match goal with
    x : _ |- _ => apply lem in x
  end.
Abort.
现在我们可以推广这个

Ltac apply_in_premises t :=
  repeat match goal with
    x : _ |- _ => apply t in x
  end.
然后像这样使用它:

Goal P O -> P (S O) -> True.
  intros.
  apply_in_premises lem.
Abort.
不幸的是,如果应用
lem
生成可以应用
lem
的其他内容,这种方法可能会导致无限循环

Axiom P : nat -> Prop.
Axiom lem : forall (n : nat), P n -> P (S n).
Ltac apply_in_premises t :=
  repeat match goal with
    x : _ |- _ => apply t in x
  end.

Goal P O -> P (S O) -> nat -> True.
  intros.
  apply_in_premises lem. (* infinite loop *)
Abort.
如果您对此感到担忧,您可以在评论中使用Yves建议的变体。只需将
apply t in x
更改为
apply t in x;还原x将确保该假设不会再次匹配。然而,最终结果将包含目标中的所有假设,如
P->G
,而不是
P:P
作为前提和
G
作为目标

要自动重新导入这些假设,我们可以跟踪假设被还原的次数,然后再次导入

Ltac intro_n n :=
  match n with
  | 0 => idtac
  | S ?n' => intro; intro_n n'
  end.

Ltac apply_in_premises_n t n :=
  match goal with
  | x : _ |- _ => apply t in x; revert x;
                  apply_in_premises_n t (S n)
  | _ => intro_n n (* now intro all the premises that were reverted *)
  end.

Tactic Notation "apply_in_premises" uconstr(t) := apply_in_premises_n t 0.

Axiom P : nat -> Prop.
Axiom lem : forall (n : nat), P n -> P (S n).

Goal P O -> P (S O) -> nat -> True.
  intros.
  apply_in_premises lem. (* only applies `lem` once in each of the premises *)
Abort.
在这里,策略
intro\u n n
应用
intro
n


一般来说,我还没有测试过这个,但是在上面的例子中它运行得很好。如果一个假设无法恢复,它可能会失败(例如,如果其他假设依赖于它)。它还可以对假设进行重新排序,因为当一个还原的假设被重新引入时,它会被放在假设列表的末尾。

您是否尝试了
在x中应用t;还原x
。最后,您的目标将包含所有新创建的假设。这并不完美,但它应该避免循环行为。@Yves,它工作得很好。我找到了一种方法来确保再次介绍所有的假设,等我有时间的时候再编辑。谢谢