处理当前目标中的 let-in 表达式

jes*_*slg 6 let coq

我在围绕statemonad做一些 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.
Run Code Online (Sandbox Code Playgroud)

调用后的结果目标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.
Run Code Online (Sandbox Code Playgroud)

Ant*_*nov 5

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

let (b, c) := f a in (b, c)
Run Code Online (Sandbox Code Playgroud)

是语法糖

match f a with (b, c) => (b, c) end
Run Code Online (Sandbox Code Playgroud)

这意味着您需要破坏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.
Run Code Online (Sandbox Code Playgroud)