From compcert Require Export Clightdefs.
Require Export VST.veric.base.
Require Export VST.veric.SeparationLogic.
Require Export VST.msl.Extensionality.
Require Export compcert.lib.Coqlib.
Require Export VST.msl.Coqlib2 VST.veric.coqlib4 VST.floyd.coqlib3.
Require Export VST.floyd.jmeq_lemmas.
Require Export VST.floyd.find_nth_tactic.
Require Export VST.veric.juicy_extspec.
Require Import VST.veric.NullExtension.
Require Import VST.floyd.assert_lemmas.
Require Import VST.floyd.SeparationLogicFacts.
Local Open Scope logic.

Fixpoint all_suf_of_labeled_statements (P: labeled_statements -> Prop) (L: labeled_statements): Prop :=
  match L with
  | LSnil => P L
  | LScons _ s L' => P L /\ all_suf_of_labeled_statements P L'
  end.

Lemma all_suf_self: forall P L,
  all_suf_of_labeled_statements P L -> P L.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: P L *)
  destruct L; simpl in *; tauto.
Qed.

Lemma all_suf_LSnil: forall P L,
  all_suf_of_labeled_statements P L -> P LSnil.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: P LSnil *)
  induction L; simpl in *; tauto.
Qed.

Lemma all_suf_select_switch: forall P L,
  all_suf_of_labeled_statements P L ->
  forall n, P (select_switch n L).
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement (select_switch n sl))) true *)
  unfold select_switch.
(* Goal: P match select_switch_case n L with | Some sl' => sl' | None => select_switch_default L end *)
  destruct (select_switch_case) eqn:?H.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  + revert l H0; induction L; intros.
    - inv H0.
    - simpl in H0.
(* Goal: P l *)
      destruct o; [if_tac in H0 |].
(* Goal: @eq bool (is_int_type t) true *)
      * subst z; inv H0.
(* Goal: P (LScons (@Some Z n) s L) *)
        destruct H as [? _]; auto.
      * apply IHL; auto.
(* Goal: all_suf_of_labeled_statements P L *)
        destruct H as [_ ?]; auto.
      * apply IHL; auto.
(* Goal: all_suf_of_labeled_statements P L *)
        destruct H as [_ ?]; auto.
  + clear H0.
(* Goal: P (select_switch_default L) *)
    induction L.
    - apply all_suf_LSnil in H.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      auto.
    - simpl.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement match o with | Some i => select_switch_default sl | None => LScons o s sl end)) true *)
      destruct o.
      * destruct H as [_ ?].
(* Goal: P (select_switch_default L) *)
        apply IHL; auto.
      * destruct H as [? _].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
Qed.

Section statement_ind.

Variables
  (P: statement -> Prop)
  (Hskip: P Sskip)
  (Hassign: forall e e0, P (Sassign e e0))
  (Hset : forall (i : ident) (e : expr), P (Sset i e))
  (Hcall : forall (o : option ident) (e : expr) (l : list expr), P (Scall o e l))
  (Hbuiltin : forall o e t l, P (Sbuiltin o e t l))
  (Hsequence : forall s : statement, P s -> forall s0 : statement, P s0 -> P (Ssequence s s0))
  (Hifthenelse : forall e s, P s -> forall s0, P s0 -> P (Sifthenelse e s s0))
  (Hloop : forall s : statement, P s -> forall s0 : statement, P s0 -> P (Sloop s s0))
  (Hbreak : P Sbreak)
  (Hcontinue : P Scontinue)
  (Hreturn : forall o : option expr, P (Sreturn o))
  (Hswitch : forall e L, all_suf_of_labeled_statements (fun L => P (seq_of_labeled_statement L)) L -> P (Sswitch e L))
  (Hlabel : forall (l : label) (s : statement), P s -> P (Slabel l s))
  (Hgoto : forall l : label, P (Sgoto l)).

Fixpoint statement_ind (s: statement): P s :=
  match s as s0 return (P s0) with
  | Sskip => Hskip
  | Sassign e e0 => Hassign e e0
  | Sset i e => Hset i e
  | Scall o e l => Hcall o e l
  | Sbuiltin o e t l => Hbuiltin o e t l
  | Ssequence s0 s1 => Hsequence s0 (statement_ind s0) s1 (statement_ind s1)
  | Sifthenelse e s0 s1 => Hifthenelse e s0 (statement_ind s0) s1 (statement_ind s1)
  | Sloop s0 s1 => Hloop s0 (statement_ind s0) s1 (statement_ind s1)
  | Sbreak => Hbreak
  | Scontinue => Hcontinue
  | Sreturn o => Hreturn o
  | Sswitch e l => Hswitch e l (labeled_statements_ind l)
  | Slabel l s0 => Hlabel l s0 (statement_ind s0)
  | Sgoto l => Hgoto l
  end
with labeled_statements_ind (L: labeled_statements): all_suf_of_labeled_statements (fun L => P (seq_of_labeled_statement L)) L :=
  match L with
  | LSnil => Hskip
  | LScons _ s L' => conj (Hsequence _ (statement_ind s) _ (all_suf_self _ _ (labeled_statements_ind L'))) (labeled_statements_ind L')
  end.

End statement_ind.

Ltac induction_stmt s :=
  revert dependent s;
  let s1 := fresh s "1" in
  let s2 := fresh s "2" in
  let IHs := fresh "IH" s in
  let IHs1 := fresh "IH" s1 in
  let IHs2 := fresh "IH" s2 in
  refine (statement_ind _ _ _ _ _ _ _ _ _ _ _ _ _ _ _);
  [
  | intros ?e ?e
  | intros ?i ?e
  | intros ?o ?e ?l
  | intros ?o ?e ?t ?l
  | intros s1 IHs1 s2 IHs2
  | intros ?e s1 IHs1 s2 IHs2
  | intros s1 IHs1 s2 IHs2
  |
  |
  | intros ?o
  | intros ?e ?l ?IH; specialize (all_suf_select_switch _ _ IH); clear IH; intro IH; cbv beta in IH
  | intros ?l s IHs
  | intros ?l ].

Module AuxDefs.

Section AuxDefs.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Variable semax_external: forall {Hspec: OracleKind} (ids: list ident) (ef: external_function)
  (A: rmaps.TypeTree)
  (P Q: forall ts, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred),
    Prop.

Inductive semax {CS: compspecs} {Espec: OracleKind} (Delta: tycontext): (environ -> mpred) -> statement -> ret_assert -> Prop :=
| semax_ifthenelse :
   forall P (b: expr) c d R,
     @semax CS Espec Delta (P && local (`(typed_true (typeof b)) (eval_expr b))) c R ->
     @semax CS Espec Delta (P && local (`(typed_false (typeof b)) (eval_expr b))) d R ->
     @semax CS Espec Delta (!! (bool_type (typeof b) = true) && tc_expr Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr)) && P) (Sifthenelse b c d) R
| semax_seq:
  forall R P Q h t,
    @semax CS Espec Delta P h (overridePost Q R) ->
    @semax CS Espec Delta Q t R ->
    @semax CS Espec Delta P (Ssequence h t) R
| semax_break: forall Q,
    @semax CS Espec Delta (RA_break Q) Sbreak Q
| semax_continue: forall Q,
    @semax CS Espec Delta (RA_continue Q) Scontinue Q
| semax_loop: forall Q Q' incr body R,
     @semax CS Espec Delta  Q body (loop1_ret_assert Q' R) ->
     @semax CS Espec Delta Q' incr (loop2_ret_assert Q R) ->
     @semax CS Espec Delta Q (Sloop body incr) R
| semax_switch: forall (Q: environ->mpred) a sl R,
     (forall rho, Q rho |-- tc_expr Delta a rho) ->
     (forall n,
     @semax CS Espec Delta 
               (local (`eq (eval_expr a) `(Vint n)) &&  Q)
               (seq_of_labeled_statement (select_switch (Int.unsigned n) sl))
               (switch_ret_assert R)) ->
     @semax CS Espec Delta (!! (is_int_type (typeof a) = true) && Q) (Sswitch a sl) R
| semax_call_backward: forall ret a bl R,
     @semax CS Espec Delta
         (EX argsig: _, EX retsig: _, EX cc: _,
          EX A: _, EX P: _, EX Q: _, EX NEP: _, EX NEQ: _, EX ts: _, EX x: _,
         !! (Cop.classify_fun (typeof a) =
             Cop.fun_case_f (type_of_params argsig) retsig cc /\
             (retsig = Tvoid -> ret = None) /\
             tc_fn_return Delta ret retsig) &&
          (|>((tc_expr Delta a) && (tc_exprlist Delta (snd (split argsig)) bl)))  &&
         `(func_ptr (mk_funspec  (argsig,retsig) cc A P Q NEP NEQ)) (eval_expr a) &&
          |>((`(P ts x: environ -> mpred) (make_args' (argsig,retsig) (eval_exprlist (snd (split argsig)) bl))) * oboxopt Delta ret (maybe_retval (Q ts x) retsig ret -* R)))
         (Scall ret a bl)
         (normal_ret_assert R)
| semax_return: forall (R: ret_assert) ret ,
      @semax CS Espec Delta
                ( (tc_expropt Delta ret (ret_type Delta)) &&
                `(RA_return R : option val -> environ -> mpred) (cast_expropt ret (ret_type Delta)) (@id environ))
                (Sreturn ret)
                R
| semax_set_ptr_compare_load_cast_load_backward: forall (P: environ->mpred) id e,
    @semax CS Espec Delta
       ((|> ( (tc_expr Delta e) &&
             (tc_temp_id id (typeof e) Delta e) &&
             subst id (eval_expr e) P)) ||
        (EX cmp: Cop.binary_operation, EX e1: expr, EX e2: expr,
         EX ty: type, EX sh1: share, EX sh2: share,
          !! (e = Ebinop cmp e1 e2 ty /\
              sepalg.nonidentity sh1 /\ sepalg.nonidentity sh2 /\
              is_comparison cmp = true /\
              eqb_type (typeof e1) int_or_ptr_type = false /\
              eqb_type (typeof e2) int_or_ptr_type = false /\
              typecheck_tid_ptr_compare Delta id = true) &&
            ( |> ( (tc_expr Delta e1) &&
              (tc_expr Delta e2)  &&
          local (`(blocks_match cmp) (eval_expr e1) (eval_expr e2)) &&
          (`(mapsto_ sh1 (typeof e1)) (eval_expr e1) * TT) &&
          (`(mapsto_ sh2 (typeof e2)) (eval_expr e2) * TT) &&
          subst id (eval_expr (Ebinop cmp e1 e2 ty)) P))) ||
        (EX sh: share, EX t2: type, EX v2: val,
              !! (typeof_temp Delta id = Some t2 /\
                  is_neutral_cast (typeof e) t2 = true /\
                  readable_share sh) &&
         |> ( (tc_lvalue Delta e) &&
              local (`(tc_val (typeof e) v2)) &&
              (`(mapsto sh (typeof e)) (eval_lvalue e) (`v2) * TT) &&
              subst id (`v2) P)) ||
        (EX sh: share, EX e1: expr, EX t1: type, EX v2: val,
              !! (e = Ecast e1 t1 /\
                  typeof_temp Delta id = Some t1 /\
                  cast_pointer_to_bool (typeof e1) t1 = false /\
                  readable_share sh) &&
         |> ( (tc_lvalue Delta e1) &&
              local (`(tc_val t1) (`(eval_cast (typeof e1) t1 v2))) &&
              (`(mapsto sh (typeof e1)) (eval_lvalue e1) (`v2) * TT) &&
              subst id (`(force_val (sem_cast (typeof e1) t1 v2))) P)))
        (Sset id e) (normal_ret_assert P)
| semax_store_backward: forall e1 e2 P,
   @semax CS Espec Delta
          (EX sh: share, !! writable_share sh && |> ( (tc_lvalue Delta e1) &&  (tc_expr Delta (Ecast e2 (typeof e1)))  &&
             ((`(mapsto_ sh (typeof e1)) (eval_lvalue e1)) * (`(mapsto sh (typeof e1)) (eval_lvalue e1) (`force_val (`(sem_cast (typeof e2) (typeof e1)) (eval_expr e2))) -* P))))
          (Sassign e1 e2)
          (normal_ret_assert P)
| semax_skip: forall P, @semax CS Espec Delta P Sskip (normal_ret_assert P)
| semax_builtin: forall P opt ext tl el, @semax CS Espec Delta FF (Sbuiltin opt ext tl el) P
| semax_label: forall (P:environ -> mpred) (c:statement) (Q:ret_assert) l,
    @semax CS Espec Delta P c Q -> @semax CS Espec Delta P (Slabel l c) Q
| semax_goto: forall P l, @semax CS Espec Delta FF (Sgoto l) P
| semax_conseq: forall P' (R': ret_assert) P c (R: ret_assert) ,
    local (tc_environ Delta) && ((allp_fun_id Delta) && P) |-- |==> |> FF || P' ->
    local (tc_environ Delta) && ((allp_fun_id Delta) && RA_normal R') |-- |==> |> FF || RA_normal R ->
    local (tc_environ Delta) && ((allp_fun_id Delta) && RA_break R') |-- |==> |> FF || RA_break R ->
    local (tc_environ Delta) && ((allp_fun_id Delta) && RA_continue R') |-- |==> |> FF || RA_continue R ->
    (forall vl, local (tc_environ Delta) && ((allp_fun_id Delta) && RA_return R' vl) |-- |==> |> FF || RA_return R vl) ->
   @semax CS Espec Delta P' c R' -> @semax CS Espec Delta P c R.

Definition semax_body
       (V: varspecs) (G: funspecs) {C: compspecs} (f: function) (spec: ident * funspec): Prop :=
  match spec with (_, mk_funspec _ cc A P Q NEP NEQ) =>
    forall Espec ts x, (*exists Ann,*)
      @semax C Espec (func_tycontext f V G nil (*Ann*))
          (P ts x *  stackframe_of f)
          (Ssequence f.(fn_body) (Sreturn None))
          (frame_ret_assert (function_body_ret_assert (fn_return f) (Q ts x)) (stackframe_of f))
 end.

Inductive semax_func: forall {Espec: OracleKind} (V: varspecs) (G: funspecs) {C: compspecs} (fdecs: list (ident * Clight.fundef)) (G1: funspecs), Prop :=
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
| semax_func_nil:   forall {Espec: OracleKind},
    forall V G C, @semax_func Espec V G C nil nil
| semax_func_cons:
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  forall {Espec: OracleKind},
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
     forall fs id f cc A P Q NEP NEQ (V: varspecs) (G G': funspecs) {C: compspecs},
      andb (id_in_list id (map (@fst _ _) G))
      (andb (negb (id_in_list id (map (@fst ident Clight.fundef) fs)))
        (semax_body_params_ok f)) = true ->
      Forall
         (fun it : ident * type =>
          complete_type cenv_cs (snd it) =
          true) (fn_vars f) ->
       var_sizes_ok (f.(fn_vars)) ->
       f.(fn_callconv) = cc ->
       precondition_closed f P ->
      semax_body V G f (id, mk_funspec (fn_funsig f) cc A P Q NEP NEQ)->
      semax_func V G fs G' ->
      semax_func V G ((id, Internal f)::fs)
                 ((id, mk_funspec (fn_funsig f) cc A P Q NEP NEQ)  :: G')
| semax_func_cons_ext:
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  forall {Espec: OracleKind},
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
   forall (V: varspecs) (G: funspecs) {C: compspecs} fs id ef argsig retsig A P Q NEP NEQ
          argsig'
          (G': funspecs) cc (ids: list ident),
      ids = map fst argsig' -> (* redundant but useful for the client,
               to calculate ids by reflexivity *)
      argsig' = zip_with_tl ids argsig ->
      ef_sig ef =
      mksignature
        (typlist_of_typelist (type_of_params argsig'))
        (opttyp_of_type retsig) cc ->
      id_in_list id (map (@fst _ _) fs) = false ->
      length ids = length (typelist2list argsig) ->
      (forall gx ts x (ret : option val),
         (Q ts x (make_ext_rval gx ret)
            && !!step_lemmas.has_opttyp ret (opttyp_of_type retsig)
            |-- !!tc_option_val retsig ret)) ->
      @semax_external Espec ids ef A P Q ->
      semax_func V G fs G' ->
      semax_func V G ((id, External ef argsig retsig cc)::fs)
           ((id, mk_funspec (argsig', retsig) cc A P Q NEP NEQ)  :: G').

End AuxDefs.

End AuxDefs.

Module DeepEmbedded
       (Def: CLIGHT_SEPARATION_HOARE_LOGIC_DEF)
       (MinimumLogic: MINIMUM_CLIGHT_SEPARATION_HOARE_LOGIC with Module CSHL_Def := Def).

Module DeepEmbeddedDef <: CLIGHT_SEPARATION_HOARE_LOGIC_DEF.

Definition semax := @AuxDefs.semax.

Definition semax_func := @AuxDefs.semax_func (@Def.semax_external).

Definition semax_external := @Def.semax_external.

End DeepEmbeddedDef.

Module DeepEmbeddedDefs := DerivedDefs (DeepEmbeddedDef).

Import DeepEmbeddedDef DeepEmbeddedDefs.

Module CConseq: CLIGHT_SEPARATION_HOARE_LOGIC_COMPLETE_CONSEQUENCE with Module CSHL_Def := DeepEmbeddedDef.

Module CSHL_Def := DeepEmbeddedDef.

Definition semax_conseq := @AuxDefs.semax_conseq.

End CConseq.

Module CConseqFacts := GenCConseqFacts (DeepEmbeddedDef) (CConseq).

Module Conseq := GenConseq (DeepEmbeddedDef) (CConseq).

Module ConseqFacts := GenConseqFacts (DeepEmbeddedDef) (Conseq).

Import CConseq CConseqFacts Conseq ConseqFacts.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_skip_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R,
    @semax CS Espec Delta P Sskip R ->
    local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || RA_normal R.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R))) *)
  remember Sskip as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + apply derives_full_refl.
  + specialize (IHsemax H0).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue R))) *)
    solve_derives_trans.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_break_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R,
    @semax CS Espec Delta P Sbreak R ->
    local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || RA_break R.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_break R))) *)
  remember Sbreak as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + apply derives_full_refl.
  + specialize (IHsemax H0).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue R))) *)
    solve_derives_trans.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_continue_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R,
    @semax CS Espec Delta P Scontinue R ->
    local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || RA_continue R.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue R))) *)
  remember Scontinue as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + apply derives_full_refl.
  + specialize (IHsemax H0).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue R))) *)
    solve_derives_trans.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_return_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P ret R,
  @semax CS Espec Delta P (Sreturn ret) R ->
  local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || ((tc_expropt Delta ret (ret_type Delta)) && `(|==> |> FF || RA_return R : option val -> environ -> mpred) (cast_expropt ret (ret_type Delta)) (@id environ)).
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expropt CS Delta ret (ret_type Delta)) (@liftx (Tarrow (option val) (Tarrow environ (LiftEnviron mpred))) ((@bupd (forall (_ : option val) (_ : environ), mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@LiftSepLog (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@LiftBupdSepLog (option val) (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric)) (@orp (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@later (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@LiftIndir (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric)) (@FF (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) (RA_return R)) : forall (_ : option val) (_ : environ), mpred) : forall (_ : option val) (_ : environ), mpred) (@cast_expropt CS ret (ret_type Delta)) (@id environ))))) *)
  remember (Sreturn ret) as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + inv H0.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expropt CS Delta ret (ret_type Delta)) (@liftx (Tarrow (option val) (Tarrow environ (LiftEnviron mpred))) (RA_return R) (@cast_expropt CS ret (ret_type Delta)) (@id environ))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expropt CS Delta ret (ret_type Delta)) (@liftx (Tarrow (option val) (Tarrow environ (LiftEnviron mpred))) (@bupd (forall (_ : option val) (_ : environ), mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@LiftSepLog (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@LiftBupdSepLog (option val) (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric)) (@orp (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@later (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@LiftIndir (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric)) (@FF (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) (RA_return R))) (@cast_expropt CS ret (ret_type Delta)) (@id environ))))) *)
    reduce2ENTAIL.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (writable_share sh)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P)))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (writable_share sh)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (@tc_expr CS Delta' (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P))))) *)
    apply andp_ENTAIL; [apply ENTAIL_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
    reduce2derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F) (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof b)) (@eval_expr CS b)))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof b)) (@eval_expr CS b)))) F) *)
    unfold_lift.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)) F) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)) *)
    intro rho.
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
    simpl.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))) *)
    eapply derives_trans; [| apply bupd_intro].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply orp_right2; auto.
  + derives_rewrite -> H; clear H.
    derives_rewrite -> (IHsemax H0); clear IHsemax.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expropt CS Delta ret (ret_type Delta)) (@liftx (Tarrow (option val) (Tarrow environ (LiftEnviron mpred))) (@bupd (forall (_ : option val) (_ : environ), mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@LiftSepLog (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@LiftBupdSepLog (option val) (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric)) (@orp (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@later (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@LiftIndir (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric)) (@FF (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) (RA_return R'))) (@cast_expropt CS ret (ret_type Delta)) (@id environ))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expropt CS Delta ret (ret_type Delta)) (@liftx (Tarrow (option val) (Tarrow environ (LiftEnviron mpred))) (@bupd (forall (_ : option val) (_ : environ), mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@LiftSepLog (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@LiftBupdSepLog (option val) (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric)) (@orp (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@later (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@LiftIndir (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric)) (@FF (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) (RA_return R))) (@cast_expropt CS ret (ret_type Delta)) (@id environ))))) *)
    apply derives_bupd_derives_bupd0.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) P (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr f) (eval_var id (type_of_funspec f)))))) *)
    reduceR.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expropt CS Delta ret (ret_type Delta)) (@liftx (Tarrow (option val) (Tarrow environ (LiftEnviron mpred))) (@bupd (forall (_ : option val) (_ : environ), mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@LiftSepLog (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@LiftBupdSepLog (option val) (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric)) (@orp (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@later (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@LiftIndir (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric)) (@FF (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) (RA_return R'))) (@cast_expropt CS ret (ret_type Delta)) (@id environ))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expropt CS Delta ret (ret_type Delta)) (@liftx (Tarrow (option val) (Tarrow environ (LiftEnviron mpred))) (@bupd (forall (_ : option val) (_ : environ), mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@LiftSepLog (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@LiftBupdSepLog (option val) (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric)) (@orp (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@later (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (@LiftIndir (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric)) (@FF (forall (_ : option val) (_ : environ), mpred) (@LiftNatDed (option val) (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) (RA_return R))) (@cast_expropt CS ret (ret_type Delta)) (@id environ))) *)
    apply andp_ENTAILL; [solve_andp |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F) (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof b)) (@eval_expr CS b)))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof b)) (@eval_expr CS b)))) F) *)
    unfold_lift.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)) F) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)) *)
    intro rho.
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
    simpl.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (local (tc_environ Delta) rho) (@andp mpred Nveric (allp_fun_id Delta rho) (@bupd mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric (@orp mpred Nveric (@later mpred Nveric Iveric (@prop mpred Nveric False)) (RA_return R' (@cast_expropt CS ret (ret_type Delta) rho) (@id environ rho)))))) (@bupd mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric (@orp mpred Nveric (@later mpred Nveric Iveric (@prop mpred Nveric False)) (RA_return R (@cast_expropt CS ret (ret_type Delta) rho) (@id environ rho)))) *)
    forget (cast_expropt ret (ret_type Delta) rho) as vl.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (local (tc_environ Delta) rho) (@andp mpred Nveric (allp_fun_id Delta rho) (@bupd mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric (@orp mpred Nveric (@later mpred Nveric Iveric (@prop mpred Nveric False)) (RA_return R' vl (@id environ rho)))))) (@bupd mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric (@orp mpred Nveric (@later mpred Nveric Iveric (@prop mpred Nveric False)) (RA_return R vl (@id environ rho)))) *)
    revert rho.
    change (local (tc_environ Delta) && (allp_fun_id Delta && (|==> |> FF || RA_return R' vl)) |-- |==> |> FF || RA_return R vl).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_return R' vl))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_return R vl))) *)
    apply derives_full_bupd0_left, H4.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_seq_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R h t,
    @semax CS Espec Delta P (Ssequence h t) R ->
    exists Q, @semax CS Espec Delta P h (overridePost Q R) /\
              @semax CS Espec Delta Q t R.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @semax CS Espec Delta P h (overridePost (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta Q t R)) Q)) R) *)
  remember (Ssequence h t) as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + inv H0.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    exists Q; auto.
  + subst c.
(* Goal: @semax CS Espec Delta P h (overridePost (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta Q t R)) Q)) R) *)
    pose proof IHsemax eq_refl. clear IHsemax.
(* Goal: @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
    destruct H0 as [Q [? ?]].
(* Goal: @ex (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => and (@semax CS Espec Delta P h (overridePost Q R)) (@semax CS Espec Delta Q t R)) *)
    exists Q.
(* Goal: and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)) *)
    split.
    - apply (AuxDefs.semax_conseq _ P' (overridePost Q R')); auto.
      * clear.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (RA_continue (frame_ret_assert R' F)))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue (frame_ret_assert R F)))) *)
        destruct R, R'.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (RA_continue (Build_ret_assert (RA_normal R') (RA_break R') (RA_continue Post') (RA_return R'))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue Post'))) *)
        apply derives_full_refl.
      * destruct R, R'; auto.
      * destruct R, R'; auto.
      * destruct R, R'; auto.
    - eapply semax_conseq; eauto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (RA_continue (Build_ret_assert (RA_normal R') (RA_break R') (RA_continue Post') (RA_return R'))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue Post'))) *)
      apply derives_full_refl.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_seq_inv': forall {CS: compspecs} {Espec: OracleKind} Delta P R h t,
    @semax CS Espec Delta P (Ssequence h t) R ->
    @semax CS Espec Delta P h (overridePost (EX Q: environ -> mpred, !! (@semax CS Espec Delta Q t R) && Q) R).
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @semax CS Espec Delta P h (overridePost (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta Q t R)) Q)) R) *)
  remember (Ssequence h t) as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + inv H0.
(* Goal: @semax CS Espec Delta Q (Sloop body incr) Post' *)
    clear IHsemax1 IHsemax2.
(* Goal: @semax CS Espec Delta P h (overridePost (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta Q t R)) Q)) R) *)
    eapply semax_post_simple; [.. | exact H].
    - destruct R; unfold overridePost, tycontext.RA_normal.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P')) *)
      apply (exp_right Q).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply andp_right; [apply prop_right |]; auto.
    - destruct R; apply derives_refl.
    - destruct R; apply derives_refl.
    - intro; destruct R; apply derives_refl.
  + subst c.
(* Goal: @semax CS Espec Delta P h (overridePost (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta Q t R)) Q)) R) *)
    pose proof IHsemax eq_refl. clear IHsemax.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    eapply AuxDefs.semax_conseq; [.. | exact H0]; auto.
    - unfold overridePost, tycontext.RA_normal.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (let (RA_normal, _, _, _) := match R' with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta Q t R')) Q)) b c r end in RA_normal))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (let (RA_normal, _, _, _) := match R with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta Q t R)) Q)) b c r end in RA_normal))) *)
      destruct R' as [R'0 R'1 R'2 R'3] at 1; clear R'0 R'1 R'2 R'3.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta Q t R')) Q)))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (let (RA_normal, _, _, _) := match R with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta Q t R)) Q)) b c r end in RA_normal))) *)
      destruct R as [R0 R1 R2 R3] at 1; clear R0 R1 R2 R3.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
      reduce2derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta Q t R')) Q)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta Q t R)) Q)) *)
      apply exp_derives.
(* Goal: forall x : forall _ : environ, mpred, @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R')) x) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R)) x) *)
      intros Q.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
      normalize.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta Q t R)) Q) *)
      apply andp_right; [apply prop_right | auto].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      eapply semax_conseq; [.. | apply H6]; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (RA_continue (Build_ret_assert (RA_normal R') (RA_break R') (RA_continue Post') (RA_return R'))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue Post'))) *)
      apply derives_full_refl.
    - destruct R, R'; auto.
    - destruct R, R'; auto.
    - destruct R, R'; auto.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_store_inv: forall {CS: compspecs} {Espec: OracleKind} Delta e1 e2 P Q,
  @semax CS Espec Delta P (Sassign e1 e2) Q ->
  local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || (EX sh: share, !! writable_share sh && |> ( (tc_lvalue Delta e1) &&  (tc_expr Delta (Ecast e2 (typeof e1)))  &&
             ((`(mapsto_ sh (typeof e1)) (eval_lvalue e1)) * (`(mapsto sh (typeof e1)) (eval_lvalue e1) (`force_val (`(sem_cast (typeof e2) (typeof e1)) (eval_expr e2))) -* |==> |> FF || RA_normal Q)))).
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (writable_share sh)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1) : forall _ : val, mpred) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1) : forall (_ : val) (_ : val), mpred) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1) : forall _ : val, option val) (@eval_expr CS e2)))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Q))))))))))) *)
  remember (Sassign e1 e2) as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + inv H0.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
    reduce2derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (writable_share sh)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (writable_share sh)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))))))))) *)
    apply exp_derives; intro sh.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply andp_derives; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply later_derives; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply andp_derives; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply sepcon_derives; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply wand_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))) *)
    eapply derives_trans; [| apply bupd_intro].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))) *)
    apply orp_right2, derives_refl.
  + subst c.
    derives_rewrite -> H.
    derives_rewrite -> (IHsemax eq_refl).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) P (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr f) (eval_var id (type_of_funspec f)))))) *)
    reduceR.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))))))))) *)
    apply exp_ENTAILL; intro sh.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))) *)
    apply andp_ENTAILL; [reduceLL; apply ENTAIL_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))) *)
    apply later_ENTAILL.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))) *)
    apply andp_ENTAILL; [reduceLL; apply ENTAIL_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))) *)
    apply sepcon_ENTAILL; [reduceLL; apply ENTAIL_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))) (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))) *)
    apply wand_ENTAILL; [reduceLL; apply ENTAIL_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))) *)
    apply derives_full_bupd0_left, H1.
Qed.

Lemma tc_fn_return_temp_guard_opt: forall ret retsig Delta,
  tc_fn_return Delta ret retsig ->
  temp_guard_opt Delta ret.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
  destruct ret; hnf in H |- *; [destruct ((temp_types Delta) ! i) |]; auto; congruence.
Qed.

Lemma oboxopt_ENTAILL: forall Delta ret retsig P Q,
  tc_fn_return Delta ret retsig ->
  local (tc_environ Delta) && (allp_fun_id Delta && P) |-- Q ->
  local (tc_environ Delta) && (allp_fun_id Delta && oboxopt Delta ret P) |-- oboxopt Delta ret Q.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
  apply oboxopt_left2'; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
  eapply tc_fn_return_temp_guard_opt; eauto.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_call_inv: forall {CS: compspecs} {Espec: OracleKind} Delta ret a bl Pre Post,
  @semax CS Espec Delta Pre (Scall ret a bl) Post ->
  local (tc_environ Delta) && (allp_fun_id Delta && Pre) |-- |==> |> FF ||
         (EX argsig: _, EX retsig: _, EX cc: _,
          EX A: _, EX P: _, EX Q: _, EX NEP: _, EX NEQ: _, EX ts: _, EX x: _,
         !! (Cop.classify_fun (typeof a) =
             Cop.fun_case_f (type_of_params argsig) retsig cc /\
             (retsig = Tvoid -> ret = None) /\
             tc_fn_return Delta ret retsig) &&
          (|>((tc_expr Delta a) && (tc_exprlist Delta (snd (split argsig)) bl)))  &&
         `(func_ptr (mk_funspec  (argsig,retsig) cc A P Q NEP NEQ)) (eval_expr a) &&
          |>((`(P ts x: environ -> mpred) (make_args' (argsig,retsig) (eval_exprlist (snd (split argsig)) bl))) * oboxopt Delta ret (maybe_retval (Q ts x) retsig ret -* |==> |> FF || RA_normal Post))).
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) Pre)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list (prod ident type)) (fun argsig : list (prod ident type) => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ) : forall _ : val, mpred) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) ((P ts x : forall _ : environ, mpred) : forall _ : environ, mpred) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))))))))))))))) *)
  remember (Scall ret a bl) as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + inv H0.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
    reduce2derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list (prod ident type)) (fun argsig : list (prod ident type) => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list (prod ident type)) (fun argsig : list (prod ident type) => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert R))))))))))))))))))) *)
    apply exp_derives; intro argsig.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert R)))))))))))))))))) *)
    apply exp_derives; intro retsig.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert R))))))))))))))))) *)
    apply exp_derives; intro cc.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert R)))))))))))))))) *)
    apply exp_derives; intro A.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert R))))))))))))))) *)
    apply exp_derives; intro P.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert R)))))))))))))) *)
    apply exp_derives; intro Q.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert R))))))))))))) *)
    apply exp_derives; intro NEP.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert R)))))))))))) *)
    apply exp_derives; intro NEQ.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert R))))))))))) *)
    apply exp_derives; intro ts.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert R)))))))))) *)
    apply exp_derives; intro x.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply andp_derives; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply later_derives; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply sepcon_derives; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply oboxopt_K; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply wand_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))) *)
    eapply derives_trans; [| apply bupd_intro].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))) *)
    apply orp_right2, derives_refl.
  + subst c.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R)))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R)))))))))))))) *)
    rename P into Pre, R into Post.
    derives_rewrite -> H.
    derives_rewrite -> (IHsemax eq_refl); clear IHsemax.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) P (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr f) (eval_var id (type_of_funspec f)))))) *)
    reduceR.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list (prod ident type)) (fun argsig : list (prod ident type) => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list (prod ident type)) (fun argsig : list (prod ident type) => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))))))))))))) *)
    apply exp_ENTAILL; intro argsig.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))))))))))))))) *)
    apply exp_ENTAILL; intro retsig.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))))))))))) *)
    apply exp_ENTAILL; intro cc.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))))))))))))) *)
    apply exp_ENTAILL; intro A.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))))))))) *)
    apply exp_ENTAILL; intro P.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))))))))))) *)
    apply exp_ENTAILL; intro Q.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))))))) *)
    apply exp_ENTAILL; intro NEP.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))))))))) *)
    apply exp_ENTAILL; intro NEQ.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))))) *)
    apply exp_ENTAILL; intro ts.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))))))) *)
    apply exp_ENTAILL; intro x.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
    normalize.
(* Goal: @semax CS Espec Delta P (Ssequence (Ssequence s1 s2) s3) R *)
    destruct H0 as [? [? ?]].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))) *)
    apply andp_ENTAILL; [reduceLL; apply ENTAIL_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))) *)
    apply later_ENTAILL.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))) *)
    apply sepcon_ENTAILL; [reduceLL; apply ENTAIL_refl |].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    eapply oboxopt_ENTAILL; eauto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))) (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))) *)
    apply wand_ENTAILL; [reduceLL; apply ENTAIL_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))) *)
    apply derives_full_bupd0_left, H1.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_Sset_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R id e,
  @semax CS Espec Delta P (Sset id e) R ->
  local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF ||
    ( (|> ( (tc_expr Delta e) &&
             (tc_temp_id id (typeof e) Delta e) &&
             subst id (eval_expr e) (|==> |> FF || RA_normal R))) ||
      (EX cmp: Cop.binary_operation, EX e1: expr, EX e2: expr,
         EX ty: type, EX sh1: share, EX sh2: share,
          !! (e = Ebinop cmp e1 e2 ty /\
              sepalg.nonidentity sh1 /\ sepalg.nonidentity sh2 /\
              is_comparison cmp = true /\
              eqb_type (typeof e1) int_or_ptr_type = false /\
              eqb_type (typeof e2) int_or_ptr_type = false /\
              typecheck_tid_ptr_compare Delta id = true) &&
            ( |> ( (tc_expr Delta e1) &&
              (tc_expr Delta e2)  &&
          local (`(blocks_match cmp) (eval_expr e1) (eval_expr e2)) &&
          (`(mapsto_ sh1 (typeof e1)) (eval_expr e1) * TT) &&
          (`(mapsto_ sh2 (typeof e2)) (eval_expr e2) * TT) &&
          subst id (eval_expr (Ebinop cmp e1 e2 ty)) (|==> |> FF || RA_normal R)))) ||
      (EX sh: share, EX t2: type, EX v2: val,
              !! (typeof_temp Delta id = Some t2 /\
                  is_neutral_cast (typeof e) t2 = true /\
                  readable_share sh) &&
         |> ( (tc_lvalue Delta e) &&
              local (`(tc_val (typeof e) v2)) &&
              (`(mapsto sh (typeof e)) (eval_lvalue e) (`v2) * TT) &&
              subst id (`v2) (|==> |> FF || RA_normal R))) ||
      (EX sh: share, EX e1: expr, EX t1: type, EX v2: val,
              !! (e = Ecast e1 t1 /\
                  typeof_temp Delta id = Some t1 /\
                  cast_pointer_to_bool (typeof e1) t1 = false /\
                  readable_share sh) &&
         |> ( (tc_lvalue Delta e1) &&
              local (`(tc_val t1) (`(eval_cast (typeof e1) t1 v2))) &&
              (`(mapsto sh (typeof e1)) (eval_lvalue e1) (`v2) * TT) &&
              subst id (`(force_val (sem_cast (typeof e1) t1 v2))) (|==> |> FF || RA_normal R)))).
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp : forall (_ : val) (_ : val), Prop) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1) : forall _ : val, mpred) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2) : forall _ : val, mpred) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R)))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2 : Prop)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e) : forall (_ : val) (_ : val), mpred) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1 : forall _ : val, Prop) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2 : val))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1) : forall (_ : val) (_ : val), mpred) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2) : val)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R)))))))))))))) *)
  remember (Sset id e) as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + inv H0.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
    reduce2derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) P))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) P)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))))))) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))))))) *)
    apply orp_derives; [apply orp_derives; [apply orp_derives |] |].
    - apply later_derives.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply andp_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))) *)
      apply subst_derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))) *)
      eapply derives_trans; [| apply bupd_intro].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))) *)
      apply orp_right2, derives_refl.
    - apply exp_derives; intros cmp.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))))) *)
      apply exp_derives; intros e1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))))))))))) *)
      apply exp_derives; intros e2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))))) *)
      apply exp_derives; intros ty.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))))))))) *)
      apply exp_derives; intros sh1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))) *)
      apply exp_derives; intros sh2.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply andp_derives; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply later_derives; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply andp_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))) *)
      apply subst_derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))) *)
      eapply derives_trans; [| apply bupd_intro].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))) *)
      apply orp_right2, derives_refl.
    - apply exp_derives; intros sh.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) P)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))))))))) *)
      apply exp_derives; intros t2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))) *)
      apply exp_derives; intros v2.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply andp_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))) *)
      apply later_derives.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply andp_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))) *)
      apply subst_derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))) *)
      eapply derives_trans; [| apply bupd_intro].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))) *)
      apply orp_right2, derives_refl.
    - apply exp_derives; intros sh.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))))) *)
      apply exp_derives; intros e1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))))))))) *)
      apply exp_derives; intros t1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))) *)
      apply exp_derives; intros v2.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply andp_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))) *)
      apply later_derives.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply andp_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))) *)
      apply subst_derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))) *)
      eapply derives_trans; [| apply bupd_intro].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))) *)
      apply orp_right2, derives_refl.
  + subst c.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R)))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R)))))))))))))) *)
    rename P into Pre, R into Post.
    derives_rewrite -> H.
    derives_rewrite -> (IHsemax eq_refl); clear IHsemax.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) P (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr f) (eval_var id (type_of_funspec f)))))) *)
    reduceR.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))))))) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))))))) *)
    apply orp_ENTAILL; [apply orp_ENTAILL; [apply orp_ENTAILL |] |].
    - apply later_ENTAILL.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))) *)
      unfold tc_temp_id, typecheck_temp_id.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@denote_tc_assert CS match @PTree.get type id (temp_types Delta) with | Some t => tc_andp (tc_bool (is_neutral_cast (implicit_deref (typeof e)) t) (invalid_cast (typeof e) t)) (@isCastResultType CS (implicit_deref (typeof e)) t e) | None => tc_FF (var_not_in_tycontext Delta id) end)) (@subst mpred id (@eval_expr CS e) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@denote_tc_assert CS match @PTree.get type id (temp_types Delta) with | Some t => tc_andp (tc_bool (is_neutral_cast (implicit_deref (typeof e)) t) (invalid_cast (typeof e) t)) (@isCastResultType CS (implicit_deref (typeof e)) t e) | None => tc_FF (var_not_in_tycontext Delta id) end)) (@subst mpred id (@eval_expr CS e) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))) *)
      destruct ((temp_types Delta) ! id) eqn:?H; [| normalize].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))) *)
      eapply andp_subst_ENTAILL; [eauto | | reduceLL; apply ENTAIL_refl |].
      * destruct (is_neutral_cast (implicit_deref (typeof e)) t) eqn:?H; [| normalize].
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
        intro rho; unfold_lift; unfold local, lift1; simpl.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
        normalize.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (allp_fun_id Delta rho) (@andp mpred Nveric (@tc_expr CS Delta e rho) (@denote_tc_assert CS (@isCastResultType CS (implicit_deref (typeof e)) t e) rho))) (@prop mpred Nveric (tc_val' t (@eval_expr CS e rho))) *)
        apply andp_left2, andp_left1.
(* Goal: @derives mpred Nveric (@tc_expr CS Delta e rho) (@prop mpred Nveric (tc_val' t (@eval_expr CS e rho))) *)
        eapply derives_trans; [apply typecheck_expr_sound; auto |].
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
        normalize.
(* Goal: tc_val' t (@eval_expr CS e rho) *)
        intros _.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply expr2.neutral_cast_subsumption'; eauto.
      * apply derives_full_bupd0_left.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
    - apply exp_ENTAILL; intro cmp.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))))) *)
      apply exp_ENTAILL; intro e1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))))))))) *)
      apply exp_ENTAILL; intro e2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))))) *)
      apply exp_ENTAILL; intro ty.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))))))) *)
      apply exp_ENTAILL; intro sh1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))) *)
      apply exp_ENTAILL; intro sh2.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
      normalize.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))) *)
      destruct H0 as [He [? [? [? [? [? ?]]]]]].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))) *)
      apply later_ENTAILL.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))) *)
      unfold typecheck_tid_ptr_compare in H10.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))) *)
      destruct ((temp_types Delta) ! id) eqn:?H; [| inv H10].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))) *)
      eapply andp_subst_ENTAILL; [eauto | | reduceLL; apply ENTAIL_refl |].
      * unfold_lift; unfold local, lift1; intro rho.
        rewrite <- He; simpl.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
        normalize.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (allp_fun_id Delta rho) (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@tc_expr CS Delta e1 rho) (@tc_expr CS Delta e2 rho)) (@prop mpred Nveric (blocks_match cmp (@eval_expr CS e1 rho) (@eval_expr CS e2 rho)))) (@sepcon mpred Nveric Sveric (mapsto_ sh1 (typeof e1) (@eval_expr CS e1 rho)) (@prop mpred Nveric True))) (@sepcon mpred Nveric Sveric (mapsto_ sh2 (typeof e2) (@eval_expr CS e2 rho)) (@prop mpred Nveric True)))) (@prop mpred Nveric (tc_val' t (@eval_expr CS e rho))) *)
        apply andp_left2, andp_left1, andp_left1.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@tc_expr CS Delta e1 rho) (@tc_expr CS Delta e2 rho)) (@prop mpred Nveric (blocks_match cmp (@eval_expr CS e1 rho) (@eval_expr CS e2 rho)))) (@prop mpred Nveric (tc_val' t (@eval_expr CS e rho))) *)
        eapply derives_trans; [apply andp_derives; [| apply derives_refl]; apply andp_derives; apply typecheck_expr_sound; auto |].
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
        normalize.
(* Goal: tc_val' t (@eval_expr CS e rho) *)
        subst e.
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
        simpl.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F) (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof b)) (@eval_expr CS b)))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof b)) (@eval_expr CS b)))) F) *)
        unfold_lift.
(* Goal: tc_val' t (force_val2 (@sem_binary_operation' CS cmp (typeof e1) (typeof e2)) (@eval_expr CS e1 rho) (@eval_expr CS e2 rho)) *)
        replace (sem_binary_operation' cmp) with (sem_cmp (expr.op_to_cmp cmp)); [| destruct cmp; inv H7; auto].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply binop_lemmas2.tc_val'_sem_cmp; auto.
      * apply derives_full_bupd0_left.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
    - apply exp_ENTAILL; intro sh.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))) *)
      apply exp_ENTAILL; intro t2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))) *)
      apply exp_ENTAILL; intro v2.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
      normalize.
(* Goal: @semax CS Espec Delta P (Ssequence (Ssequence s1 s2) s3) R *)
      destruct H0 as [? [? ?]].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))) *)
      apply later_ENTAILL.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))) *)
      unfold typeof_temp in H0.
(* Goal: @eq bool (is_int_type t) true *)
      destruct ((temp_types Delta) ! id) eqn:?H; inv H0.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))) *)
      eapply andp_subst_ENTAILL; [eauto | | reduceLL; apply ENTAIL_refl |].
      * reduceL.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) F (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) *)
        apply andp_left1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl)) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
        apply andp_left2.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
        unfold_lift; unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        intros _; eapply expr2.neutral_cast_subsumption; eauto.
      * apply derives_full_bupd0_left.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
    - apply exp_ENTAILL; intro sh.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))))) *)
      apply exp_ENTAILL; intro e1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))))))) *)
      apply exp_ENTAILL; intro t1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))))) *)
      apply exp_ENTAILL; intro t2.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
      normalize.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))) *)
      destruct H0 as [He [? [? ?]]].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R')))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post)))))) *)
      apply later_ENTAILL.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))) *)
      unfold typeof_temp in H0.
(* Goal: @eq bool (is_int_type t) true *)
      destruct ((temp_types Delta) ! id) eqn:?H; inv H0.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal R'))))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 t2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) t2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 t2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal Post))))) *)
      eapply andp_subst_ENTAILL; [eauto | | reduceLL; apply ENTAIL_refl |].
      * reduceL.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) F (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) *)
        apply andp_left1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl)) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
        apply andp_left2.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
        unfold_lift; unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        intros _; auto.
      * apply derives_full_bupd0_left.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_Sbuiltin_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R opt ext tl el,
  @semax CS Espec Delta P (Sbuiltin opt ext tl el) R -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || FF.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) *)
  remember (Sbuiltin opt ext tl el) as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + reduceL; apply FF_left.
  + derives_rewrite -> H.
    derives_rewrite -> (IHsemax H0).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) *)
    reduceL; apply FF_left.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_Slabel_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R l c,
  @semax CS Espec Delta P (Slabel l c) R -> @semax CS Espec Delta P c R.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @semax CS Espec Delta P c R *)
  remember (Slabel l c) as c0 eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + inv H0.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement (LScons (@Some Z n) s sl))) true *)
    apply H.
  + specialize (IHsemax H0).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    eapply semax_conseq; eauto.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_Sgoto_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R l,
  @semax CS Espec Delta P (Sgoto l) R -> local (tc_environ Delta) && (allp_fun_id Delta && P) |-- |==> |> FF || FF.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) *)
  remember (Sgoto l) as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + reduceL; apply FF_left.
  + derives_rewrite -> H.
    derives_rewrite -> (IHsemax H0).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) *)
    reduceL; apply FF_left.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_ifthenelse_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R b c1 c2,
  @semax CS Espec Delta P (Sifthenelse b c1 c2) R ->
  local (tc_environ Delta) && (allp_fun_id Delta && P) |--
  |==> |> FF || (!! (bool_type (typeof b) = true) && tc_expr Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr)) &&
  EX P': environ -> mpred,
  !! (@semax CS Espec Delta (P' && local (`(typed_true (typeof b)) (eval_expr b))) c1 R /\
      @semax CS Espec Delta (P' && local (`(typed_false (typeof b)) (eval_expr b))) c2 R) &&
  P').
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (bool_type (typeof b)) true)) (@tc_expr CS Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr)))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_true (typeof b) : forall _ : val, Prop) (@eval_expr CS b)))) c1 R) (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof b) : forall _ : val, Prop) (@eval_expr CS b)))) c2 R))) P'))))) *)
  remember (Sifthenelse b c1 c2) as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + inv H0; clear IHsemax1 IHsemax2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
    reduce2derives.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply andp_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_true (typeof b)) (@eval_expr CS b)))) c1 R) (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof b)) (@eval_expr CS b)))) c2 R))) P')) *)
    apply (exp_right P).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) Q) (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) Q) *)
    apply andp_right; [apply prop_right; auto |].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    auto.
  + derives_rewrite -> H.
    derives_rewrite -> (IHsemax H0); clear IHsemax.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
    reduce2derives.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply andp_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R'))) P')) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P')) *)
    apply exp_derives; intros P''.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
    normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply andp_right; auto.
(* Goal: @derives mpred Nveric (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (seplog.func_at f (@pair block Z b Z0)) (P rho)) (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => Vptr b Ptrofs.zero end (Vptr b Ptrofs.zero))) *)
    apply prop_right.
(* Goal: and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)) *)
    destruct H6; split.
    - eapply semax_conseq; eauto. apply derives_full_refl.
    - eapply semax_conseq; eauto. apply derives_full_refl.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_loop_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R body incr,
  @semax CS Espec Delta P (Sloop body incr) R ->
  local (tc_environ Delta) && (allp_fun_id Delta && P) |--
  |==> |> FF || EX Q: environ -> mpred, EX Q': environ -> mpred,
  !! (@semax CS Espec Delta Q body (loop1_ret_assert Q' R) /\
      @semax CS Espec Delta Q' incr (loop2_ret_assert Q R)) &&
  Q.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q))))) *)
  remember (Sloop body incr) as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + inv H0; clear IHsemax1 IHsemax2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
    reduce2derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P')) *)
    apply (exp_right Q).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)) *)
    apply (exp_right Q').
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) Q) (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) Q) *)
    apply andp_right; [apply prop_right; auto |].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    auto.
  + derives_rewrite -> H.
    derives_rewrite -> (IHsemax H0); clear IHsemax.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
    reduce2derives.
(* Goal: forall x : forall _ : environ, mpred, @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R')) x) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R)) x) *)
    apply exp_derives; intros Q.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R')) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R')))) Q)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)) *)
    apply exp_derives; intros Q'.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
    normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply andp_right; [apply prop_right |]; auto.
(* Goal: and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)) *)
    destruct H6.
(* Goal: and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)) *)
    split.
    - destruct R as [nR bR cR rR], R' as [nR' bR' cR' rR']; simpl in H6, H7 |- *.
(* Goal: @semax CS Espec Delta Q' incr (Build_ret_assert Q nR (fun _ : environ => @prop mpred Nveric False) rR) *)
      simpl RA_normal in H1; simpl RA_break in H2; simpl RA_continue in H3; simpl RA_return in H4.
(* Goal: @semax CS Espec Delta Q' incr (Build_ret_assert Q nR (fun _ : environ => @prop mpred Nveric False) rR) *)
      eapply semax_conseq; [.. | eassumption]; unfold loop1_ret_assert.
      * apply derives_full_refl.
      * simpl RA_normal.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (RA_continue (Build_ret_assert (RA_normal R') (RA_break R') (RA_continue Post') (RA_return R'))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue Post'))) *)
        apply derives_full_refl.
      * simpl RA_break.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
      * simpl RA_continue.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (RA_continue (Build_ret_assert (RA_normal R') (RA_break R') (RA_continue Post') (RA_return R'))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue Post'))) *)
        apply derives_full_refl.
      * simpl RA_return.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
    - destruct R as [nR bR cR rR], R' as [nR' bR' cR' rR']; simpl in H6, H7 |- *.
(* Goal: @semax CS Espec Delta Q' incr (Build_ret_assert Q nR (fun _ : environ => @prop mpred Nveric False) rR) *)
      simpl RA_normal in H1; simpl RA_break in H2; simpl RA_continue in H3; simpl RA_return in H4.
(* Goal: @semax CS Espec Delta Q' incr (Build_ret_assert Q nR (fun _ : environ => @prop mpred Nveric False) rR) *)
      eapply semax_conseq; [.. | eassumption]; unfold loop1_ret_assert.
      * apply derives_full_refl.
      * simpl RA_normal.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (RA_continue (Build_ret_assert (RA_normal R') (RA_break R') (RA_continue Post') (RA_return R'))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue Post'))) *)
        apply derives_full_refl.
      * simpl RA_break.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
      * simpl RA_continue.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (RA_continue (Build_ret_assert (RA_normal R') (RA_break R') (RA_continue Post') (RA_return R'))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue Post'))) *)
        apply derives_full_refl.
      * simpl RA_return.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_switch_inv: forall {CS: compspecs} {Espec: OracleKind} Delta P R a sl,
  @semax CS Espec Delta P (Sswitch a sl) R ->
  local (tc_environ Delta) && (allp_fun_id Delta && P) |--
        |==> |> FF || !! (is_int_type (typeof a) = true) && (tc_expr Delta a) &&
        EX P': environ -> mpred,
  !! (forall n,
     @semax CS Espec Delta 
               (local (`eq (eval_expr a) `(Vint n)) && P')
               (seq_of_labeled_statement (select_switch (Int.unsigned n) sl))
               (switch_ret_assert R)) && P'.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  remember (Sswitch a sl) as c eqn:?H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n : val)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))))) *)
  induction H; try solve [inv H0].
  + inv H0.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
    reduce2derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) Q) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@tc_expr CS Delta a)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P'))) *)
    rewrite andp_assoc.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply andp_derives; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply andp_right; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P')) *)
    apply (exp_right Q).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) Q) (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) Q) *)
    apply andp_right; [apply prop_right; auto |].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    auto.
  + derives_rewrite -> H.
    derives_rewrite -> (IHsemax H0); clear IHsemax.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
    reduce2derives.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply andp_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R'))) P')) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) P') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) P')) *)
    apply exp_derives; intros P''.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply andp_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) P'') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R'))) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) P'') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R))) *)
    apply prop_derives; intro.
(* Goal: forall n : Int.int, @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) P'') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R) *)
    intro n; specialize (H6 n).
(* Goal: @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) P'') (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R) *)
    eapply semax_conseq; [.. | exact H6].
    - apply derives_full_refl.
    - destruct R as [nR bR cR rR], R' as [nR' bR' cR' rR'].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (RA_normal (switch_ret_assert (Build_ret_assert nR' bR' cR' rR'))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (switch_ret_assert (Build_ret_assert nR bR cR rR))))) *)
      reduce2derives; apply FF_left.
    - destruct R as [nR bR cR rR], R' as [nR' bR' cR' rR'].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (RA_break (switch_ret_assert (Build_ret_assert nR' bR' cR' rR'))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_break (switch_ret_assert (Build_ret_assert nR bR cR rR))))) *)
      exact H1.
    - destruct R as [nR bR cR rR], R' as [nR' bR' cR' rR'].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (RA_continue (switch_ret_assert (Build_ret_assert nR' bR' cR' rR'))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue (switch_ret_assert (Build_ret_assert nR bR cR rR))))) *)
      exact H3.
    - destruct R as [nR bR cR rR], R' as [nR' bR' cR' rR'].
(* Goal: forall vl : option val, @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (RA_return (switch_ret_assert (Build_ret_assert nR' bR' cR' rR')) vl))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_return (switch_ret_assert (Build_ret_assert nR bR cR rR)) vl))) *)
      exact H4.
Qed.

Module Extr: CLIGHT_SEPARATION_HOARE_LOGIC_EXTRACTION with Module CSHL_Def := CSHL_Def.

Module CSHL_Def := CSHL_Def.
Import CSHL_Def.

Arguments semax {_} {_} _ _ _ _.

Lemma semax_extract_exists:
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  forall {CS: compspecs} {Espec: OracleKind},
  forall (A : Type)  (P : A -> environ->mpred) c (Delta: tycontext) (R: ret_assert),
  (forall x, @semax CS Espec Delta (P x) c R) ->
   @semax CS Espec Delta (EX x:A, P x) c R.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  revert A P R H; induction_stmt c; intros.
  + pose proof (fun x => semax_skip_inv _ _ _ (H x)).
    eapply semax_conseq.
    - rewrite !exp_andp2; apply exp_left.
      intro x.
      apply H0.
    - apply derives_full_refl.
    - apply derives_full_refl.
    - apply derives_full_refl.
    - intros; apply derives_full_refl.
    - eapply semax_post''; [.. | apply AuxDefs.semax_skip].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (RA_normal (normal_ret_assert (RA_normal Q)))) (RA_normal Q) *)
      apply ENTAIL_refl.
  + pose proof (fun x => semax_store_inv _ _ _ _ _ (H x)).
    clear H.
    apply exp_left in H0.
    rewrite <- !(exp_andp2 A) in H0.
    eapply semax_conseq; [exact H0 | intros; apply derives_full_refl .. | clear H0 ].
    eapply semax_conseq; [apply derives_full_refl | .. | apply AuxDefs.semax_store_backward].
    - reduceL. apply derives_refl.
    - reduceL. apply FF_left.
    - reduceL. apply FF_left.
    - intros; reduceL. apply FF_left.
  + pose proof (fun x => semax_Sset_inv _ _ _ _ _ (H x)).
    clear H.
    apply exp_left in H0.
    rewrite <- !(exp_andp2 A) in H0.
    eapply semax_conseq; [exact H0 | intros; apply derives_full_refl .. | clear H0 ].
    eapply semax_conseq; [apply derives_full_refl | .. | apply AuxDefs.semax_set_ptr_compare_load_cast_load_backward].
    - reduceL. apply derives_refl.
    - reduceL. apply FF_left.
    - reduceL. apply FF_left.
    - intros; reduceL. apply FF_left.
  + pose proof (fun x => semax_call_inv _ _ _ _ _ _ (H x)).
    clear H.
    apply exp_left in H0.
    rewrite <- !(exp_andp2 A) in H0.
    eapply semax_conseq; [exact H0 | intros; apply derives_full_refl .. | clear H0 ].
    eapply semax_conseq; [apply derives_full_refl | .. | apply AuxDefs.semax_call_backward].
    - reduceL. apply derives_refl.
    - reduceL. apply FF_left.
    - reduceL. apply FF_left.
    - intros; reduceL. apply FF_left.
  + pose proof (fun x => semax_Sbuiltin_inv _ _ _ _ _ _ _ (H x)).
    eapply semax_conseq; [| intros; apply derives_full_refl .. | apply AuxDefs.semax_builtin].
    rewrite !exp_andp2.
    apply exp_left; intros x; specialize (H0 x).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    auto.
  + apply AuxDefs.semax_seq with (EX Q: environ -> mpred, !! (semax Delta Q c2 R) && Q).
    - apply IHc1.
      intro x.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply semax_seq_inv'; auto.
    - apply IHc2.
(* Goal: forall x : forall _ : environ, mpred, @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R')) x) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R)) x) *)
      intros Q.
      apply semax_pre with (EX H0: semax Delta Q c2 R, Q).
      * apply andp_left2.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
        apply derives_extract_prop; intros.
        apply (exp_right H0).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
      * apply IHc2.
        intro H0.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
  + eapply semax_conseq; [| intros; apply derives_full_refl .. | apply (AuxDefs.semax_ifthenelse _ (EX P': environ -> mpred, !! (semax Delta (P' && local (`(typed_true (typeof e)) (eval_expr e))) c1 R /\ semax Delta (P' && local (`(typed_false (typeof e)) (eval_expr e))) c2 R) && P'))].
    - pose proof (fun x => semax_ifthenelse_inv _ _ _ _ _ _ (H x)).
      clear H.
      apply exp_left in H0.
      rewrite <- !(exp_andp2 A) in H0.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) P')) *)
      exact H0.
    - rewrite exp_andp1.
      apply IHc1.
      intro P'.
      apply semax_pre with (EX H0: semax Delta (P' && local ((` (typed_true (typeof e))) (eval_expr e))) c1 R, P' && local ((` (typed_true (typeof e))) (eval_expr e))).
      * apply andp_left2.
        rewrite !andp_assoc.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
        apply derives_extract_prop; intros.
        apply (exp_right (proj1 H0)).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (local (tc_environ Delta'))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) Q) *)
        solve_andp.
      * apply IHc1.
        intro H0.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
    - rewrite exp_andp1.
      apply IHc2.
      intro P'.
      apply semax_pre with (EX H0: semax Delta (P' && local ((` (typed_false (typeof e))) (eval_expr e))) c2 R, P' && local ((` (typed_false (typeof e))) (eval_expr e))).
      * apply andp_left2.
        rewrite !andp_assoc.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
        apply derives_extract_prop; intros.
        apply (exp_right (proj2 H0)).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (local (tc_environ Delta'))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) Q) *)
        solve_andp.
      * apply IHc2.
        intro H0.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
  + pose proof (fun x => semax_loop_inv _ _ _ _ _ (H x)).
    eapply (AuxDefs.semax_conseq _ 
      (EX Q : environ -> mpred, EX Q' : environ -> mpred,
         EX H: semax Delta Q c1 (loop1_ret_assert Q' R),
           EX H0: semax Delta Q' c2 (loop2_ret_assert Q R), Q));
    [| intros; apply derives_full_refl .. |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
    {
      rewrite !exp_andp2.
      apply exp_left.
      intros x.
      derives_rewrite -> (H0 x).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
      reduce2derives.
(* Goal: forall x : forall _ : environ, mpred, @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R')) x) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R)) x) *)
      apply exp_derives; intros Q.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R')) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R')))) Q)) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)) *)
      apply exp_derives; intros Q'.
      apply derives_extract_prop; intros [? ?].
      apply (exp_right H1).
      apply (exp_right H2).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      auto.
    }
    apply (AuxDefs.semax_loop _ _
      (EX Q : environ -> mpred, EX Q' : environ -> mpred,
         EX H: semax Delta Q c1 (loop1_ret_assert Q' R),
           EX H0: semax Delta Q' c2 (loop2_ret_assert Q R), Q')).
    - apply IHc1.
(* Goal: forall x : forall _ : environ, mpred, @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R')) x) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R)) x) *)
      intros Q.
      apply IHc1.
      intros Q'.
      apply IHc1.
      intros ?H.
      apply IHc1.
      intros ?H.
      eapply semax_post_simple; [.. | exact H1].
      * destruct R as [nR bR cR rR].
        unfold loop1_ret_assert.
        apply (exp_right Q), (exp_right Q'), (exp_right H1), (exp_right H2).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_return (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return) vl) (tycontext.RA_return (Build_ret_assert Q RA_normal Q RA_return) vl) *)
        apply derives_refl.
      * destruct R as [nR bR cR rR].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_return (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return) vl) (tycontext.RA_return (Build_ret_assert Q RA_normal Q RA_return) vl) *)
        apply derives_refl.
      * destruct R as [nR bR cR rR].
        unfold loop1_ret_assert.
        apply (exp_right Q), (exp_right Q'), (exp_right H1), (exp_right H2).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_return (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return) vl) (tycontext.RA_return (Build_ret_assert Q RA_normal Q RA_return) vl) *)
        apply derives_refl.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
      * intros.
        destruct R as [nR bR cR rR].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_return (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return) vl) (tycontext.RA_return (Build_ret_assert Q RA_normal Q RA_return) vl) *)
        apply derives_refl.
    - apply IHc2.
(* Goal: forall x : forall _ : environ, mpred, @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R')) x) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R)) x) *)
      intros Q.
      apply IHc2.
      intros Q'.
      apply IHc2.
      intros ?H.
      apply IHc2.
      intros ?H.
      eapply semax_post_simple; [.. | exact H2].
      * destruct R as [nR bR cR rR].
        unfold loop1_ret_assert.
        apply (exp_right Q), (exp_right Q'), (exp_right H1), (exp_right H2).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_return (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return) vl) (tycontext.RA_return (Build_ret_assert Q RA_normal Q RA_return) vl) *)
        apply derives_refl.
      * destruct R as [nR bR cR rR].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_return (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return) vl) (tycontext.RA_return (Build_ret_assert Q RA_normal Q RA_return) vl) *)
        apply derives_refl.
      * destruct R as [nR bR cR rR].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_return (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return) vl) (tycontext.RA_return (Build_ret_assert Q RA_normal Q RA_return) vl) *)
        apply derives_refl.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
      * intros.
        destruct R as [nR bR cR rR].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_return (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return) vl) (tycontext.RA_return (Build_ret_assert Q RA_normal Q RA_return) vl) *)
        apply derives_refl.
  + pose proof (fun x => semax_break_inv _ _ _ (H x)).
    eapply semax_conseq; [| intros; apply derives_full_refl .. |].
    - rewrite !exp_andp2; apply exp_left.
      intro x; apply H0.
    - apply AuxDefs.semax_break.
  + pose proof (fun x => semax_continue_inv _ _ _ (H x)).
    eapply semax_conseq; [| intros; apply derives_full_refl .. |].
    - rewrite !exp_andp2; apply exp_left.
      intro x; apply H0.
    - apply AuxDefs.semax_continue.
  + pose proof (fun x => semax_return_inv _ _ _ _ (H x)).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
    eapply (semax_conseq _ _ {| RA_normal := _; RA_break := _; RA_continue := _; RA_return := |==> |> FF || RA_return R |}); [.. | apply AuxDefs.semax_return].
    - rewrite !exp_andp2.
      apply exp_left; intros x.
      derives_rewrite -> (H0 x).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (RA_continue (Build_ret_assert (RA_normal R') (RA_break R') (RA_continue Post') (RA_return R'))))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_continue Post'))) *)
      apply derives_full_refl.
    - apply derives_full_refl.
    - apply derives_full_refl.
    - apply derives_full_refl.
    - intros; unfold RA_return at 1. apply derives_full_bupd0_left, derives_full_refl.
  + pose proof (fun x => semax_switch_inv _ _ _ _ _ (H x)).
    eapply semax_conseq; [| intros; apply derives_full_refl .. |].
    - rewrite !exp_andp2; apply exp_left.
      intro x; apply H0.
    - rewrite andp_assoc.
      apply AuxDefs.semax_switch; [intros; simpl; solve_andp |].
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
      intros.
      specialize (IH (Int.unsigned n)).
      rewrite !exp_andp2.
      apply IH.
(* Goal: forall x : forall _ : environ, mpred, Extr.CSHL_Def.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (bool_type (typeof e)) true)) (@tc_expr CS Delta (Eunop Cop.Onotbool e (Tint I32 Signed noattr)))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) x (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_true (typeof e)) (@eval_expr CS e)))) (Ssequence c1 c) Q) (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) x (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof e)) (@eval_expr CS e)))) (Ssequence c2 c) Q))) x)) (Ssequence (Sifthenelse e c1 c2) c) Q *)
      intros P'.
      apply semax_pre with (EX H: forall n0 : int,
           semax Delta (local ((` eq) (eval_expr e) (` (Vint n0))) && P')
             (seq_of_labeled_statement (select_switch (Int.unsigned n0) l))
             (switch_ret_assert R), local ((` eq) (eval_expr e) (` (Vint n))) && P').
      * rewrite (andp_comm (prop _)), <- !andp_assoc, <- (andp_comm (prop _)).
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
        apply derives_extract_prop; intros.
        apply (exp_right H1).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (local (tc_environ Delta'))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) Q) *)
        solve_andp.
      * apply IH.
        intros ?H.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
  + pose proof (fun x => semax_Slabel_inv _ _ _ _ _ (H x)).
(* Goal: @semax CS Espec Delta P (Slabel l (Ssequence c1 c2)) Q *)
    apply AuxDefs.semax_label.
    apply IHc.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    auto.
  + pose proof (fun x => semax_Sgoto_inv _ _ _ _ (H x)).
    eapply semax_conseq; [| intros; apply derives_full_refl .. | apply AuxDefs.semax_goto].
    rewrite !exp_andp2.
    apply exp_left; intros x; specialize (H0 x).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    auto.
Qed.

End Extr.

Module ExtrFacts := GenExtrFacts (CSHL_Def) (Conseq) (Extr).
Module ExtrIFacts := GenIExtrFacts (CSHL_Def) (CConseq) (Extr).

Import Extr ExtrFacts ExtrIFacts.

Module DeepEmbeddedMinimumSeparationLogic <: MINIMUM_CLIGHT_SEPARATION_HOARE_LOGIC with Module CSHL_Def := DeepEmbeddedDef.

Module CSHL_Def := DeepEmbeddedDef.

Module CSHL_Defs := DeepEmbeddedDefs.

Definition semax_extract_exists := @semax_extract_exists.

Definition semax_func_nil := @AuxDefs.semax_func_nil (@Def.semax_external).

Definition semax_func_cons := @AuxDefs.semax_func_cons (@Def.semax_external).

Definition semax_func_cons_ext := @AuxDefs.semax_func_cons_ext (@Def.semax_external).

Theorem semax_ifthenelse :
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  forall {CS: compspecs} {Espec: OracleKind},
   forall Delta P (b: expr) c d R,
      bool_type (typeof b) = true ->
     @semax CS Espec Delta (P && local (`(typed_true (typeof b)) (eval_expr b))) c R ->
     @semax CS Espec Delta (P && local (`(typed_false (typeof b)) (eval_expr b))) d R ->
     @semax CS Espec Delta (tc_expr Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr)) && P) (Sifthenelse b c d) R.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr))) P) (Sifthenelse b c d) R *)
  pose proof @AuxDefs.semax_ifthenelse _ _ _ _ _ _ _ _ H0 H1.
(* Goal: semax CS Espec Delta Q (Sswitch a sl) R *)
  eapply semax_pre_simple; [| exact H2].
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
  normalize.
Qed.

Definition semax_seq := @AuxDefs.semax_seq.

Definition semax_break := @AuxDefs.semax_break.

Definition semax_continue := @AuxDefs.semax_continue.

Definition semax_loop := @AuxDefs.semax_loop.

Theorem semax_switch: 
  forall {CS: compspecs} Espec Delta (Q: environ -> mpred) a sl R,
     is_int_type (typeof a) = true ->
     (forall rho, Q rho |-- tc_expr Delta a rho) ->
     (forall n,
     @semax CS Espec Delta (fun rho => andp (prop (eval_expr a rho = Vint n)) (Q rho))
               (seq_of_labeled_statement (select_switch (Int.unsigned n) sl))
               (switch_ret_assert R)) ->
     @semax CS Espec Delta Q (Sswitch a sl) R.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: semax CS Espec Delta Q (Sswitch a sl) R *)
  pose proof AuxDefs.semax_switch _ _ _ _ _ H0 H1.
(* Goal: semax CS Espec Delta Q (Sswitch a sl) R *)
  eapply semax_pre_simple; [| exact H2].
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
  normalize.
Qed.

Module CallB: CLIGHT_SEPARATION_HOARE_LOGIC_CALL_BACKWARD with Module CSHL_Def := DeepEmbeddedDef.

Module CSHL_Def := DeepEmbeddedDef.

Definition semax_call_backward := @AuxDefs.semax_call_backward.

End CallB.

Module CallF := CallB2F (DeepEmbeddedDef) (Conseq) (CallB).

Definition semax_call := @CallF.semax_call_forward.

Definition semax_return := @AuxDefs.semax_return.

Module Sset: CLIGHT_SEPARATION_HOARE_LOGIC_SSET_BACKWARD with Module CSHL_Def := DeepEmbeddedDef.

Module CSHL_Def := DeepEmbeddedDef.

Definition semax_set_ptr_compare_load_cast_load_backward := @AuxDefs.semax_set_ptr_compare_load_cast_load_backward.

End Sset.

Module SetB := Sset2Set (DeepEmbeddedDef) (Conseq) (Sset).

Module SetF := SetB2F (DeepEmbeddedDef) (Conseq) (SetB).

Definition semax_set_forward := @SetF.semax_set_forward.

Module PtrCmpB := Sset2PtrCmp (DeepEmbeddedDef) (Conseq) (Sset).

Module PtrCmpF := PtrCmpB2F (DeepEmbeddedDef) (Conseq) (PtrCmpB).

Definition semax_ptr_compare := @PtrCmpF.semax_ptr_compare_forward.

Module LoadB := Sset2Load (DeepEmbeddedDef) (Conseq) (Sset).

Module LoadF := LoadB2F (DeepEmbeddedDef) (Conseq) (LoadB).

Definition semax_load := @LoadF.semax_load_forward.

Module CastLoadB := Sset2CastLoad (DeepEmbeddedDef) (Conseq) (Sset).

Module CastLoadF := CastLoadB2F (DeepEmbeddedDef) (Conseq) (CastLoadB).

Definition semax_cast_load := @CastLoadF.semax_cast_load_forward.

Module StoreB: CLIGHT_SEPARATION_HOARE_LOGIC_STORE_BACKWARD with Module CSHL_Def := DeepEmbeddedDef.

Module CSHL_Def := DeepEmbeddedDef.

Definition semax_store_backward := @AuxDefs.semax_store_backward.

End StoreB.

Module StoreF := StoreB2F (DeepEmbeddedDef) (Conseq) (StoreB).

Definition semax_store := @StoreF.semax_store_forward.

Definition semax_skip := @AuxDefs.semax_skip.

Definition semax_conseq := @AuxDefs.semax_conseq.

Definition semax_Slabel := @AuxDefs.semax_label.

Definition semax_ext := @MinimumLogic.semax_ext.

Definition semax_ext_void := @MinimumLogic.semax_ext_void.

Definition semax_external_FF := @MinimumLogic.semax_external_FF.

End DeepEmbeddedMinimumSeparationLogic.

Module DeepEmbeddedPracticalLogic <: PRACTICAL_CLIGHT_SEPARATION_HOARE_LOGIC.

Module CSHL_Def := DeepEmbeddedDef.

Module CSHL_Defs := DeepEmbeddedDefs.

Module CSHL_MinimumLogic := DeepEmbeddedMinimumSeparationLogic.

Definition semax_set := @DeepEmbeddedMinimumSeparationLogic.SetB.semax_set_backward.

Arguments semax {_} {_} _ _ _ _.

Lemma modifiedvars_aux: forall id, (fun i => isSome (insert_idset id idset0) ! i) = eq id.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @eq (forall _ : positive, Prop) (fun i : positive => @isSome unit (@PTree.get unit i (insert_idset id idset0))) (@eq ident id) *)
  extensionality i.
(* Goal: @eq Prop (@isSome unit (@PTree.get unit i (insert_idset id idset0))) (@eq ident id i) *)
  apply prop_ext.
(* Goal: iff (@isSome unit (@PTree.get unit i (insert_idset id idset0))) (@eq ident id i) *)
  unfold insert_idset.
(* Goal: iff (@isSome unit (@PTree.get unit i (@PTree.set unit id tt idset0))) (@eq ident id i) *)
  destruct (ident_eq i id).
  + subst.
(* Goal: iff (@isSome unit (@PTree.get unit id (@PTree.set unit id tt idset0))) (@eq ident id id) *)
    rewrite PTree.gss.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    simpl; tauto.
  + rewrite PTree.gso by auto.
(* Goal: iff (@isSome unit (@PTree.get unit i idset0)) (@eq ident id i) *)
    unfold idset0.
(* Goal: iff (@isSome unit (@PTree.get unit i (PTree.empty unit))) (@eq ident id i) *)
    rewrite PTree.gempty.
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
    simpl.
(* Goal: iff False (@eq ident id i) *)
    split; [tauto | intro].
(* Goal: False *)
    congruence.
Qed.

Lemma sepcon_derives_full: forall Delta P1 P2 Q1 Q2,
  local (tc_environ Delta) && (allp_fun_id Delta && P1) |-- |==> |> FF || P2 ->
  local (tc_environ Delta) && (allp_fun_id Delta && Q1) |-- |==> |> FF || Q2 ->
  local (tc_environ Delta) && (allp_fun_id Delta && (P1 * Q1)) |-- |==> |> FF || (P2 * Q2).
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
  pose proof sepcon_ENTAILL  _ _ _ _ _ H H0.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P1 Q1))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P2 Q2))) *)
  eapply derives_trans; [exact H1 |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) P2)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) Q2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P2 Q2))) *)
  clear.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) P2)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) Q2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P2 Q2))) *)
  eapply derives_trans; [apply bupd_sepcon |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) P2) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) Q2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P2 Q2))) *)
  apply bupd_mono.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) P2) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) Q2)) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P2 Q2)) *)
  rewrite distrib_orp_sepcon, !distrib_orp_sepcon2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) Q2)) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P2 (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P2 Q2))) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P2 Q2)) *)
  repeat apply orp_left.
  + apply orp_right1.
    rewrite <- later_sepcon.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    rewrite FF_sepcon; auto.
  + apply orp_right1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) Q2) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) *)
    rewrite sepcon_comm.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) F (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) F) *)
    apply wand_sepcon_adjoint.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P2 (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) *)
    eapply derives_trans; [apply now_later |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) F (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) F) *)
    apply wand_sepcon_adjoint.
    rewrite <- later_sepcon.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P2 (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) *)
    rewrite sepcon_FF.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    auto.
  + apply orp_right1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) F (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) F) *)
    apply wand_sepcon_adjoint.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P2 (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) *)
    eapply derives_trans; [apply now_later |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) F (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) F) *)
    apply wand_sepcon_adjoint.
    rewrite <- later_sepcon.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P2 (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) *)
    rewrite sepcon_FF.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    auto.
  + apply orp_right2; auto.
Qed.

Lemma semax_frame:
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  forall {CS: compspecs} {Espec: OracleKind},
  forall Delta P s R F,
   closed_wrt_modvars s F ->
  @semax CS Espec Delta P s R ->
    @semax CS Espec Delta (P * F) s (frame_ret_assert R F).
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @semax CS Espec Delta' P c R *)
  induction H0.
  + apply semax_pre with (!! (bool_type (typeof b) = true) && tc_expr Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr)) && (P * F)).
    - normalize.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr))) P) F)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)) *)
      apply andp_left2, andp_right.
      * eapply derives_trans; [apply sepcon_derives; [apply andp_left1 |]; apply derives_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)) F) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)) *)
        intro rho.
(* Goal: @derives mpred Nveric (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@tc_expr CS Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr))) F rho) (@tc_expr CS Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr)) rho) *)
        apply (predicates_sl.extend_sepcon (extend_tc.extend_tc_expr Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr)) rho)).
      * eapply derives_trans; [apply sepcon_derives; [apply andp_left2 |]; apply derives_refl |].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
    - rewrite semax_lemmas.closed_Sifthenelse in H; destruct H.
(* Goal: @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (bool_type (typeof b)) true)) (@tc_expr CS Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr)))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)) (Sifthenelse b c d) (frame_ret_assert R F) *)
      apply AuxDefs.semax_ifthenelse.
      * eapply semax_pre; [| apply IHsemax1; auto].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl)) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
        apply andp_left2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F) (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof b)) (@eval_expr CS b)))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof b)) (@eval_expr CS b)))) F) *)
        unfold_lift.
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
        intro rho; unfold local, lift1; simpl.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
        normalize.
      * eapply semax_pre; [| apply IHsemax2; auto].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl)) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
        apply andp_left2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F) (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof b)) (@eval_expr CS b)))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof b)) (@eval_expr CS b)))) F) *)
        unfold_lift.
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
        intro rho; unfold local, lift1; simpl.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
        normalize.
  + rewrite semax_lemmas.closed_Ssequence in H; destruct H.
    apply AuxDefs.semax_seq with (Q * F).
    - destruct R; apply IHsemax1; auto.
    - destruct R; apply IHsemax2; auto.
  + replace (RA_break Q * F) with (RA_break (frame_ret_assert Q F)) by (destruct Q; auto).
(* Goal: @semax CS Espec Delta (RA_break Post') Sbreak Post' *)
    apply AuxDefs.semax_break.
  + replace (RA_continue Q * F) with (RA_continue (frame_ret_assert Q F)) by (destruct Q; auto).
(* Goal: @semax CS Espec Delta (RA_continue (frame_ret_assert Q F)) Scontinue (frame_ret_assert Q F) *)
    apply AuxDefs.semax_continue.
  + rewrite semax_lemmas.closed_Sloop in H; destruct H.
    eapply AuxDefs.semax_loop with (Q' * F).
    - destruct R; apply IHsemax1; auto.
    - replace (loop2_ret_assert (Q * F) (frame_ret_assert R F))
        with (frame_ret_assert (loop2_ret_assert Q R) F)
        by (destruct R; simpl; f_equal; extensionality rho; apply pred_ext; normalize).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply IHsemax2; auto.
  + rewrite corable_andp_sepcon1 by (apply corable_prop).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    eapply AuxDefs.semax_switch; auto.
    - intro.
(* Goal: @derives mpred Nveric (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) Q F rho) (@tc_expr CS Delta a rho) *)
      eapply derives_trans; [apply sepcon_derives; [apply H0 | apply derives_refl] |].
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@tc_expr CS Delta a rho) (F rho)) (@tc_expr CS Delta a rho) *)
      apply (predicates_sl.extend_sepcon (extend_tc.extend_tc_expr Delta a rho)).
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
    - intros.
      rewrite <- corable_andp_sepcon1 by (intro; apply corable_prop).
      replace (switch_ret_assert (frame_ret_assert R F)) with
        (frame_ret_assert (switch_ret_assert R) F)
        by (destruct R; simpl; f_equal; extensionality rho; apply pred_ext; normalize).
(* Goal: @AuxDefs.semax CS Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) Q) F) (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (frame_ret_assert (switch_ret_assert R) F) *)
      apply (H2 n).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      eapply semax_lemmas.closed_Sswitch; eauto.
  + rewrite frame_normal.
(* Goal: @semax CS Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list (prod ident type)) (fun argsig : list (prod ident type) => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))))))))))) F) (Scall ret a bl) (normal_ret_assert (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F)) *)
    eapply semax_pre; [.. | apply AuxDefs.semax_call_backward; auto].
    - apply andp_left2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))) F) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F))))))) *)
      rewrite exp_sepcon1. apply exp_derives; intros argsig.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))) F) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F))))))) *)
      rewrite exp_sepcon1. apply exp_derives; intros retsig.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))) F) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F))))))) *)
      rewrite exp_sepcon1. apply exp_derives; intros cc.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))) F) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F))))))) *)
      rewrite exp_sepcon1. apply exp_derives; intros A.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))) F) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F))))))) *)
      rewrite exp_sepcon1. apply exp_derives; intros P.
(* Goal: forall x : forall _ : environ, mpred, @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R')) x) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R)) x) *)
      rewrite exp_sepcon1. apply exp_derives; intros Q.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))) F) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F))))))) *)
      rewrite exp_sepcon1. apply exp_derives; intros NEP.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))) F) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F))))))) *)
      rewrite exp_sepcon1. apply exp_derives; intros NEQ.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))) F) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F))))))) *)
      rewrite exp_sepcon1. apply exp_derives; intros ts.
      rewrite exp_sepcon1. apply exp_derives; intros x.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
      normalize.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))) F) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F)))))) *)
      apply andp_right; [apply andp_right |].
      * apply wand_sepcon_adjoint.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) F (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) *)
        apply andp_left1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) F (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) *)
        apply andp_left1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) F (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) F) *)
        apply wand_sepcon_adjoint.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))) F) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F))))) *)
        eapply derives_trans; [apply sepcon_derives; [apply derives_refl | apply now_later] |].
        rewrite <- later_sepcon.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))) *)
        apply later_derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)) F) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)) *)
        intro rho.
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
        simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@tc_expr CS Delta a rho) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl rho)) (F rho)) (@andp mpred Nveric (@tc_expr CS Delta a rho) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl rho)) *)
        apply (predicates_sl.extend_sepcon (extend_tc.extend_andp _ _ (extend_tc.extend_tc_expr Delta a rho) (extend_tc.extend_tc_exprlist Delta (snd (split argsig)) bl rho))).
      * apply wand_sepcon_adjoint.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))) (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) F (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) *)
        apply andp_left1, andp_left2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) F (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) F) *)
        apply wand_sepcon_adjoint.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply derives_left_sepcon_right_corable; auto.
(* Goal: forall x : bool, Extr.CSHL_Def.semax CS Espec Delta (if x then Q1 else Q2) c Q *)
        intro.
(* Goal: @corable mpred Nveric Sveric CSLveric (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a) b) *)
        apply corable_func_ptr.
      * apply wand_sepcon_adjoint.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl)) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
        apply andp_left2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) F (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) F) *)
        apply wand_sepcon_adjoint.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))) F) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F))))) *)
        eapply derives_trans; [apply sepcon_derives; [apply derives_refl | apply now_later] |].
        rewrite <- later_sepcon.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))) *)
        apply later_derives.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        rewrite sepcon_assoc; apply sepcon_derives; auto.

(* Goal: @semax CS Espec Delta P (Ssequence (Ssequence s1 s2) s3) R *)
        destruct H0 as [? [? ?]].
        rewrite <- (oboxopt_closed Delta ret F) at 1 by (try eapply tc_fn_return_temp_guard_opt; eauto).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)) (oboxopt Delta ret F)) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F))) *)
        eapply derives_trans; [apply oboxopt_sepcon |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (oboxopt Delta ret (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R) F)) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) R F))) *)
        apply oboxopt_K.
        rewrite <- (sepcon_emp (maybe_retval _ _ _)) at 2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P) F) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@emp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)) *)
        eapply derives_trans; [| apply wand_frame_hor].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply sepcon_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) F (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) F) *)
        apply wand_sepcon_adjoint.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        rewrite sepcon_emp; auto.
  + eapply semax_pre; [| apply AuxDefs.semax_return].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl)) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
    apply andp_left2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)))) *)
    apply andp_right.
    - intro rho; simpl.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) *)
      eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left1, derives_refl |].
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@tc_expropt CS Delta ret (ret_type Delta) rho) (F rho)) (@tc_expropt CS Delta ret (ret_type Delta) rho) *)
      apply (predicates_sl.extend_sepcon (extend_tc.extend_tc_expropt Delta ret (ret_type Delta) rho)).
    - intro rho; simpl.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))) *)
      eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left2, derives_refl |].
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
      destruct R; simpl.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_return (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return) vl) (tycontext.RA_return (Build_ret_assert Q RA_normal Q RA_return) vl) *)
      apply derives_refl.
  + rewrite frame_normal.
(* Goal: @semax CS Espec Delta' (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) P))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) P)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))))))) (Sset id e) (normal_ret_assert P) *)
    eapply semax_pre; [| apply AuxDefs.semax_set_ptr_compare_load_cast_load_backward].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl)) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
    apply andp_left2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) P))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) P)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))))))) F) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)))))))))) *)
    rewrite !distrib_orp_sepcon.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) P))) F) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P)))))))))) F)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) P))))))) F)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)))))))) F)) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)))))))))) *)
    repeat apply orp_derives.
    - eapply derives_trans; [apply sepcon_derives; [apply derives_refl |]; apply now_later |].
      rewrite <- later_sepcon.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))) *)
      apply later_derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)))) *)
      apply andp_right.
      * intro rho; simpl.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) *)
        eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left1, derives_refl |].
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@tc_expr CS Delta e rho) (@tc_temp_id id (typeof e) CS Delta e rho)) (F rho)) (@andp mpred Nveric (@tc_expr CS Delta e rho) (@tc_temp_id id (typeof e) CS Delta e rho)) *)
        apply (predicates_sl.extend_sepcon (extend_tc.extend_andp _ _ (extend_tc.extend_tc_expr Delta e rho) (extend_tc.extend_tc_temp_id id (typeof e) Delta e rho))).
      * eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left2, derives_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P) F) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)) *)
        rewrite subst_sepcon.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        rewrite (closed_wrt_subst _ _ F); auto.
(* Goal: @closed_wrt_vars mpred (@eq ident id) F *)
        unfold closed_wrt_modvars in H.
        rewrite <- modifiedvars_aux.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
    - rewrite exp_sepcon1; apply exp_derives; intros cmp.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))))) *)
      rewrite exp_sepcon1; apply exp_derives; intros e1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))))))))))) *)
      rewrite exp_sepcon1; apply exp_derives; intros e2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))))) *)
      rewrite exp_sepcon1; apply exp_derives; intros ty.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))))))))) *)
      rewrite exp_sepcon1; apply exp_derives; intros sh1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))) *)
      rewrite exp_sepcon1; apply exp_derives; intros sh2.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
      normalize.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P)))) F) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))) *)
      eapply derives_trans; [apply sepcon_derives; [apply derives_refl |]; apply now_later |].
      rewrite <- later_sepcon.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))) *)
      apply later_derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P)) F) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))) *)
      apply andp_right; [apply andp_right; [apply andp_right; [apply andp_right |] |] |].
      * eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left1, andp_left1, andp_left1, andp_left1, derives_refl |].
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
        intro rho; simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@tc_expr CS Delta e1 rho) (@tc_expr CS Delta e2 rho)) (F rho)) (@andp mpred Nveric (@tc_expr CS Delta e1 rho) (@tc_expr CS Delta e2 rho)) *)
        apply (predicates_sl.extend_sepcon (extend_tc.extend_andp _ _ (extend_tc.extend_tc_expr Delta e1 rho) (extend_tc.extend_tc_expr Delta e2 rho))).
      * unfold local, lift1; unfold_lift; intro rho; simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@tc_expr CS Delta e1 rho) (@tc_expr CS Delta e2 rho)) (@prop mpred Nveric (blocks_match cmp (@eval_expr CS e1 rho) (@eval_expr CS e2 rho)))) (@sepcon mpred Nveric Sveric (mapsto_ sh1 (typeof e1) (@eval_expr CS e1 rho)) (@prop mpred Nveric True))) (@sepcon mpred Nveric Sveric (mapsto_ sh2 (typeof e2) (@eval_expr CS e2 rho)) (@prop mpred Nveric True))) (@subst mpred id (@liftx (Tarrow val (Tarrow val (LiftEnviron val))) (force_val2 (@sem_binary_operation' CS cmp (typeof e1) (typeof e2))) (@eval_expr CS e1) (@eval_expr CS e2)) P rho)) (F rho)) (@prop mpred Nveric (blocks_match cmp (@eval_expr CS e1 rho) (@eval_expr CS e2 rho))) *)
        eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left1, andp_left1, andp_left1, andp_left2, derives_refl |].
        rewrite <- (andp_TT (prop _)) at 1.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
        normalize.
      * eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left1, andp_left1, andp_left2, derives_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric))) F) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric))) *)
        rewrite sepcon_assoc.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply sepcon_derives; auto.
      * eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left1, andp_left2, derives_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric))) F) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric))) *)
        rewrite sepcon_assoc.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply sepcon_derives; auto.
      * eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left2, derives_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P) F) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)) *)
        rewrite subst_sepcon.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        rewrite (closed_wrt_subst _ _ F); auto.
(* Goal: @closed_wrt_vars mpred (@eq ident id) F *)
        unfold closed_wrt_modvars in H.
        rewrite <- modifiedvars_aux.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
    - rewrite exp_sepcon1; apply exp_derives; intros sh.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) P)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))))))))) *)
      rewrite exp_sepcon1; apply exp_derives; intros t2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))) *)
      rewrite exp_sepcon1; apply exp_derives; intros v2.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
      normalize.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P)))) F) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))) *)
      eapply derives_trans; [apply sepcon_derives; [apply derives_refl |]; apply now_later |].
      rewrite <- later_sepcon.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))) *)
      apply later_derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)) F) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))) *)
      apply andp_right; [apply andp_right; [apply andp_right |] |].
      * eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left1, andp_left1, andp_left1, derives_refl |].
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
        intro rho; simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@tc_lvalue CS Delta e rho) (F rho)) (@tc_lvalue CS Delta e rho) *)
        apply (predicates_sl.extend_sepcon (extend_tc.extend_tc_lvalue Delta e rho)).
      * unfold local, lift1; unfold_lift; intro rho; simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@tc_lvalue CS Delta e1 rho) (@prop mpred Nveric (tc_val t1 (force_val (sem_cast (typeof e1) t1 v2))))) (@sepcon mpred Nveric Sveric (mapsto sh (typeof e1) (@eval_lvalue CS e1 rho) v2) (@prop mpred Nveric True))) (@subst mpred id (fun _ : environ => force_val (sem_cast (typeof e1) t1 v2)) P rho)) (F rho)) (@prop mpred Nveric (tc_val t1 (force_val (sem_cast (typeof e1) t1 v2)))) *)
        eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left1, andp_left1, andp_left2, derives_refl |].
        rewrite <- (andp_TT (prop _)) at 1.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
        normalize.
      * eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left1, andp_left2, derives_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric))) F) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric))) *)
        rewrite sepcon_assoc.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply sepcon_derives; auto.
      * eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left2, derives_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P) F) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)) *)
        rewrite subst_sepcon.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        rewrite (closed_wrt_subst _ _ F); auto.
(* Goal: @closed_wrt_vars mpred (@eq ident id) F *)
        unfold closed_wrt_modvars in H.
        rewrite <- modifiedvars_aux.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
    - rewrite exp_sepcon1; apply exp_derives; intros sh.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))))) *)
      rewrite exp_sepcon1; apply exp_derives; intros e1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))))))))) *)
      rewrite exp_sepcon1; apply exp_derives; intros t1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P))))))))) *)
      rewrite exp_sepcon1; apply exp_derives; intros v2.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
      normalize.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P)))) F) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))) *)
      eapply derives_trans; [apply sepcon_derives; [apply derives_refl |]; apply now_later |].
      rewrite <- later_sepcon.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))) *)
      apply later_derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)) F) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))) *)
      apply andp_right; [apply andp_right; [apply andp_right |] |].
      * eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left1, andp_left1, andp_left1, derives_refl |].
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
        intro rho; simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@tc_lvalue CS Delta e1 rho) (F rho)) (@tc_lvalue CS Delta e1 rho) *)
        apply (predicates_sl.extend_sepcon (extend_tc.extend_tc_lvalue Delta e1 rho)).
      * unfold local, lift1; unfold_lift; intro rho; simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@tc_lvalue CS Delta e1 rho) (@prop mpred Nveric (tc_val t1 (force_val (sem_cast (typeof e1) t1 v2))))) (@sepcon mpred Nveric Sveric (mapsto sh (typeof e1) (@eval_lvalue CS e1 rho) v2) (@prop mpred Nveric True))) (@subst mpred id (fun _ : environ => force_val (sem_cast (typeof e1) t1 v2)) P rho)) (F rho)) (@prop mpred Nveric (tc_val t1 (force_val (sem_cast (typeof e1) t1 v2)))) *)
        eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left1, andp_left1, andp_left2, derives_refl |].
        rewrite <- (andp_TT (prop _)) at 1.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
        normalize.
      * eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left1, andp_left2, derives_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric))) F) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric))) *)
        rewrite sepcon_assoc.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply sepcon_derives; auto.
      * eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left2, derives_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P) F) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)) *)
        rewrite subst_sepcon.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        rewrite (closed_wrt_subst _ _ F); auto.
(* Goal: @closed_wrt_vars mpred (@eq ident id) F *)
        unfold closed_wrt_modvars in H.
        rewrite <- modifiedvars_aux.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        auto.
  + rewrite frame_normal.
(* Goal: @semax CS Espec Delta' (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (writable_share sh)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P)))))) (Sassign e1 e2) (normal_ret_assert P) *)
    eapply semax_pre; [| apply AuxDefs.semax_store_backward].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl)) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
    apply andp_left2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_normal (normal_ret_assert P)))))))))))) *)
    rewrite exp_sepcon1; apply exp_derives; intros sh.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
    normalize.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P)))) F) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))) *)
    eapply derives_trans; [apply sepcon_derives; [apply derives_refl |]; apply now_later |].
    rewrite <- later_sepcon.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F))))) *)
    apply later_derives.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P))) F) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)))) *)
    apply andp_right.
    - eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left1, derives_refl |].
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
      intro rho; simpl.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@tc_lvalue CS Delta e1 rho) (@tc_expr CS Delta (Ecast e2 (typeof e1)) rho)) (F rho)) (@andp mpred Nveric (@tc_lvalue CS Delta e1 rho) (@tc_expr CS Delta (Ecast e2 (typeof e1)) rho)) *)
      apply (predicates_sl.extend_sepcon (extend_tc.extend_andp _ _ (extend_tc.extend_tc_lvalue Delta e1 rho) (extend_tc.extend_tc_expr Delta (Ecast e2 (typeof e1)) rho))).
    - eapply derives_trans; [apply sepcon_derives; [| apply derives_refl]; apply andp_left2, derives_refl |].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      rewrite sepcon_assoc; apply sepcon_derives; auto.
      rewrite <- (sepcon_emp ((` (mapsto sh (typeof e1))) (eval_lvalue e1)
                   ((` (force_val oo sem_cast (typeof e2) (typeof e1))) (eval_expr e2)))) at 2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P) F) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) (@emp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) P F)) *)
      eapply derives_trans; [| apply wand_frame_hor].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P) F) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow val (LiftEnviron val)) (@Basics.compose val (option val) val force_val (sem_cast (typeof e2) (typeof e1))) (@eval_expr CS e2))) P) (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@emp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) F)) *)
      apply sepcon_derives; [apply derives_refl |].
      rewrite <- wand_sepcon_adjoint.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      rewrite sepcon_emp; auto.
  + rewrite frame_normal.
(* Goal: @semax CS Espec Delta P Sskip (normal_ret_assert P) *)
    apply AuxDefs.semax_skip.
  + rewrite FF_sepcon.
(* Goal: @semax CS Espec Delta (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (Sbuiltin opt ext tl el) Post' *)
    apply AuxDefs.semax_builtin.
  + apply AuxDefs.semax_label.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply IHsemax; auto.
  + rewrite FF_sepcon.
(* Goal: @semax CS Espec Delta (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) (Sgoto l) Post' *)
    apply AuxDefs.semax_goto.
  + eapply semax_conseq; [.. | apply IHsemax; auto].
    - apply sepcon_derives_full; [exact H0 |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
      reduce2derives.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      auto.
    - destruct R, R'.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (tycontext.RA_normal (frame_ret_assert (Build_ret_assert RA_normal0 RA_break0 RA_continue0 RA_return0) F)))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (tycontext.RA_normal (frame_ret_assert (Build_ret_assert RA_normal RA_break RA_continue RA_return) F)))) *)
      apply sepcon_derives_full; [exact H1 |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
      reduce2derives.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      auto.
    - destruct R, R'.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (tycontext.RA_break (frame_ret_assert (Build_ret_assert RA_normal0 RA_break0 RA_continue0 RA_return0) F)))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (tycontext.RA_break (frame_ret_assert (Build_ret_assert RA_normal RA_break RA_continue RA_return) F)))) *)
      apply sepcon_derives_full; [exact H2 |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
      reduce2derives.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      auto.
    - destruct R, R'.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (tycontext.RA_continue (frame_ret_assert (Build_ret_assert RA_normal0 RA_break0 RA_continue0 RA_return0) F)))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (tycontext.RA_continue (frame_ret_assert (Build_ret_assert RA_normal RA_break RA_continue RA_return) F)))) *)
      apply sepcon_derives_full; [exact H3 |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
      reduce2derives.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      auto.
    - intros; destruct R, R'.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (tycontext.RA_return (frame_ret_assert (Build_ret_assert RA_normal0 RA_break0 RA_continue0 RA_return0) F) vl))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (tycontext.RA_return (frame_ret_assert (Build_ret_assert RA_normal RA_break RA_continue RA_return) F) vl))) *)
      apply sepcon_derives_full; [apply H4 |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) F)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) F)) *)
      reduce2derives.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      auto.
Qed.

Lemma tc_fn_return_sub:
  forall (CS : compspecs) (Delta Delta' : tycontext),
  tycontext_sub Delta Delta' ->
  forall ret retsig,
  tc_fn_return Delta ret retsig ->
  tc_fn_return Delta' ret retsig.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
  hnf in H0 |- *.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
  destruct ret; auto.
(* Goal: @eq bool match @PTree.get type id (temp_types Delta') with | Some t => is_int_type t | None => false end true *)
  destruct H as [? _].
(* Goal: match @PTree.get type i (temp_types Delta') with | Some t' => @eq type retsig t' | None => False end *)
  specialize (H i).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
  destruct ((temp_types Delta) ! i), ((temp_types Delta') ! i); auto.
  + subst; auto.
  + tauto.
Qed.

Lemma obox_sub:
  forall (Delta Delta' : tycontext) id P rho,
    tycontext_sub Delta Delta' ->
    temp_guard Delta id ->
    tc_environ Delta rho ->
    obox Delta id P rho |-- obox Delta' id P rho.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives mpred Nveric (obox Delta id P rho) (obox Delta' id P rho) *)
  unfold obox.
(* Goal: @eq bool match @PTree.get type id (temp_types Delta') with | Some t => is_int_type t | None => false end true *)
  destruct H as [? _].
(* Goal: @eq bool match @PTree.get type id (temp_types Delta') with | Some t => is_int_type t | None => false end true *)
  specialize (H id).
(* Goal: @eq bool match @PTree.get type id (temp_types Delta') with | Some t => is_int_type t | None => false end true *)
  hnf in H0.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
  destruct ((temp_types Delta) ! id), ((temp_types Delta') ! id); auto.
  + subst; auto.
  + tauto.
  + tauto.
Qed.

Lemma oboxopt_sub:
  forall (Delta Delta' : tycontext) id P rho,
    tycontext_sub Delta Delta' ->
    temp_guard_opt Delta id ->
    tc_environ Delta rho ->
    oboxopt Delta id P rho |-- oboxopt Delta' id P rho.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @derives mpred Nveric (oboxopt Delta id P rho) (oboxopt Delta' id P rho) *)
  destruct id.
  + apply obox_sub; auto.
  + simpl.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    auto.
Qed.

Lemma typecheck_tid_ptr_compare_sub: forall Delta Delta' id,
  tycontext_sub Delta Delta' ->
  typecheck_tid_ptr_compare Delta id = true ->
  typecheck_tid_ptr_compare Delta' id = true.
Proof.
(* Goal: forall (Delta Delta' : tycontext) (id : positive) (_ : tycontext_sub Delta Delta') (_ : @eq bool (typecheck_tid_ptr_compare Delta id) true), @eq bool (typecheck_tid_ptr_compare Delta' id) true *)
  unfold typecheck_tid_ptr_compare.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @eq bool match @PTree.get type id (temp_types Delta') with | Some t => is_int_type t | None => false end true *)
  destruct H as [? _].
(* Goal: @eq bool match @PTree.get type id (temp_types Delta') with | Some t => is_int_type t | None => false end true *)
  specialize (H id).
(* Goal: @eq bool match @PTree.get type id (temp_types Delta') with | Some t => is_int_type t | None => false end true *)
  hnf in H0.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
  destruct ((temp_types Delta) ! id), ((temp_types Delta') ! id); auto.
  + subst; auto.
  + inv H0.
Qed.

Theorem semax_extensionality_Delta:
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  forall {CS: compspecs} {Espec: OracleKind},
  forall Delta Delta' P c R,
       tycontext_sub Delta Delta' ->
     @semax CS Espec Delta P c R -> @semax CS Espec Delta' P c R.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @semax CS Espec Delta' P c R *)
  induction H0.
  + apply semax_pre with (!! (bool_type (typeof b) = true) && tc_expr Delta' (Eunop Cop.Onotbool b (Tint I32 Signed noattr)) && P); [| apply AuxDefs.semax_ifthenelse; auto].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P)))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (@tc_expr CS Delta' (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P))) *)
    apply andp_ENTAIL; [| apply ENTAIL_refl].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (writable_share sh)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P)))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (writable_share sh)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (@tc_expr CS Delta' (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P))))) *)
    apply andp_ENTAIL; [apply ENTAIL_refl |].
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
    intro rho; simpl.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
    unfold local, lift1; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply Clight_assert_lemmas.tc_expr_sub; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    eapply semax_lemmas.typecheck_environ_sub; eauto.
  + eapply AuxDefs.semax_seq; eauto.
  + eapply AuxDefs.semax_break; eauto.
  + eapply AuxDefs.semax_continue; eauto.
  + eapply AuxDefs.semax_loop; eauto.
  + eapply semax_pre with (!! (is_int_type (typeof a) = true) && (Q && local (tc_environ Delta'))); [solve_andp |].
(* Goal: @semax CS Espec Delta' (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (is_int_type (typeof a)) true)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (local (tc_environ Delta')))) (Sswitch a sl) R *)
    eapply AuxDefs.semax_switch.
    - intros; simpl.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (Q rho) (local (tc_environ Delta') rho)) (@tc_expr CS Delta' a rho) *)
      rewrite (add_andp _ _ (H0 _)).
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
      unfold local, lift1; normalize.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl)) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
      apply andp_left2.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply Clight_assert_lemmas.tc_expr_sub; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      eapply semax_lemmas.typecheck_environ_sub; eauto.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
    - intros.
(* Goal: @AuxDefs.semax CS Espec Delta' (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (local (tc_environ Delta')))) (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert R) *)
      eapply semax_pre; [| apply H2].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Q (local (tc_environ Delta'))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) Q) *)
      solve_andp.
  + eapply semax_pre; [| apply AuxDefs.semax_call_backward].
(* 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) (list (prod ident type)) (fun argsig : list (prod ident type) => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list (prod ident type)) (fun argsig : list (prod ident type) => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta' ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' a) (@tc_exprlist CS Delta' (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta' ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))))))))))) *)
    apply exp_ENTAIL; intros argsig.
(* 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) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta' ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' a) (@tc_exprlist CS Delta' (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta' ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))))))))))) *)
    apply exp_ENTAIL; intros retsig.
(* 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) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta' ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' a) (@tc_exprlist CS Delta' (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta' ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))))))))) *)
    apply exp_ENTAIL; intros cc.
(* 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) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta' ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' a) (@tc_exprlist CS Delta' (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta' ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))))))))) *)
    apply exp_ENTAIL; intros A.
(* 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) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta' ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' a) (@tc_exprlist CS Delta' (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta' ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))))))) *)
    apply exp_ENTAIL; intros P.
(* Goal: forall x : forall _ : environ, mpred, @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R')) x) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@semax CS Espec Delta x t R)) x) *)
    apply exp_ENTAIL; intros Q.
(* 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) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta' ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' a) (@tc_exprlist CS Delta' (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta' ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))))) *)
    apply exp_ENTAIL; intros NEP.
(* 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) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta' ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' a) (@tc_exprlist CS Delta' (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta' ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))))) *)
    apply exp_ENTAIL; intros NEQ.
(* 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) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A => functors.MixVariantFunctorGenerator.fconst A | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta' ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' a) (@tc_exprlist CS Delta' (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta' ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))) *)
    apply exp_ENTAIL; intros ts.
    apply exp_ENTAIL; intros x.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
    normalize.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta' ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' a) (@tc_exprlist CS Delta' (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta' ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))) *)
    apply andp_ENTAIL; [apply andp_ENTAIL; [apply andp_right; [apply andp_left1 |] |] |].
    - intro rho; unfold local, lift1; normalize.
(* Goal: @derives mpred Nveric (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (seplog.func_at f (@pair block Z b Z0)) (P rho)) (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => Vptr b Ptrofs.zero end (Vptr b Ptrofs.zero))) *)
      simpl; apply prop_right.
(* Goal: and (@eq Cop.classify_fun_cases match typeof a with | Tvoid => Cop.fun_default | Tint i s a => Cop.fun_default | Tlong s a => Cop.fun_default | Tfloat f a => Cop.fun_default | Tpointer (Tvoid as t) a => Cop.fun_default | Tpointer (Tint i s a0 as t) a => Cop.fun_default | Tpointer (Tlong s a0 as t) a => Cop.fun_default | Tpointer (Tfloat f a0 as t) a => Cop.fun_default | Tpointer (Tpointer t0 a0 as t) a => Cop.fun_default | Tpointer (Tarray t0 z a0 as t) a => Cop.fun_default | Tpointer (Tfunction args res cc as t) a => Cop.fun_case_f args res cc | Tpointer (Tstruct i a0 as t) a => Cop.fun_default | Tpointer (Tunion i a0 as t) a => Cop.fun_default | Tarray t z a => Cop.fun_default | Tfunction args res cc => Cop.fun_case_f args res cc | Tstruct i a => Cop.fun_default | Tunion i a => Cop.fun_default end (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta' ret retsig)) *)
      destruct H0; split; [auto |].
(* Goal: and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta' ret retsig) *)
      destruct H2; split; [auto |].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      eapply tc_fn_return_sub; eauto.
    - apply later_ENTAIL.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (@tc_expr CS Delta' (Ecast e2 (typeof e1)))) *)
      apply andp_ENTAIL.
      * intro rho; simpl; unfold local, lift1; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply Clight_assert_lemmas.tc_expr_sub; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply semax_lemmas.typecheck_environ_sub; eauto.
      * intro rho; simpl; unfold local, lift1; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply Clight_assert_lemmas.tc_exprlist_sub; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply semax_lemmas.typecheck_environ_sub; eauto.
    - apply ENTAIL_refl.
    - apply later_ENTAIL.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta' ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))) *)
      apply sepcon_ENTAIL; [apply ENTAIL_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))) (oboxopt Delta' ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R)) *)
      destruct H0 as [_ [_ ?]].
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
      intro rho; simpl.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
      unfold local, lift1; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply oboxopt_sub; auto.
      * eapply tc_fn_return_temp_guard_opt; eauto.
      * eapply semax_lemmas.typecheck_environ_sub; eauto.
  + eapply semax_pre; [| apply AuxDefs.semax_return].
    assert (ret_type Delta = ret_type Delta') by (unfold tycontext_sub in *; tauto).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expropt CS Delta ret (ret_type Delta)) (@liftx (Tarrow (option val) (Tarrow environ (LiftEnviron mpred))) (RA_return R) (@cast_expropt CS ret (ret_type Delta)) (@id environ)))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expropt CS Delta' ret (ret_type Delta')) (@liftx (Tarrow (option val) (Tarrow environ (LiftEnviron mpred))) (RA_return R) (@cast_expropt CS ret (ret_type Delta')) (@id environ))) *)
    rewrite H0.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P)))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (@tc_expr CS Delta' (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P))) *)
    apply andp_ENTAIL; [| apply ENTAIL_refl].
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
    intro rho; simpl.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
    unfold local, lift1; normalize.
(* Goal: @derives mpred Nveric (@tc_expropt CS Delta ret (ret_type Delta') rho) (@tc_expropt CS Delta' ret (ret_type Delta') rho) *)
    destruct ret.
    - apply Clight_assert_lemmas.tc_expr_sub; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      eapply semax_lemmas.typecheck_environ_sub; eauto.
    - simpl; auto.
  + eapply semax_pre; [| apply AuxDefs.semax_set_ptr_compare_load_cast_load_backward].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) P))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) P)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)))))))))) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' e) (@tc_temp_id id (typeof e) CS Delta' e)) (@subst mpred id (@eval_expr CS e) P))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta' id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' e1) (@tc_expr CS Delta' e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta' id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) P)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta' id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))))))) *)
    apply orp_ENTAIL; [apply orp_ENTAIL; [apply orp_ENTAIL |] |].
    - apply later_ENTAIL.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P)))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (@tc_expr CS Delta' (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P))) *)
      apply andp_ENTAIL; [| apply ENTAIL_refl].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (@tc_expr CS Delta' (Ecast e2 (typeof e1)))) *)
      apply andp_ENTAIL.
      * unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply Clight_assert_lemmas.tc_expr_sub; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply semax_lemmas.typecheck_environ_sub; eauto.
      * unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply Clight_assert_lemmas.tc_temp_id_sub; auto.
    - apply exp_ENTAIL; intro cmp.
(* 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) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta' id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))))) *)
      apply exp_ENTAIL; intro e1.
(* 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) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta' id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' e1) (@tc_expr CS Delta' e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P)))))))) *)
      apply exp_ENTAIL; intro e2.
(* 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) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta' id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' e1) (@tc_expr CS Delta' e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))))) *)
      apply exp_ENTAIL; intro ty.
(* 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) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta' id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' e1) (@tc_expr CS Delta' e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P)))))) *)
      apply exp_ENTAIL; intro sh1.
(* 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) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta' id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' e1) (@tc_expr CS Delta' e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))) *)
      apply exp_ENTAIL; intro sh2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta' id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta' e1) (@tc_expr CS Delta' e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P)))) *)
      apply andp_ENTAIL; [| apply later_ENTAIL, andp_ENTAIL; [apply andp_ENTAIL; [apply andp_ENTAIL; [apply andp_ENTAIL; [apply andp_ENTAIL |] |] |] |]].
      * 
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        destruct H1; split; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        destruct H2; split; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        destruct H3; split; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        destruct H4; split; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        destruct H5; split; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        destruct H6; split; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply typecheck_tid_ptr_compare_sub; eauto.
      * unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply Clight_assert_lemmas.tc_expr_sub; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply semax_lemmas.typecheck_environ_sub; eauto.
      * unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply Clight_assert_lemmas.tc_expr_sub; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply semax_lemmas.typecheck_environ_sub; eauto.
      * apply ENTAIL_refl.
      * apply ENTAIL_refl.
      * apply ENTAIL_refl.
      * apply ENTAIL_refl.
    - apply exp_ENTAIL; intro sh.
(* 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) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) P))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta' id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) P)))))) *)
      apply exp_ENTAIL; intro t2.
(* 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 v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta' id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))) *)
      apply exp_ENTAIL; intro v2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta' id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)))) *)
      apply andp_ENTAIL; [| apply later_ENTAIL, andp_ENTAIL; [apply andp_ENTAIL; [apply andp_ENTAIL |] |] ].
      * unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        destruct H1; split; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply Clight_assert_lemmas.typeof_temp_sub; eauto.
      * unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply Clight_assert_lemmas.tc_lvalue_sub; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply semax_lemmas.typecheck_environ_sub; eauto.
      * apply ENTAIL_refl.
      * apply ENTAIL_refl.
      * apply ENTAIL_refl.
    - apply exp_ENTAIL; intro sh.
(* 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) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta' id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))))) *)
      apply exp_ENTAIL; intro e1.
(* 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) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta' id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)))))) *)
      apply exp_ENTAIL; intro t1.
(* 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 v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta' id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))) *)
      apply exp_ENTAIL; intro v2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta' id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P)))) *)
      apply andp_ENTAIL; [| apply later_ENTAIL, andp_ENTAIL; [apply andp_ENTAIL; [apply andp_ENTAIL |] |] ].
      * unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        destruct H1; split; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        destruct H2; split; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply Clight_assert_lemmas.typeof_temp_sub; eauto.
      * unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply Clight_assert_lemmas.tc_lvalue_sub; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply semax_lemmas.typecheck_environ_sub; eauto.
      * apply ENTAIL_refl.
      * apply ENTAIL_refl.
      * apply ENTAIL_refl.
  + eapply semax_pre; [| apply AuxDefs.semax_store_backward].    
(* 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) share (fun sh : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (writable_share sh)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (writable_share sh)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (@tc_expr CS Delta' (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P)))))) *)
    apply exp_ENTAIL; intro sh.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (writable_share sh)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P)))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (writable_share sh)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (@tc_expr CS Delta' (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P))))) *)
    apply andp_ENTAIL; [apply ENTAIL_refl |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (@tc_expr CS Delta' (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P)))) *)
    apply later_ENTAIL.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P)))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (@tc_expr CS Delta' (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P))) *)
    apply andp_ENTAIL; [| apply ENTAIL_refl].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1))))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta' e1) (@tc_expr CS Delta' (Ecast e2 (typeof e1)))) *)
    apply andp_ENTAIL.
    - unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply Clight_assert_lemmas.tc_lvalue_sub; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      eapply semax_lemmas.typecheck_environ_sub; eauto.
    - unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply Clight_assert_lemmas.tc_expr_sub; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      eapply semax_lemmas.typecheck_environ_sub; eauto.
  + apply AuxDefs.semax_skip.
  + apply AuxDefs.semax_builtin.
  + apply AuxDefs.semax_label; auto.
  + apply AuxDefs.semax_goto.
  + eapply semax_conseq; [.. | exact IHsemax].
    - eapply derives_trans; [| exact H0].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply andp_derives; [| apply andp_derives]; auto.
      * unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply semax_lemmas.typecheck_environ_sub; eauto.
      * intro; apply Clight_assert_lemmas.allp_fun_id_sub; auto.
    - eapply derives_trans; [| exact H1].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply andp_derives; [| apply andp_derives]; auto.
      * unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply semax_lemmas.typecheck_environ_sub; eauto.
      * intro; apply Clight_assert_lemmas.allp_fun_id_sub; auto.
    - eapply derives_trans; [| exact H2].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply andp_derives; [| apply andp_derives]; auto.
      * unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply semax_lemmas.typecheck_environ_sub; eauto.
      * intro; apply Clight_assert_lemmas.allp_fun_id_sub; auto.
    - eapply derives_trans; [| exact H3].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply andp_derives; [| apply andp_derives]; auto.
      * unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply semax_lemmas.typecheck_environ_sub; eauto.
      * intro; apply Clight_assert_lemmas.allp_fun_id_sub; auto.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
    - intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta')) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta') (RA_return R' vl))) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (RA_return R vl))) *)
      eapply derives_trans; [| apply H4].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply andp_derives; [| apply andp_derives]; auto.
      * unfold local, lift1; intro rho; simpl; normalize.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        eapply semax_lemmas.typecheck_environ_sub; eauto.
      * intro; apply Clight_assert_lemmas.allp_fun_id_sub; auto.
Qed.

Lemma semax_loop_nocontinue:
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  forall {CS: compspecs} {Espec: OracleKind},
 forall Delta P body incr R,
 @semax CS Espec Delta P (Ssequence body incr) (loop_nocontinue_ret_assert P R) ->
 @semax CS Espec Delta P (Sloop body incr) R.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @semax CS Espec Delta P (Ssequence (Slabel l c1) c2) Q *)
  apply semax_seq_inv in H.
(* Goal: @semax CS Espec Delta P (Sloop body incr) R *)
  destruct H as [Q [? ?]].
(* Goal: @semax CS Espec Delta P (Sloop body incr) R *)
  eapply (AuxDefs.semax_loop _ P Q).
  + clear - H.
    unfold overridePost, loop_nocontinue_ret_assert, loop1_ret_assert in *.
(* Goal: @AuxDefs.semax CS Espec Delta P body match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end *)
    eapply semax_post; [| | | | exact H].
    - apply andp_left2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
      destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_return (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return) vl) (tycontext.RA_return (Build_ret_assert Q RA_normal Q RA_return) vl) *)
      apply derives_refl.
    - apply andp_left2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
      destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_return (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return) vl) (tycontext.RA_return (Build_ret_assert Q RA_normal Q RA_return) vl) *)
      apply derives_refl.
    - apply andp_left2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
      destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_continue (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return)) (tycontext.RA_continue (Build_ret_assert Q RA_normal Q RA_return)) *)
      apply FF_left.
    - intro.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl)) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
      apply andp_left2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
      destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_return (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return) vl) (tycontext.RA_return (Build_ret_assert Q RA_normal Q RA_return) vl) *)
      apply derives_refl.
  + clear - H0.
    unfold overridePost, loop_nocontinue_ret_assert, loop2_ret_assert in *.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    auto.
Qed.

Lemma semax_if_seq:
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
 forall {CS: compspecs} {Espec: OracleKind} Delta P e c1 c2 c Q,
 semax Delta P (Sifthenelse e (Ssequence c1 c) (Ssequence c2 c)) Q ->
 semax Delta P (Ssequence (Sifthenelse e c1 c2) c) Q.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @semax CS Espec Delta P (Ssequence (Sifthenelse e c1 c2) c) Q *)
  apply semax_ifthenelse_inv in H.
(* Goal: @semax CS Espec Delta P (Ssequence (Sifthenelse e c1 c2) c) Q *)
  eapply semax_conseq; [exact H | intros; apply derives_full_refl .. |].
(* Goal: CConseq.CSHL_Def.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (bool_type (typeof e)) true)) (@tc_expr CS Delta (Eunop Cop.Onotbool e (Tint I32 Signed noattr)))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun P' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_true (typeof e)) (@eval_expr CS e)))) (Ssequence c1 c) Q) (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof e)) (@eval_expr CS e)))) (Ssequence c2 c) Q))) P'))) (Ssequence (Sifthenelse e c1 c2) c) Q *)
  rewrite exp_andp2.
(* Goal: @AuxDefs.semax CS Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) bool (fun x : bool => if x then Q1 else Q2)) c Q *)
  apply semax_extract_exists.
(* Goal: forall x : forall _ : environ, mpred, Extr.CSHL_Def.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (bool_type (typeof e)) true)) (@tc_expr CS Delta (Eunop Cop.Onotbool e (Tint I32 Signed noattr)))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) x (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_true (typeof e)) (@eval_expr CS e)))) (Ssequence c1 c) Q) (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) x (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof e)) (@eval_expr CS e)))) (Ssequence c2 c) Q))) x)) (Ssequence (Sifthenelse e c1 c2) c) Q *)
  intros P'.
(* Goal: Extr.CSHL_Def.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (bool_type (typeof e)) true)) (@tc_expr CS Delta (Eunop Cop.Onotbool e (Tint I32 Signed noattr)))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_true (typeof e)) (@eval_expr CS e)))) (Ssequence c1 c) Q) (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof e)) (@eval_expr CS e)))) (Ssequence c2 c) Q))) P')) (Ssequence (Sifthenelse e c1 c2) c) Q *)
  rewrite andp_comm, andp_assoc.
(* Goal: Extr.CSHL_Def.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_true (typeof e)) (@eval_expr CS e)))) (Ssequence c1 c) Q) (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof e)) (@eval_expr CS e)))) (Ssequence c2 c) Q))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (bool_type (typeof e)) true)) (@tc_expr CS Delta (Eunop Cop.Onotbool e (Tint I32 Signed noattr)))))) (Ssequence (Sifthenelse e c1 c2) c) Q *)
  apply semax_extract_prop; intros [? ?].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr f) (eval_var id (type_of_funspec f))) *)
  rewrite andp_comm.
(* Goal: @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  apply semax_seq_inv in H0.
(* Goal: @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  apply semax_seq_inv in H1.
(* Goal: DeepEmbedded.Conseq.CSHL_Def.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (bool_type (typeof e)) true)) (@tc_expr CS Delta (Eunop Cop.Onotbool e (Tint I32 Signed noattr)))) P') (Ssequence (Sifthenelse e c1 c2) c) Q *)
  destruct H0 as [Q1 [? ?]], H1 as [Q2 [? ?]].
(* Goal: DeepEmbedded.Conseq.CSHL_Def.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (bool_type (typeof e)) true)) (@tc_expr CS Delta (Eunop Cop.Onotbool e (Tint I32 Signed noattr)))) P') (Ssequence (Sifthenelse e c1 c2) c) Q *)
  apply AuxDefs.semax_seq with (orp Q1 Q2); [apply AuxDefs.semax_ifthenelse |].
  + eapply semax_post; [| | | | exact H0].
    - destruct Q; apply andp_left2, orp_right1, derives_refl.
    - destruct Q; apply andp_left2, derives_refl.
    - destruct Q; apply andp_left2, derives_refl.
    - intro; destruct Q; apply andp_left2, derives_refl.
  + eapply semax_post; [| | | | exact H1].
    - destruct Q; apply andp_left2, orp_right2, derives_refl.
    - destruct Q; apply andp_left2, derives_refl.
    - destruct Q; apply andp_left2, derives_refl.
    - intro; destruct Q; apply andp_left2, derives_refl.
  + rewrite orp_is_exp.
(* Goal: @AuxDefs.semax CS Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) bool (fun x : bool => if x then Q1 else Q2)) c Q *)
    apply semax_extract_exists.
(* Goal: forall x : bool, Extr.CSHL_Def.semax CS Espec Delta (if x then Q1 else Q2) c Q *)
    intro.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    destruct x; auto.
Qed.

Lemma semax_loop_unroll1:
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  forall {CS: compspecs} {Espec: OracleKind} Delta P P' Q body incr R,
  @semax CS Espec Delta P body (loop1_ret_assert P' R) ->
  @semax CS Espec Delta P' incr (loop2_ret_assert Q R) ->
  @semax CS Espec Delta Q (Sloop body incr) R ->
  @semax CS Espec Delta P (Sloop body incr) R.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @semax CS Espec Delta P (Sloop body incr) R *)
  apply semax_loop_inv in H1.
  apply semax_pre with (P || Q ||
                  (EX Q : environ -> mpred,
                    (EX Q' : environ -> mpred,
                     !! (semax Delta Q body (loop1_ret_assert Q' R) /\
                         semax Delta Q' incr (loop2_ret_assert Q R)) && Q))).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  { apply andp_left2, orp_right1, orp_right1, derives_refl. }
  apply AuxDefs.semax_loop with (P' ||
                  (EX Q : environ -> mpred,
                    (EX Q' : environ -> mpred,
                     !! (semax Delta Q body (loop1_ret_assert Q' R) /\
                         semax Delta Q' incr (loop2_ret_assert Q R)) && Q'))).
  + apply semax_orp; [apply semax_orp |].
    - eapply semax_post; [.. | exact H].
      * unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_continue (Build_ret_assert P' RA_normal P' RA_return))) (tycontext.RA_continue (Build_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q')))) RA_normal (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q')))) RA_return)) *)
        apply andp_left2, orp_right1, derives_refl.
      * unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_return (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl)) (tycontext.RA_return (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl) *)
        apply andp_left2, derives_refl.
      * unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_continue (Build_ret_assert P' RA_normal P' RA_return))) (tycontext.RA_continue (Build_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q')))) RA_normal (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q')))) RA_return)) *)
        apply andp_left2, orp_right1, derives_refl.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
      * intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
        unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_return (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl)) (tycontext.RA_return (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl) *)
        apply andp_left2, derives_refl.
    - eapply semax_conseq; [exact H1 | intros; apply derives_full_refl .. |].
      apply semax_extract_exists; intros Q'.
(* Goal: Extr.CSHL_Def.semax CS Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q'0 : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q' body (loop1_ret_assert Q'0 R)) (@semax CS Espec Delta Q'0 incr (loop2_ret_assert Q' R)))) Q'0)) incr (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) R) *)
      apply semax_extract_exists; intros Q''.
(* Goal: Extr.CSHL_Def.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q' body (loop1_ret_assert Q'' R)) (@semax CS Espec Delta Q'' incr (loop2_ret_assert Q' R)))) Q'') incr (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) R) *)
      apply semax_extract_prop; intros [?H ?H].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply semax_post with (loop1_ret_assert Q'' R); auto.
      * unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_normal (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)))) (tycontext.RA_normal (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return))) *)
        apply andp_left2, orp_right2, (exp_right Q'), (exp_right Q'').
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_normal (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q' body (Build_ret_assert Q'' RA_normal Q'' RA_return)) (@semax CS Espec Delta Q'' incr (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q') *)
        apply andp_right; [apply prop_right; auto | apply derives_refl].
      * unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_return (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl)) (tycontext.RA_return (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl) *)
        apply andp_left2, derives_refl.
      * unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_normal (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)))) (tycontext.RA_normal (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return))) *)
        apply andp_left2, orp_right2, (exp_right Q'), (exp_right Q'').
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_normal (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q' body (Build_ret_assert Q'' RA_normal Q'' RA_return)) (@semax CS Espec Delta Q'' incr (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q') *)
        apply andp_right; [apply prop_right; auto | apply derives_refl].
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
      * intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
        unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_return (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl)) (tycontext.RA_return (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl) *)
        apply andp_left2, derives_refl.
    - apply semax_extract_exists; intros Q'.
(* Goal: Extr.CSHL_Def.semax CS Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q'0 : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q' body (loop1_ret_assert Q'0 R)) (@semax CS Espec Delta Q'0 incr (loop2_ret_assert Q' R)))) Q'0)) incr (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) R) *)
      apply semax_extract_exists; intros Q''.
(* Goal: Extr.CSHL_Def.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q' body (loop1_ret_assert Q'' R)) (@semax CS Espec Delta Q'' incr (loop2_ret_assert Q' R)))) Q'') incr (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) R) *)
      apply semax_extract_prop; intros [?H ?H].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply semax_post with (loop1_ret_assert Q'' R); auto.
      * unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_normal (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)))) (tycontext.RA_normal (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return))) *)
        apply andp_left2, orp_right2, (exp_right Q'), (exp_right Q'').
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_normal (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q' body (Build_ret_assert Q'' RA_normal Q'' RA_return)) (@semax CS Espec Delta Q'' incr (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q') *)
        apply andp_right; [apply prop_right; auto | apply derives_refl].
      * unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_return (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl)) (tycontext.RA_return (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl) *)
        apply andp_left2, derives_refl.
      * unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_normal (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)))) (tycontext.RA_normal (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return))) *)
        apply andp_left2, orp_right2, (exp_right Q'), (exp_right Q'').
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_normal (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q' body (Build_ret_assert Q'' RA_normal Q'' RA_return)) (@semax CS Espec Delta Q'' incr (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q') *)
        apply andp_right; [apply prop_right; auto | apply derives_refl].
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
      * intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
        unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_return (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl)) (tycontext.RA_return (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl) *)
        apply andp_left2, derives_refl.
  + apply semax_orp.
    - apply semax_post with (loop2_ret_assert Q R); auto.
      * unfold loop2_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_normal (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return))) (tycontext.RA_normal (Build_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return))) (@semax CS Espec Delta Q' incr (Build_ret_assert Q RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return)))) Q)))) RA_normal (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) RA_return)) *)
        apply andp_left2, orp_right1, orp_right2, derives_refl.
      * unfold loop2_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_return (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl)) (tycontext.RA_return (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl) *)
        apply andp_left2, derives_refl.
      * unfold loop2_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_return (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl)) (tycontext.RA_return (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl) *)
        apply andp_left2, derives_refl.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
      * intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
        unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_return (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl)) (tycontext.RA_return (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl) *)
        apply andp_left2, derives_refl.
    - apply semax_extract_exists; intros Q'.
(* Goal: Extr.CSHL_Def.semax CS Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q'0 : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q' body (loop1_ret_assert Q'0 R)) (@semax CS Espec Delta Q'0 incr (loop2_ret_assert Q' R)))) Q'0)) incr (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) R) *)
      apply semax_extract_exists; intros Q''.
(* Goal: Extr.CSHL_Def.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q' body (loop1_ret_assert Q'' R)) (@semax CS Espec Delta Q'' incr (loop2_ret_assert Q' R)))) Q'') incr (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) R) *)
      apply semax_extract_prop; intros [?H ?H].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
      apply semax_post with (loop2_ret_assert Q' R); auto.
      * unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_normal (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)))) (tycontext.RA_normal (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return))) *)
        apply andp_left2, orp_right2, (exp_right Q'), (exp_right Q'').
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (tycontext.RA_normal (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q' body (Build_ret_assert Q'' RA_normal Q'' RA_return)) (@semax CS Espec Delta Q'' incr (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q') *)
        apply andp_right; [apply prop_right; auto | apply derives_refl].
      * unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_return (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl)) (tycontext.RA_return (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl) *)
        apply andp_left2, derives_refl.
      * unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_return (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl)) (tycontext.RA_return (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl) *)
        apply andp_left2, derives_refl.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
      * intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (RA_return match match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert P n (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric)) r end with | {| RA_normal := RA_normal; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q b c r end vl) (RA_return match R with | {| RA_normal := n; RA_break := b; RA_continue := c; RA_return := r |} => Build_ret_assert Q n Q r end vl) *)
        unfold loop1_ret_assert; destruct R.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (tycontext.RA_return (loop2_ret_assert Q' (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl)) (tycontext.RA_return (loop2_ret_assert (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (Build_ret_assert Q' RA_normal Q' RA_return)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q (Build_ret_assert RA_normal RA_break RA_continue RA_return))))) Q)))) (Build_ret_assert RA_normal RA_break RA_continue RA_return)) vl) *)
        apply andp_left2, derives_refl.
Qed.

Theorem seq_assoc:
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  forall {CS: compspecs} {Espec: OracleKind},
   forall Delta P s1 s2 s3 R,
        @semax CS Espec Delta P (Ssequence s1 (Ssequence s2 s3)) R <->
        @semax CS Espec Delta P (Ssequence (Ssequence s1 s2) s3) R.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  split; intros.
  + apply semax_seq_inv in H.
(* Goal: @semax CS Espec Delta P (Ssequence (Slabel l c1) c2) Q *)
    destruct H as [? [? ?]].
(* Goal: @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
    apply semax_seq_inv in H0.
(* Goal: @semax CS Espec Delta P (Ssequence (Ssequence s1 s2) s3) R *)
    destruct H0 as [? [? ?]].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    eapply AuxDefs.semax_seq; eauto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    eapply AuxDefs.semax_seq; eauto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    destruct R; auto.
  + apply semax_seq_inv in H.
(* Goal: @semax CS Espec Delta P (Ssequence (Slabel l c1) c2) Q *)
    destruct H as [? [? ?]].
(* Goal: @semax CS Espec Delta P (Ssequence (Slabel l c1) c2) Q *)
    apply semax_seq_inv in H.
(* Goal: @semax CS Espec Delta P (Ssequence (Slabel l c1) c2) Q *)
    destruct H as [? [? ?]].
(* Goal: @semax CS Espec Delta P (Ssequence s1 (Ssequence s2 s3)) R *)
    eapply AuxDefs.semax_seq with x0; [destruct R; exact H |].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    eapply AuxDefs.semax_seq; eauto.
Qed.

Theorem semax_seq_skip:
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  forall {CS: compspecs} {Espec: OracleKind},
  forall Delta P s Q,
    @semax CS Espec Delta P s Q <-> @semax CS Espec Delta P (Ssequence s Sskip) Q.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  split; intros.
  + apply AuxDefs.semax_seq with (RA_normal Q).
    - destruct Q; auto.
    - eapply semax_post; [.. | apply AuxDefs.semax_skip].
      * apply ENTAIL_refl.
      * apply andp_left2, FF_left.
      * apply andp_left2, FF_left.
      * intros; apply andp_left2, FF_left.
  + apply semax_seq_inv in H.
(* Goal: @semax CS Espec Delta P (Ssequence (Slabel l c1) c2) Q *)
    destruct H as [? [? ?]].
(* Goal: @semax CS Espec Delta P s Q *)
    apply semax_skip_inv in H0.
(* Goal: @semax CS Espec Delta P s Q *)
    eapply semax_conseq; [apply derives_full_refl | .. | exact H].
    - destruct Q; auto.
    - destruct Q; apply derives_full_refl.
    - destruct Q; apply derives_full_refl.
    - intros; destruct Q; apply derives_full_refl.
Qed.

Theorem semax_skip_seq:
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  forall {CS: compspecs} {Espec: OracleKind},
  forall Delta P s Q,
    @semax CS Espec Delta P s Q <-> @semax CS Espec Delta P (Ssequence Sskip s) Q.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  split; intros.
  + apply AuxDefs.semax_seq with P; auto.
(* Goal: @AuxDefs.semax CS Espec Delta P Sskip (overridePost P Q) *)
    eapply semax_post; [.. | apply AuxDefs.semax_skip].
    - destruct Q; apply ENTAIL_refl.
    - apply andp_left2, FF_left.
    - apply andp_left2, FF_left.
    - intros; apply andp_left2, FF_left.
  + apply semax_seq_inv in H.
(* Goal: @semax CS Espec Delta P (Ssequence (Slabel l c1) c2) Q *)
    destruct H as [? [? ?]].
(* Goal: @semax CS Espec Delta P s Q *)
    apply semax_skip_inv in H.
(* Goal: @semax CS Espec Delta P s Q *)
    eapply semax_conseq; [| intros; apply derives_full_refl .. | exact H0].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    destruct Q; auto.
Qed.

Theorem semax_seq_Slabel:
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
   forall {CS:compspecs} {Espec: OracleKind},
     forall Delta (P:environ -> mpred) (c1 c2:statement) (Q:ret_assert) l,
   @semax CS Espec Delta P (Ssequence (Slabel l c1) c2) Q <-> 
   @semax CS Espec Delta P (Slabel l (Ssequence c1 c2)) Q.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  split; intros.
  + apply semax_seq_inv in H.
(* Goal: @semax CS Espec Delta P (Ssequence (Slabel l c1) c2) Q *)
    destruct H as [? [? ?]].
(* Goal: @semax CS Espec Delta P (Ssequence (Slabel l c1) c2) Q *)
    apply semax_Slabel_inv in H.
(* Goal: @semax CS Espec Delta P (Slabel l (Ssequence c1 c2)) Q *)
    apply AuxDefs.semax_label.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    eapply AuxDefs.semax_seq; eauto.
  + apply semax_Slabel_inv in H.
(* Goal: @semax CS Espec Delta P (Ssequence (Slabel l c1) c2) Q *)
    apply semax_seq_inv in H.
(* Goal: @semax CS Espec Delta P (Ssequence (Slabel l c1) c2) Q *)
    destruct H as [? [? ?]].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    eapply AuxDefs.semax_seq; eauto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply AuxDefs.semax_label; auto.
Qed.

Fixpoint fold_Ssequence lc :=
  match lc with
  | nil => Sskip
  | c1 :: nil => c1
  | c :: lc0 => Ssequence c (fold_Ssequence lc0)
  end.

Definition non_Sseq c :=
  match c with
  | Ssequence _ _ => False
  | _ => True
  end.

Inductive unfold_Sseq_rel: statement -> list statement -> Prop :=
  | singleton: forall c, non_Sseq c -> unfold_Sseq_rel c (c :: nil)
  | tl_step: forall c1 c2 lc, non_Sseq c1 -> unfold_Sseq_rel c2 lc ->
                 unfold_Sseq_rel (Ssequence c1 c2) (c1 :: lc)
  | hd_step: forall c1 c2 c3 lc, unfold_Sseq_rel (Ssequence c1 (Ssequence c2 c3)) lc ->
                 unfold_Sseq_rel (Ssequence (Ssequence c1 c2) c3) lc
  .

Lemma unfold_Sseq_rel_non_nil: forall {c} {P: Prop}, unfold_Sseq_rel c nil -> P.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: P *)
  remember nil as lc.
(* Goal: @semax_equiv CS Espec (fold_Ssequence lc) c *)
  induction H.
  + congruence.
  + congruence.
  + auto.
Qed.

Definition semax_equiv {CS: compspecs} {Espec: OracleKind} c1 c2: Prop := forall Delta P Q, semax Delta P c1 Q <-> semax Delta P c2 Q.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_equiv_seq: forall {CS: compspecs} {Espec: OracleKind} c1 c2 c3 c4,
  semax_equiv c1 c2 ->
  semax_equiv c3 c4 ->
  semax_equiv (Ssequence c1 c3) (Ssequence c2 c4).
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  hnf; intros; split; intros.
  + apply semax_seq_inv in H1.
(* Goal: @semax CS Espec Delta P (Ssequence c1 c3) Q *)
    destruct H1 as [? [? ?]].
(* Goal: @semax CS Espec Delta P (Ssequence c2 c4) Q *)
    rewrite (H Delta P _) in H1.
(* Goal: @semax CS Espec Delta P (Ssequence c2 c4) Q *)
    rewrite (H0 Delta _ _) in H2.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    eapply AuxDefs.semax_seq; eauto.
  + apply semax_seq_inv in H1.
(* Goal: @semax CS Espec Delta P (Ssequence c1 c3) Q *)
    destruct H1 as [? [? ?]].
    rewrite <- (H Delta P _) in H1.
    rewrite <- (H0 Delta _ _) in H2.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    eapply AuxDefs.semax_seq; eauto.
Qed.

Lemma semax_equiv_sym: forall {CS: compspecs} {Espec: OracleKind} c1 c2, semax_equiv c1 c2 -> semax_equiv c2 c1.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
  hnf in H |- *.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: iff (@semax CS Espec Delta P c1 Q) (@semax CS Espec Delta P c3 Q) *)
  specialize (H Delta P Q).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
  tauto.
Qed.

Lemma semax_equiv_trans: forall {CS: compspecs} {Espec: OracleKind} c1 c2 c3, semax_equiv c1 c2 -> semax_equiv c2 c3 -> semax_equiv c1 c3.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
  hnf in H, H0 |- *.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: iff (@semax CS Espec Delta P c1 Q) (@semax CS Espec Delta P c3 Q) *)
  specialize (H Delta P Q).
(* Goal: iff (@semax CS Espec Delta P c1 Q) (@semax CS Espec Delta P c3 Q) *)
  specialize (H0 Delta P Q).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
  tauto.
Qed.
  
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma unfold_Sseq_rel_sound: forall {CS: compspecs} {Espec: OracleKind} c lc,
  unfold_Sseq_rel c lc -> semax_equiv (fold_Ssequence lc) c.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @semax_equiv CS Espec (fold_Ssequence lc) c *)
  induction H.
  + simpl.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    hnf; intros; tauto.
  + simpl.
(* Goal: @semax_equiv CS Espec match lc with | nil => c1 | cons s l => Ssequence c1 (fold_Ssequence lc) end (Ssequence c1 c2) *)
    destruct lc; [apply (unfold_Sseq_rel_non_nil H0) |].
(* Goal: @semax_equiv CS Espec (Ssequence c1 (fold_Ssequence (@cons statement s lc))) (Ssequence c1 c2) *)
    apply semax_equiv_seq; [hnf; intros; tauto | assumption].
  + eapply semax_equiv_trans; [eauto |].
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
    hnf; intros.
(* Goal: iff (@semax CS Espec Delta P (Ssequence c1 (Ssequence c2 c3)) Q) (@semax CS Espec Delta P (Ssequence (Ssequence c1 c2) c3) Q) *)
    apply seq_assoc.
Qed.

Lemma unfold_Ssequence_unfold_Sseq_rel: forall c, unfold_Sseq_rel c (unfold_Ssequence c).
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
  induction c; try solve [apply singleton, I].
  revert c2 IHc2.
  clear IHc1.
  induction c1; intros; try solve [apply tl_step; [apply I | auto]].
  apply hd_step.
  replace (unfold_Ssequence (Ssequence (Ssequence c1_1 c1_2) c2)) with
    (unfold_Ssequence (Ssequence c1_1 (Ssequence c1_2 c2))).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  2:{
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
    simpl.
    rewrite <- app_assoc.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement (select_switch_default LSnil))) true *)
    reflexivity.
  }
  apply IHc1_1.
  apply IHc1_2.
  apply IHc2.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma unfold_Ssequence_sound: forall {CS: compspecs} {Espec: OracleKind} c, semax_equiv (fold_Ssequence (unfold_Ssequence c)) c.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @semax_equiv CS Espec (fold_Ssequence (unfold_Ssequence c)) c *)
  apply unfold_Sseq_rel_sound.
(* Goal: unfold_Sseq_rel c (unfold_Ssequence c) *)
  apply unfold_Ssequence_unfold_Sseq_rel.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_unfold_Ssequence': forall {CS: compspecs} {Espec: OracleKind} c1 c2,
  unfold_Ssequence c1 = unfold_Ssequence c2 ->
  (forall P Q Delta, semax Delta P c1 Q <-> semax Delta P c2 Q).
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
  eapply semax_equiv_trans.
  + apply semax_equiv_sym.
    apply unfold_Ssequence_sound.
  + rewrite H.
    apply unfold_Ssequence_sound.
Qed.

(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
Lemma semax_unfold_Ssequence: forall {CS: compspecs} {Espec: OracleKind} c1 c2,
  unfold_Ssequence c1 = unfold_Ssequence c2 ->
  (forall P Q Delta, @semax CS Espec Delta P c1 Q -> @semax CS Espec Delta P c2 Q).
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @semax CS Espec Delta P c2 Q *)
  pose proof semax_unfold_Ssequence' _ _ H.
  clear - H0 H1.
(* Goal: @semax CS Espec Delta P c2 Q *)
  firstorder.
Qed.

Lemma semax_fun_id:
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) P) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) *)
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P Q) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q : forall _ : environ, mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall _ : environ, mpred) (fun Q' : forall _ : environ, mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta Q body (loop1_ret_assert Q' R)) (@semax CS Espec Delta Q' incr (loop2_ret_assert Q R)))) Q)))) (Sloop body incr) R *)
  forall {CS: compspecs} {Espec: OracleKind},
      forall id f Delta P Q c,
    (var_types Delta) ! id = None ->
    (glob_specs Delta) ! id = Some f ->
    (glob_types Delta) ! id = Some (type_of_funspec f) ->
    @semax CS Espec Delta (P && `(func_ptr f) (eval_var id (type_of_funspec f)))
                  c Q ->
    @semax CS Espec Delta P c Q.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @semax CS Espec Delta P c Q *)
  eapply semax_conseq; [| intros; apply derives_full_refl .. | apply H2].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@bupd (forall _ : environ, mpred) own.gname compcert_rmaps.RML.R.preds (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@LiftBupdSepLog environ mpred own.gname compcert_rmaps.RML.R.preds Nveric Sveric Bveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@FF (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric))) (@andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) P (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr f) (eval_var id (type_of_funspec f)))))) *)
  reduceR.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@andp (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) P (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr f) (eval_var id (type_of_funspec f)))) *)
  apply andp_right; [solve_andp |].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P)) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr f) (eval_var id (type_of_funspec f))) *)
  rewrite andp_comm.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P) (@imp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr f) (eval_var id (type_of_funspec f)))) *)
  rewrite imp_andp_adjoint.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) P) (@imp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr f) (eval_var id (type_of_funspec f)))) *)
  rewrite imp_andp_adjoint.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (allp_fun_id Delta) (@imp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@imp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr f) (eval_var id (type_of_funspec f))))) *)
  apply (allp_left _ id).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@allp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) funspec (fun fs : funspec => @imp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq (option funspec) (@PTree.get funspec id (glob_specs Delta)) (@Some funspec fs))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) block (fun b : block => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow (option block) (Tarrow (option block) (LiftEnviron Prop))) (@eq (option block)) (fun rho : lift_S (Tarrow (option block) (LiftEnviron Prop)) => @Map.get block (ge_of rho) id) (@liftx (LiftEnviron (option block)) (@Some block b)))) (@liftx (LiftEnviron (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap)) (seplog.func_at fs (@pair block Z b Z0))))))) (@imp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@imp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr f) (eval_var id (type_of_funspec f))))) *)
  apply (allp_left _ f).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
  rewrite prop_imp by auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) block (fun b : block => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow (option block) (Tarrow (option block) (LiftEnviron Prop))) (@eq (option block)) (fun rho : lift_S (Tarrow (option block) (LiftEnviron Prop)) => @Map.get block (ge_of rho) id) (@liftx (LiftEnviron (option block)) (@Some block b)))) (@liftx (LiftEnviron (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap)) (seplog.func_at f (@pair block Z b Z0))))) (@imp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P (@imp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr f) (eval_var id (type_of_funspec f))))) *)
  apply exp_left; intros b.
  rewrite <- imp_andp_adjoint.
  rewrite <- imp_andp_adjoint.
(* Goal: @semax_equiv CS Espec (fold_Ssequence (@cons statement c1 lc)) (Ssequence c1 c2) *)
  unfold local, lift1; unfold_lift; intro rho; simpl.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (func_ptr f (eval_var id (type_of_funspec f) rho)) *)
  unfold eval_var, func_ptr.
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@exp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric block (fun b : block => @andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b0 ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b0 Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b0 => Vptr b0 Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0)))) *)
  apply (exp_right b).
(* Goal: @derives mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@andp mpred Nveric (@prop mpred Nveric (@eq (option block) (@Map.get block (ge_of rho) id) (@Some block b))) (seplog.func_at f (@pair block Z b Z0))) (P rho)) (@prop mpred Nveric (tc_environ Delta rho))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
  normalize.
(* Goal: @derives mpred Nveric (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (seplog.func_at f (@pair block Z b Z0)) (P rho)) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) id with | Some b => Vptr b Ptrofs.zero | None => Vundef end end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
  rewrite H3.
(* Goal: @derives mpred Nveric (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (seplog.func_at f (@pair block Z b Z0)) (P rho)) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => Vptr b Ptrofs.zero end (Vptr b Ptrofs.zero))) (seplog.func_at f (@pair block Z b Z0))) *)
  apply andp_right; [| solve_andp].
(* Goal: @derives mpred Nveric (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (seplog.func_at f (@pair block Z b Z0)) (P rho)) (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => Vptr b Ptrofs.zero end (Vptr b Ptrofs.zero))) *)
  apply prop_right.
(* Goal: @eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => Vptr b Ptrofs.zero end (Vptr b Ptrofs.zero) *)
  destruct H4 as [_ [? _]].
(* Goal: @eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => Vptr b Ptrofs.zero end (Vptr b Ptrofs.zero) *)
  specialize (H4 id).
(* Goal: @eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => Vptr b Ptrofs.zero end (Vptr b Ptrofs.zero) *)
  rewrite H in H4.
(* Goal: @eq val match @Map.get (prod block type) (ve_of rho) id with | Some (pair b ty' as p) => if eqb_type (type_of_funspec f) ty' then Vptr b Ptrofs.zero else Vundef | None => Vptr b Ptrofs.zero end (Vptr b Ptrofs.zero) *)
  destruct (Map.get (ve_of rho) id) as [[? ?] |]; [exfalso | auto].
(* Goal: False *)
  specialize (H4 t).
(* Goal: False *)
  destruct H4 as [_ ?].
(* Goal: False *)
  specialize (H4 ltac:(eexists; eauto)).
(* Goal: False *)
  congruence.
Qed.

Lemma nocontinue_ls_spec: forall sl, nocontinue_ls sl = true -> nocontinue (seq_of_labeled_statement sl) = true.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement (select_switch_default sl))) true *)
  induction sl.
  + reflexivity.
  + simpl in *.
(* Goal: @eq bool (if nocontinue s then nocontinue (seq_of_labeled_statement sl) else false) true *)
    destruct (nocontinue s); [| inv H].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    auto.
Qed.

Lemma nocontinue_ls_spec': forall sl n, nocontinue_ls sl = true -> nocontinue (seq_of_labeled_statement (select_switch n sl)) = true.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement (select_switch n sl))) true *)
  apply nocontinue_ls_spec in H.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement (select_switch n sl))) true *)
  unfold select_switch.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement match select_switch_case n sl with | Some sl' => sl' | None => select_switch_default sl end)) true *)
  destruct (select_switch_case n sl) eqn:?Hs.
  + induction sl.
    - inv Hs.
    - simpl in Hs.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement l)) true *)
      destruct o as [c|]; [destruct (zeq c n) |].
      * subst c; inv Hs.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement (LScons (@Some Z n) s sl))) true *)
        apply H.
      * change (nocontinue s && nocontinue (seq_of_labeled_statement sl) = true)%bool in H.
(* Goal: @semax CS Espec Delta P (Ssequence h t) Post' *)
        rewrite andb_true_iff in H.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply IHsl; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        tauto.
      * change (nocontinue s && nocontinue (seq_of_labeled_statement sl) = true)%bool in H.
(* Goal: @semax CS Espec Delta P (Ssequence h t) Post' *)
        rewrite andb_true_iff in H.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        apply IHsl; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
        tauto.
  + induction sl.
    - reflexivity.
    - simpl in Hs |- *.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement match o with | Some i => select_switch_default sl | None => LScons o s sl end)) true *)
      destruct o.
      * change (nocontinue s && nocontinue (seq_of_labeled_statement sl) = true)%bool in H.
(* Goal: @semax CS Espec Delta P (Ssequence h t) Post' *)
        rewrite andb_true_iff in H.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement (select_switch_default sl))) true *)
        apply IHsl; [tauto |].
(* Goal: @eq (option labeled_statements) (select_switch_case n sl) (@None labeled_statements) *)
        if_tac in Hs; [inv Hs | auto].
      * exact H.
Qed.

Lemma semax_nocontinue_inv:
  forall CS Espec Delta Pre s Post Post',
    nocontinue s = true ->
    RA_normal Post = RA_normal Post' ->
    RA_break Post = RA_break Post' ->
    RA_return Post = RA_return Post' ->
    @semax CS Espec Delta Pre s Post -> @semax CS Espec Delta Pre s Post'.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  intros.
(* Goal: @semax CS Espec Delta Pre s Post' *)
  revert Post' H0 H1 H2.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
  induction H3; intros.
  + change (nocontinue c && nocontinue d = true)%bool in H.
(* Goal: @semax CS Espec Delta P (Ssequence h t) Post' *)
    rewrite andb_true_iff in H.
(* Goal: @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (bool_type (typeof b)) true)) (@tc_expr CS Delta (Eunop Cop.Onotbool b (Tint I32 Signed noattr)))) P) (Sifthenelse b c d) Post' *)
    specialize (IHsemax1 (proj1 H) _ H0 H1 H2).
(* Goal: @semax CS Espec Delta P (Ssequence h t) Post' *)
    specialize (IHsemax2 (proj2 H) _ H0 H1 H2).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply AuxDefs.semax_ifthenelse; auto.
  + change (nocontinue h && nocontinue t = true)%bool in H.
(* Goal: @semax CS Espec Delta P (Ssequence h t) Post' *)
    rewrite andb_true_iff in H.
(* Goal: @semax CS Espec Delta P (Ssequence h t) Post' *)
    specialize (IHsemax1 (proj1 H)).
(* Goal: @semax CS Espec Delta P (Ssequence h t) Post' *)
    specialize (IHsemax2 (proj2 H) _ H0 H1 H2).
(* Goal: @semax CS Espec Delta P (Ssequence h t) Post' *)
    eapply AuxDefs.semax_seq; [| eauto].
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply IHsemax1; destruct Post', R; auto.
  + rewrite H1.
(* Goal: @semax CS Espec Delta (RA_break Post') Sbreak Post' *)
    apply AuxDefs.semax_break.
  + inv H.
  + clear IHsemax1 IHsemax2.
    replace (loop1_ret_assert Q' R) with (loop1_ret_assert Q' Post') in H3_
      by (destruct Post', R; simpl; f_equal; auto).
    replace (loop2_ret_assert Q R) with (loop2_ret_assert Q Post') in H3_0
      by (destruct Post', R; simpl; f_equal; auto).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    eapply AuxDefs.semax_loop; eauto.
  + apply AuxDefs.semax_switch; auto.
(* Goal: forall n : Int.int, @AuxDefs.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) Q) (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert Post') *)
    intros n; specialize (H2 n).
(* Goal: @AuxDefs.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) Q) (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert Post') *)
    simpl in H.
(* Goal: @AuxDefs.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) Q) (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert Post') *)
    apply (nocontinue_ls_spec' _ (Int.unsigned n)) in H.
(* Goal: @AuxDefs.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (@eq val) (@eval_expr CS a) (@liftx (LiftEnviron val) (Vint n)))) Q) (seq_of_labeled_statement (select_switch (Int.unsigned n) sl)) (switch_ret_assert Post') *)
    specialize (H2 H).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply H2; destruct Post', R; simpl; auto.
  + eapply semax_post with (normal_ret_assert R);
      [intros; apply andp_left2; try apply FF_left; rewrite H0; auto .. |].
(* Goal: @semax CS Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list (prod ident type)) (fun argsig : list (prod ident type) => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun retsig : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) calling_convention (fun cc : calling_convention => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) rmaps.TypeTree (fun A : rmaps.TypeTree => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun P : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred) (fun Q : forall ts : list Type, functors.MixVariantFunctor._functor (rmaps.dependent_type_functor_rec ts (AssertTT A)) mpred => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A P) (fun NEP : @super_non_expansive A P => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@super_non_expansive A Q) (fun NEQ : @super_non_expansive A Q => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (list Type) (fun ts : list Type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred) (fun x : functors.MixVariantFunctor._functor ((fix dtfr (T : rmaps.TypeTree) : functors.MixVariantFunctor.functor := match T with | rmaps.ConstType A0 => functors.MixVariantFunctorGenerator.fconst A0 | rmaps.Mpred => functors.MixVariantFunctorGenerator.fidentity | rmaps.DependentType n => functors.MixVariantFunctorGenerator.fconst (@nth Type n ts unit) | rmaps.ProdType T1 T2 => functors.MixVariantFunctorGenerator.fpair (dtfr T1) (dtfr T2) | rmaps.ArrowType T1 T2 => functors.MixVariantFunctorGenerator.ffunc (dtfr T1) (dtfr T2) | rmaps.PiType I0 f => @functors.MixVariantFunctorGenerator.fpi I0 (fun i : I0 => dtfr (f i)) | rmaps.ListType T0 => functors.MixVariantFunctorGenerator.flist (dtfr T0) end) A) mpred => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq Cop.classify_fun_cases (Cop.classify_fun (typeof a)) (Cop.fun_case_f (type_of_params argsig) retsig cc)) (and (forall _ : @eq type retsig Tvoid, @eq (option ident) ret (@None ident)) (tc_fn_return Delta ret retsig)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta a) (@tc_exprlist CS Delta (@snd (list ident) (list type) (@split ident type argsig)) bl)))) (@liftx (Tarrow val (LiftEnviron mpred)) (func_ptr (mk_funspec (@pair (list (prod ident type)) type argsig retsig) cc A P Q NEP NEQ)) (@eval_expr CS a))) (@later (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow environ (LiftEnviron mpred)) (P ts x) (make_args' (@pair (list (prod ident type)) type argsig retsig) (@eval_exprlist CS (@snd (list ident) (list type) (@split ident type argsig)) bl))) (oboxopt Delta ret (@wand (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (maybe_retval (Q ts x) retsig ret) R))))))))))))))) (Scall ret a bl) (normal_ret_assert R) *)
    apply AuxDefs.semax_call_backward.
  + rewrite H2.
(* Goal: @semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expropt CS Delta ret (ret_type Delta)) (@liftx (Tarrow (option val) (Tarrow environ (LiftEnviron mpred))) (RA_return Post') (@cast_expropt CS ret (ret_type Delta)) (@id environ))) (Sreturn ret) Post' *)
    apply AuxDefs.semax_return.
  + eapply semax_post with (normal_ret_assert P);
      [intros; apply andp_left2; try apply FF_left; rewrite H0; auto .. |].
(* Goal: @semax CS Espec Delta (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@orp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e) (@tc_temp_id id (typeof e) CS Delta e)) (@subst mpred id (@eval_expr CS e) P))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) Cop.binary_operation (fun cmp : Cop.binary_operation => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e2 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun ty : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh1 : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh2 : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ebinop cmp e1 e2 ty)) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh1) (and (@sepalg.nonidentity share Share.Join_ba pa_share sh2) (and (@eq bool (is_comparison cmp) true) (and (@eq bool (eqb_type (typeof e1) int_or_ptr_type) false) (and (@eq bool (eqb_type (typeof e2) int_or_ptr_type) false) (@eq bool (typecheck_tid_ptr_compare Delta id) true)))))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_expr CS Delta e1) (@tc_expr CS Delta e2)) (local (@liftx (Tarrow val (Tarrow val (LiftEnviron Prop))) (blocks_match cmp) (@eval_expr CS e1) (@eval_expr CS e2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh1 (typeof e1)) (@eval_expr CS e1)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh2 (typeof e2)) (@eval_expr CS e2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@eval_expr CS (Ebinop cmp e1 e2 ty)) P))))))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t2 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq (option type) (typeof_temp Delta id) (@Some type t2)) (and (@eq bool (is_neutral_cast (typeof e) t2) true) (readable_share sh)))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e) (local (@liftx (LiftEnviron Prop) (tc_val (typeof e) v2)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e)) (@eval_lvalue CS e) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) v2) P)))))))) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) expr (fun e1 : expr => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) type (fun t1 : type => @exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun v2 : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@eq expr e (Ecast e1 t1)) (and (@eq (option type) (typeof_temp Delta id) (@Some type t1)) (and (@eq bool (cast_pointer_to_bool (typeof e1) t1) false) (readable_share sh))))) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (local (@liftx (Tarrow val (LiftEnviron Prop)) (tc_val t1) (@liftx (LiftEnviron val) (eval_cast (typeof e1) t1 v2))))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (LiftEnviron val) v2)) (@TT (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric)))) (@subst mpred id (@liftx (LiftEnviron val) (force_val (sem_cast (typeof e1) t1 v2))) P))))))))) (Sset id e) (normal_ret_assert P) *)
    apply AuxDefs.semax_set_ptr_compare_load_cast_load_backward.
  + eapply semax_post with (normal_ret_assert P);
      [intros; apply andp_left2; try apply FF_left; rewrite H0; auto .. |].
(* Goal: @semax CS Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) share (fun sh : share => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (writable_share sh)) (@later (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftIndir environ mpred Nveric Iveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@tc_lvalue CS Delta e1) (@tc_expr CS Delta (Ecast e2 (typeof e1)))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (LiftEnviron mpred)) (mapsto_ sh (typeof e1)) (@eval_lvalue CS e1)) (@wand (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (Tarrow val (Tarrow val (LiftEnviron mpred))) (mapsto sh (typeof e1)) (@eval_lvalue CS e1) (@liftx (Tarrow (option val) (LiftEnviron val)) force_val (@liftx (Tarrow val (LiftEnviron (option val))) (sem_cast (typeof e2) (typeof e1)) (@eval_expr CS e2)))) P)))))) (Sassign e1 e2) (normal_ret_assert P) *)
    apply AuxDefs.semax_store_backward.
  + eapply semax_post with (normal_ret_assert P);
      [intros; apply andp_left2; try apply FF_left; rewrite H0; auto .. |].
(* Goal: @semax CS Espec Delta P Sskip (normal_ret_assert P) *)
    apply AuxDefs.semax_skip.
  + apply AuxDefs.semax_builtin.
  + specialize (IHsemax H _ H0 H1 H2).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
    apply AuxDefs.semax_label; auto.
  + apply AuxDefs.semax_goto.
  + apply (AuxDefs.semax_conseq _ P' (Build_ret_assert (RA_normal R') (RA_break R') (RA_continue Post') (RA_return R'))).
    - exact H0.
    - rewrite <- H6; exact H1.
    - rewrite <- H7; exact H2.
    - apply derives_full_refl.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
    - intros. rewrite <- H8; exact (H4 vl).
    - apply IHsemax; auto.
Qed.

Lemma semax_loop_nocontinue1:
  forall CS Espec Delta Pre s1 s2 s3 Post,
  nocontinue s1 = true ->
  nocontinue s2 = true ->
  nocontinue s3 = true ->
   @semax CS Espec Delta Pre (Sloop (Ssequence s1 (Ssequence s2 s3)) Sskip) Post ->
    @semax CS Espec Delta Pre (Sloop (Ssequence s1 s2) s3) Post.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
intros.
 rename H1 into Hs3. rename H2 into H1.
(* Goal: @semax CS Espec Delta P (Sloop body incr) R *)
apply semax_loop_inv in H1.
eapply AuxDefs.semax_conseq.
apply H1.
instantiate (1:=Post).
1,2,3,4: intros; eapply derives_trans; [  | apply bupd_orp_l];
(* Goal: forall x : bool, Extr.CSHL_Def.semax CS Espec Delta (if x then Q1 else Q2) c Q *)
apply orp_right2; apply andp_left2; apply andp_left2; apply bupd_intro.
apply semax_extract_exists; intro Q.
apply semax_extract_exists; intro Q'.
(* Goal: Extr.CSHL_Def.semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (and (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_true (typeof e)) (@eval_expr CS e)))) (Ssequence c1 c) Q) (@semax CS Espec Delta (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (local (@liftx (Tarrow val (LiftEnviron Prop)) (typed_false (typeof e)) (@eval_expr CS e)))) (Ssequence c2 c) Q))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) P' (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@eq bool (bool_type (typeof e)) true)) (@tc_expr CS Delta (Eunop Cop.Onotbool e (Tint I32 Signed noattr)))))) (Ssequence (Sifthenelse e c1 c2) c) Q *)
apply semax_extract_prop; intros [? ?].
apply seq_assoc in H2.
apply semax_seq_inv in H2.
destruct H2 as [Q3 [? ?]].
apply AuxDefs.semax_loop with Q3.
*
assert (nocontinue (Ssequence s1 s2) = true).
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
simpl; rewrite H,H0; auto.
forget (Ssequence s1 s2) as s.
clear - H2 H5.
revert H2.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement (select_switch_default LSnil))) true *)
apply semax_nocontinue_inv; auto; destruct Post; try reflexivity.
*
clear - H4 H3 Hs3.
apply semax_seq_skip.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
econstructor; eauto.
clear - H4 Hs3.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement (select_switch_default LSnil))) true *)
revert H4; apply semax_nocontinue_inv; auto; destruct Post; try reflexivity.
Qed.

Lemma semax_convert_for_while':
 forall CS Espec Delta Pre s1 e2 s3 s4 s5 Post,
  nocontinue s4 = true ->
  nocontinue s3 = true -> 
  @semax CS Espec Delta Pre 
    (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post ->
  @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post.
Proof.
(* Goal: forall (CS : compspecs) (Espec : OracleKind) (Delta : tycontext) (Pre : forall _ : environ, mpred) (s1 : statement) (e2 : expr) (s3 s4 s5 : statement) (Post : ret_assert) (_ : @eq bool (nocontinue s4) true) (_ : @eq bool (nocontinue s3) true) (_ : @semax CS Espec Delta Pre (Ssequence s1 (Ssequence (Swhile e2 (Ssequence s4 s3)) s5)) Post), @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
intros.
(* Goal: @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
rename H0 into H9. rename H1 into H0.
(* Goal: @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
apply semax_seq_inv in H0.
(* Goal: @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
destruct H0 as [Q [? ?]].
(* Goal: @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
apply semax_seq_inv in H1.
(* Goal: @semax CS Espec Delta Pre (Ssequence (Sfor s1 e2 s4 s3) s5) Post *)
destruct H1 as [R [? ?]].
unfold Sfor, Swhile  in *.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
apply AuxDefs.semax_seq with R; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
apply AuxDefs.semax_seq with Q; auto.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
rewrite overridePost_overridePost; auto.
clear - H1 H H9.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement (select_switch_default LSnil))) true *)
assert (nocontinue (Sifthenelse e2 Sskip Sbreak) = true) by reflexivity.
(* Goal: @AuxDefs.semax CS Espec Delta Q (Sloop (Ssequence (Sifthenelse e2 Sskip Sbreak) s4) s3) (overridePost R Post) *)
forget (Sifthenelse e2 Sskip Sbreak) as s1.
forget (overridePost R Post) as R'; clear - H H1 H0 H9.
(* Goal: @AuxDefs.semax CS Espec Delta Q (Sloop (Ssequence s1 s4) s3) R' *)
fold semax.
(* Goal: @eq bool (nocontinue (seq_of_labeled_statement sl)) true *)
apply semax_loop_nocontinue1; auto.
Qed.


Definition semax_extract_prop := @ExtrFacts.semax_extract_prop.

Definition semax_extract_later_prop := @ExtrIFacts.semax_extract_later_prop.

End DeepEmbeddedPracticalLogic.

End DeepEmbedded.

(* After this succeeds, remove "weakest_pre" in veric/semax.v. *)
