5

我有一个目标,其中包含对foo匹配分支中某些引理的调用。R该调用使用分支本地变量作为其参数之一:

| SomeConstr => fun R => .... (foo a b c R) ....

我想执行 beta 扩展,foo以便调用变为:

| SomeConstr => fun R => .... ((fun d => foo a b c d) R) ....

这将使我能够进一步概括(fun d => foo a b c d),这将不再依赖于分支本地的变量。因为我正在处理非常大的证明,所以我想用 Ltac 来写这个。这是一个尝试:

match goal with
| [ |- context[(foo ?A ?B ?C ?R)] ] =>
  let d := fresh "d" in
  replace (foo A B C R) with ((fun d => foo A B C d) R)
end.

然而,“没有匹配的匹配子句”失败。如果我match用它替换分支的主体idtac仍然失败,那么问题显然是由于未能匹配给定的表达式造成的。但是,如果我少匹配一个参数,则匹配成功。例如:

match goal with
| [ |- context[(foo ?A ?B ?C)] ] =>
  idtac A; idtac B; idtac C
end.

在连续的行中打印“a”、“b”和“c”。我也可以说:

match goal with
| [ |- context[(foo ?A ?B ?C)] ] =>
  let d := fresh "d" in
  replace (foo A B C) with (fun d => foo A B C d) by auto
end.

这成功了,但有趣的是,目标仍然没有改变,即。电话仍然是形式(foo a b c R)而不是((fun d => foo a b c d) R)。我在这里做错了什么?

4

1 回答 1

7

replace策略执行β减少。你可以通过写作看到这一点

Goal True.
  replace True with ((fun x => x) True) by auto.

如果您改为使用该change策略(仅在replace可以通过 解决的附带条件时才有效reflexivity),那么它应该可以工作。例如,

Goal True.
  change True with ((fun x => x) True).

将目标更改为(fun x : Prop => x) True

这是未记录的,我已在 GitHub 上将其报告为问题

于 2018-02-02T05:06:56.950 回答