我如何实现重复假设的coq策略?

我如何实现重复假设的coq策略?,coq,coq-tactic,ltac,Coq,Coq Tactic,Ltac,作为我一般问题的最小示例,假设我们有以下内容: Parameter C: Prop. Definition blah := C. 我想实施一种策略,在目标的所有假设中自动展开blah 我试过这个: Ltac my_auto_unfold := repeat match goal with | [ H: ?P |- ?P ] => unfold blah in H end. Theorem g: blah -> blah -> blah. Proof. intros

作为我一般问题的最小示例,假设我们有以下内容:

Parameter C: Prop.

Definition blah := C.
我想实施一种策略,在目标的所有假设中自动展开
blah

我试过这个:

Ltac my_auto_unfold := repeat match goal with 
  | [ H: ?P |- ?P ] => unfold blah in H
end.


Theorem g: blah -> blah -> blah.
Proof.
intros.
my_auto_unfold.

但是只有一个假设已经展开。

你的代码片段的问题是,
[H:?p |-?p]
在这种情况下总是匹配的。第一次它将匹配
H:blah
,第二次它将匹配
H:C
——因为C和blah在Coq中是可转换的——展开不会改变任何东西,因此中止
重复

我会写

Ltac my_auto_unfold nam := repeat lazymatch goal with 
  | [ H : nam |- _ ] => unfold nam in H
end.

Theorem g: blah -> blah -> blah.
Proof.
intros.
my_auto_unfold blah. auto. Qed.
你甚至可以写

Theorem g: blah -> blah -> blah.
Proof.
  intros.
  match goal with
  | [ |- ?p] => my_auto_unfold p
  end.
  auto. Qed.

如果你愿意的话。

我想你可能在寻找
的进展。如果您这样做:

Ltac my_auto_unfold := repeat match goal with 
  | [ H: ?P |- ?P ] => progress unfold blah in H
end.
然后它将在两个假设中展开
blah
。你甚至可以:

Ltac in_all_hyps tac :=
    repeat match goal with
           | [ H : _ |- _ ] => progress tac H
           end.
来概括这个模式。请注意,这可能会在每个假设中多次运行该策略


如果你想把所有的假设按顺序重复一遍,这将非常困难(特别是如果你想保留evar上下文,而不是在证明项中添加愚蠢的东西)。下面是一个快速而肮脏的方法(假设你的战术没有打乱目标):


我们的想法是,插入一个虚拟标识符来标记您在目标中的位置(即,标记可以引入多少变量),然后将所有上下文还原到目标中,这样您就可以一次一个假设地重新引入上下文,对您刚才介绍的每个假设运行策略。

是否在*|-。
中展开废话。
做您想做的事?在这个特定示例中,它做了我需要的事情,但一般问题仍然是:如何实现一个重复假设的策略?
|[H:nam |-|]=>在H
中,它只会匹配特定形状的假设。但我真正想要的是对所有假设重复应用一种策略,与它们的形状无关。
Parameter C: Prop.
Definition blah := C.

Definition BLOCK := True.

Ltac repeat_until_block tac :=
  lazymatch goal with
  | [ |- BLOCK -> _ ] => intros _
  | [ |- _ ] => tac (); repeat_until_block tac
  end.
Ltac on_each_hyp_once tac :=
  generalize (I : BLOCK);
  repeat match goal with
         | [ H : _ |- _ ] => revert H
         end;
  repeat_until_block
    ltac:(fun _
          => intro;
             lazymatch goal with
             | [ H : _ |- _ ] => tac H
             end).

Theorem g: blah -> blah -> fst (id blah, True).
Proof.
  intros.
  on_each_hyp_once ltac:(fun H => unfold blah in H).