(* 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.
(*****************************************************************)
(* indom :                                                       *)
(*    lemma automated with Canonical Structures to prove/rewrite *)
(*    expressions with the form                                  *)
(*      x \in dom (... :+ x :-> v :+ ... )                       *)
(*    for some v. Usage:                                         *)
(*      rewrite/apply: (indom D)                                 *)
(*    where D : def (... :+ x :-> v :+ ...)                      *)
(*****************************************************************)
(* Tagging for controling the instance search *)
Structure tagged_heap := Tag {untag :> heap}.
Definition right_tag := Tag.
Definition left_tag := right_tag.
Canonical Structure found_tag h := left_tag h.
Definition invariant x (h : tagged_heap) :=
def (untag h) -> x \in dom (untag h).
(* Main structure and instances *)
Structure find (x : ptr) :=
Form { heap_of :> tagged_heap;
_ : invariant x heap_of }.

(* Specifications: *)
Lemma found_pf A x (v : A) : invariant x (found_tag (x :-> v)).
Canonical Structure search_left x (h : heap) (f : find x) :=
@Form x (left_tag (untag (heap_of f) :+ h)) (@left_pf x h f).
Lemma right_pf x (h : heap) (f : find x) :
invariant x (right_tag (h :+ untag (heap_of f))).