是否有办法为场所中的每个可能的H调用apply lem in H
,例如rewrite lem in *
?
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.
答案 0 :(得分:0)
我找不到内置的任何内容,但是可以用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; revert x
将确保不会再次匹配该假设。但是,最终结果将具有目标中的所有假设,例如P -> G
,而不是以p: P
为前提,以G
为目标。
要自动重新intro
得出这些假设,我们可以跟踪假设已还原多少次,然后再次引入它们。
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_n n
适用intro
n
次。
我一般没有对此进行测试,但是在上述情况下效果很好。如果无法还原假设(例如,如果其他假设依赖于假设),则可能会失败。它也可能会重新排列假设,因为重新引入已恢复的假设时,该假设将被置于假设列表的末尾。