(* for now, giving up on the previously convenient add_funspecs because it is too much dependent now Definition add_funspecs (Espec : OracleKind) (ext_link: string -> ident) (fs : list (ident * funspecOracle Espec.(@OK_ty))) : OracleKind := match Espec as e return match e with Build_OracleKind ty _ => list (ident * funspecOracle ty) -> OracleKind end with | Build_OracleKind ty spec => fun fs => Build_OracleKind ty (add_funspecsOracle_rec ext_link ty spec fs) end fs. *)
(*! Adapting semax_external to a judgment mentioning oracles *)
Definition semax_external_oracle (Espec: OracleKind) (ids: list ident) ef (A: Type) (P Q: A -> Espec.(@OK_ty) -> environ -> pred rmap):
pred nat :=
ALL gx: genv, ALL x: A,
|>  ALL F: pred rmap, ALL ts: list typ, ALL args: list val, ALL z : Espec.(@OK_ty),
juicy_mem_op (P x z (make_ext_args (filter_genv gx) ids args) * F) >=>
EX x': ext_spec_type OK_spec ef,
ext_spec_pre' Espec ef x' (genv_symb_injective gx) ts args z &&
! ALL tret: option typ, ALL ret: option val, ALL z': OK_ty,
ext_spec_post' Espec ef x' (genv_symb_injective gx) tret ret z' >=>
juicy_mem_op (Q x z' (make_ext_rval (filter_genv gx) ret) * F).
Section semax_ext_oracle.
Variable Espec : OracleKind.
Local Notation ty := Espec.(@OK_ty).
Local Notation spec := Espec.(@OK_spec).

Lemma semax_ext'_oracle (ext_link: Strings.String.string -> ident) id sig cc A P Q (fs : list (ident * funspecOracle ty)) :
let f := mk_funspecOracle ty sig cc A P Q in
In (ext_link id, f) fs ->
list_norepet (map fst fs) ->
(forall n, semax_external_oracle
(Build_OracleKind _ (add_funspecsOracle_rec ext_link ty spec fs))
(fst (split (fst sig)))
(EF_external id (funsig2signature sig cc))
_ P Q n).