Section ScanSection.
(* The algorithm is defined as follows: - if the heap is h1 :+ h2, then recurse over h1 and h2 and concatenate the results. - if the heap is x :-> v, then return [x] - otherwise, return [] *)
(* Structure to control the flow of the algorithm *)
Structure tagged_heap := Tag {untag : heap}.
Local Coercion untag : tagged_heap >-> heap.
Definition default_tag := Tag.
Definition ptr_tag := default_tag.
Canonical Structure union_tag h := ptr_tag h.
Definition axiom h s :=
def h -> uniq s /\ forall x, x \in s -> x \in dom h.
(* Main structure *)
Structure form s := Form {heap_of : tagged_heap; _ : axiom heap_of s}.
Local Coercion heap_of : form >-> tagged_heap.
Canonical Structure union_form s1 s2 h1 h2 :=
Form (@union_pf s1 s2 h1 h2).
Canonical Structure ptr_form A x (v : A) :=
Form (@ptr_pf A x v).
Canonical Structure foundx_form x y (s : Search.form y) :=
Form (foundx_pf x s).
Canonical Structure foundy_form x y (s : Search.form x) :=
Form (foundy_pf y s).
Canonical Structure foundz_form x y z (s : form x y) :=
Form (foundz_pf z s).
Arguments noaliasR_fwd1 [s f] D x y [g].
Notation noaliasR_fwd D x y := (noaliasR_fwd1 D x y (Logic.eq_refl _)).
Notation "()" := (Logic.eq_refl _).
Example exnc A (x1 x2 x3 x4 : ptr) (v1 v2 : A) (h1 h2 : heap) :
def (h1 :+ x2 :-> 1 :+ h2 :+ x1 :-> v2 :+ (x3 :-> v1 :+ empty)) ->
(x1 != x2) /\
(x1 != x2) && (x2 != x3) && (x3 != x1) /\
(x2 == x3) = false /\ (x1 == x2) = false.
Arguments scan_it [s f].
Definition search_them x y g := @Search2.find2E x y g.
Arguments search_them x y [g].
Example without_notation
A (x1 x2 x3 : ptr) (v1 v2 v3 : A) (h1 h2 : heap) :
def (h1 :+ (x1 :-> v1 :+ x2 :-> v2) :+ (h2 :+ x3 :-> v3))
-> (x1 != x3).
(* Lemma noaliasR_fwd_wrong2 s (f : Scan.form s) (d : def f) x y (g : Search2.form x y) : (@search_them x y g (@scan_it s f d)). *)
Notation noaliasR_fwd' x y D := (search_them x y (scan_it D)).
Example exnc A (x1 x2 x3 x4 : ptr) (v1 v2 : A) (h1 h2 : heap) :
def (h1 :+ x2 :-> 1 :+ h2 :+ x1 :-> v2 :+ (x3 :-> v1 :+ empty)) ->
(x1 != x2) /\
(x1 != x2) && (x2 != x3) && (x3 != x1) /\
(x2 == x3) = false /\ (x1 == x2) = false.

Lemma noaliasR_fwd3 s (f : Scan.form s) (D : def f) x y
(g : check x y s) : x != y_of g.