Definition funspecOracle2pre (ext_link: Strings.String.string -> ident) (A : Type) (P : A -> Z -> environ -> mpred) (ids: list ident) (id: ident) sig (ef: external_function) x ge_s
           (tys : list typ) args z m : Prop :=
  match oi_eq_dec (Some (id, sig)) (ef_id_sig ext_link ef) as s
  return ((if s then (rmap * A)%type else ext_spec_type Espec ef) -> Prop)
  with
  | left _ =>
    fun x => exists phi0 phi1, join phi0 phi1 (m_phi m)
                       /\ P (snd x) z (make_ext_args (filter_genv (symb2genv ge_s)) ids args) phi0
                       /\ necR (fst x) phi1
  | right n => fun x' => ext_spec_pre Espec ef x' ge_s tys args z m
  end x.Definition funspecOracle2post (ext_link: Strings.String.string -> ident) (A : Type) (Q : A -> Z -> environ -> mpred)
                        id sig ef x ge_s (tret : option typ) ret z m : Prop :=
  match oi_eq_dec (Some (id, sig)) (ef_id_sig ext_link ef) as s
  return ((if s then (rmap * A)%type else ext_spec_type Espec ef) -> Prop)
  with
  | left _ =>
    fun x => exists phi0 phi1, join phi0 phi1 (m_phi m)
                       /\ Q (snd x) z (make_ext_rval (filter_genv (symb2genv ge_s)) ret) phi0
                       /\ necR (fst x) phi1
  | right n => fun x' => ext_spec_post Espec ef x' ge_s tret ret z m
  end x.Inductive funspecOracle : Type :=
  mk_funspecOracle : funsig -> calling_convention -> forall A : Type,
      (A -> Z -> environ -> mpred) ->
      (A -> Z -> environ -> mpred) -> funspecOracle.Inductive funspecOracle : Type :=
  mk_funspecOracle : funsig -> calling_convention -> forall A : Type,
      (A -> Z -> environ -> mpred) ->
      (A -> Z -> environ -> mpred) -> funspecOracle.Definition funspecOracle2extspec (ext_link: Strings.String.string -> ident) (f : ident * funspecOracle)
  : external_specification juicy_mem external_function Z :=
  match f with
    | (id, mk_funspecOracle ((params, sigret) as fsig) cc A P Q) =>
      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 * A)%type else ext_spec_type Espec ef)
        (funspecOracle2pre ext_link A P (fst (split params)) id sig)
        (funspecOracle2post ext_link A Q id sig)
        (fun rv z m => False)
  end.

(* Specifications: *)
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.
Lemma all_funspecsOracle_wf f : wf_funspecOracle f.