Coq `匹配目标';t匹配let分解表达式

Coq `匹配目标';t匹配let分解表达式,coq,coq-tactic,Coq,Coq Tactic,我试图证明一个定理,其中涉及一个函数,该函数使用一个析构函数let表达式,并试图使用match-goal策略来析构函数的右侧,但由于某种原因,该模式与我所期望的不匹配: match goal with (* why doesn't this match? *) | [ |- context[let _ := ?X in _] ] => destruct X end. 如果您有来自的Cpdt(我非常喜欢他的自动化风格),那么这里有一个应该可以运行的代码片段 我已经找到了一个证明,但

我试图证明一个定理,其中涉及一个函数,该函数使用一个析构函数
let
表达式,并试图使用
match-goal
策略来析构函数的右侧,但由于某种原因,该模式与我所期望的不匹配:

match goal with
  (* why doesn't this match? *)
  | [ |- context[let _ := ?X in _] ] => destruct X
end.
如果您有来自的
Cpdt
(我非常喜欢他的自动化风格),那么这里有一个应该可以运行的代码片段

我已经找到了一个证明,但我正计划证明更多类似形状的定理,我希望有一个能够证明其中许多定理的自动化策略

Set Implicit Arguments. Set Asymmetric Patterns.
Require Import List Cpdt.CpdtTactics.
Import ListNotations.

Section PairList.
  Variable K V: Set.
  Variable K_eq_dec: forall x y: K, {x = y} + {x <> y}.
  Variable V_eq_dec: forall x y: V, {x = y} + {x <> y}.

  Definition Pair: Type := (K * V).
  Definition PairList := list Pair.
  (* ... *)

  Fixpoint set (l: PairList) (key: K) (value: V): PairList :=
    match l with
    | [] => [(key, value)]
    | pr::l' => let (k, _) := pr in
      if K_eq_dec key k then (key, value)::l' else pr::(set l' key value)
    end.

  Theorem set_NotEmpty: forall (before after: PairList) key value,
    after = set before key value -> after <> [].
  Proof.
    intros before after. induction before.
    - crush.
    - intros. rewrite -> H. simpl.

      (* the context at this step:
        1 subgoal

          K, V : Set
          K_eq_dec : ...
          V_eq_dec : ...
          a : Pair
          before : list Pair
          after : PairList
          IHbefore: ...
          key : K
          value : V
          H : ...
          ============================
          (let (k, _) := a in
           if K_eq_dec key k
           then (key, value) :: before
           else
            a :: set before key value) <> []
      *)

      (* a successful proof
        destruct a.
        destruct (K_eq_dec key k); crush.
      *)

      match goal with
        (* why doesn't this match? *)
        | [ |- context[let _ := ?X in _] ] => destruct X
        | [ |- context[(() <> [])] ] => idtac X
      end.
      (* the above command prints this:
        (let (k, _) := a in
         if K_eq_dec key k
         then (key, value) :: before
         else
          a :: set before key value)
      *)
  Qed.
End PairList.
设置隐式参数。设置不对称模式。
需要导入列表Cpdt.Cpdt。
导入列表符号。
部分成对列表。
变量kv:Set。
变量K_eq_dec:forall xy:K,{x=y}+{xy}。
变量V_eq_dec:forall xy:V,{x=y}+{xy}。
定义对:类型:=(K*V)。
定义对列表:=列表对。
(* ... *)
不动点集(l:PairList)(键:K)(值:V):PairList:=
匹配
|[]=>[(键、值)]
|pr::l'=>让(k,u):=pr在
如果K_eq_dec key K,那么(key,value)::l’else pr:(设置l’key value)
结束。
定理集\u NotEmpty:forall(前后:PairList)键值,
after=在键值之前设置->在[]之后。
证明。
前后介绍。诱导前。
-压碎。
-介绍。重写->H.siml。
(*此步骤的上下文:
1子目标
K、 V:一套
K_eq_dec:。。。
V_eq_dec:。。。
a:一双
前:列表对
之后:派利斯特
我以前:。。。
关键字:K
值:V
H:。。。
============================
(设(k,u):=a in
如果K_eq_dec键K
然后(键、值)::之前
其他的
a::在键值之前设置)[]
*)
(*成功的证明
破坏a。
破坏(K_eq_dec键K);粉碎。
*)
将目标与
(*为什么不匹配?*)
|[|-context[let:=?X in]=>析构函数X
|[|-context[(()[])]=>idtac X
结束。
(*上述命令将打印以下内容:
(设(k,u):=a in
如果K_eq_dec键K
然后(键、值)::之前
其他的
a::设置在键值之前)
*)
Qed。
结束配对。

解构let实际上是匹配项,因此您需要查找
匹配项。当战术不匹配时,您可以看到目标中的所有表达式都被
Set-Printing-all删除。

      match goal with
        | [ |- context[let _ := ?X in _] ] => destruct X
        (* ADD THIS LINE *)
        | [ |- context[match ?X with _ => _ end]] => destruct X
        | [ |- context[(() <> [])] ] => idtac X
      end.
将目标与
|[|-context[let:=?X in]=>析构函数X
(*添加此行*)
|[|-context[match?X与=>\uend]]=>析构函数X
|[|-context[(()[])]=>idtac X
结束。

解构let实际上是匹配项,因此您需要查找
匹配项。当战术不匹配时,您可以看到目标中的所有表达式都被
Set-Printing-all删除。

      match goal with
        | [ |- context[let _ := ?X in _] ] => destruct X
        (* ADD THIS LINE *)
        | [ |- context[match ?X with _ => _ end]] => destruct X
        | [ |- context[(() <> [])] ] => idtac X
      end.
将目标与
|[|-context[let:=?X in]=>析构函数X
(*添加此行*)
|[|-context[match?X与=>\uend]]=>析构函数X
|[|-context[(()[])]=>idtac X
结束。

效果很好!非常感谢。不过我很好奇,
match-goal
使用
if
语句和not-let语句有什么潜在原因?当遇到if时,这一行就起作用了。我的理解是,if语句也是
匹配的糖分。李耀霞在开始他的消息时使用了“destructuring lets are…”。你在问题中使用的符号是普通let,而不是destructuring let。有两种
let
构造,其中只有一种是匹配糖。这非常有效!非常感谢。不过我很好奇,
match-goal
使用
if
语句和not-let语句有什么潜在原因?当遇到if时,这一行就起作用了。我的理解是,if语句也是
匹配的糖分。李耀霞在开始他的消息时使用了“destructuring lets are…”。你在问题中使用的符号是普通let,而不是destructuring let。有两种
let
构造,其中只有一种是匹配的sugar。