Coq 模式匹配从目标模式匹配中获得的假设

Coq 模式匹配从目标模式匹配中获得的假设,coq,ltac,Coq,Ltac,考虑以下发展: Definition done {T : Type} (x : T) := True. Goal Test. pose 1 as n. assert (done n) by constructor. Fail ltac:( match goal with | [ H : done _ |- _ ] => fail | [ H : _ |- _ ] => match goal with | [ _: don

考虑以下发展:

Definition done {T : Type} (x : T) := True.

Goal Test.
  pose 1 as n.
  assert (done n) by constructor.
  Fail ltac:(
    match goal with 
    | [ H : done _ |- _ ] => fail
    | [ H : _ |- _ ] =>
      match goal with
      | [ _: done H |- _ ] => idtac "H == n"
      | [ _: done n |- _ ] => idtac "H != n"; fail 2
      end
    end
  ).
Abort.
这将打印
H!=n
。我发现这非常令人惊讶,因为范围内唯一的假设是
n
done n
-和
done n
已经由顶级匹配的第一个分支发出


我如何匹配
done n
而不明确地引用
n
,就像第二个匹配的第一个分支一样?

我想你对
匹配的工作方式感到困惑。匹配的第一个分支与每个假设匹配,如果总是失败,则测试第二个分支,依此类推。在您的示例中,第一个分支匹配假设
H
,但相应策略(
fail
)的执行失败,因此尝试第二个分支,该分支也匹配假设
H

实际上,外部
匹配的第一个分支似乎做了您想要做的事情(即,匹配形式为
完成
)的假设,因此我没有真正理解您内部
匹配的要点

比如说,

match goal with 
| [ H' : done _ |- _ ] => idtac H'
end.
打印
H
,表明符合正确的假设


注意,在策略上使用
Fail
不需要
ltac:()
表达式。例如,
失败。
有效。

谢谢,我现在明白了!