【问题标题】:Dealing with let-in expressions in current goal处理当前目标中的 let-in 表达式
【发布时间】:2018-06-24 23:58:32
【问题描述】:

我在围绕 state monad 做一些 coq 证明时卡住了。具体来说,我已经将情况简化为这个证明:

Definition my_call {A B C} (f : A -> B * C) (a : A) : B * C :=
  let (b, c) := f a in (b, c).

Lemma mycall_is_call : forall {A B C} (f : A -> B * C) (a : A), my_call f a = f a.
Proof.
  intros A B C f a.
  unfold my_call.
  (* stuck! *)
Abort.

调用unfold 后得到的目标是(let (b, c) := f a in (b, c)) = f a。如果我没记错的话,等式的两边应该是完全一样的,但是我不知道如何从这里表现出来。有什么帮助吗?

--

作为旁注,我看到当函数的结果中不涉及任何产品类型时,coq 会自动应用简化:

Definition my_call' {A B : Type} (f : A -> B) (a : A) : B :=
  let b := f a in b.

Lemma my_call_is_call' : forall A B (f : A -> B) (a : A), my_call' f a = f a.
Proof.
  intros A B f a.
  unfold my_call'.
  reflexivity.
Qed.

【问题讨论】:

    标签: coq let


    【解决方案1】:

    一旦你回忆起来,就很容易看到下一步需要做什么

    let (b, c) := f a in (b, c)
    

    的语法糖
    match f a with (b, c) => (b, c) end
    

    这意味着您需要在 f a 上进行破坏才能完成证明:

    Lemma mycall_is_call {A B C} (f : A -> B * C) a :
      my_call f a = f a.
    Proof.
      unfold my_call.
      now destruct (f a).
    Qed.
    

    【讨论】:

    • 这么简单!不知道从letmatch 的语法糖。谢谢。
    • 请注意,您可以Set Printing All 使语法糖消失。
    • 使用原始投影定义的对(如here),我们可以仅使用reflexivity 证明mycall_is_call 引理。
    猜你喜欢
    • 2014-01-01
    • 2019-01-29
    • 2015-07-26
    • 2013-04-05
    • 2019-10-14
    • 1970-01-01
    • 2017-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多