(* Copyright (C) 2012  G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer  This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.  You should have received a copy of the GNU General Public License along with this program.  If not, see <http://www.gnu.org/licenses/>. *)
From mathcomp
From LemmaOverloading
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Class Update (h1 h2 k1 k2 : heap) :=
{ rest : heap; update1 : h1 = k1 :+ rest; update2 : h2 = k2 :+ rest}.
Arguments update1 [h1 h2 k1 k2].
Arguments update2 [h1 h2 k1 k2].
Arguments rest [h1 h2 k1 k2].
Program
Instance found_struct k1 k2 : Update k1 k2 k1 k2 | 1 := {| rest := empty |}.
Next Obligation. by rewrite unh0. Qed.
Next Obligation. by rewrite unh0. Qed.
Program
Instance left_struct l h1 h2 k1 k2 (f : Update h1 h2 k1 k2) :
Update (l :+ h1) (l :+ h2) k1 k2 | 2 := {| rest := (l :+ rest f) |}.
Next Obligation.
have H : h1 = k1 :+ (rest f) by eapply (update1 f).
by rewrite -unCA -H.
Qed.
Next Obligation.
have H : h2 = k2 :+ (rest f) by eapply (update2 f).
by rewrite -unCA -H.
Qed.
Program
Instance right_struct l h1 h2 k1 k2 (f : Update h1 h2 k1 k2) :
Update (h1 :+ l) (h2 :+ l) k1 k2 | 2 := {| rest := (rest f :+ l) |}.
Next Obligation.
have H : h1 = k1 :+ (rest f) by eapply (update1 f).
by rewrite unA -H.
Qed.
Next Obligation.
have H : h2 = k2 :+ (rest f) by eapply (update2 f).
by rewrite unA -H.
Qed.
Notation cont A := (ans A -> heap -> Prop).
Section EvalWriteR.
Variables (A B C : Type).

(* Specifications: *)
Lemma bnd_writeR s (v : A) (w : C) x h1 h2
(f : Update h1 h2 (x:->v) (x:->w)) (r : cont B) :
verify (s tt) h1 r ->
verify (bind_s (write_s x v) s) h2 r.