Require Import VST.floyd.proofauto.
Require Import VST.progs.bst.

Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs. mk_varspecs prog. Defined.

Definition t_struct_tree := Tstruct _tree noattr.

Section TREES.
Variable V : Type.
Variable default: V.

Definition key := Z.

Inductive tree : Type :=
 | E : tree
 | T: tree -> key -> V -> tree -> tree.

Definition empty_tree : tree := E.

Fixpoint lookup (x: key) (t : tree) : V :=
  match t with
  | E => default
  | T tl k v tr => if x <? k then lookup x tl
                         else if k <? x then lookup x tr
                         else v
  end.

Fixpoint insert (x: key) (v: V) (s: tree) : tree :=
 match s with
 | E => T E x v E
 | T a y v' b => if  x <? y then T (insert x v a) y v' b
                        else if y <? x then T a y v' (insert x v b)
                        else T a x v b
 end.

Fixpoint pushdown_left (a: tree) (bc: tree) : tree :=
 match bc with
 | E => a
 | T b y vy c => T (pushdown_left a b) y vy c
 end.

Fixpoint delete (x: key) (s: tree) : tree :=
 match s with
 | E => E
 | T a y v' b => if  x <? y then T (delete x a) y v' b
                        else if y <? x then T a y v' (delete x b)
                        else pushdown_left a b
 end.

End TREES.
Arguments E {V}.
Arguments T {V} _ _ _ _.
Arguments insert {V} x v s.
Arguments lookup {V} default x t.
Arguments pushdown_left {V} a bc.
Arguments delete {V} x s.

Fixpoint tree_rep (t: tree val) (p: val) : mpred :=
 match t with
 | E => !!(p=nullval) && emp
 | T a x v b => !! (Int.min_signed <= x <= Int.max_signed /\ tc_val (tptr Tvoid) v) &&
    EX pa:val, EX pb:val,
    data_at Tsh t_struct_tree (Vint (Int.repr x),(v,(pa,pb))) p *
    tree_rep a pa * tree_rep b pb
 end.

Definition treebox_rep (t: tree val) (b: val) :=
 EX p: val, data_at Tsh (tptr t_struct_tree) p b * tree_rep t p.

(* TODO: seems not useful *)
Lemma treebox_rep_spec: forall (t: tree val) (b: val),
  treebox_rep t b =
  EX p: val, 
  match t with
  | E => !!(p=nullval) && data_at Tsh (tptr t_struct_tree) p b
  | T l x v r => !! (Int.min_signed <= x <= Int.max_signed /\ tc_val (tptr Tvoid) v) &&
      data_at Tsh (tptr t_struct_tree) p b *
      spacer Tsh (sizeof tint) (sizeof size_t) p *
      field_at Tsh t_struct_tree [StructField _key] (Vint (Int.repr x)) p *
      field_at Tsh t_struct_tree [StructField _value] v p *
      treebox_rep l (field_address t_struct_tree [StructField _left] p) *
      treebox_rep r (field_address t_struct_tree [StructField _right] p)
  end.
Proof.
(* Goal: forall (sh : share) (x y : Z) (p : val) (_ : @eq Z x y), @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
  intros.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval b1) (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@E val)) b1) (treebox_rep (@delete val x t) b))) (treebox_rep (@delete val x t) b) *)
  unfold treebox_rep at 1.
(* Goal: @eq mpred (@exp mpred Nveric val (fun p : val => @sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (tree_rep t p))) (@exp mpred Nveric val (fun p : val => match t with | E => @andp mpred Nveric (@prop mpred Nveric (@eq val p nullval)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) | T l x v r => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed x) (Z.le x Int.max_signed)) (tc_val (tptr Tvoid) v))) (@data_at CompSpecs Tsh (tptr t_struct_tree) p b)) (spacer Tsh (@sizeof (@cenv_cs CompSpecs) tint) (@sizeof (@cenv_cs CompSpecs) size_t) p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr x)) p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (treebox_rep l (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p))) (treebox_rep r (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p)) end)) *)
  f_equal.
(* Goal: @eq (forall _ : val, mpred) (fun p : val => @sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (tree_rep t p)) (fun p : val => match t with | E => @andp mpred Nveric (@prop mpred Nveric (@eq val p nullval)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) | T l x v r => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed x) (Z.le x Int.max_signed)) (tc_val (tptr Tvoid) v))) (@data_at CompSpecs Tsh (tptr t_struct_tree) p b)) (spacer Tsh (@sizeof (@cenv_cs CompSpecs) tint) (@sizeof (@cenv_cs CompSpecs) size_t) p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr x)) p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (treebox_rep l (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p))) (treebox_rep r (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p)) end) *)
  extensionality p.
(* Goal: @eq mpred (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (tree_rep t p)) match t with | E => @andp mpred Nveric (@prop mpred Nveric (@eq val p nullval)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) | T l x v r => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed x) (Z.le x Int.max_signed)) (tc_val (tptr Tvoid) v))) (@data_at CompSpecs Tsh (tptr t_struct_tree) p b)) (spacer Tsh (@sizeof (@cenv_cs CompSpecs) tint) (@sizeof (@cenv_cs CompSpecs) size_t) p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr x)) p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (treebox_rep l (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p))) (treebox_rep r (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p)) end *)
  destruct t; simpl.
  + apply pred_ext; entailer!.
  + unfold treebox_rep.
(* Goal: @eq mpred (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed k) (Z.le k Int.max_signed)) (is_pointer_or_null v))) (@exp mpred Nveric val (fun pa : val => @exp mpred Nveric val (fun pb : val => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p) (tree_rep t1 pa)) (tree_rep t2 pb)))))) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed k) (Z.le k Int.max_signed)) (is_pointer_or_null v))) (@data_at CompSpecs Tsh (tptr t_struct_tree) p b)) (spacer Tsh (Zpos (xO (xO xH))) (Zpos (xO (xO xH))) p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@exp mpred Nveric val (fun p0 : val => @sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p0 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p)) (tree_rep t1 p0)))) (@exp mpred Nveric val (fun p0 : val => @sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p0 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p)) (tree_rep t2 p0)))) *)
    apply pred_ext; entailer!.
    - Intros pa pb.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) pb (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p)) (tree_rep t1 pb))) (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) pa (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p)) (tree_rep t2 pa))) (@exp mpred Nveric val (fun pa : val => @exp mpred Nveric val (fun pb : val => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p) (tree_rep t1 pa)) (tree_rep t2 pb)))) *)
      Exists pb pa.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p))) (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val p1 p2))) p) *)
      unfold_data_at (data_at _ _ _ p).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p2 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p))) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p2 p)))) *)
      rewrite (field_at_data_at _ t_struct_tree [StructField _left]).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p))) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p2 p)))) *)
      rewrite (field_at_data_at _ t_struct_tree [StructField _right]).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@emp mpred Nveric Sveric) (tree_rep t p)) (tree_rep t p) *)
      cancel.
    - Intros pa pb.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) pb (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p)) (tree_rep t1 pb))) (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) pa (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p)) (tree_rep t2 pa))) (@exp mpred Nveric val (fun pa : val => @exp mpred Nveric val (fun pb : val => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p) (tree_rep t1 pa)) (tree_rep t2 pb)))) *)
      Exists pb pa.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p))) (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val p1 p2))) p) *)
      unfold_data_at (data_at _ _ _ p).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p2 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p))) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p2 p)))) *)
      rewrite (field_at_data_at _ t_struct_tree [StructField _left]).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p))) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p2 p)))) *)
      rewrite (field_at_data_at _ t_struct_tree [StructField _right]).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@emp mpred Nveric Sveric) (tree_rep t p)) (tree_rep t p) *)
      cancel.
Qed.

Definition mallocN_spec :=
 DECLARE _mallocN
  WITH n: Z
  PRE [ 1%positive OF tint]
     PROP (4 <= n <= Int.max_unsigned)
     LOCAL (temp 1%positive (Vint (Int.repr n)))
     SEP ()
  POST [ tptr tvoid ]
     EX v: val,
     PROP (malloc_compatible n v)
     LOCAL (temp ret_temp v)
     SEP (memory_block Tsh n v).

Definition freeN_spec :=
 DECLARE _freeN
  WITH p : val , n : Z
  PRE [ 1%positive OF tptr tvoid , 2%positive OF tint]
     (* we should also require natural_align_compatible (eval_id 1) *)
      PROP() LOCAL (temp 1%positive p; temp 2%positive (Vint (Int.repr n)))
      SEP (memory_block Tsh n p)
  POST [ tvoid ]
    PROP () LOCAL () SEP ().

Definition treebox_new_spec :=
 DECLARE _treebox_new
  WITH u : unit
  PRE  [  ]
       PROP() LOCAL() SEP ()
  POST [ tptr (tptr t_struct_tree) ]
    EX v:val,
    PROP()
    LOCAL(temp ret_temp v)
    SEP (data_at Tsh (tptr t_struct_tree) nullval v).

Definition insert_spec :=
 DECLARE _insert
  WITH b: val, x: Z, v: val, t: tree val
  PRE  [ _t OF (tptr (tptr t_struct_tree)), _x OF tint,
        _value OF (tptr Tvoid)   ]
    PROP( Int.min_signed <= x <= Int.max_signed; is_pointer_or_null v)
    LOCAL(temp _t b; temp _x (Vint (Int.repr x)); temp _value v)
    SEP (treebox_rep t b)
  POST [ Tvoid ] 
    PROP()
    LOCAL()
    SEP (treebox_rep (insert x v t) b).

Definition lookup_spec :=
 DECLARE _lookup
  WITH b: val, x: Z, v: val, t: tree val
  PRE  [ _t OF (tptr (tptr t_struct_tree)), _x OF tint  ]
    PROP( Int.min_signed <= x <= Int.max_signed)
    LOCAL(temp _t b; temp _x (Vint (Int.repr x)))
    SEP (treebox_rep t b)
  POST [ tptr Tvoid ]
    PROP()
    LOCAL(temp ret_temp (lookup nullval x t))
    SEP (treebox_rep t b).

Definition turn_left_spec :=
 DECLARE _turn_left
  WITH ta: tree val, x: Z, vx: val, tb: tree val, y: Z, vy: val, tc: tree val, b: val, l: val, pa: val, r: val
  PRE  [ __l OF (tptr (tptr (Tstruct _tree noattr))),
        _l OF (tptr (Tstruct _tree noattr)),
        _r OF (tptr (Tstruct _tree noattr))]
    PROP(Int.min_signed <= x <= Int.max_signed; is_pointer_or_null vx)
    LOCAL(temp __l b; temp _l l; temp _r r)
    SEP (data_at Tsh (tptr t_struct_tree) l b;
         data_at Tsh t_struct_tree (Vint (Int.repr x), (vx, (pa, r))) l;
         tree_rep ta pa;
         tree_rep (T tb y vy tc) r)
  POST [ Tvoid ] 
    EX pc: val,
    PROP(Int.min_signed <= y <= Int.max_signed; is_pointer_or_null vy)
    LOCAL()
    SEP (data_at Tsh (tptr t_struct_tree) r b;
         data_at Tsh t_struct_tree (Vint (Int.repr y), (vy, (l, pc))) r;
         tree_rep (T ta x vx tb) l;
         tree_rep tc pc).

Definition pushdown_left_spec :=
 DECLARE _pushdown_left
  WITH ta: tree val, x: Z, v: val, tb: tree val, b: val, p: val
  PRE  [ _t OF (tptr (tptr (Tstruct _tree noattr)))]
    PROP(Int.min_signed <= x <= Int.max_signed; tc_val (tptr Tvoid) v)
    LOCAL(temp _t b)
    SEP (data_at Tsh (tptr t_struct_tree) p b;
         field_at Tsh t_struct_tree [StructField _key] (Vint (Int.repr x)) p;
         field_at Tsh t_struct_tree [StructField _value] v p;
         treebox_rep ta (field_address t_struct_tree [StructField _left] p);
         treebox_rep tb (field_address t_struct_tree [StructField _right] p))
  POST [ Tvoid ] 
    PROP()
    LOCAL()
    SEP (treebox_rep (pushdown_left ta tb) b).

Definition delete_spec :=
 DECLARE _delete
  WITH b: val, x: Z, t: tree val
  PRE  [ _t OF (tptr (tptr t_struct_tree)), _x OF tint]
    PROP( Int.min_signed <= x <= Int.max_signed)
    LOCAL(temp _t b; temp _x (Vint (Int.repr x)))
    SEP (treebox_rep t b)
  POST [ Tvoid ] 
    PROP()
    LOCAL()
    SEP (treebox_rep (delete x t) b).

Definition tree_free_spec :=
 DECLARE _tree_free
  WITH t: tree val, p: val
  PRE  [ _p OF (tptr t_struct_tree) ]
       PROP() LOCAL(temp _p p) SEP (tree_rep t p)
  POST [ Tvoid ]
    PROP()
    LOCAL()
    SEP (emp).

Definition treebox_free_spec :=
 DECLARE _treebox_free
  WITH t: tree val, b: val
  PRE  [ _b OF (tptr (tptr t_struct_tree)) ]
       PROP() LOCAL(temp _b b) SEP (treebox_rep t b)
  POST [ Tvoid ]
    PROP()
    LOCAL()
    SEP (emp).

Definition Gprog : funspecs :=
    ltac:(with_library prog [
    mallocN_spec; freeN_spec; treebox_new_spec;
    tree_free_spec; treebox_free_spec;
    insert_spec; lookup_spec;
    turn_left_spec; pushdown_left_spec; delete_spec
  ]).

Lemma tree_rep_saturate_local:
   forall t p, tree_rep t p |-- !! is_pointer_or_null p.
Proof.
(* Goal: forall (sh : share) (x y : Z) (p : val) (_ : @eq Z x y), @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
destruct t; simpl; intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
entailer!.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed k) (Z.le k Int.max_signed)) (is_pointer_or_null v))) (@exp mpred Nveric val (fun pa : val => @exp mpred Nveric val (fun pb : val => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (tree_rep t1_1 pa)) (tree_rep t1_2 pb))))) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
Intros pa pb. entailer!.
Qed.

Hint Resolve tree_rep_saturate_local: saturate_local.

Lemma tree_rep_valid_pointer:
  forall t p, tree_rep t p |-- valid_pointer p.
Proof.
(* Goal: forall (sh : share) (x y : Z) (p : val) (_ : @eq Z x y), @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
intros.
(* Goal: @derives mpred Nveric (tree_rep t p) (valid_pointer p) *)
destruct t; simpl; normalize; auto with valid_pointer.
Qed.
Hint Resolve tree_rep_valid_pointer: valid_pointer.

Lemma treebox_rep_saturate_local:
   forall t b, treebox_rep t b |-- !! field_compatible (tptr t_struct_tree) [] b.
Proof.
(* Goal: forall (sh : share) (x y : Z) (p : val) (_ : @eq Z x y), @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (Abs (empty_tree val) (@t_empty val nullval))) (treebox_rep (empty_tree val) v)) (@nil mpred))))) *)
unfold treebox_rep.
(* Goal: semax CompSpecs Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun vret : val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p vret) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_empty val nullval) vret) (@cons mpred (Freezer.FRZL FR1) (@nil mpred))))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xI xH))) tint) (@cons expr (Evar ___stringlit_1 (tarray tschar (Zpos (xO (xI xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_2 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xO (xO xH)))) tint) (@cons expr (Evar ___stringlit_3 (tarray tschar (Zpos (xI (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_4 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))))))) MORE_COMMANDS) POSTCONDITION *)
Intros p.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
entailer!.
Qed.

Hint Resolve treebox_rep_saturate_local: saturate_local.

Definition insert_inv (b0: val) (t0: tree val) (x: Z) (v: val): environ -> mpred :=
  EX b: val, EX t: tree val,
  PROP()
  LOCAL(temp _t b; temp _x (Vint (Int.repr x));   temp _value v)
  SEP(treebox_rep t b;  (treebox_rep (insert x v t) b -* treebox_rep (insert x v t0) b0)).

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (tree_rep t1_2 pb)) (@nil mpred)))))) (@liftx (LiftEnviron mpred) (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1))) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@cons mpred (treebox_rep t1_1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred)))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
Lemma ramify_PPQQ {A: Type} {NA: NatDed A} {SA: SepLog A} {CA: ClassicalSep A}: forall P Q,
  P |-- P * (Q -* Q).
Proof.
(* Goal: forall (sh : share) (x y : Z) (p : val) (_ : @eq Z x y), @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
  intros.
(* Goal: @derives A NA P (@sepcon A NA SA P (@wand A NA SA Q Q)) *)
  apply RAMIF_PLAIN.solve with emp.
  + rewrite sepcon_emp; auto.
  + rewrite emp_sepcon; auto.
Qed.

Lemma tree_rep_nullval: forall t,
  tree_rep t nullval |-- !! (t = E).
Proof.
(* Goal: forall (sh : share) (x y : Z) (p : val) (_ : @eq Z x y), @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
  intros.
(* Goal: @derives mpred Nveric (tree_rep t nullval) (@prop mpred Nveric (@eq (tree val) t (@E val))) *)
  destruct t; [entailer! |].
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep (@T val t1_1 k v t1_2) p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
  simpl tree_rep.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed k) (Z.le k Int.max_signed)) (is_pointer_or_null v))) (@exp mpred Nveric val (fun pa : val => @exp mpred Nveric val (fun pb : val => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (tree_rep t1_1 pa)) (tree_rep t1_2 pb))))) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
  Intros pa pb. entailer!.
Qed.

Hint Resolve tree_rep_nullval: saturate_local.

Lemma treebox_rep_leaf: forall x p b (v: val),
  is_pointer_or_null v ->
  Int.min_signed <= x <= Int.max_signed ->
  data_at Tsh t_struct_tree (Vint (Int.repr x), (v, (nullval, nullval))) p * data_at Tsh (tptr t_struct_tree) p b |-- treebox_rep (T E x v E) b.
Proof.
(* Goal: forall (sh : share) (x y : Z) (p : val) (_ : @eq Z x y), @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
  intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
  unfold treebox_rep, tree_rep. Exists p nullval nullval. entailer!.
Qed.

Lemma bst_left_entail: forall (t1 t1' t2: tree val) k (v p1 p2 p b: val),
  Int.min_signed <= k <= Int.max_signed ->
  is_pointer_or_null v ->
  data_at Tsh (tptr t_struct_tree) p b *
  data_at Tsh t_struct_tree (Vint (Int.repr k), (v, (p1, p2))) p *
  tree_rep t1 p1 * tree_rep t2 p2
  |-- treebox_rep t1 (field_address t_struct_tree [StructField _left] p) *
       (treebox_rep t1'
         (field_address t_struct_tree [StructField _left] p) -*
        treebox_rep (T t1' k v t2) b).
Proof.
(* Goal: forall (sh : share) (x y : Z) (p : val) (_ : @eq Z x y), @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
  intros.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p))) (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val p1 p2))) p) *)
  unfold_data_at (data_at _ _ _ p).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p2 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p))) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p2 p)))) *)
  rewrite (field_at_data_at _ t_struct_tree [StructField _left]).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval b1) (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@E val)) b1) (treebox_rep (@delete val x t) b))) (treebox_rep (@delete val x t) b) *)
  unfold treebox_rep at 1. Exists p1. cancel.

  rewrite <- wand_sepcon_adjoint.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p2 p)) (tree_rep t2 p2)) (treebox_rep t1' (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p))) (treebox_rep (@T val t1' k v t2) b) *)
  clear p1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (Abs (empty_tree val) (@t_empty val nullval))) (treebox_rep (empty_tree val) v)) (@nil mpred))))) *)
  unfold treebox_rep.
(* Goal: @derives mpred Nveric (@data_at CompSpecs Tsh (tptr t_struct_tree) (Vint (Int.repr Z0)) p) (@exp mpred Nveric val (fun a : val => @andp mpred Nveric (@prop mpred Nveric (@eq val p a)) (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval a))) *)
  Exists p.
(* Goal: @derives mpred Nveric (@emp mpred Nveric Sveric) (tree_rep (empty_tree val) nullval) *)
  simpl.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (@exp mpred Nveric val (fun p : val => @sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p b1) (tree_rep t1 p))) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1) b1) (treebox_rep (@delete val x t) b)) (@nil mpred)))))) (Ssequence (Sset _p (Ederef (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (tptr (Tstruct _tree noattr)))) MORE_COMMANDS) POSTCONDITION *)
  Intros p1.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (tree_rep t1 p1)) (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p)) (tree_rep t2' p2))) (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed k) (Z.le k Int.max_signed)) (is_pointer_or_null v))) (@exp mpred Nveric val (fun pa : val => @exp mpred Nveric val (fun pb : val => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p) (tree_rep t1 pa)) (tree_rep t2' pb)))))) *)
  Exists p1 p2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
  entailer!.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p))) (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val p1 p2))) p) *)
  unfold_data_at (data_at _ _ _ p).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p2 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p))) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p2 p)))) *)
  rewrite (field_at_data_at _ t_struct_tree [StructField _left]).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@emp mpred Nveric Sveric) (tree_rep t p)) (tree_rep t p) *)
  cancel.
Qed.

Lemma bst_right_entail: forall (t1 t2 t2': tree val) k (v p1 p2 p b: val),
  Int.min_signed <= k <= Int.max_signed ->
  is_pointer_or_null v ->
  data_at Tsh (tptr t_struct_tree) p b *
  data_at Tsh t_struct_tree (Vint (Int.repr k), (v, (p1, p2))) p *
  tree_rep t1 p1 * tree_rep t2 p2
  |-- treebox_rep t2 (field_address t_struct_tree [StructField _right] p) *
       (treebox_rep t2'
         (field_address t_struct_tree [StructField _right] p) -*
        treebox_rep (T t1 k v t2') b).
Proof.
(* Goal: forall (sh : share) (x y : Z) (p : val) (_ : @eq Z x y), @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
  intros.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p))) (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val p1 p2))) p) *)
  unfold_data_at (data_at _ _ _ p).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p))) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p2 p)))) *)
  rewrite (field_at_data_at _ t_struct_tree [StructField _right]).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval b1) (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@E val)) b1) (treebox_rep (@delete val x t) b))) (treebox_rep (@delete val x t) b) *)
  unfold treebox_rep at 1. Exists p2. cancel.

  rewrite <- wand_sepcon_adjoint.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (tree_rep t1 p1)) (treebox_rep t2' (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p))) (treebox_rep (@T val t1 k v t2') b) *)
  clear p2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (Abs (empty_tree val) (@t_empty val nullval))) (treebox_rep (empty_tree val) v)) (@nil mpred))))) *)
  unfold treebox_rep.
(* Goal: @derives mpred Nveric (@data_at CompSpecs Tsh (tptr t_struct_tree) (Vint (Int.repr Z0)) p) (@exp mpred Nveric val (fun a : val => @andp mpred Nveric (@prop mpred Nveric (@eq val p a)) (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval a))) *)
  Exists p.
(* Goal: @derives mpred Nveric (@emp mpred Nveric Sveric) (tree_rep (empty_tree val) nullval) *)
  simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (tree_rep t1 p1)) (@exp mpred Nveric val (fun p0 : val => @sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p0 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p)) (tree_rep t2' p0)))) (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed k) (Z.le k Int.max_signed)) (is_pointer_or_null v))) (@exp mpred Nveric val (fun pa : val => @exp mpred Nveric val (fun pb : val => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p) (tree_rep t1 pa)) (tree_rep t2' pb)))))) *)
  Intros p2.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (tree_rep t1 p1)) (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p)) (tree_rep t2' p2))) (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed k) (Z.le k Int.max_signed)) (is_pointer_or_null v))) (@exp mpred Nveric val (fun pa : val => @exp mpred Nveric val (fun pb : val => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p) (tree_rep t1 pa)) (tree_rep t2' pb)))))) *)
  Exists p1 p2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
  entailer!.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p))) (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val p1 p2))) p) *)
  unfold_data_at (data_at _ _ _ p).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p)) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p)) (@data_at CompSpecs Tsh (tptr t_struct_tree) p2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p))) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p) (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1 p) (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p2 p)))) *)
  rewrite (field_at_data_at _ t_struct_tree [StructField _right]).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@emp mpred Nveric Sveric) (tree_rep t p)) (tree_rep t p) *)
  cancel.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (tree_rep t1_2 pb)) (@nil mpred)))))) (@liftx (LiftEnviron mpred) (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1))) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@cons mpred (treebox_rep t1_1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred)))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
Lemma modus_ponens_wand' {A}{ND: NatDed A}{SL: SepLog A}:
  forall P Q R: A, P |-- Q -> P * (Q -* R) |-- R.
Proof.
(* Goal: forall (sh : share) (x y : Z) (p : val) (_ : @eq Z x y), @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
  intros.
  eapply derives_trans; [| apply modus_ponens_wand].
  apply sepcon_derives; [| apply derives_refl].
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
  auto.
Qed.

Lemma if_trueb: forall {A: Type} b (a1 a2: A), b = true -> (if b then a1 else a2) = a1.
Proof. intros; subst; auto. Qed.

Lemma if_falseb: forall {A: Type} b (a1 a2: A), b = false -> (if b then a1 else a2) = a2.
Proof. intros; subst; auto. Qed.

Ltac simpl_compb := first [ rewrite if_trueb by (apply Z.ltb_lt; omega)
                          | rewrite if_falseb by (apply Z.ltb_ge; omega)].

Lemma body_insert: semax_body Vprog Gprog f_insert insert_spec.
Proof.
(* Goal: semax_body Vprog Gprog CompSpecs f_main main_spec *)
  start_function.
  eapply semax_pre; [
    | apply (semax_loop _ (insert_inv b t x v) (insert_inv b t x v) )].
  * (* Precondition *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t (offset_val (align (Z.add (align (Z.add (align (Z.add (align Z0 (@alignof (@cenv_cs CompSpecs) tint)) (@sizeof (@cenv_cs CompSpecs) tint)) (@alignof (@cenv_cs CompSpecs) (tptr tvoid))) (@sizeof (@cenv_cs CompSpecs) (tptr tvoid))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@sizeof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) p1)) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef)))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v0 (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@insert val x v (@T val t1_1 k v0 t1_2)) b1) (treebox_rep (@insert val x v t) b)) (@nil mpred)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef)))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@insert val x v t0) b0) (treebox_rep (@insert val x v t) b)) (@nil mpred)))))))) *)
    unfold insert_inv.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t b) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) *)
    Exists b t. entailer.
(* Goal: @derives mpred Nveric (treebox_rep t b) (@sepcon mpred Nveric Sveric (treebox_rep t b) (@wand mpred Nveric Sveric (treebox_rep (@delete val x t) b) (treebox_rep (@delete val x t) b))) *)
    apply ramify_PPQQ.
  * (* Loop body *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t (offset_val (align (Z.add (align (Z.add (align (Z.add (align Z0 (@alignof (@cenv_cs CompSpecs) tint)) (@sizeof (@cenv_cs CompSpecs) tint)) (@alignof (@cenv_cs CompSpecs) (tptr tvoid))) (@sizeof (@cenv_cs CompSpecs) (tptr tvoid))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@sizeof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) p1)) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef)))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v0 (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@insert val x v (@T val t1_1 k v0 t1_2)) b1) (treebox_rep (@insert val x v t) b)) (@nil mpred)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef)))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@insert val x v t0) b0) (treebox_rep (@insert val x v t) b)) (@nil mpred)))))))) *)
    unfold insert_inv.
(* Goal: semax CompSpecs Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) (Ssequence Sskip (Ssequence (Sset _p (Ederef (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (tptr (Tstruct _tree noattr)))) (Sifthenelse (Ebinop Oeq (Etempvar _p (tptr (Tstruct _tree noattr))) (Ecast (Econst_int (Int.repr Z0) tint) (tptr tvoid)) tint) (Sreturn (@None expr)) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) (Sifthenelse (Ebinop Olt (Etempvar _x tint) (Etempvar _y tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _left (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Sifthenelse (Ebinop Olt (Etempvar _y tint) (Etempvar _x tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _right (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@None expr))))))))) (loop1_ret_assert (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) POSTCONDITION) *)
    Intros b1 t1.
    forward. (* Sskip *)
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval b1) (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@E val)) b1) (treebox_rep (@delete val x t) b))) (treebox_rep (@delete val x t) b) *)
    unfold treebox_rep at 1. Intros p1.
    forward. (* p = *t; *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep t1 p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Sifthenelse (Ebinop Oeq (Etempvar _p (tptr (Tstruct _tree noattr))) (Ecast (Econst_int (Int.repr Z0) tint) (tptr tvoid)) tint) (Sreturn (@None expr)) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) (Sifthenelse (Ebinop Olt (Etempvar _x tint) (Etempvar _y tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _left (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Sifthenelse (Ebinop Olt (Etempvar _y tint) (Etempvar _x tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _right (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@None expr))))))) POSTCONDITION *)
    forward_if.
    + (* then clause *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep t1 p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Sreturn (@None expr)) POSTCONDITION *)
      subst p1.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p nullval) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval b1) (@cons mpred (tree_rep t1 nullval) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@insert val x v t1) b1) (treebox_rep (@insert val x v t) b)) (@nil mpred))))))) (Ssequence (Ssequence (Scall (@Some ident _t'1) (Evar _mallocN (Tfunction (Tcons tint Tnil) (tptr tvoid) cc_default)) (@cons expr (Esizeof (Tstruct _tree noattr) tuint) (@nil expr))) (Sset _p (Ecast (Etempvar _t'1 (tptr tvoid)) (tptr (Tstruct _tree noattr))))) MORE_COMMANDS) POSTCONDITION *)
      Time forward_call (sizeof t_struct_tree).
(* Goal: and (Z.le (Zpos (xO (xO xH))) (@sizeof (@cenv_cs CompSpecs) t_struct_tree)) (Z.le (@sizeof (@cenv_cs CompSpecs) t_struct_tree) Int.max_unsigned) *)
(* Goal: semax CompSpecs Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun vret : val => PROPx (@cons Prop (malloc_compatible (@sizeof (@cenv_cs CompSpecs) t_struct_tree) vret) (@nil Prop)) (LOCALx (@cons localdef (temp _p vret) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef))))) (SEPx (@cons mpred (memory_block Tsh (@sizeof (@cenv_cs CompSpecs) t_struct_tree) vret) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval b1) (@cons mpred (tree_rep t1 nullval) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@insert val x v t1) b1) (treebox_rep (@insert val x v t) b)) (@nil mpred))))))))) (Ssequence (Sassign (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint) (Etempvar _x tint)) MORE_COMMANDS) POSTCONDITION *)
        1: simpl; rep_omega.
(* Goal: semax CompSpecs Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun vret : val => PROPx (@cons Prop (malloc_compatible (@sizeof (@cenv_cs CompSpecs) t_struct_tree) vret) (@nil Prop)) (LOCALx (@cons localdef (temp _p vret) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef))))) (SEPx (@cons mpred (memory_block Tsh (@sizeof (@cenv_cs CompSpecs) t_struct_tree) vret) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval b1) (@cons mpred (tree_rep t1 nullval) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@insert val x v t1) b1) (treebox_rep (@insert val x v t) b)) (@nil mpred))))))))) (Ssequence (Sassign (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint) (Etempvar _x tint)) MORE_COMMANDS) POSTCONDITION *)
      Intros p'.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
      rewrite memory_block_data_at_ by auto.
      forward. (* p->key=x; *)
(* Goal: @derives mpred Nveric (@emp mpred Nveric Sveric) (tree_rep (empty_tree val) nullval) *)
      simpl.
      forward. (* p->value=value; *)
      forward. (* p->left=NULL; *)
      forward. (* p->right=NULL; *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p nullval) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval b1) (@cons mpred (tree_rep t1 nullval) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Sreturn (@None expr)) POSTCONDITION *)
      assert_PROP (t1= (@E _)).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
        1: entailer!.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep (@T val t1_1 k v t1_2) p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
      subst t1. simpl tree_rep. rewrite !prop_true_andp by auto.
      forward. (* *t = p; *)
      forward. (* return; *)
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
      apply modus_ponens_wand'.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
      apply treebox_rep_leaf; auto.
    + (* else clause *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep t1 p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
      destruct t1.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep (@T val t1_1 k v t1_2) p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
        { simpl tree_rep. normalize. }
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep (@T val t1_1 k v t1_2) p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
      simpl tree_rep.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed k) (Z.le k Int.max_signed)) (is_pointer_or_null v))) (@exp mpred Nveric val (fun pa : val => @exp mpred Nveric val (fun pb : val => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (tree_rep t1_1 pa)) (tree_rep t1_2 pb))))) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
      Intros pa pb. clear H1.
      forward. (* y=p->key; *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))))) (Sifthenelse (Ebinop Olt (Etempvar _x tint) (Etempvar _y tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _left (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Sifthenelse (Ebinop Olt (Etempvar _y tint) (Etempvar _x tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _right (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@None expr))))) POSTCONDITION *)
      forward_if; [ | forward_if ].
      - (* Inner if, then clause: x<k *)
        forward. (* t=&p->left *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t (offset_val (align (Z.add (align (Z.add (align (Z.add (align Z0 (@alignof (@cenv_cs CompSpecs) tint)) (@sizeof (@cenv_cs CompSpecs) tint)) (@alignof (@cenv_cs CompSpecs) (tptr tvoid))) (@sizeof (@cenv_cs CompSpecs) (tptr tvoid))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@sizeof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) p1)) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef)))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v0 (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@insert val x v (@T val t1_1 k v0 t1_2)) b1) (treebox_rep (@insert val x v t) b)) (@nil mpred)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef)))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@insert val x v t0) b0) (treebox_rep (@insert val x v t) b)) (@nil mpred)))))))) *)
        unfold insert_inv.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t (offset_val (align (Z.add (align (Z.add (align Z0 (@alignof (@cenv_cs CompSpecs) tint)) (@sizeof (@cenv_cs CompSpecs) tint)) (@alignof (@cenv_cs CompSpecs) (tptr tvoid))) (@sizeof (@cenv_cs CompSpecs) (tptr tvoid))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) p1)) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) *)
        Exists (offset_val 8 p1) t1_1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
        entailer!. simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (if Z.ltb k k then @T val t1_1 k v (@delete val k t1_2) else @pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
        simpl_compb.
        (* TODO: SIMPLY THIS LINE *)
        replace (offset_val 8 p1)
          with (field_address t_struct_tree [StructField _left] p1)
          by (unfold field_address; simpl;
              rewrite if_true by auto with field_compatible; auto).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1)) (tree_rep t1_1 pa)) (tree_rep t1_2 pb)) (@wand mpred Nveric Sveric (treebox_rep (@T val t1_1 k v (@delete val x t1_2)) b1) (treebox_rep (@delete val x t) b))) (@sepcon mpred Nveric Sveric (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1_2) (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (treebox_rep (@delete val x t) b))) *)
        apply RAMIF_PLAIN.trans'.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
        apply bst_left_entail; auto.
      - (* Inner if, second branch:  k<x *)
        forward. (* t=&p->right *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t (offset_val (align (Z.add (align (Z.add (align (Z.add (align Z0 (@alignof (@cenv_cs CompSpecs) tint)) (@sizeof (@cenv_cs CompSpecs) tint)) (@alignof (@cenv_cs CompSpecs) (tptr tvoid))) (@sizeof (@cenv_cs CompSpecs) (tptr tvoid))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@sizeof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) p1)) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef)))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v0 (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@insert val x v (@T val t1_1 k v0 t1_2)) b1) (treebox_rep (@insert val x v t) b)) (@nil mpred)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef)))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@insert val x v t0) b0) (treebox_rep (@insert val x v t) b)) (@nil mpred)))))))) *)
        unfold insert_inv.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t (offset_val (align (Z.add (align (Z.add (align (Z.add (align Z0 (@alignof (@cenv_cs CompSpecs) tint)) (@sizeof (@cenv_cs CompSpecs) tint)) (@alignof (@cenv_cs CompSpecs) (tptr tvoid))) (@sizeof (@cenv_cs CompSpecs) (tptr tvoid))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@sizeof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) p1)) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) *)
        Exists (offset_val 12 p1) t1_2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
        entailer!. simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (if Z.ltb k k then @T val t1_1 k v (@delete val k t1_2) else @pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
        simpl_compb; simpl_compb.
        (* TODO: SIMPLY THIS LINE *)
        replace (offset_val 12 p1)
          with (field_address t_struct_tree [StructField _right] p1)
          by (unfold field_address; simpl;
              rewrite if_true by auto with field_compatible; auto).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1)) (tree_rep t1_1 pa)) (tree_rep t1_2 pb)) (@wand mpred Nveric Sveric (treebox_rep (@T val t1_1 k v (@delete val x t1_2)) b1) (treebox_rep (@delete val x t) b))) (@sepcon mpred Nveric Sveric (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1_2) (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (treebox_rep (@delete val x t) b))) *)
        apply RAMIF_PLAIN.trans'.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
        apply bst_right_entail; auto.
      - (* Inner if, third branch: x=k *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
        assert (x=k) by omega.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
        subst x.  clear H H1 H3.
        forward. (* p->value=value *)
(* Goal: @derives mpred Nveric (@emp mpred Nveric Sveric) (tree_rep (empty_tree val) nullval) *)
        forward. (* return *) simpl.
        (* TODO: SIMPLY THIS LINE *)
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (if Z.ltb k k then @T val t1_1 k v (@delete val k t1_2) else @pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
        simpl_compb.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (if Z.ltb k k then @T val t1_1 k v (@delete val k t1_2) else @pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
        simpl_compb.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
        apply modus_ponens_wand'.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (Abs (empty_tree val) (@t_empty val nullval))) (treebox_rep (empty_tree val) v)) (@nil mpred))))) *)
        unfold treebox_rep. Exists p1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
        simpl tree_rep. Exists pa pb. entailer!.
  * (* After the loop *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint))) MORE_COMMANDS) POSTCONDITION *)
    forward.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (@eq val p1 nullval)) (@emp mpred Nveric Sveric)) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@E val)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
    unfold loop2_ret_assert. apply andp_left2. normalize. 
Qed.

Definition lookup_inv (b0 p0: val) (t0: tree val) (x: Z): environ -> mpred :=
  EX p: val, EX t: tree val, 
  PROP(lookup nullval x t = lookup nullval x t0) 
  LOCAL(temp _p p; temp _x (Vint (Int.repr x)))
  SEP(tree_rep t p;  (tree_rep t p -* tree_rep t0 p0)).

Lemma body_lookup: semax_body Vprog Gprog f_lookup lookup_spec.
Proof.
(* Goal: semax_body Vprog Gprog CompSpecs f_main main_spec *)
  start_function.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (Abs (empty_tree val) (@t_empty val nullval))) (treebox_rep (empty_tree val) v)) (@nil mpred))))) *)
  unfold treebox_rep. Intros p.
  forward. (* p=*t; *)
  apply (semax_post_ret1 nil
          (data_at Tsh (tptr t_struct_tree) p b :: tree_rep t p :: nil)).
(* Goal: not (@eq type (ret_type Delta) Tvoid) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret1_tycon Delta))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp (@lookup val nullval x t)) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@cons mpred (tree_rep t p) (@nil mpred))))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp (@lookup val nullval x t)) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t b) (@nil mpred))))) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (temp _t b) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@cons mpred (tree_rep t p) (@nil mpred)))))) (Ssequence (Swhile (Ebinop One (Etempvar _p (tptr (Tstruct _tree noattr))) (Ecast (Econst_int (Int.repr Z0) tint) (tptr tvoid)) tint) LOOP_BODY) MORE_COMMANDS) (frame_ret_assert (function_body_ret_assert (ret_type Delta) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp (@lookup val nullval x t)) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@cons mpred (tree_rep t p) (@nil mpred))))))) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric))) *)
  1: intro HH; inversion HH.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
  1: unfold treebox_rep; Exists p; entailer!.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (temp _t b) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@cons mpred (tree_rep t p) (@nil mpred)))))) (Ssequence (Swhile (Ebinop One (Etempvar _p (tptr (Tstruct _tree noattr))) (Ecast (Econst_int (Int.repr Z0) tint) (tptr tvoid)) tint) LOOP_BODY) MORE_COMMANDS) (frame_ret_assert (function_body_ret_assert (ret_type Delta) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp (@lookup val nullval x t)) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p b) (@cons mpred (tree_rep t p) (@nil mpred))))))) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric))) *)
  apply semax_frame''.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (temp _t b) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (tree_rep t p) (@nil mpred))))) (Ssequence (Swhile (Ebinop One (Etempvar _p (tptr (Tstruct _tree noattr))) (Ecast (Econst_int (Int.repr Z0) tint) (tptr tvoid)) tint) LOOP_BODY) MORE_COMMANDS) (frame_ret_assert (function_body_ret_assert (ret_type Delta) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp (@lookup val nullval x t)) (@nil localdef)) (SEPx (@cons mpred (tree_rep t p) (@nil mpred)))))) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric))) *)
  forward_while (lookup_inv b p t x).
  * (* precondition implies loop invariant *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
    Exists p t. entailer!.
    apply -> wand_sepcon_adjoint. cancel.
  * (* type-check loop condition *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
    entailer!.
  * (* loop body preserves invariant *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (@eq val p1 nullval)) (@emp mpred Nveric Sveric)) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@E val)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
    destruct t0; unfold tree_rep at 1; fold tree_rep. normalize.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed k) (Z.le k Int.max_signed)) (is_pointer_or_null v))) (@exp mpred Nveric val (fun pa : val => @exp mpred Nveric val (fun pb : val => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (tree_rep t1_1 pa)) (tree_rep t1_2 pb))))) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
    Intros pa pb.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint))) MORE_COMMANDS) POSTCONDITION *)
    forward.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))))) (Sifthenelse (Ebinop Olt (Etempvar _x tint) (Etempvar _y tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _left (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Sifthenelse (Ebinop Olt (Etempvar _y tint) (Etempvar _x tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _right (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@None expr))))) POSTCONDITION *)
    forward_if; [ | forward_if ].
    + (* then clause: x<y *)
      forward. (* p=p<-left *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p pa) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v0 (@pair val val pa pb))) p0) (@cons mpred (tree_rep t0_1 pa) (@cons mpred (tree_rep t0_2 pb) (@cons mpred (@wand mpred Nveric Sveric (tree_rep (@T val t0_1 k v0 t0_2) p0) (tree_rep t p)) (@nil mpred))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (prod val (tree val)) (fun a : prod val (tree val) => PROPx (@cons Prop (@eq val (@lookup val nullval x (@snd val (tree val) a)) (@lookup val nullval x t)) (@nil Prop)) (LOCALx (@cons localdef (temp _p (@fst val (tree val) a)) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (tree_rep (@snd val (tree val) a) (@fst val (tree val) a)) (@cons mpred (@wand mpred Nveric Sveric (tree_rep (@snd val (tree val) a) (@fst val (tree val) a)) (tree_rep t p)) (@nil mpred))))))) *)
      Exists (pa,t0_1). unfold fst,snd.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
      entailer!.
      - rewrite <- H0; simpl.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
        simpl_compb; auto.
      - (* TODO: merge the following 2 lines *)
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v0 (@pair val val pa pb))) p0) (tree_rep t0_1 pa)) (@wand mpred Nveric Sveric (tree_rep (@T val t0_1 k v0 t0_2) p0) (tree_rep t p))) (@wand mpred Nveric Sveric (tree_rep t0_2 pb) (tree_rep t p)) *)
        apply RAMIF_PLAIN.trans''.
        apply -> wand_sepcon_adjoint.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
        simpl. Exists pa pb; entailer!.
    + (* else-then clause: y<x *)
      forward. (* p=p<-right *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p pb) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v0 (@pair val val pa pb))) p0) (@cons mpred (tree_rep t0_1 pa) (@cons mpred (tree_rep t0_2 pb) (@cons mpred (@wand mpred Nveric Sveric (tree_rep (@T val t0_1 k v0 t0_2) p0) (tree_rep t p)) (@nil mpred))))))))) (PROPx (@cons Prop (@eq val (@lookup val nullval x (@snd val (tree val) (@pair val (tree val) pb t0_2))) (@lookup val nullval x t)) (@nil Prop)) (LOCALx (@cons localdef (temp _p (@fst val (tree val) (@pair val (tree val) pb t0_2))) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (tree_rep (@snd val (tree val) (@pair val (tree val) pb t0_2)) (@fst val (tree val) (@pair val (tree val) pb t0_2))) (@cons mpred (@wand mpred Nveric Sveric (tree_rep (@snd val (tree val) (@pair val (tree val) pb t0_2)) (@fst val (tree val) (@pair val (tree val) pb t0_2))) (tree_rep t p)) (@nil mpred)))))) *)
      Exists (pb,t0_2). unfold fst,snd.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
      entailer!.
      - rewrite <- H0; simpl.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
        simpl_compb; simpl_compb; auto.
      - (* TODO: merge the following 2 lines *)
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v0 (@pair val val pa pb))) p0) (tree_rep t0_1 pa)) (@wand mpred Nveric Sveric (tree_rep (@T val t0_1 k v0 t0_2) p0) (tree_rep t p))) (@wand mpred Nveric Sveric (tree_rep t0_2 pb) (tree_rep t p)) *)
        apply RAMIF_PLAIN.trans''.
        apply -> wand_sepcon_adjoint.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
        simpl. Exists pa pb; entailer!.
    + (* else-else clause: x=y *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
      assert (x=k) by omega. subst x. clear H H3 H4.
      forward. (* v=p->value *)
(* Goal: @derives mpred Nveric (@emp mpred Nveric Sveric) (tree_rep (empty_tree val) nullval) *)
      forward. (* return v; *) simpl.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (Abs (empty_tree val) (@t_empty val nullval))) (treebox_rep (empty_tree val) v)) (@nil mpred))))) *)
      unfold treebox_rep. unfold normal_ret_assert.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
      entailer!.
      - rewrite <- H0. simpl.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
        simpl_compb; simpl_compb; auto.
      - (* TODO: merge the following 2 lines *)
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
        apply modus_ponens_wand'.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
        Exists pa pb; entailer!.
  * (* after the loop *)
    forward. (* return NULL; *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
    entailer!.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (tree_rep (@E val) nullval) (@wand mpred Nveric Sveric (tree_rep (@E val) nullval) (tree_rep t p))) (tree_rep t p) *)
    apply modus_ponens_wand.
Qed.

Lemma body_turn_left: semax_body Vprog Gprog f_turn_left turn_left_spec.
Proof.
(* Goal: semax_body Vprog Gprog CompSpecs f_main main_spec *)
  start_function.
(* Goal: @derives mpred Nveric (@emp mpred Nveric Sveric) (tree_rep (empty_tree val) nullval) *)
  simpl.
  Intros pb pc.
  forward. (* mid=r->left *)
  forward. (* l->right=mid *)
  forward. (* r->left=l *)
  forward. (* _l = r *)
  Opaque tree_rep. forward. Transparent tree_rep. (* return *)
  (* TODO: simplify the following proof *)
  Exists pc.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
  entailer!.
(* Goal: @derives mpred Nveric (@emp mpred Nveric Sveric) (tree_rep (empty_tree val) nullval) *)
  simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1)) (tree_rep t1_1 pa)) (tree_rep t1_2 pb)) (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed k) (Z.le k Int.max_signed)) (is_pointer_or_null v))) (@exp mpred Nveric val (fun pa : val => @exp mpred Nveric val (fun pb : val => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (tree_rep t1_1 pa)) (tree_rep t1_2 pb)))))) *)
  Exists pa pb.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
  entailer!.
Qed.

Definition pushdown_left_inv (b_res: val) (t_res: tree val): environ -> mpred :=
  EX b: val, EX ta: tree val, EX x: Z, EX v: val, EX tb: tree val,
  PROP  () 
  LOCAL (temp _t b)
  SEP   (treebox_rep (T ta x v tb) b;
         (treebox_rep (pushdown_left ta tb) b -* treebox_rep t_res b_res)).

Lemma cancel_emp_spacer:
  forall sh x y p, x=y -> 
    emp |-- spacer sh x y p.
Proof.
(* Goal: forall (sh : share) (x y : Z) (p : val) (_ : @eq Z x y), @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
intros.
(* Goal: @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
subst.
(* Goal: @derives mpred Nveric (spacer sh y y p) (@emp mpred Nveric Sveric) *)
unfold spacer.
(* Goal: @derives mpred Nveric (@emp mpred Nveric Sveric) (tree_rep (empty_tree val) nullval) *)
rewrite Z.sub_diag. simpl. auto.
Qed.

Lemma cancel_spacer_emp:
  forall sh x y p, x=y -> 
    spacer sh x y p |-- emp.
Proof.
(* Goal: forall (sh : share) (x y : Z) (p : val) (_ : @eq Z x y), @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
intros.
(* Goal: @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
subst.
(* Goal: @derives mpred Nveric (spacer sh y y p) (@emp mpred Nveric Sveric) *)
unfold spacer.
(* Goal: @derives mpred Nveric (@emp mpred Nveric Sveric) (tree_rep (empty_tree val) nullval) *)
rewrite Z.sub_diag. simpl. auto.
Qed.

Lemma body_pushdown_left: semax_body Vprog Gprog f_pushdown_left pushdown_left_spec.
Proof.
(* Goal: semax_body Vprog Gprog CompSpecs f_main main_spec *)
  start_function.
  eapply semax_pre; [
    | apply (semax_loop _ (pushdown_left_inv b (pushdown_left ta tb))
                         (pushdown_left_inv b (pushdown_left ta tb)))].
  + (* Precondition *)
    unfold pushdown_left_inv.
    Exists b ta x v tb.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
    entailer!.
    eapply derives_trans; [| apply ramify_PPQQ].
    rewrite (treebox_rep_spec (T ta x v tb)).
(* Goal: @derives mpred Nveric (@data_at CompSpecs Tsh (tptr t_struct_tree) (Vint (Int.repr Z0)) p) (@exp mpred Nveric val (fun a : val => @andp mpred Nveric (@prop mpred Nveric (@eq val p a)) (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval a))) *)
    Exists p.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
    entailer!.
  + (* Loop body *)
    unfold pushdown_left_inv.
    clear x v H H0.
    Intros b0 ta0 x vx tbc0.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval b1) (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@E val)) b1) (treebox_rep (@delete val x t) b))) (treebox_rep (@delete val x t) b) *)
    unfold treebox_rep at 1.
    Intros p0.
    forward. (* skip *)
    forward. (* p = *t; *)
      (* TODO entailer: The following should be solve automatically. satuate local does not work *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
 (*     1: rewrite (add_andp _ _ (tree_rep_saturate_local _ _)); entailer!. *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep (@T val t1_1 k v t1_2) p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
    simpl tree_rep.
    Intros pa pbc.
    forward. (* q = p->right *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep t1 p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Sifthenelse (Ebinop Oeq (Etempvar _p (tptr (Tstruct _tree noattr))) (Ecast (Econst_int (Int.repr Z0) tint) (tptr tvoid)) tint) (Sreturn (@None expr)) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) (Sifthenelse (Ebinop Olt (Etempvar _x tint) (Etempvar _y tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _left (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Sifthenelse (Ebinop Olt (Etempvar _y tint) (Etempvar _x tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _right (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@None expr))))))) POSTCONDITION *)
    forward_if.
    - subst.
      assert_PROP (tbc0 = (@E _)).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
        1: entailer!.
(* Goal: @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
      subst.
      forward. (* q=p->left *)
      forward. (* *t=q *)
      Time forward_call (p0, sizeof t_struct_tree). (* freeN(p, sizeof ( *p )); *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (tree_rep t1_2 pb)) (@nil mpred)))))) (@liftx (LiftEnviron mpred) (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1))) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@cons mpred (treebox_rep t1_1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred)))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
      {
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
        entailer!.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
        rewrite memory_block_data_at_ by auto.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@emp mpred Nveric Sveric) (tree_rep t p)) (tree_rep t p) *)
        cancel.
      }
      forward. (* return *)
(* Goal: @derives mpred Nveric (@emp mpred Nveric Sveric) (tree_rep (empty_tree val) nullval) *)
      simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
      apply modus_ponens_wand'.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) pa p1) (tree_rep t1_1 pa)) (@exp mpred Nveric val (fun p : val => @sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (tree_rep t1_1 p))) *)
      Exists pa.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
      entailer!.
    - destruct tbc0 as [| tb0 y vy tc0].
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep (@T val t1_1 k v t1_2) p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
        { simpl tree_rep. normalize. }
      Time forward_call (ta0, x, vx, tb0, y, vy, tc0, b0, p0, pa, pbc). (* turn_left(t, p, q); *)
      Intros pc.
      forward. (* t = &q->left; *)
      Exists (field_address t_struct_tree [StructField _left] pbc) ta0 x vx tb0.
      (* TODO entailer: not to simply too much in entailer? *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
      Opaque tree_rep. entailer!. Transparent tree_rep.
        (* TODO: simplify this line *)
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1)) (tree_rep t1_1 pa)) (tree_rep t1_2 pb)) (@wand mpred Nveric Sveric (treebox_rep (@T val t1_1 k v (@delete val x t1_2)) b1) (treebox_rep (@delete val x t) b))) (@sepcon mpred Nveric Sveric (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1_2) (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (treebox_rep (@delete val x t) b))) *)
      apply RAMIF_PLAIN.trans'.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
      apply bst_left_entail; auto.
  + forward. (* Sskip *)
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
    apply andp_left2; auto.
Qed.

Definition delete_inv (b0: val) (t0: tree val) (x: Z): environ -> mpred :=
  EX b: val, EX t: tree val,
  PROP()
  LOCAL(temp _t b; temp _x (Vint (Int.repr x)))
  SEP(treebox_rep t b;  (treebox_rep (delete x t) b -* treebox_rep (delete x t0) b0)).

Lemma body_delete: semax_body Vprog Gprog f_delete delete_spec.
Proof.
(* Goal: semax_body Vprog Gprog CompSpecs f_main main_spec *)
  start_function.
  eapply semax_pre; [
    | apply (semax_loop _ (delete_inv b t x) (delete_inv b t x) )].
  * (* Precondition *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t (offset_val (align (Z.add (align (Z.add (align (Z.add (align Z0 (@alignof (@cenv_cs CompSpecs) tint)) (@sizeof (@cenv_cs CompSpecs) tint)) (@alignof (@cenv_cs CompSpecs) (tptr tvoid))) (@sizeof (@cenv_cs CompSpecs) (tptr tvoid))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@sizeof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) p1)) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) *)
    unfold delete_inv.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t b) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) *)
    Exists b t. entailer.
(* Goal: @derives mpred Nveric (treebox_rep t b) (@sepcon mpred Nveric Sveric (treebox_rep t b) (@wand mpred Nveric Sveric (treebox_rep (@delete val x t) b) (treebox_rep (@delete val x t) b))) *)
    apply ramify_PPQQ.
  * (* Loop body *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t (offset_val (align (Z.add (align (Z.add (align (Z.add (align Z0 (@alignof (@cenv_cs CompSpecs) tint)) (@sizeof (@cenv_cs CompSpecs) tint)) (@alignof (@cenv_cs CompSpecs) (tptr tvoid))) (@sizeof (@cenv_cs CompSpecs) (tptr tvoid))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@sizeof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) p1)) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) *)
    unfold delete_inv.
(* Goal: semax CompSpecs Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) (Ssequence Sskip (Ssequence (Sset _p (Ederef (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (tptr (Tstruct _tree noattr)))) (Sifthenelse (Ebinop Oeq (Etempvar _p (tptr (Tstruct _tree noattr))) (Ecast (Econst_int (Int.repr Z0) tint) (tptr tvoid)) tint) (Sreturn (@None expr)) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) (Sifthenelse (Ebinop Olt (Etempvar _x tint) (Etempvar _y tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _left (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Sifthenelse (Ebinop Olt (Etempvar _y tint) (Etempvar _x tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _right (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@None expr))))))))) (loop1_ret_assert (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) POSTCONDITION) *)
    Intros b1 t1.
    forward. (* Sskip *)
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval b1) (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@E val)) b1) (treebox_rep (@delete val x t) b))) (treebox_rep (@delete val x t) b) *)
    unfold treebox_rep at 1. Intros p1.
    forward. (* p = *t; *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep t1 p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Sifthenelse (Ebinop Oeq (Etempvar _p (tptr (Tstruct _tree noattr))) (Ecast (Econst_int (Int.repr Z0) tint) (tptr tvoid)) tint) (Sreturn (@None expr)) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) (Sifthenelse (Ebinop Olt (Etempvar _x tint) (Etempvar _y tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _left (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Sifthenelse (Ebinop Olt (Etempvar _y tint) (Etempvar _x tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _right (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@None expr))))))) POSTCONDITION *)
    forward_if.
    + (* then clause *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep t1 p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Sreturn (@None expr)) POSTCONDITION *)
      subst p1.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p nullval) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval b1) (@cons mpred (tree_rep t1 nullval) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Sreturn (@None expr)) POSTCONDITION *)
      assert_PROP (t1= (@E _)).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
        1: entailer!.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep (@T val t1_1 k v t1_2) p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
      subst t1. simpl tree_rep. rewrite !prop_true_andp by auto.
      forward. (* return; *)
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval b1) (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@E val)) b1) (treebox_rep (@delete val x t) b))) (treebox_rep (@delete val x t) b) *)
      unfold treebox_rep at 1.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
      apply modus_ponens_wand'.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (Abs (empty_tree val) (@t_empty val nullval))) (@exp mpred Nveric val (fun p : val => @sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p v) (tree_rep (empty_tree val) p)))) (@nil mpred))))) *)
      Exists nullval.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep (@T val t1_1 k v t1_2) p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
      simpl tree_rep.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
      entailer!.
    + (* else clause *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep t1 p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
      destruct t1.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep (@T val t1_1 k v t1_2) p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
        { simpl tree_rep. normalize. }
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (tree_rep (@T val t1_1 k v t1_2) p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
      simpl tree_rep.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed k) (Z.le k Int.max_signed)) (is_pointer_or_null v))) (@exp mpred Nveric val (fun pa : val => @exp mpred Nveric val (fun pb : val => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (tree_rep t1_1 pa)) (tree_rep t1_2 pb))))) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
      Intros pa pb. clear H0.
      forward. (* y=p->key; *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))))) (Sifthenelse (Ebinop Olt (Etempvar _x tint) (Etempvar _y tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _left (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Sifthenelse (Ebinop Olt (Etempvar _y tint) (Etempvar _x tint) tint) (Sset _t (Eaddrof (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _right (tptr (Tstruct _tree noattr))) (tptr (tptr (Tstruct _tree noattr))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@None expr))))) POSTCONDITION *)
      forward_if; [ | forward_if ].
      - (* Inner if, then clause: x<k *)
        forward. (* t=&p->left *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t (offset_val (align (Z.add (align (Z.add (align (Z.add (align Z0 (@alignof (@cenv_cs CompSpecs) tint)) (@sizeof (@cenv_cs CompSpecs) tint)) (@alignof (@cenv_cs CompSpecs) (tptr tvoid))) (@sizeof (@cenv_cs CompSpecs) (tptr tvoid))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@sizeof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) p1)) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) *)
        unfold delete_inv.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t (offset_val (align (Z.add (align (Z.add (align Z0 (@alignof (@cenv_cs CompSpecs) tint)) (@sizeof (@cenv_cs CompSpecs) tint)) (@alignof (@cenv_cs CompSpecs) (tptr tvoid))) (@sizeof (@cenv_cs CompSpecs) (tptr tvoid))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) p1)) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) *)
        Exists (offset_val 8 p1) t1_1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
        entailer!. simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (if Z.ltb k k then @T val t1_1 k v (@delete val k t1_2) else @pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
        simpl_compb.
        (* TODO: SIMPLY THIS LINE *)
        replace (offset_val 8 p1)
          with (field_address t_struct_tree [StructField _left] p1)
          by (unfold field_address; simpl;
              rewrite if_true by auto with field_compatible; auto).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1)) (tree_rep t1_1 pa)) (tree_rep t1_2 pb)) (@wand mpred Nveric Sveric (treebox_rep (@T val t1_1 k v (@delete val x t1_2)) b1) (treebox_rep (@delete val x t) b))) (@sepcon mpred Nveric Sveric (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1_2) (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (treebox_rep (@delete val x t) b))) *)
        apply RAMIF_PLAIN.trans'.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
        apply bst_left_entail; auto.
      - (* Inner if, second branch:  k<x *)
        forward. (* t=&p->right *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t (offset_val (align (Z.add (align (Z.add (align (Z.add (align Z0 (@alignof (@cenv_cs CompSpecs) tint)) (@sizeof (@cenv_cs CompSpecs) tint)) (@alignof (@cenv_cs CompSpecs) (tptr tvoid))) (@sizeof (@cenv_cs CompSpecs) (tptr tvoid))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@sizeof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) p1)) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) *)
        unfold delete_inv.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t (offset_val (align (Z.add (align (Z.add (align (Z.add (align Z0 (@alignof (@cenv_cs CompSpecs) tint)) (@sizeof (@cenv_cs CompSpecs) tint)) (@alignof (@cenv_cs CompSpecs) (tptr tvoid))) (@sizeof (@cenv_cs CompSpecs) (tptr tvoid))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@sizeof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) (@alignof (@cenv_cs CompSpecs) (tptr (Tstruct _tree noattr)))) p1)) (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun b0 : val => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tree val) (fun t0 : tree val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b0) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))) (SEPx (@cons mpred (treebox_rep t0 b0) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x t0) b0) (treebox_rep (@delete val x t) b)) (@nil mpred)))))))) *)
        Exists (offset_val 12 p1) t1_2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
        entailer!. simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (if Z.ltb k k then @T val t1_1 k v (@delete val k t1_2) else @pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
        simpl_compb; simpl_compb.
        (* TODO: SIMPLY THIS LINE *)
        replace (offset_val 12 p1)
          with (field_address t_struct_tree [StructField _right] p1)
          by (unfold field_address; simpl;
              rewrite if_true by auto with field_compatible; auto).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1)) (tree_rep t1_1 pa)) (tree_rep t1_2 pb)) (@wand mpred Nveric Sveric (treebox_rep (@T val t1_1 k v (@delete val x t1_2)) b1) (treebox_rep (@delete val x t) b))) (@sepcon mpred Nveric Sveric (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@wand mpred Nveric Sveric (treebox_rep (@delete val x t1_2) (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (treebox_rep (@delete val x t) b))) *)
        apply RAMIF_PLAIN.trans'.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
        apply bst_right_entail; auto.
      - (* Inner if, third branch: x=k *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
        assert (x=k) by omega.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
        subst x.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
        unfold_data_at (data_at _ _ _ p1).
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) pa p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (@cons mpred (tree_rep t1_1 pa) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred)))))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
        gather_SEP 3 5.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) pa p1) (tree_rep t1_1 pa)) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred))))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
        replace_SEP 0 (treebox_rep t1_1 (field_address t_struct_tree [StructField _left] p1)).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (tree_rep t1_2 pb)) (@nil mpred)))))) (@liftx (LiftEnviron mpred) (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1))) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@cons mpred (treebox_rep t1_1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred)))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
        {
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
          unfold treebox_rep; entailer!.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) pa p1) (tree_rep t1_1 pa)) (@exp mpred Nveric val (fun p : val => @sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (tree_rep t1_1 p))) *)
          Exists pa.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (tree_rep t1_2 pb)) (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) pb (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (tree_rep t1_2 pb)) *)
          rewrite field_at_data_at.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
          entailer!.
        }
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (treebox_rep t1_1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (@cons mpred (tree_rep t1_2 pb) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred))))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
        gather_SEP 4 5.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (tree_rep t1_2 pb)) (@cons mpred (treebox_rep t1_1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred)))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
        replace_SEP 0 (treebox_rep t1_2 (field_address t_struct_tree [StructField _right] p1)).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (tree_rep t1_2 pb)) (@nil mpred)))))) (@liftx (LiftEnviron mpred) (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1))) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@cons mpred (treebox_rep t1_1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred)))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
        {
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
          unfold treebox_rep; entailer!.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (tree_rep t1_2 pb)) (@exp mpred Nveric val (fun p : val => @sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (tree_rep t1_2 p))) *)
          Exists pb.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (tree_rep t1_2 pb)) (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) pb (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (tree_rep t1_2 pb)) *)
          rewrite field_at_data_at.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
          entailer!.
        }
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@cons mpred (treebox_rep t1_1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred)))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
        Time forward_call (t1_1, k, v, t1_2, b1, p1).
        forward. (* return *)
(* Goal: @derives mpred Nveric (@emp mpred Nveric Sveric) (tree_rep (empty_tree val) nullval) *)
        simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (if Z.ltb k k then @T val t1_1 k v (@delete val k t1_2) else @pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
        simpl_compb.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (if Z.ltb k k then @T val t1_1 k v (@delete val k t1_2) else @pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
        simpl_compb.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (@wand mpred Nveric Sveric (treebox_rep (@pushdown_left val t1_1 t1_2) b1) (treebox_rep (@delete val k t) b))) (treebox_rep (@delete val k t) b) *)
        apply modus_ponens_wand'.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
        auto.
  * (* After the loop *)
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
    forward. apply andp_left2; auto. 
Qed.

Lemma body_treebox_new: semax_body Vprog Gprog f_treebox_new treebox_new_spec.
Proof.
(* Goal: semax_body Vprog Gprog CompSpecs f_main main_spec *)
  start_function.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@nil mpred)))) (Ssequence (Ssequence (Scall (@Some ident _t'1) (Evar _mallocN (Tfunction (Tcons tint Tnil) (tptr tvoid) cc_default)) (@cons expr (Esizeof (tptr (Tstruct _tree noattr)) tuint) (@nil expr))) (Sset _p (Ecast (Etempvar _t'1 (tptr tvoid)) (tptr (tptr (Tstruct _tree noattr)))))) MORE_COMMANDS) POSTCONDITION *)
  Time forward_call (sizeof (tptr t_struct_tree)).
(* Goal: and (Z.le (Zpos (xO (xO xH))) (@sizeof (@cenv_cs CompSpecs) (tptr t_struct_tree))) (Z.le (@sizeof (@cenv_cs CompSpecs) (tptr t_struct_tree)) Int.max_unsigned) *)
(* Goal: semax CompSpecs Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun vret : val => PROPx (@cons Prop (malloc_compatible (@sizeof (@cenv_cs CompSpecs) (tptr t_struct_tree)) vret) (@nil Prop)) (LOCALx (@cons localdef (temp _p vret) (@nil localdef)) (SEPx (@cons mpred (memory_block Tsh (@sizeof (@cenv_cs CompSpecs) (tptr t_struct_tree)) vret) (@nil mpred)))))) (Ssequence (Sassign (Ederef (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (tptr (Tstruct _tree noattr))) (Ecast (Econst_int (Int.repr Z0) tint) (tptr tvoid))) MORE_COMMANDS) POSTCONDITION *)
  simpl sizeof; computable.
(* Goal: semax CompSpecs Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun vret : val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p vret) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_empty val nullval) vret) (@cons mpred (Freezer.FRZL FR1) (@nil mpred))))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xI xH))) tint) (@cons expr (Evar ___stringlit_1 (tarray tschar (Zpos (xO (xI xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_2 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xO (xO xH)))) tint) (@cons expr (Evar ___stringlit_3 (tarray tschar (Zpos (xI (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_4 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))))))) MORE_COMMANDS) POSTCONDITION *)
  Intros p.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
  rewrite memory_block_data_at_ by auto.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint))) MORE_COMMANDS) POSTCONDITION *)
  forward.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint))) MORE_COMMANDS) POSTCONDITION *)
  forward.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
  Exists p. entailer!.
Qed.

Lemma body_tree_free: semax_body Vprog Gprog f_tree_free tree_free_spec.
Proof.
(* Goal: semax_body Vprog Gprog CompSpecs f_main main_spec *)
  start_function.
  forward_if (PROP()LOCAL()SEP()).
  + destruct t; simpl tree_rep.
      1: Intros. contradiction.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (and (and (Z.le Int.min_signed k) (Z.le k Int.max_signed)) (is_pointer_or_null v))) (@exp mpred Nveric val (fun pa : val => @exp mpred Nveric val (fun pb : val => @sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh t_struct_tree (@pair val (prod val (prod val val)) (Vint (Int.repr k)) (@pair val (prod val val) v (@pair val val pa pb))) p1) (tree_rep t1_1 pa)) (tree_rep t1_2 pb))))) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
    Intros pa pb.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint))) MORE_COMMANDS) POSTCONDITION *)
    forward.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint))) MORE_COMMANDS) POSTCONDITION *)
    forward.
    Time forward_call (p, sizeof t_struct_tree).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (tree_rep t1_2 pb)) (@nil mpred)))))) (@liftx (LiftEnviron mpred) (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1))) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@cons mpred (treebox_rep t1_1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred)))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
    {
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
      entailer!.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
      rewrite memory_block_data_at_ by auto.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@emp mpred Nveric Sveric) (tree_rep t p)) (tree_rep t p) *)
      cancel.
    }
    Time forward_call (t1,pa).
    Time forward_call (t2,pb).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
    entailer!.
  + forward.
(* Goal: @derives mpred Nveric (spacer sh x y p) (@emp mpred Nveric Sveric) *)
    subst.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
    entailer!.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr x))) (@nil localdef)))) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (@eq val p1 nullval)) (@emp mpred Nveric Sveric)) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val x (@E val)) b1) (treebox_rep (@delete val x t) b)) (@nil mpred))))))) (Ssequence (Sset _y (Efield (Ederef (Etempvar _p (tptr (Tstruct _tree noattr))) (Tstruct _tree noattr)) _key tint)) MORE_COMMANDS) POSTCONDITION *)
    simpl; normalize.
  + forward.
Qed.

Lemma body_treebox_free: semax_body Vprog Gprog f_treebox_free treebox_free_spec.
Proof.
(* Goal: semax_body Vprog Gprog CompSpecs f_main main_spec *)
  start_function.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (Abs (empty_tree val) (@t_empty val nullval))) (treebox_rep (empty_tree val) v)) (@nil mpred))))) *)
  unfold treebox_rep.
(* Goal: semax CompSpecs Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun vret : val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p vret) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_empty val nullval) vret) (@cons mpred (Freezer.FRZL FR1) (@nil mpred))))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xI xH))) tint) (@cons expr (Evar ___stringlit_1 (tarray tschar (Zpos (xO (xI xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_2 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xO (xO xH)))) tint) (@cons expr (Evar ___stringlit_3 (tarray tschar (Zpos (xI (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_4 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))))))) MORE_COMMANDS) POSTCONDITION *)
  Intros p.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint))) MORE_COMMANDS) POSTCONDITION *)
  forward.
  Time forward_call (t,p).
  Time forward_call (b, sizeof (tptr t_struct_tree)).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
  entailer!.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
  rewrite memory_block_data_at_ by auto.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@emp mpred Nveric Sveric) (tree_rep t p)) (tree_rep t p) *)
  cancel.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint))) MORE_COMMANDS) POSTCONDITION *)
  forward.
Qed.

Module Abstractions.
(* Demonstration of data abstraction via subsume_funspec. *)


(* Definitions of [combine] and [Abs] taken from 
   Verified Functional Algorithms (Software Foundations Volume 3),
   chapter SearchTree *)
Section TREE_ABS.

Definition total_map (A:Type) := key -> A.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (tree_rep t1_2 pb)) (@nil mpred)))))) (@liftx (LiftEnviron mpred) (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1))) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@cons mpred (treebox_rep t1_1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred)))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
Definition t_empty {A:Type} (v : A) : total_map A :=
  (fun _ => v).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (tree_rep t1_2 pb)) (@nil mpred)))))) (@liftx (LiftEnviron mpred) (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1))) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@cons mpred (treebox_rep t1_1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred)))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
Definition t_update {A:Type} (m : total_map A)
                    (x : key) (v : A) :=
  fun x' => if x =? x' then v else m x'.


(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (@sepcon mpred Nveric Sveric (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) pb p1) (tree_rep t1_2 pb)) (@nil mpred)))))) (@liftx (LiftEnviron mpred) (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1))) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _y (Vint (Int.repr k))) (@cons localdef (temp _p p1) (@cons localdef (temp _t b1) (@cons localdef (temp _x (Vint (Int.repr k))) (@nil localdef))))) (SEPx (@cons mpred (treebox_rep t1_2 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _right) (@nil gfield)) p1)) (@cons mpred (treebox_rep t1_1 (@field_address CompSpecs t_struct_tree (@cons gfield (StructField _left) (@nil gfield)) p1)) (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) p1 b1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _key) (@nil gfield)) (Vint (Int.repr k)) p1) (@cons mpred (@field_at CompSpecs Tsh t_struct_tree (@cons gfield (StructField _value) (@nil gfield)) v p1) (@cons mpred (@wand mpred Nveric Sveric (treebox_rep (@delete val k (@T val t1_1 k v t1_2)) b1) (treebox_rep (@delete val k t) b)) (@nil mpred)))))))))) (Ssequence (Scall (@None ident) (Evar _pushdown_left (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _t (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) MORE_COMMANDS) POSTCONDITION *)
Definition combine {A} (pivot: key) (m1 m2: total_map A) : total_map A :=
  fun x : key => if zlt x pivot  then m1 x else m2 x.

Inductive Abs:  tree val -> total_map val -> Prop :=
| Abs_E: Abs E (t_empty nullval)
| Abs_T: forall a b l k v r,
      Abs l a ->
      Abs r b ->
      Abs (T l k v r)  (t_update (combine k a b) k v).

Theorem insert_relate:
 forall k v t cts,
    Abs t cts ->
    Abs (insert k v t) (t_update cts k v).
Admitted.  (* This is an exercise in Verified Functional Algorithms *)

Theorem lookup_relate:
  forall k t cts ,
    Abs t cts -> lookup nullval k t =  cts k.
Admitted.  (* This is an exercise in Verified Functional Algorithms *)


Definition tmap_rep (m: total_map val) (p: val) : mpred :=
   EX t: tree val, !! Abs t m && treebox_rep t p.

Definition abs_insert_spec :=
 DECLARE _insert
  WITH b: val, x: Z, v: val, m: total_map val
  PRE  [ _t OF (tptr (tptr t_struct_tree)), _x OF tint,
        _value OF (tptr Tvoid)   ]
    PROP( Int.min_signed <= x <= Int.max_signed; is_pointer_or_null v)
    LOCAL(temp _t b; temp _x (Vint (Int.repr x)); temp _value v)
    SEP (tmap_rep m b)
  POST [ Tvoid ] 
    PROP()
    LOCAL()
    SEP (tmap_rep (t_update m x v) b).

Definition abs_treebox_new_spec :=
 DECLARE _treebox_new
  WITH u : unit
  PRE  [  ]
       PROP() LOCAL() SEP ()
  POST [ tptr (tptr t_struct_tree) ]
    EX v:val,
    PROP()
    LOCAL(temp ret_temp v)
    SEP (tmap_rep (t_empty nullval) v).

Definition abs_treebox_free_spec :=
 DECLARE _treebox_free
  WITH m: total_map val, p: val
  PRE  [ _b OF (tptr (tptr t_struct_tree)) ]
       PROP() LOCAL(temp _b p) SEP (tmap_rep m p)
  POST [ Tvoid ]
    PROP()
    LOCAL()
    SEP (emp).

Definition main_spec :=
 DECLARE _main
  WITH gv : globals
  PRE  [] main_pre prog nil gv
  POST [ tint ] main_post prog nil gv.

Lemma subsume_insert:
 subsume_funspec (snd insert_spec) (snd abs_insert_spec).
Proof.
(* Goal: subsume_funspec (@snd ident funspec treebox_free_spec) (@snd ident funspec abs_treebox_free_spec) *)
apply NDsubsume_subsume.
(* Goal: is_NDfunspec (@snd ident funspec abs_treebox_free_spec) *)
(* Goal: NDsubsume_funspec (@snd ident funspec treebox_free_spec) (@snd ident funspec abs_treebox_free_spec) *)
split; reflexivity.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
split3; auto.
(* Goal: forall x2 : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (prod (prod val Z) val) (total_map val))) mpred, @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec insert_spec))))) (let (p, m) := x2 in let (p0, v) := p in let (b, x) := p0 in PROPx (@cons Prop (and (Z.le Int.min_signed x) (Z.le x Int.max_signed)) (@cons Prop (is_pointer_or_null v) (@nil Prop))) (LOCALx (@cons localdef (temp _t b) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef)))) (SEPx (@cons mpred (tmap_rep m b) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (prod (prod val Z) val) (tree val))) mpred) (fun x1 : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (prod (prod val Z) val) (tree val))) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (p, t) := x1 in let (p0, v) := p in let (b, x) := p0 in PROPx (@cons Prop (and (Z.le Int.min_signed x) (Z.le x Int.max_signed)) (@cons Prop (is_pointer_or_null v) (@nil Prop))) (LOCALx (@cons localdef (temp _t b) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef)))) (SEPx (@cons mpred (treebox_rep t b) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec insert_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (p, t) := x1 in let (p0, v) := p in let (b, x) := p0 in PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (treebox_rep (@insert val x v t) b) (@nil mpred))))))) (let (p, m) := x2 in let (p0, v) := p in let (b, x) := p0 in PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (tmap_rep (@t_update val m x v) b) (@nil mpred)))))))))) *)
intros [[[b x] v] m].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (tmap_rep m p) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred) (fun x1 : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (t, b) := x1 in PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b b) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t b) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (_, _) := x1 in PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))))))) *)
unfold tmap_rep.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (@exp mpred Nveric (tree val) (fun t : tree val => @andp mpred Nveric (@prop mpred Nveric (Abs t m)) (treebox_rep t p))) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred) (fun x1 : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (t, b) := x1 in PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b b) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t b) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (_, _) := x1 in PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))))))) *)
Intros t.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec insert_spec))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _t b) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef)))) (SEPx (@cons mpred (treebox_rep t b) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (prod (prod val Z) val) (tree val))) mpred) (fun x1 : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (prod (prod val Z) val) (tree val))) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (p, t) := x1 in let (p0, v) := p in let (b, x) := p0 in PROPx (@cons Prop (and (Z.le Int.min_signed x) (Z.le x Int.max_signed)) (@cons Prop (is_pointer_or_null v) (@nil Prop))) (LOCALx (@cons localdef (temp _t b) (@cons localdef (temp _x (Vint (Int.repr x))) (@cons localdef (temp _value v) (@nil localdef)))) (SEPx (@cons mpred (treebox_rep t b) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec insert_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (p, t) := x1 in let (p0, v) := p in let (b, x) := p0 in PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (treebox_rep (@insert val x v t) b) (@nil mpred))))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@exp mpred Nveric (tree val) (fun t : tree val => @andp mpred Nveric (@prop mpred Nveric (Abs t (@t_update val m x v))) (treebox_rep t b))) (@nil mpred)))))))))) *)
Exists (b, x, v, t).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t p) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t p) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))))) *)
Exists emp.
change (`emp) with (@emp (environ->mpred) _ _); rewrite !emp_sepcon.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
apply andp_right; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
entailer!.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t p) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))) *)
apply prop_right.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
simplify_Delta.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (treebox_rep (@insert val x v t) b) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@exp mpred Nveric (tree val) (fun t : tree val => @andp mpred Nveric (@prop mpred Nveric (Abs t (@t_update val m x v))) (treebox_rep t b))) (@nil mpred))))) *)
Exists (insert x v t).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
entailer!.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
apply insert_relate; auto.
Qed.

Lemma subsume_treebox_new:
 subsume_funspec (snd treebox_new_spec) (snd abs_treebox_new_spec).
Proof.
(* Goal: subsume_funspec (@snd ident funspec treebox_free_spec) (@snd ident funspec abs_treebox_free_spec) *)
apply NDsubsume_subsume.
(* Goal: is_NDfunspec (@snd ident funspec abs_treebox_free_spec) *)
(* Goal: NDsubsume_funspec (@snd ident funspec treebox_free_spec) (@snd ident funspec abs_treebox_free_spec) *)
split; reflexivity.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
split3; auto.
(* Goal: forall _ : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst unit) mpred, @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_new_spec))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@nil mpred))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst unit) mpred) (fun _ : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst unit) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@nil mpred))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_new_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v : val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v : val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (tmap_rep (@t_empty val nullval) v) (@nil mpred))))))))))) *)
intros x. simpl in x.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_new_spec))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@nil mpred))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst unit) mpred) (fun _ : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst unit) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@nil mpred))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_new_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v : val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v : val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (tmap_rep (@t_empty val nullval) v) (@nil mpred))))))))))) *)
Exists x.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t p) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t p) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))))) *)
Exists emp.
change (`emp) with (@emp (environ->mpred) _ _); rewrite !emp_sepcon.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
apply andp_right; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t p) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))) *)
apply prop_right.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
simplify_Delta.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v : val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v : val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (tmap_rep (@t_empty val nullval) v) (@nil mpred)))))) *)
Intros v.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v : val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (tmap_rep (@t_empty val nullval) v) (@nil mpred)))))) *)
Exists v.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (tmap_rep m p) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred) (fun x1 : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (t, b) := x1 in PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b b) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t b) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (_, _) := x1 in PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))))))) *)
unfold tmap_rep.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@exp mpred Nveric (tree val) (fun t : tree val => @andp mpred Nveric (@prop mpred Nveric (Abs t (@t_empty val nullval))) (treebox_rep t v))) (@nil mpred))))) *)
Exists (empty_tree val).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (Abs (empty_tree val) (@t_empty val nullval))) (treebox_rep (empty_tree val) v)) (@nil mpred))))) *)
unfold treebox_rep.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Tsh (tptr t_struct_tree) nullval v) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp ret_temp v) (@nil localdef)) (SEPx (@cons mpred (@andp mpred Nveric (@prop mpred Nveric (Abs (empty_tree val) (@t_empty val nullval))) (@exp mpred Nveric val (fun p : val => @sepcon mpred Nveric Sveric (@data_at CompSpecs Tsh (tptr t_struct_tree) p v) (tree_rep (empty_tree val) p)))) (@nil mpred))))) *)
Exists nullval.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
entailer!.
(* Goal: Abs (empty_tree val) (@t_empty val nullval) *)
(* Goal: @derives mpred Nveric (@emp mpred Nveric Sveric) (tree_rep (empty_tree val) nullval) *)
constructor.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
simpl. entailer!. 
Qed.

Lemma subsume_treebox_free:
 subsume_funspec (snd treebox_free_spec) (snd abs_treebox_free_spec).
Proof.
(* Goal: subsume_funspec (@snd ident funspec treebox_free_spec) (@snd ident funspec abs_treebox_free_spec) *)
apply NDsubsume_subsume.
(* Goal: is_NDfunspec (@snd ident funspec abs_treebox_free_spec) *)
(* Goal: NDsubsume_funspec (@snd ident funspec treebox_free_spec) (@snd ident funspec abs_treebox_free_spec) *)
split; reflexivity.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
split3; auto.
(* Goal: forall x2 : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (total_map val) val)) mpred, @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec))))) (let (m, p) := x2 in PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (tmap_rep m p) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred) (fun x1 : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (t, b) := x1 in PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b b) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t b) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (_, _) := x1 in PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))) (let (_, _) := x2 in PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))))))) *)
intros [m p].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (tmap_rep m p) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred) (fun x1 : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (t, b) := x1 in PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b b) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t b) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (_, _) := x1 in PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))))))) *)
unfold tmap_rep.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (@exp mpred Nveric (tree val) (fun t : tree val => @andp mpred Nveric (@prop mpred Nveric (Abs t m)) (treebox_rep t p))) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred) (fun x1 : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (t, b) := x1 in PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b b) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t b) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (_, _) := x1 in PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))))))) *)
Intros t.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t p) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred) (fun x1 : functors.MixVariantFunctor._functor (functors.MixVariantFunctorGenerator.fconst (prod (tree val) val)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (t, b) := x1 in PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b b) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t b) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (let (_, _) := x1 in PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))))))) *)
Exists (t,p).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t p) (@nil mpred)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) mpred (fun F : mpred => @andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t p) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) F) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))))) *)
Exists emp.
change (`emp) with (@emp (environ->mpred) _ _); rewrite !emp_sepcon.
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
apply andp_right; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec))))) (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _b p) (@nil localdef)) (SEPx (@cons mpred (treebox_rep t p) (@nil mpred)))))) (@prop (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))))) *)
apply prop_right.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ (ret0_tycon (funsig_tycontext (funsig_of_funspec (@snd ident funspec treebox_free_spec)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
simplify_Delta.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
entailer!.
Qed.

Lemma body_main: semax_body Vprog Gprog f_main main_spec.
Proof.
(* Goal: semax_body Vprog Gprog CompSpecs f_main main_spec *)
start_function.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
assert_PROP (isptr (gv ___stringlit_1)) by entailer!.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
assert_PROP (isptr (gv ___stringlit_2)) by entailer!.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
assert_PROP (isptr (gv ___stringlit_3)) by entailer!.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred)))))) (PROPx (@nil Prop) (LOCALx (@nil localdef) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@nil mpred))))) *)
assert_PROP (isptr (gv ___stringlit_4)) by entailer!.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (gvars gv) (@nil localdef)) (SEPx (@cons mpred (@data_at CompSpecs Ers (tarray tschar (Zpos (xO (xO xH)))) (@map Int.int val (@Basics.compose Int.int Int.int val Vint (cast_int_int I8 Signed)) (@cons Int.int (Int.repr (Zpos (xI (xI (xI (xI (xO (xI xH)))))))) (@cons Int.int (Int.repr (Zpos (xO (xI (xI (xI (xO (xI xH)))))))) (@cons Int.int (Int.repr (Zpos (xI (xO (xI (xO (xO (xI xH)))))))) (@cons Int.int (Int.repr Z0) (@nil Int.int)))))) (gv ___stringlit_2)) (@cons mpred (@data_at CompSpecs Ers (tarray tschar (Zpos (xO (xO xH)))) (@map Int.int val (@Basics.compose Int.int Int.int val Vint (cast_int_int I8 Signed)) (@cons Int.int (Int.repr (Zpos (xI (xI (xI (xI (xO (xO xH)))))))) (@cons Int.int (Int.repr (Zpos (xO (xI (xI (xI (xO (xO xH)))))))) (@cons Int.int (Int.repr (Zpos (xI (xO (xI (xO (xO (xO xH)))))))) (@cons Int.int (Int.repr Z0) (@nil Int.int)))))) (gv ___stringlit_4)) (@cons mpred (@data_at CompSpecs Ers (tarray tschar (Zpos (xO (xI xH)))) (@map Int.int val (@Basics.compose Int.int Int.int val Vint (cast_int_int I8 Signed)) (@cons Int.int (Int.repr (Zpos (xO (xO (xI (xO (xI (xI xH)))))))) (@cons Int.int (Int.repr (Zpos (xO (xO (xO (xI (xO (xI xH)))))))) (@cons Int.int (Int.repr (Zpos (xO (xI (xO (xO (xI (xI xH)))))))) (@cons Int.int (Int.repr (Zpos (xI (xO (xI (xO (xO (xI xH)))))))) (@cons Int.int (Int.repr (Zpos (xI (xO (xI (xO (xO (xI xH)))))))) (@cons Int.int (Int.repr Z0) (@nil Int.int)))))))) (gv ___stringlit_1)) (@cons mpred (@data_at CompSpecs Ers (tarray tschar (Zpos (xI (xO xH)))) (@map Int.int val (@Basics.compose Int.int Int.int val Vint (cast_int_int I8 Signed)) (@cons Int.int (Int.repr (Zpos (xO (xI (xI (xO (xO (xI xH)))))))) (@cons Int.int (Int.repr (Zpos (xI (xI (xI (xI (xO (xI xH)))))))) (@cons Int.int (Int.repr (Zpos (xI (xO (xI (xO (xI (xI xH)))))))) (@cons Int.int (Int.repr (Zpos (xO (xI (xO (xO (xI (xI xH)))))))) (@cons Int.int (Int.repr Z0) (@nil Int.int))))))) (gv ___stringlit_3)) (@nil mpred)))))))) (Ssequence (Ssequence (Ssequence (Scall (@Some ident _t'1) (Evar _treebox_new (Tfunction Tnil (tptr (tptr (Tstruct _tree noattr))) cc_default)) (@nil expr)) (Sset _p (Etempvar _t'1 (tptr (tptr (Tstruct _tree noattr)))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xI xH))) tint) (@cons expr (Evar ___stringlit_1 (tarray tschar (Zpos (xO (xI xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_2 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xO (xO xH)))) tint) (@cons expr (Evar ___stringlit_3 (tarray tschar (Zpos (xI (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_4 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint))))))))) MORE_COMMANDS) POSTCONDITION *)
freeze [0;1;2;3] FR1.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (gvars gv) (@nil localdef)) (SEPx (@cons mpred (Freezer.FRZL FR1) (@nil mpred))))) (Ssequence (Ssequence (Ssequence (Scall (@Some ident _t'1) (Evar _treebox_new (Tfunction Tnil (tptr (tptr (Tstruct _tree noattr))) cc_default)) (@nil expr)) (Sset _p (Etempvar _t'1 (tptr (tptr (Tstruct _tree noattr)))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xI xH))) tint) (@cons expr (Evar ___stringlit_1 (tarray tschar (Zpos (xO (xI xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_2 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xO (xO xH)))) tint) (@cons expr (Evar ___stringlit_3 (tarray tschar (Zpos (xI (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_4 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint))))))))) MORE_COMMANDS) POSTCONDITION *)
forward_call subsume_treebox_new tt.
(* Goal: semax CompSpecs Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun vret : val => PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p vret) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_empty val nullval) vret) (@cons mpred (Freezer.FRZL FR1) (@nil mpred))))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xI xH))) tint) (@cons expr (Evar ___stringlit_1 (tarray tschar (Zpos (xO (xI xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_2 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xO (xO xH)))) tint) (@cons expr (Evar ___stringlit_3 (tarray tschar (Zpos (xI (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_4 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))))))) MORE_COMMANDS) POSTCONDITION *)
Intros p.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_empty val nullval) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xI xH))) tint) (@cons expr (Evar ___stringlit_1 (tarray tschar (Zpos (xO (xI xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_2 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xO (xO xH)))) tint) (@cons expr (Evar ___stringlit_3 (tarray tschar (Zpos (xI (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_4 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))))))) MORE_COMMANDS) POSTCONDITION *)
forward_call subsume_insert (p, 3, gv ___stringlit_1, t_empty nullval).
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
split. computable. auto.
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_2 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos (xO (xO xH)))) tint) (@cons expr (Evar ___stringlit_3 (tarray tschar (Zpos (xI (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _insert (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) (Tcons tint (Tcons (tptr tvoid) Tnil))) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@cons expr (Econst_int (Int.repr (Zpos xH)) tint) (@cons expr (Evar ___stringlit_4 (tarray tschar (Zpos (xO (xO xH))))) (@nil expr))))) (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint))))))) MORE_COMMANDS) POSTCONDITION *)
forward_call subsume_insert (p, 1, gv ___stringlit_2, (t_update (t_empty nullval) 3 (gv ___stringlit_1))).
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
split. computable. auto.
forward_call subsume_insert (p, 4, gv ___stringlit_3, (t_update
             (t_update (t_empty nullval) 3
                (gv ___stringlit_1)) 1 (gv ___stringlit_2))).
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
split. computable. auto.
forward_call subsume_insert (p, 1, gv ___stringlit_4, 
           (t_update
             (t_update
                (t_update (t_empty nullval) 3
                   (gv ___stringlit_1)) 1
                (gv ___stringlit_2)) 4 (gv ___stringlit_3))).
(* Goal: is_pointer_or_null (gv ___stringlit_4) *)
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (tmap_rep (@t_update val (@t_update val (@t_update val (@t_update val (@t_empty val nullval) (Zpos (xI xH)) (gv ___stringlit_1)) (Zpos xH) (gv ___stringlit_2)) (Zpos (xO (xO xH))) (gv ___stringlit_3)) (Zpos xH) (gv ___stringlit_4)) p) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Ssequence (Scall (@None ident) (Evar _treebox_free (Tfunction (Tcons (tptr (tptr (Tstruct _tree noattr))) Tnil) tvoid cc_default)) (@cons expr (Etempvar _p (tptr (tptr (Tstruct _tree noattr)))) (@nil expr))) (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint)))) MORE_COMMANDS) POSTCONDITION *)
split. computable. auto.
forward_call subsume_treebox_free ((t_update
             (t_update
                (t_update
                   (t_update (t_empty nullval) 3
                      (gv ___stringlit_1)) 1
                   (gv ___stringlit_2)) 4
                (gv ___stringlit_3)) 1 (gv ___stringlit_4)), p).
(* Goal: semax CompSpecs Espec Delta (PROPx (@nil Prop) (LOCALx (@cons localdef (temp _p p) (@cons localdef (gvars gv) (@nil localdef))) (SEPx (@cons mpred (@emp mpred Nveric Sveric) (@cons mpred (Freezer.FRZL FR1) (@nil mpred)))))) (Ssequence (Sreturn (@Some expr (Econst_int (Int.repr Z0) tint))) MORE_COMMANDS) POSTCONDITION *)
forward.
Qed.

End TREE_ABS.

End Abstractions.




