Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with let-in expressions in current goal

Tags:

let

coq

I got stuck while doing some coq proofs around the state monad. Concretely, I've simplified the situation to this proof:

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.

The resulting goal after invoking unfold is (let (b, c) := f a in (b, c)) = f a. If I'm not wrong, both sides of the equality should be exactly the same, but I don't know how to show it from here. Any help?

--

As a side note, I've seen that coq automatically applies the simplification when no product types are involved in the result of the function:

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.
like image 920
jeslg Avatar asked Jan 16 '18 09:01

jeslg


1 Answers

It's easy to see what you need to do next, once you recall that

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

is syntactic sugar for

match f a with (b, c) => (b, c) end

This means you need to destruct on f a to finish the proof:

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.
like image 156
Anton Trunov Avatar answered Nov 02 '22 08:11

Anton Trunov