Require Import VST.veric.juicy_base.
Require Import VST.veric.juicy_mem.
Require Import VST.veric.juicy_mem_lemmas.
Require Import VST.veric.juicy_mem_ops.
Require Import VST.sepcomp.extspec.
Require Import VST.veric.juicy_extspec.
Require Import VST.veric.tycontext.
Require Import VST.veric.expr2.
Require Import VST.veric.semax.
Require Import VST.veric.semax_call.
Require Import VST.veric.res_predicates.

Require Import VST.veric.res_predicates.
Require Import compcert.cfrontend.Clight.
Require Import compcert.exportclight.Clightdefs.

Definition funsig2signature (s : funsig) cc : signature :=
  mksignature (map typ_of_type (map snd (fst s))) (opttyp_of_type (snd s)) cc.

(* NOTE.   ext_link: Strings.String.string -> ident
   represents the mapping from the _name_ of an external function
  (an ASCII string) to the [ident] that's used to represent it in this program module.
  That mapping can be computed from the prog_defs component of the Clight.program
  produced by clightgen.
*)

Definition ef_id_sig (ext_link: Strings.String.string -> ident) ef :=
  match ef with EF_external id sig => Some (ext_link id, sig) | _ => None end.

Section funspecs2jspec.

Variable Z : Type.

Variable Espec : juicy_ext_spec Z.

Definition symb2genv_upper_bound (s: PTree.t block) : block :=
  Pos.succ (fold_right Pos.max  1%positive (map snd (PTree.elements s))).

Definition symb2genv (ge_s: injective_PTree block) : genv.
(* Goal: genv *)
    refine (Build_genv (@Genv.mkgenv _ _ nil (proj1_sig ge_s) (PTree.empty _) (symb2genv_upper_bound (proj1_sig ge_s)) _ _ _) (PTree.empty _)).
*
(* Goal: forall (x : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
intros.
(* Goal: Coqlib.Plt b (symb2genv_upper_bound (@proj1_sig (PTree.t block) (@PTree_injective block) ge_s)) *)
unfold Coqlib.Plt.
(* Goal: Pos.lt b (symb2genv_upper_bound (@proj1_sig (PTree.t block) (@PTree_injective block) ge_s)) *)
apply Pos.lt_le_trans with (Pos.succ b).
(* Goal: Pos.lt b (Pos.succ b) *)
(* Goal: Pos.le (Pos.succ b) (symb2genv_upper_bound (@proj1_sig (PTree.t block) (@PTree_injective block) ge_s)) *)
apply Pos.lt_succ_r.
(* Goal: Pos.le b b *)
(* Goal: Pos.le (Pos.succ b) (symb2genv_upper_bound (@proj1_sig (PTree.t block) (@PTree_injective block) ge_s)) *)
apply Pos.le_refl.
(* Goal: Pos.le (Pos.succ b) (symb2genv_upper_bound (@proj1_sig (PTree.t block) (@PTree_injective block) ge_s)) *)
unfold symb2genv_upper_bound.
(* Goal: Pos.le (Pos.succ b) (Pos.succ (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@PTree.elements block (@proj1_sig (PTree.t block) (@PTree_injective block) ge_s))))) *)
apply -> Pos.succ_le_mono.
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@PTree.elements block (@proj1_sig (PTree.t block) (@PTree_injective block) ge_s)))) *)
apply PTree.elements_correct in H.
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@PTree.elements block (@proj1_sig (PTree.t block) (@PTree_injective block) ge_s)))) *)
revert H.
(* Goal: forall (x : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
induction (PTree.elements (proj1_sig ge_s)); intros. inv H.
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
destruct H. subst. simpl.
(* Goal: Pos.le b (Pos.max b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) l))) *)
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
apply Pos.le_max_l.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
simpl.
eapply Pos.le_trans; [  | apply Pos.le_max_r].
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
auto.
*
(* Goal: forall (x : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
intros.
(* Goal: Coqlib.Plt b (symb2genv_upper_bound (@proj1_sig (PTree.t block) (@PTree_injective block) ge_s)) *)
rewrite PTree.gempty in H. inv H.
*
(* Goal: forall (x : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
intros.
destruct ge_s; simpl in *.
(* Goal: @eq positive id1 id2 *)
revert id1 id2 b H H0.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
simpl.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
auto.
Defined.

Lemma symb2genv_ax' : forall (ge_s : injective_PTree block), genv_symb_injective (symb2genv ge_s) = ge_s.
Proof.
(* Goal: forall (x : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
intros.
(* Goal: @eq (injective_PTree block) (@genv_symb_injective fundef type (genv_genv (symb2genv ge_s))) ge_s *)
destruct ge_s.
(* Goal: @eq (injective_PTree block) (@genv_symb_injective fundef type (genv_genv (symb2genv (@exist (PTree.t block) (@PTree_injective block) x p)))) (@exist (PTree.t block) (@PTree_injective block) x p) *)
unfold genv_symb_injective.
(* Goal: @eq (injective_PTree block) (@exist (PTree.t block) (@PTree_injective block) (@Genv.genv_symb fundef type (genv_genv (symb2genv (@exist (PTree.t block) (@PTree_injective block) x p)))) (fun (id1 id2 : positive) (b : block) (H : @eq (option block) (@PTree.get block id1 (@Genv.genv_symb fundef type (genv_genv (symb2genv (@exist (PTree.t block) (@PTree_injective block) x p))))) (@Some block b)) (H0 : @eq (option block) (@PTree.get block id2 (@Genv.genv_symb fundef type (genv_genv (symb2genv (@exist (PTree.t block) (@PTree_injective block) x p))))) (@Some block b)) => @Genv.genv_vars_inj fundef type (genv_genv (symb2genv (@exist (PTree.t block) (@PTree_injective block) x p))) id1 id2 b H H0)) (@exist (PTree.t block) (@PTree_injective block) x p) *)
f_equal.
Qed.

Lemma symb2genv_ax : forall (ge: genv), Genv.genv_symb (symb2genv (genv_symb_injective ge)) = Genv.genv_symb ge.
Proof.
(* Goal: forall (x : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
intros.
(* Goal: @eq (PTree.t block) (@Genv.genv_symb fundef type (genv_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge))))) (@Genv.genv_symb fundef type (genv_genv ge)) *)
reflexivity.
Qed.

(* Making this particular instance of EqDec opaque *)
Lemma oi_eq_dec : forall a a' : option (ident * signature), { a = a' } + { a <> a' }.
Proof.
(* Goal: forall a a' : option (prod ident signature), sumbool (@eq (option (prod ident signature)) a a') (not (@eq (option (prod ident signature)) a a')) *)
  intros; repeat (apply eq_dec || decide equality).
Qed.


Definition funspec2pre (ext_link: Strings.String.string -> ident) (A : TypeTree)
  (P: forall ts, dependent_type_functor_rec ts (AssertTT A) mpred)
  (ids: list ident) (id: ident) (sig : signature) (ef: external_function) x (ge_s: injective_PTree block)
           (tys : list typ) args (z : Z) m : Prop :=
  match oi_eq_dec (Some (id, sig)) (ef_id_sig ext_link ef) as s
  return ((if s then (rmap* (sigT (fun ts => dependent_type_functor_rec ts A mpred)))%type else ext_spec_type Espec ef) -> Prop)
  with
    | left _ => fun x' => Val.has_type_list args (sig_args (ef_sig ef)) /\
                      exists phi0 phi1, join phi0 phi1 (m_phi m)
                       /\ P (projT1 (snd x')) (projT2 (snd x')) (make_ext_args (filter_genv (symb2genv ge_s)) ids args) phi0
                       /\ necR (fst x') phi1 /\ joins (ghost_of (m_phi m)) (Some (ghost_PCM.ext_ref z, NoneP) :: nil)
    | right n => fun x' => ext_spec_pre Espec ef x' ge_s tys args z m
  end x.

Definition funspec2post (ext_link: Strings.String.string -> ident) (A : TypeTree)
  (Q: forall ts, dependent_type_functor_rec ts (AssertTT A) mpred)
  id sig ef x ge_s (tret : option typ) ret (z : Z) m : Prop :=
  match oi_eq_dec (Some (id, sig)) (ef_id_sig ext_link ef) as s
  return ((if s then (rmap*(sigT (fun ts => dependent_type_functor_rec ts A mpred)))%type else ext_spec_type Espec ef) -> Prop)
  with
    | left _ => fun x' => exists phi0 phi1, join phi0 phi1 (m_phi m)
                       /\ Q (projT1 (snd x')) (projT2 (snd x')) (make_ext_rval (filter_genv (symb2genv ge_s)) ret) phi0
                       /\ necR (fst x') phi1 /\ joins (ghost_of (m_phi m)) (Some (ghost_PCM.ext_ref z, NoneP) :: nil)
    | right n => fun x' => ext_spec_post Espec ef x' ge_s tret ret z m
  end x.

Definition funspec2extspec (ext_link: Strings.String.string -> ident) (f : (ident*funspec))
  : external_specification juicy_mem external_function Z :=
  match f with
    | (id, mk_funspec ((params, sigret) as fsig) cc A P Q NEP NEQ) =>
      let sig := funsig2signature fsig cc in
      Build_external_specification juicy_mem external_function Z
        (fun ef => if oi_eq_dec (Some (id, sig)) (ef_id_sig ext_link ef) then (rmap* (sigT (fun ts => dependent_type_functor_rec ts A mpred)))%type else ext_spec_type Espec ef)
        (funspec2pre ext_link A P (fst (split params)) id sig)
        (funspec2post ext_link A Q id sig)
        (fun rv z m => False)
  end.

Local Open Scope pred.

Definition wf_funspec (f : funspec) :=
  match f with
    | mk_funspec sig cc A P Q _ _ =>
        forall ts a (ge ge': genv) n args,
          Genv.genv_symb ge = Genv.genv_symb ge' ->
          P ts a (make_ext_args (filter_genv ge) n args) |-- P ts a (make_ext_args (filter_genv ge') n args)
  end.

Lemma make_ext_args_symb (ge ge' : genv)
      (H: Genv.genv_symb ge = Genv.genv_symb ge') n args :
  make_ext_args (filter_genv ge) n args = make_ext_args (filter_genv ge') n args.
Proof.
(* Goal: @eq environ (make_ext_args (filter_genv ge) n args) (make_ext_args (filter_genv ge') n args) *)
revert ge ge' n H; induction args.
* simpl; unfold filter_genv, Genv.find_symbol. intros ? ? ? ->; auto.
* intros ge ge' n H. simpl. destruct n; auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
  erewrite IHargs; eauto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
  erewrite IHargs; eauto.
Qed.

Lemma all_funspecs_wf f : wf_funspec f.
Proof.
(* Goal: wf_funspec f *)
destruct f; simpl; intros ts a ge ge' n args H.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
erewrite make_ext_args_symb; eauto.
Qed.

Program Definition funspec2jspec (ext_link: Strings.String.string -> ident) f : juicy_ext_spec Z :=
  Build_juicy_ext_spec _ (funspec2extspec ext_link f) _ _ _.
Next Obligation.
destruct f; simpl; unfold funspec2pre, pureat; simpl; destruct f; simpl;
(* Goal: forall (x : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
  destruct f; simpl; intros.
(* Goal: forall (x : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (_ : @join rmap Join_rmap phi0 phi1 (m_phi m)) (_ : @app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type l)) args)) phi0), @ex (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) (fun x' : if oi_eq_dec (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x) (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) x') (forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) as s return (forall _ : if s then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef, Prop) then fun x'0 : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) => and (Val.has_type_list args (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) l))) (@ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x'0)) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x'0)) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type l)) args)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x'0) phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))) else fun x'0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => @ext_spec_pre juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x'0 ge_s tys args z m) x')) *)
if_tac [e0|e0].
* destruct e; try discriminate; injection e0 as E; subst i sg; intros a a' Hage.
(* Goal: forall _ : and (Val.has_type_list args (sig_args (ef_sig (EF_external name (funsig2signature (@pair (list (prod ident type)) type l t) c))))) (@ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi a)) (and (@app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0)) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0)) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type l)) args)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0) phi1) (@joins ghost ghost_join (ghost_of (m_phi a)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))), and (Val.has_type_list args (sig_args (ef_sig (EF_external name (funsig2signature (@pair (list (prod ident type)) type l t) c))))) (@ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi a')) (and (@app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0)) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0)) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type l)) args)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0) phi1) (@joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))) *)
intros [Hargs [phi0 [phi1 [Hjoin [Hx [Hy Hg]]]]]].
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi a')) (and (x phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0) phi1) (@joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) *)
apply age1_juicy_mem_unpack in Hage.
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi a')) (and (x phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0) phi1) (@joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) *)
destruct Hage as [Hage Hdry].
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi a')) (and (x phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0) phi1) (@joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) *)
destruct (age1_join2 phi0 Hjoin Hage) as [x' [y' [Hjoin' [Hage' H]]]].
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
split; auto. exists x', y'; split; auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
destruct P. split. eapply h; eauto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
split. apply (necR_trans (fst t0) phi1 y'); auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
unfold necR. constructor; auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
erewrite age1_ghost_of by eauto.
change (Some (ghost_PCM.ext_ref z, NoneP) :: nil) with
  (own.ghost_approx (m_phi a') (Some (ghost_PCM.ext_ref z, NoneP) :: nil)).
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
destruct Hg; eexists; apply ghost_fmap_join; eauto.
* intros ? ?; auto.
(* Goal: forall (_ : @age juicy_mem juicy_mem_ageable a a') (_ : @ext_spec_pre juicy_mem external_function Z (JE_spec Z Espec) e t0 ge_s typs args z a), @ext_spec_pre juicy_mem external_function Z (JE_spec Z Espec) e t0 ge_s typs args z a' *)
destruct Espec; simpl; apply JE_pre_hered.
Qed.
Next Obligation.
destruct f; simpl; unfold funspec2post, pureat; simpl; destruct f; simpl;
(* Goal: forall (x : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
  destruct f; simpl; intros.
(* Goal: forall (x : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (_ : @join rmap Join_rmap phi0 phi1 (m_phi m)) (_ : @app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type l)) args)) phi0), @ex (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) (fun x' : if oi_eq_dec (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x) (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) x') (forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) as s return (forall _ : if s then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef, Prop) then fun x'0 : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) => and (Val.has_type_list args (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) l))) (@ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x'0)) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x'0)) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type l)) args)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x'0) phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))) else fun x'0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => @ext_spec_pre juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x'0 ge_s tys args z m) x')) *)
if_tac [e0|e0].
* destruct e; try discriminate; injection e0 as E; subst i sg. intros a a' Hage. destruct Q; simpl.
(* Goal: forall _ : @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi a)) (and (x phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0) phi1) (@joins ghost ghost_join (ghost_of (m_phi a)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi a')) (and (x phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0) phi1) (@joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) *)
intros [phi0 [phi1 [Hjoin [Hx [Hy Hg]]]]].
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi a')) (and (x phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0) phi1) (@joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) *)
apply age1_juicy_mem_unpack in Hage.
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi a')) (and (x phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0) phi1) (@joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) *)
destruct Hage as [Hage Hdry].
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi a')) (and (x phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0) phi1) (@joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) *)
destruct (age1_join2 phi0 Hjoin Hage) as [x' [y' [Hjoin' [Hage' H]]]].
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
exists x', y'; split; auto.
(* Goal: and (x x') (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) t0) y') (@joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))) *)
split; [solve[eapply h; eauto]|].
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
split. apply (necR_trans (fst t0) phi1 y'); auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
unfold necR. constructor; auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
erewrite age1_ghost_of by eauto.
change (Some (ghost_PCM.ext_ref z, NoneP) :: nil) with
  (own.ghost_approx (m_phi a') (Some (ghost_PCM.ext_ref z, NoneP) :: nil)).
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
destruct Hg; eexists; apply ghost_fmap_join; eauto.
* intros ? ?; auto.
(* Goal: forall (_ : @age juicy_mem juicy_mem_ageable a a') (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z Espec) e t0 ge_s tret rv z a), @ext_spec_post juicy_mem external_function Z (JE_spec Z Espec) e t0 ge_s tret rv z a' *)
destruct Espec; simpl; apply JE_post_hered.
Qed.
Next Obligation.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
intros ? ? ? ?; destruct f; destruct f; destruct f; simpl.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
intros a' Hage; auto.
Qed.

End funspecs2jspec.

Definition funspecs_norepeat (fs : funspecs) := list_norepet (map fst fs).

Fixpoint add_funspecs_rec (ext_link: Strings.String.string -> ident) (Z : Type) (Espec : juicy_ext_spec Z) (fs : funspecs) :=
  match fs with
    | nil => Espec
    | cons (i,f) fs' => funspec2jspec Z (add_funspecs_rec ext_link Z Espec fs') ext_link (i,f)
  end.

Require Import Coq.Logic.JMeq.

Lemma add_funspecs_pre  (ext_link: Strings.String.string -> ident)
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
              {Z fs id sig cc A P Q NEP NEQ}
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
              {x: sigT (fun ts => dependent_type_functor_rec ts A mpred)} {args m} Espec tys ge_s phi0 phi1 :
  let ef := EF_external id (funsig2signature sig cc) in
  funspecs_norepeat fs ->
  In (ext_link id, (mk_funspec sig cc A P Q NEP NEQ)) fs ->
  join phi0 phi1 (m_phi m) ->
  Val.has_type_list args (sig_args (ef_sig ef)) ->
  P (projT1 x) (projT2 x) (make_ext_args (filter_genv (symb2genv ge_s)) (fst (split (fst sig))) args) phi0 ->
  exists x' : ext_spec_type (JE_spec _ (add_funspecs_rec ext_link Z Espec fs)) ef,
    JMeq (phi1, x) x'
    /\ forall z, joins (ghost_of (m_phi m)) (Some (ghost_PCM.ext_ref z, NoneP) :: nil) ->
          ext_spec_pre (add_funspecs_rec ext_link Z Espec fs) ef x' ge_s tys args z m.
Proof.
(* Goal: let ef := EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc) in forall (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec (@pair (list (prod ident type)) type sig tvoid) cc A P Q NEP NEQ)) fs) (_ : @join rmap Join_rmap phi0 phi1 (m_phi m)) (_ : Val.has_type_list args (sig_args (ef_sig ef))) (_ : @app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type sig)) args)) phi0), @ex (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) (fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x) (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) x') (forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x' ge_s tys args z m)) *)
induction fs; [intros; elimtype False; auto|]; intros ef H H1 H2 Hargsty Hpre.
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
destruct H1 as [H1|H1].

(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
{
subst a; simpl in *.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
clear IHfs H; revert x H2 Hpre; unfold funspec2pre; simpl.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
destruct sig; simpl.
(* Goal: forall (x : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (_ : @join rmap Join_rmap phi0 phi1 (m_phi m)) (_ : @app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type l)) args)) phi0), @ex (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) (fun x' : if oi_eq_dec (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x) (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) x') (forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature (@pair (list (prod ident type)) type l t) cc))) as s return (forall _ : if s then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef, Prop) then fun x'0 : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) => and (Val.has_type_list args (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) l))) (@ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x'0)) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x'0)) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type l)) args)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x'0) phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))) else fun x'0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => @ext_spec_pre juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x'0 ge_s tys args z m) x')) *)
if_tac [e0|e0].
(* Goal: and (forall (b : OK_ty) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable jm' a') (_ : @joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref OK_ty b) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args b a') (forall (b : option typ) (b0 : option val) (b1 : OK_ty) (y : juicy_mem) (_ : Peano.ge (@level rmap ag_rmap (m_phi jm')) (@level rmap ag_rmap (m_phi y))) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable y a') (_ : @ext_spec_post juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) b b0 b1 a'), @ex rmap (fun y0 : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y0 z (m_phi a')) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) b0)) y0) (@app_pred rmap ag_rmap F z))))) *)
rewrite fst_split.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
intros x Hjoin Hp. exists (phi1, x). split; eauto.
(* Goal: forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), and (Val.has_type_list args (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig))) (@ex rmap (fun phi0 : rmap => @ex rmap (fun phi2 : rmap => and (@join rmap Join_rmap phi0 phi2 (m_phi m)) (and (@app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x))) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x))) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type sig)) args)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x)) phi2) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))) *)
(* Goal: forall (x : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (_ : @join rmap Join_rmap phi0 phi1 (m_phi m)) (_ : @app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type sig)) args)) phi0), @ex (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) (fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x) (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) x') (forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x' ge_s tys args z m)) *)
split; eauto 6.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
elimtype False; auto.
}

(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
{
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
assert (Hin: In (ext_link id) (map fst fs)).
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
{ eapply (in_map fst) in H1; apply H1. }
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
inversion H as [|? ? Ha Hb]; subst.
(* Goal: @ex (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef) (fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef => and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x) (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef) x') (forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef x' ge_s tys args z m)) *)
destruct (IHfs Hb H1 H2 Hargsty Hpre) as [x' H3].
(* Goal: @ex (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef) (fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef => and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x) (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef) x') (forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef x' ge_s tys args z m)) *)
clear -Ha Hin H1 H3; revert x' Ha Hin H1 H3.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
destruct a; simpl; destruct f; simpl; destruct f; simpl; unfold funspec2pre; simpl.
(* Goal: forall (x : if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) as s return (forall _ : if s then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef, Prop) then fun x' : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) => @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (Q0 (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x') phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) else fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x' ge_s tret ret z m) x) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
if_tac [e|e].
* injection e as E; subst i; destruct fs; [solve[simpl; intros; elimtype False; auto]|].
(* Goal: forall (x : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred))) (_ : not (@In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) (@cons (prod ident funspec) p fs)))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) (@cons (prod ident funspec) p fs))) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) (@cons (prod ident funspec) p fs)) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) (@cons (prod ident funspec) p fs))) (_ : @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (Q0 (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x)) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x)) (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x) phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) p fs))) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat (@cons (prod ident funspec) p fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) (@cons (prod ident funspec) p fs)) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) p fs))) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) p fs))) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
  intros x' Ha Hb; simpl in Ha, Hb.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
  elimtype False; auto.
* intros; eexists; eauto.
}
Qed.

Lemma add_funspecs_pre_void  (ext_link: Strings.String.string -> ident)
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
              {Z fs id sig cc A P Q NEP NEQ}
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
              {x: sigT (fun ts => dependent_type_functor_rec ts A mpred)}
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
              {args m} Espec tys ge_s phi0 phi1 :
  let ef := EF_external id (mksignature (map typ_of_type (map snd sig)) None cc) in
  funspecs_norepeat fs ->
  In (ext_link id, (mk_funspec (sig, tvoid) cc A P Q NEP NEQ)) fs ->
  join phi0 phi1 (m_phi m) ->
  Val.has_type_list args (sig_args (ef_sig ef)) ->
  P (projT1 x) (projT2 x) (make_ext_args (filter_genv (symb2genv ge_s)) (fst (split sig)) args) phi0 ->
  exists x' : ext_spec_type (JE_spec _ (add_funspecs_rec ext_link Z Espec fs)) ef,
    JMeq (phi1, x) x'
    /\ forall z, joins (ghost_of (m_phi m)) (Some (ghost_PCM.ext_ref z, NoneP) :: nil) ->
          ext_spec_pre (add_funspecs_rec ext_link Z Espec fs) ef x' ge_s tys args z m.
Proof.
(* Goal: let ef := EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc) in forall (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec (@pair (list (prod ident type)) type sig tvoid) cc A P Q NEP NEQ)) fs) (_ : @join rmap Join_rmap phi0 phi1 (m_phi m)) (_ : Val.has_type_list args (sig_args (ef_sig ef))) (_ : @app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type sig)) args)) phi0), @ex (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) (fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x) (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) x') (forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x' ge_s tys args z m)) *)
induction fs; [intros; elimtype False; auto|]; intros ef H H1 H2 Hargsty Hpre.
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
destruct H1 as [H1|H1].

(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
{
subst a; simpl in *.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
clear IHfs H; revert x H2 Hpre; unfold funspec2pre; simpl.
(* Goal: forall (x : if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) as s return (forall _ : if s then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef, Prop) then fun x' : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) => @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (Q0 (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x') phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) else fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x' ge_s tret ret z m) x) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
if_tac [e|e].
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
intros x Hjoin Hp. exists (phi1,x). split; eauto.
(* Goal: forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), and (Val.has_type_list args (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig))) (@ex rmap (fun phi0 : rmap => @ex rmap (fun phi2 : rmap => and (@join rmap Join_rmap phi0 phi2 (m_phi m)) (and (@app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x))) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x))) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type sig)) args)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x)) phi2) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))) *)
(* Goal: forall (x : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (_ : @join rmap Join_rmap phi0 phi1 (m_phi m)) (_ : @app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type sig)) args)) phi0), @ex (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) (fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x) (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) x') (forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x' ge_s tys args z m)) *)
unfold funsig2signature in e.
(* Goal: forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), and (Val.has_type_list args (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig))) (@ex rmap (fun phi0 : rmap => @ex rmap (fun phi2 : rmap => and (@join rmap Join_rmap phi0 phi2 (m_phi m)) (and (@app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x))) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x))) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type sig)) args)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x)) phi2) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))) *)
(* Goal: forall (x : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (_ : @join rmap Join_rmap phi0 phi1 (m_phi m)) (_ : @app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type sig)) args)) phi0), @ex (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) (fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x) (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) x') (forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x' ge_s tys args z m)) *)
simpl in e.
(* Goal: forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), and (Val.has_type_list args (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig))) (@ex rmap (fun phi0 : rmap => @ex rmap (fun phi2 : rmap => and (@join rmap Join_rmap phi0 phi2 (m_phi m)) (and (@app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x))) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x))) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type sig)) args)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x)) phi2) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))) *)
(* Goal: forall (x : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (_ : @join rmap Join_rmap phi0 phi1 (m_phi m)) (_ : @app_pred rmap ag_rmap (P (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x) (make_ext_args (filter_genv (symb2genv ge_s)) (@fst (list ident) (list type) (@split ident type sig)) args)) phi0), @ex (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) (fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x) (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef) x') (forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x' ge_s tys args z m)) *)
split; eauto 6.

(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
elimtype False; auto.
}

(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
{
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
assert (Hin: In (ext_link id) (map fst fs)).
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
{ eapply (in_map fst) in H1; apply H1. }
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
inversion H as [|? ? Ha Hb]; subst.
(* Goal: @ex (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef) (fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef => and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x) (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef) x') (forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef x' ge_s tys args z m)) *)
destruct (IHfs Hb H1 H2 Hargsty Hpre) as [x' H3].
(* Goal: @ex (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef) (fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef => and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1 x) (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef) x') (forall (z : Z) (_ : @joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) ef x' ge_s tys args z m)) *)
clear -Ha Hin H1 H3; revert x' Ha Hin H1 H3.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
destruct a; simpl; destruct f; simpl; destruct f; simpl; unfold funspec2pre; simpl.
(* Goal: forall (x : if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) as s return (forall _ : if s then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef, Prop) then fun x' : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) => @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (Q0 (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x') phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) else fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x' ge_s tret ret z m) x) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
if_tac [e|e].
* injection e as E; subst i; destruct fs; [solve[simpl; intros; elimtype False; auto]|].
(* Goal: forall (x : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred))) (_ : not (@In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) (@cons (prod ident funspec) p fs)))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) (@cons (prod ident funspec) p fs))) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) (@cons (prod ident funspec) p fs)) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) (@cons (prod ident funspec) p fs))) (_ : @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (Q0 (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x)) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x)) (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x) phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) p fs))) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat (@cons (prod ident funspec) p fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) (@cons (prod ident funspec) p fs)) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) p fs))) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) p fs))) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
  intros x' Ha Hb; simpl in Ha, Hb.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
  elimtype False; auto.
* intros; eexists; eauto.
}
Qed.

Lemma add_funspecs_post_void (ext_link: Strings.String.string -> ident)
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
  {Z Espec tret fs id sig cc A P Q NEP NEQ x ret m z ge_s} :
  let ef := EF_external id (mksignature (map typ_of_type (map snd sig)) None cc) in
  funspecs_norepeat fs ->
  In (ext_link id, (mk_funspec (sig, tvoid) cc A P Q NEP NEQ)) fs ->
  ext_spec_post (add_funspecs_rec ext_link Z Espec fs) ef x ge_s tret ret z m ->
  exists (phi0 phi1 phi1' : rmap) (x': sigT (fun ts => dependent_type_functor_rec ts A mpred)),
       join phi0 phi1 (m_phi m)
    /\ necR phi1' phi1
    /\ JMeq x (phi1', x')
    /\ Q (projT1 x') (projT2 x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret) phi0.
Proof.
(* Goal: let ef := EF_external id (funsig2signature sig cc) in forall (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
induction fs; [intros; elimtype False; auto|]; intros ef H H1 Hpost.
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
destruct H1 as [H1|H1].

(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
{
subst a; simpl in *.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
clear IHfs H; revert x Hpost; unfold funspec2post; simpl.
(* Goal: forall (x : if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) as s return (forall _ : if s then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef, Prop) then fun x' : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) => @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (Q0 (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x') phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) else fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x' ge_s tret ret z m) x) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
if_tac [e|e].
(* Goal: forall (x : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (_ : @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x)) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x)) (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x) phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
(* Goal: forall (x : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature (@pair (list (prod ident type)) type l t) cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
intros x [phi0 [phi1 [Hjoin [Hq [Hnec Hg]]]]].
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
(* Goal: forall (x : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature (@pair (list (prod ident type)) type l t) cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
exists phi0, phi1, (fst x), (snd x).
split; auto. split; auto. destruct x; simpl in *. split; destruct s; auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
elimtype False; auto.
}

(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
{
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
assert (Hin: In (ext_link id) (map fst fs)).
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
{ apply (in_map fst) in H1; auto. }
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
inversion H as [|? ? Ha Hb]; subst.
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
clear -Ha Hin H1 Hb Hpost IHfs; revert x Ha Hin H1 Hb Hpost IHfs.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
destruct a; simpl; destruct f; simpl; unfold funspec2post; simpl.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
destruct f; simpl.
(* Goal: forall (x : if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) as s return (forall _ : if s then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef, Prop) then fun x' : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) => @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (Q0 (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x') phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) else fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x' ge_s tret ret z m) x) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
if_tac [e|e].
* injection e as E; subst i; destruct fs; [solve[simpl; intros; elimtype False; auto]|].
(* Goal: forall (x : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred))) (_ : not (@In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) (@cons (prod ident funspec) p fs)))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) (@cons (prod ident funspec) p fs))) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) (@cons (prod ident funspec) p fs)) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) (@cons (prod ident funspec) p fs))) (_ : @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (Q0 (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x)) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x)) (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x) phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) p fs))) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat (@cons (prod ident funspec) p fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) (@cons (prod ident funspec) p fs)) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) p fs))) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) p fs))) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
  intros x' Ha Hb; simpl in Ha, Hb.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
  elimtype False; auto.
* intros. apply IHfs; auto.
}
Qed.

(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
Lemma add_funspecs_post (ext_link: Strings.String.string -> ident){Z Espec tret fs id sig cc A P Q NEP NEQ x ret m z ge_s} :
  let ef := EF_external id (funsig2signature sig cc) in
  funspecs_norepeat fs ->
  In (ext_link id, (mk_funspec sig cc A P Q NEP NEQ)) fs ->
  ext_spec_post (add_funspecs_rec ext_link Z Espec fs) ef x ge_s tret ret z m ->
  exists (phi0 phi1 phi1' : rmap) (x': sigT (fun ts => dependent_type_functor_rec ts A mpred)),
       join phi0 phi1 (m_phi m)
    /\ necR phi1' phi1
    /\ JMeq x (phi1',x')
    /\ Q (projT1 x') (projT2 x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret) phi0.
Proof.
(* Goal: let ef := EF_external id (funsig2signature sig cc) in forall (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
induction fs; [intros; elimtype False; auto|]; intros ef H H1 Hpost.
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
destruct H1 as [H1|H1].

(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
{
subst a; simpl in *.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
clear IHfs H; revert x Hpost; unfold funspec2post; simpl.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
destruct sig; simpl.
(* Goal: forall (x : if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) as s return (forall _ : if s then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef, Prop) then fun x' : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) => @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (Q0 (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x') phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) else fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x' ge_s tret ret z m) x) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
if_tac [e|e].
(* Goal: forall (x : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (_ : @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x)) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x)) (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) x) phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
(* Goal: forall (x : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature (@pair (list (prod ident type)) type l t) cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
intros x [phi0 [phi1 [Hjoin [Hq [Hnec Hg]]]]].
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
(* Goal: forall (x : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature (@pair (list (prod ident type)) type l t) cc))) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature (@pair (list (prod ident type)) type l t) cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
exists phi0, phi1, (fst x), (snd x).
split; auto. split; auto. destruct x; simpl in *. split; auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
elimtype False; auto.
}

(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
{
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
assert (Hin: In (ext_link id) (map fst fs)).
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
{ apply (in_map fst) in H1; auto. }
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
inversion H as [|? ? Ha Hb]; subst.
(* Goal: @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) a fs))) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
clear -Ha Hin H1 Hb Hpost IHfs; revert x Ha Hin H1 Hb Hpost IHfs.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
destruct a; simpl; destruct f; simpl; unfold funspec2post; simpl.
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
destruct f; simpl.
(* Goal: forall (x : if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : not (@In ident i (@map (prod ident funspec) ident (@fst ident funspec) fs))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) fs)) (_ : (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) as s return (forall _ : if s then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef, Prop) then fun x' : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) => @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (Q0 (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x')) (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x') phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))))))) else fun x' : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef => @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) ef x' ge_s tret ret z m) x) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat fs) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) fs) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (if oi_eq_dec (@Some (prod ident signature) (@pair ident signature i (funsig2signature (@pair (list (prod ident type)) type l t) c))) (@Some (prod ident signature) (@pair ident signature (ext_link id) (funsig2signature sig cc))) then prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) else @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec fs)) (EF_external id (funsig2signature sig cc))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
if_tac [e|e].
* injection e as E; subst i; destruct fs; [solve[simpl; intros; elimtype False; auto]|].
(* Goal: forall (x : prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred))) (_ : not (@In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) (@cons (prod ident funspec) p fs)))) (_ : @In ident (ext_link id) (@map (prod ident funspec) ident (@fst ident funspec) (@cons (prod ident funspec) p fs))) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) (@cons (prod ident funspec) p fs)) (_ : @list_norepet ident (@map (prod ident funspec) ident (@fst ident funspec) (@cons (prod ident funspec) p fs))) (_ : @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@app_pred rmap ag_rmap (Q0 (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x)) (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred) (@snd rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x)) (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0) (and (@necR rmap ag_rmap (@fst rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred)) x) phi1) (@joins ghost ghost_join (ghost_of (m_phi m)) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref Z z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))))))))) (_ : forall (x0 : @ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) p fs))) (EF_external id (funsig2signature sig cc))) (_ : funspecs_norepeat (@cons (prod ident funspec) p fs)) (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) (mk_funspec sig cc A P Q NEP NEQ)) (@cons (prod ident funspec) p fs)) (_ : @ext_spec_post juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) p fs))) (EF_external id (funsig2signature sig cc)) x0 ge_s tret ret z m), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (@ext_spec_type juicy_mem external_function Z (JE_spec Z (add_funspecs_rec ext_link Z Espec (@cons (prod ident funspec) p fs))) (EF_external id (funsig2signature sig cc))) x0 (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0)))))))), @ex rmap (fun phi0 : rmap => @ex rmap (fun phi1 : rmap => @ex rmap (fun phi1' : rmap => @ex (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) (fun x' : @sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) => and (@join rmap Join_rmap phi0 phi1 (m_phi m)) (and (@necR rmap ag_rmap phi1' phi1) (and (@JMeq (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A0) mpred))) x (prod rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred))) (@pair rmap (@sigT (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred)) phi1' x')) (@app_pred rmap ag_rmap (Q (@projT1 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (@projT2 (list Type) (fun ts : list Type => _functor (dependent_type_functor_rec ts A) mpred) x') (make_ext_rval (filter_genv (symb2genv ge_s)) ret)) phi0))))))) *)
  intros x' Ha Hb; simpl in Ha, Hb.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
  elimtype False; auto.
* intros. apply IHfs; auto.
}
Qed.

Definition add_funspecs (Espec : OracleKind) (ext_link: Strings.String.string -> ident) (fs : funspecs) : OracleKind :=
  match Espec with
    | Build_OracleKind ty spec =>
      Build_OracleKind ty (add_funspecs_rec ext_link ty spec fs)
  end.

Lemma necR_jm_phi : forall jm jm', necR jm jm' -> necR (m_phi jm) (m_phi jm').
Proof.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
  induction 1; auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
  - apply age_jm_phi in H; constructor; auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
  - eapply necR_trans; eauto.
Qed.

Section semax_ext.

Variable Espec : OracleKind.

Lemma semax_ext' (ext_link: Strings.String.string -> ident) id sig cc A P Q NEP NEQ (fs : funspecs) :
  let f := mk_funspec sig cc A P Q NEP NEQ in
  In (ext_link  id,f) fs ->
  funspecs_norepeat fs ->
  (forall n, semax_external (add_funspecs Espec ext_link fs) (fst (split (fst sig)))
               (EF_external id (funsig2signature sig cc)) _ P Q n).
Proof.
(* Goal: let f := mk_funspec (@pair (list (prod ident type)) type sig tvoid) cc A P Q NEP NEQ in forall (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) f) fs) (_ : funspecs_norepeat fs) (n : nat), @app_pred nat ag_nat (semax_external (add_funspecs Espec ext_link fs) (@fst (list ident) (list type) (@split ident type sig)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) A P Q) n *)
intros f Hin Hnorepeat.
(* Goal: forall n : nat, @app_pred nat ag_nat (semax_external (add_funspecs Espec ext_link fs) (@fst (list ident) (list type) (@split ident type sig)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) A P Q) n *)
unfold semax_external.
(* Goal: forall n : nat, @app_pred nat ag_nat (@allp nat ag_nat genv (fun gx : genv => @allp nat ag_nat (list Type) (fun Ts : list Type => @allp nat ag_nat (_functor (dependent_type_functor_rec Ts A) (@pred rmap ag_rmap)) (fun x : _functor (dependent_type_functor_rec Ts A) (@pred rmap ag_rmap) => @box nat ag_nat (@laterM nat ag_nat) (@allp nat ag_nat (@pred rmap ag_rmap) (fun F : @pred rmap ag_rmap => @allp nat ag_nat (list typ) (fun ts : list typ => @allp nat ag_nat (list val) (fun args : list val => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (@andp juicy_mem juicy_mem_ageable (@prop juicy_mem juicy_mem_ageable (Val.has_type_list args (sig_args (ef_sig (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)))))) (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (P Ts x (make_ext_args (filter_genv gx) (@fst (list ident) (list type) (@split ident type sig)) args)) F))) (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@OK_ty (add_funspecs Espec ext_link fs)) (JE_spec (@OK_ty (add_funspecs Espec ext_link fs)) (@OK_spec (add_funspecs Espec ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@OK_ty (add_funspecs Espec ext_link fs)) (JE_spec (@OK_ty (add_funspecs Espec ext_link fs)) (@OK_spec (add_funspecs Espec ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@OK_ty (add_funspecs Espec ext_link fs)) (fun z : @OK_ty (add_funspecs Espec ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@OK_ty (add_funspecs Espec ext_link fs)) z)) (ext_spec_pre' (add_funspecs Espec ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv gx)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@OK_ty (add_funspecs Espec ext_link fs)) (fun z' : @OK_ty (add_funspecs Espec ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs Espec ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv gx)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv gx) ret)) F))))))))))))))))))) n *)
intros n ge Ts x n0 Hlater F ts args jm H jm' H2 [Hargsty H3].
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@OK_ty (add_funspecs Espec ext_link fs)) (JE_spec (@OK_ty (add_funspecs Espec ext_link fs)) (@OK_spec (add_funspecs Espec ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@OK_ty (add_funspecs Espec ext_link fs)) (JE_spec (@OK_ty (add_funspecs Espec ext_link fs)) (@OK_spec (add_funspecs Espec ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@OK_ty (add_funspecs Espec ext_link fs)) (fun z : @OK_ty (add_funspecs Espec ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@OK_ty (add_funspecs Espec ext_link fs)) z)) (ext_spec_pre' (add_funspecs Espec ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@OK_ty (add_funspecs Espec ext_link fs)) (fun z' : @OK_ty (add_funspecs Espec ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs Espec ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
destruct H3 as [s [t [Hjoin [Hp Hf]]]].
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@OK_ty (add_funspecs Espec ext_link fs)) (JE_spec (@OK_ty (add_funspecs Espec ext_link fs)) (@OK_spec (add_funspecs Espec ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@OK_ty (add_funspecs Espec ext_link fs)) (JE_spec (@OK_ty (add_funspecs Espec ext_link fs)) (@OK_spec (add_funspecs Espec ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@OK_ty (add_funspecs Espec ext_link fs)) (fun z : @OK_ty (add_funspecs Espec ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@OK_ty (add_funspecs Espec ext_link fs)) z)) (ext_spec_pre' (add_funspecs Espec ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@OK_ty (add_funspecs Espec ext_link fs)) (fun z' : @OK_ty (add_funspecs Espec ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs Espec ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
destruct Espec.

assert (Hp'': P Ts x (make_ext_args (filter_genv (symb2genv (genv_symb_injective ge)))
                                 (fst (split (fst sig))) args) s).
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
{ generalize (all_funspecs_wf f) as Hwf2; intro.
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type (@fst (list (prod ident type)) type sig))) args)) s *)
  specialize (Hwf2 Ts x ge (symb2genv (genv_symb_injective ge)) (fst (split (fst sig))) args).
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
  spec Hwf2.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
  rewrite symb2genv_ax; auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
  apply Hwf2; auto. }

destruct (@add_funspecs_pre ext_link _ _ _ _ _ _ _ _ _ _ (existT _ Ts x) _ _ OK_spec ts (genv_symb_injective ge) s t Hnorepeat Hin Hjoin Hargsty Hp'')
  as [x' [Heq Hpre]].
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
simpl.
(* Goal: @ex (@ext_spec_type juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun b : @ext_spec_type juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => and (forall (b0 : OK_ty) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable jm' a') (_ : @joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref OK_ty b0) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) b (@genv_symb_injective fundef type (genv_genv ge)) ts args b0 a') (forall (b0 : option typ) (b1 : option val) (b2 : OK_ty) (y : juicy_mem) (_ : Peano.ge (@level rmap ag_rmap (m_phi jm')) (@level rmap ag_rmap (m_phi y))) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable y a') (_ : @ext_spec_post juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) b (@genv_symb_injective fundef type (genv_genv ge)) b0 b1 b2 a'), @ex rmap (fun y0 : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y0 z (m_phi a')) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) b1)) y0) (@app_pred rmap ag_rmap F z)))))) *)
exists x'.
(* Goal: and (forall (b : OK_ty) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable jm' a') (_ : @joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref OK_ty b) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args b a') (forall (b : option typ) (b0 : option val) (b1 : OK_ty) (y : juicy_mem) (_ : Peano.ge (@level rmap ag_rmap (m_phi jm')) (@level rmap ag_rmap (m_phi y))) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable y a') (_ : @ext_spec_post juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) b b0 b1 a'), @ex rmap (fun y0 : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y0 z (m_phi a')) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) b0)) y0) (@app_pred rmap ag_rmap F z))))) *)
split.
(* Goal: forall (b : OK_ty) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable jm' a') (_ : @joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref OK_ty b) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args b a' *)
(* Goal: forall (b : option typ) (b0 : option val) (b1 : OK_ty) (y : juicy_mem) (_ : Peano.ge (@level rmap ag_rmap (m_phi jm')) (@level rmap ag_rmap (m_phi y))) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable y a') (_ : @ext_spec_post juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) b b0 b1 a'), @ex rmap (fun y0 : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y0 z (m_phi a')) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) b0)) y0) (@app_pred rmap ag_rmap F z)))) *)
intros z ???.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
eapply nec_hereditary, Hpre; auto.
(* Goal: @hereditary juicy_mem (@age juicy_mem juicy_mem_ageable) (@ext_spec_pre juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z) *)
(* Goal: @joins ghost ghost_join (ghost_of (m_phi jm')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref OK_ty z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))) *)
(* Goal: forall (b : option typ) (b0 : option val) (b1 : OK_ty) (y : juicy_mem) (_ : Peano.ge (@level rmap ag_rmap (m_phi jm')) (@level rmap ag_rmap (m_phi y))) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable y a') (_ : @ext_spec_post juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) b b0 b1 a'), @ex rmap (fun y0 : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y0 z (m_phi a')) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) b0)) y0) (@app_pred rmap ag_rmap F z)))) *)
apply JE_pre_hered.
(* Goal: @joins ghost ghost_join (ghost_of (m_phi jm')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref OK_ty z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))) *)
(* Goal: forall (b : option typ) (b0 : option val) (b1 : OK_ty) (y : juicy_mem) (_ : Peano.ge (@level rmap ag_rmap (m_phi jm')) (@level rmap ag_rmap (m_phi y))) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable y a') (_ : @ext_spec_post juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) b b0 b1 a'), @ex rmap (fun y0 : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y0 z (m_phi a')) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) b0)) y0) (@app_pred rmap ag_rmap F z)))) *)
apply necR_jm_phi in H0.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
erewrite necR_ghost_of in H1 by eauto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
eapply ext_join_unapprox; eauto.

(* Goal: forall (b : option typ) (b0 : option val) (b1 : OK_ty) (y : juicy_mem) (_ : Peano.ge (@level rmap ag_rmap (m_phi jm')) (@level rmap ag_rmap (m_phi y))) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable y a') (_ : @ext_spec_post juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) b b0 b1 a'), @ex rmap (fun y0 : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y0 z (m_phi a')) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) b0)) y0) (@app_pred rmap ag_rmap F z)))) *)
intros tret ret z' jm2 Hlev jm3 Hnec Hpost.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
eapply add_funspecs_post in Hpost; eauto.
(* Goal: @ex rmap (fun y : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y z (m_phi jm3)) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) y) (@app_pred rmap ag_rmap F z)))) *)
destruct Hpost as [phi0 [phi1 [phi1' [x'' [Hjoin' [Hnec' [Hjmeq' Hq']]]]]]].
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
exists phi0, phi1; split; auto.
(* Goal: and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) phi0) (@app_pred rmap ag_rmap F phi1) *)
assert (E : (t, existT _ Ts x) = (phi1',x'')) by (eapply JMeq_eq, JMeq_trans; eauto).
(* Goal: and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) phi0) (@app_pred rmap ag_rmap F phi1) *)
inv E.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
split; auto.
unfold filter_genv, Genv.find_symbol in Hq'|-*.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
rewrite symb2genv_ax in Hq'; auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
eapply pred_nec_hereditary; eauto.
Qed.

Lemma semax_ext (ext_link: Strings.String.string -> ident) id ids sig sig' cc A P Q NEP NEQ (fs : funspecs) :
  let f := mk_funspec sig cc A P Q NEP NEQ in
  In (ext_link id,f) fs ->
  funspecs_norepeat fs ->
  ids = fst (split (fst sig)) ->
  sig' = funsig2signature sig cc ->
  (forall n, semax_external (add_funspecs Espec ext_link fs) ids (EF_external id sig') _ P Q n).
Proof.
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
intros; subst.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
eapply semax_ext'; eauto.
Qed.

(* Lemmas [semax_ext'_void] and [semax_ext_void] were needed before we
used optyp_of_type of funsig2signature, we should be able to get rid
of them now *)
Lemma semax_ext'_void (ext_link: Strings.String.string -> ident) id sig cc A P Q NEP NEQ (fs : funspecs) :
  let f := mk_funspec (sig, tvoid) cc A P Q NEP NEQ in
  In (ext_link  id,f) fs ->
  funspecs_norepeat fs ->
  (forall n, semax_external (add_funspecs Espec ext_link fs) (fst (split sig))
               (EF_external id (mksignature (map typ_of_type (map snd sig)) None cc)) _ P Q n).
Proof.
(* Goal: let f := mk_funspec (@pair (list (prod ident type)) type sig tvoid) cc A P Q NEP NEQ in forall (_ : @In (prod ident funspec) (@pair ident funspec (ext_link id) f) fs) (_ : funspecs_norepeat fs) (n : nat), @app_pred nat ag_nat (semax_external (add_funspecs Espec ext_link fs) (@fst (list ident) (list type) (@split ident type sig)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) A P Q) n *)
intros f Hin Hnorepeat.
(* Goal: forall n : nat, @app_pred nat ag_nat (semax_external (add_funspecs Espec ext_link fs) (@fst (list ident) (list type) (@split ident type sig)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) A P Q) n *)
unfold semax_external.
(* Goal: forall n : nat, @app_pred nat ag_nat (@allp nat ag_nat genv (fun gx : genv => @allp nat ag_nat (list Type) (fun Ts : list Type => @allp nat ag_nat (_functor (dependent_type_functor_rec Ts A) (@pred rmap ag_rmap)) (fun x : _functor (dependent_type_functor_rec Ts A) (@pred rmap ag_rmap) => @box nat ag_nat (@laterM nat ag_nat) (@allp nat ag_nat (@pred rmap ag_rmap) (fun F : @pred rmap ag_rmap => @allp nat ag_nat (list typ) (fun ts : list typ => @allp nat ag_nat (list val) (fun args : list val => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (@andp juicy_mem juicy_mem_ageable (@prop juicy_mem juicy_mem_ageable (Val.has_type_list args (sig_args (ef_sig (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)))))) (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (P Ts x (make_ext_args (filter_genv gx) (@fst (list ident) (list type) (@split ident type sig)) args)) F))) (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@OK_ty (add_funspecs Espec ext_link fs)) (JE_spec (@OK_ty (add_funspecs Espec ext_link fs)) (@OK_spec (add_funspecs Espec ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@OK_ty (add_funspecs Espec ext_link fs)) (JE_spec (@OK_ty (add_funspecs Espec ext_link fs)) (@OK_spec (add_funspecs Espec ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@OK_ty (add_funspecs Espec ext_link fs)) (fun z : @OK_ty (add_funspecs Espec ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@OK_ty (add_funspecs Espec ext_link fs)) z)) (ext_spec_pre' (add_funspecs Espec ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv gx)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@OK_ty (add_funspecs Espec ext_link fs)) (fun z' : @OK_ty (add_funspecs Espec ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs Espec ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv gx)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv gx) ret)) F))))))))))))))))))) n *)
intros n ge Ts x n0 Hlater F ts args jm H jm' H2 [Hargsty H3].
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@OK_ty (add_funspecs Espec ext_link fs)) (JE_spec (@OK_ty (add_funspecs Espec ext_link fs)) (@OK_spec (add_funspecs Espec ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@OK_ty (add_funspecs Espec ext_link fs)) (JE_spec (@OK_ty (add_funspecs Espec ext_link fs)) (@OK_spec (add_funspecs Espec ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@OK_ty (add_funspecs Espec ext_link fs)) (fun z : @OK_ty (add_funspecs Espec ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@OK_ty (add_funspecs Espec ext_link fs)) z)) (ext_spec_pre' (add_funspecs Espec ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@OK_ty (add_funspecs Espec ext_link fs)) (fun z' : @OK_ty (add_funspecs Espec ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs Espec ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
destruct H3 as [s [t [Hjoin [Hp Hf]]]].
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@OK_ty (add_funspecs Espec ext_link fs)) (JE_spec (@OK_ty (add_funspecs Espec ext_link fs)) (@OK_spec (add_funspecs Espec ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@OK_ty (add_funspecs Espec ext_link fs)) (JE_spec (@OK_ty (add_funspecs Espec ext_link fs)) (@OK_spec (add_funspecs Espec ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@OK_ty (add_funspecs Espec ext_link fs)) (fun z : @OK_ty (add_funspecs Espec ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@OK_ty (add_funspecs Espec ext_link fs)) z)) (ext_spec_pre' (add_funspecs Espec ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@OK_ty (add_funspecs Espec ext_link fs)) (fun z' : @OK_ty (add_funspecs Espec ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs Espec ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
destruct Espec.
assert (Hp'': P Ts x (make_ext_args (filter_genv (symb2genv (genv_symb_injective ge)))
                                 (fst (split sig)) args) s).
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
{ generalize (all_funspecs_wf f) as Hwf2; intro.
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
  specialize (Hwf2 Ts x ge (symb2genv (genv_symb_injective ge)) (fst (split sig)) args).
(* Goal: @app_pred rmap ag_rmap (P Ts x (make_ext_args (filter_genv (symb2genv (@genv_symb_injective fundef type (genv_genv ge)))) (@fst (list ident) (list type) (@split ident type sig)) args)) s *)
  spec Hwf2.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
  rewrite symb2genv_ax; auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
  apply Hwf2; auto. }

destruct (@add_funspecs_pre_void ext_link _ _ _ _ _ _ _ _ _ _ (existT _ Ts x) _ _ OK_spec ts (genv_symb_injective ge) s t Hnorepeat Hin Hjoin Hargsty Hp'')
  as [x' [Heq Hpre]].
(* Goal: @app_pred juicy_mem juicy_mem_ageable (@exp juicy_mem juicy_mem_ageable (@ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun x' : @ext_spec_type juicy_mem external_function (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (JE_spec (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (@juicy_extspec.OK_spec (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs))) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => @andp juicy_mem juicy_mem_ageable (@allp juicy_mem juicy_mem_ageable (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @imp juicy_mem juicy_mem_ageable (juicy_mem_op (@ext_compat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) z)) (ext_spec_pre' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z))) (@unfash juicy_mem juicy_mem_ageable (@allp nat ag_nat (option typ) (fun tret : option typ => @allp nat ag_nat (option val) (fun ret : option val => @allp nat ag_nat (@juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs)) (fun z' : @juicy_extspec.OK_ty (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) => @fash juicy_mem juicy_mem_ageable (@imp juicy_mem juicy_mem_ageable (ext_spec_post' (add_funspecs (Build_OracleKind OK_ty OK_spec) ext_link fs) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) tret ret z') (juicy_mem_op (@sepcon rmap Join_rmap Perm_rmap ag_rmap Age_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) F)))))))))) jm' *)
simpl.
(* Goal: @ex (@ext_spec_type juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc))) (fun b : @ext_spec_type juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) => and (forall (b0 : OK_ty) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable jm' a') (_ : @joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref OK_ty b0) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) b (@genv_symb_injective fundef type (genv_genv ge)) ts args b0 a') (forall (b0 : option typ) (b1 : option val) (b2 : OK_ty) (y : juicy_mem) (_ : Peano.ge (@level rmap ag_rmap (m_phi jm')) (@level rmap ag_rmap (m_phi y))) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable y a') (_ : @ext_spec_post juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) b (@genv_symb_injective fundef type (genv_genv ge)) b0 b1 b2 a'), @ex rmap (fun y0 : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y0 z (m_phi a')) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) b1)) y0) (@app_pred rmap ag_rmap F z)))))) *)
exists x'.
(* Goal: and (forall (b : OK_ty) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable jm' a') (_ : @joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref OK_ty b) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args b a') (forall (b : option typ) (b0 : option val) (b1 : OK_ty) (y : juicy_mem) (_ : Peano.ge (@level rmap ag_rmap (m_phi jm')) (@level rmap ag_rmap (m_phi y))) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable y a') (_ : @ext_spec_post juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) b b0 b1 a'), @ex rmap (fun y0 : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y0 z (m_phi a')) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) b0)) y0) (@app_pred rmap ag_rmap F z))))) *)
split.
(* Goal: forall (b : OK_ty) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable jm' a') (_ : @joins ghost ghost_join (ghost_of (m_phi a')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref OK_ty b) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds))))), @ext_spec_pre juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args b a' *)
(* Goal: forall (b : option typ) (b0 : option val) (b1 : OK_ty) (y : juicy_mem) (_ : Peano.ge (@level rmap ag_rmap (m_phi jm')) (@level rmap ag_rmap (m_phi y))) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable y a') (_ : @ext_spec_post juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) b b0 b1 a'), @ex rmap (fun y0 : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y0 z (m_phi a')) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) b0)) y0) (@app_pred rmap ag_rmap F z)))) *)
intros z ???.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
eapply nec_hereditary, Hpre; auto.
(* Goal: @hereditary juicy_mem (@age juicy_mem juicy_mem_ageable) (@ext_spec_pre juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) ts args z) *)
(* Goal: @joins ghost ghost_join (ghost_of (m_phi jm')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref OK_ty z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))) *)
(* Goal: forall (b : option typ) (b0 : option val) (b1 : OK_ty) (y : juicy_mem) (_ : Peano.ge (@level rmap ag_rmap (m_phi jm')) (@level rmap ag_rmap (m_phi y))) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable y a') (_ : @ext_spec_post juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) b b0 b1 a'), @ex rmap (fun y0 : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y0 z (m_phi a')) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) b0)) y0) (@app_pred rmap ag_rmap F z)))) *)
apply JE_pre_hered.
(* Goal: @joins ghost ghost_join (ghost_of (m_phi jm')) (@cons (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)) (@Some (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds) (@pair (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds (@ghost_PCM.ext_ref OK_ty z) NoneP)) (@nil (option (prod (@sigT ghost.Ghost (fun g : ghost.Ghost => @Specif.sig (@ghost.G g) (fun a : @ghost.G g => @ghost.valid g a))) preds)))) *)
(* Goal: forall (b : option typ) (b0 : option val) (b1 : OK_ty) (y : juicy_mem) (_ : Peano.ge (@level rmap ag_rmap (m_phi jm')) (@level rmap ag_rmap (m_phi y))) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable y a') (_ : @ext_spec_post juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) b b0 b1 a'), @ex rmap (fun y0 : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y0 z (m_phi a')) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) b0)) y0) (@app_pred rmap ag_rmap F z)))) *)
apply necR_jm_phi in H0.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
erewrite necR_ghost_of in H1 by eauto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
eapply ext_join_unapprox; eauto.

(* Goal: forall (b : option typ) (b0 : option val) (b1 : OK_ty) (y : juicy_mem) (_ : Peano.ge (@level rmap ag_rmap (m_phi jm')) (@level rmap ag_rmap (m_phi y))) (a' : juicy_mem) (_ : @necR juicy_mem juicy_mem_ageable y a') (_ : @ext_spec_post juicy_mem external_function OK_ty (JE_spec OK_ty (add_funspecs_rec ext_link OK_ty OK_spec fs)) (EF_external id (mksignature (@map type typ typ_of_type (@map (prod ident type) type (@snd ident type) sig)) (@None typ) cc)) x' (@genv_symb_injective fundef type (genv_genv ge)) b b0 b1 a'), @ex rmap (fun y0 : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y0 z (m_phi a')) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) b0)) y0) (@app_pred rmap ag_rmap F z)))) *)
intros tret ret z' jm2 Hlev jm3 Hnec Hpost.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
eapply add_funspecs_post_void in Hpost; eauto.
(* Goal: @ex rmap (fun y : rmap => @ex rmap (fun z : rmap => and (@join rmap Join_rmap y z (m_phi jm3)) (and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) y) (@app_pred rmap ag_rmap F z)))) *)
destruct Hpost as [phi0 [phi1 [phi1' [x'' [Hjoin' [Hnec' [Hjmeq' Hq']]]]]]].
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
exists phi0, phi1; split; auto.
(* Goal: and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) phi0) (@app_pred rmap ag_rmap F phi1) *)
assert (E : (t, existT _ Ts x) = (phi1',x'')) by (eapply JMeq_eq, JMeq_trans; eauto).
(* Goal: and (@app_pred rmap ag_rmap (Q Ts x (make_ext_rval (filter_genv ge) ret)) phi0) (@app_pred rmap ag_rmap F phi1) *)
inv E.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
split; auto.
unfold filter_genv, Genv.find_symbol in Hq'|-*.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
rewrite symb2genv_ax in Hq'; auto.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
eapply pred_nec_hereditary; eauto.
Qed.

Lemma semax_ext_void (ext_link: Strings.String.string -> ident) id ids sig sig' cc A P Q NEP NEQ (fs : funspecs) :
  let f := mk_funspec (sig, tvoid) cc A P Q NEP NEQ in
  In (ext_link id,f) fs ->
  funspecs_norepeat fs ->
  ids = fst (split sig) ->
  sig' = mksignature (map typ_of_type (map snd sig)) None cc ->
  (forall n, semax_external (add_funspecs Espec ext_link fs) ids (EF_external id sig') _ P Q n).
Proof.
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
(* Goal: Pos.le b (@fold_right positive positive Pos.max xH (@map (prod positive block) block (@snd positive block) (@cons (prod positive block) a l))) *)
intros; subst.
(* Goal: forall (id1 id2 : positive) (b : block) (_ : @eq (option block) (@PTree.get block id1 x) (@Some block b)) (_ : @eq (option block) (@PTree.get block id2 x) (@Some block b)), @eq positive id1 id2 *)
eapply semax_ext'_void; eauto.
Qed.

End semax_ext.
