Definition mpred : Type := predicates_hered.pred rmap.
Instance Nm: seplog.NatDed mpred := alg_seplog.algNatDed rmap.
Instance Sm: seplog.SepLog mpred := alg_seplog.algSepLog rmap.
Instance Cm: seplog.ClassicalSep mpred := alg_seplog.algClassicalSep rmap.
Instance Im: seplog.Indir mpred := alg_seplog.algIndir rmap.
Instance Rm: alg_seplog.RecIndir mpred := alg_seplog.algRecIndir rmap.
Instance SIm: seplog.SepIndir mpred := alg_seplog.algSepIndir rmap.
Instance SRm: alg_seplog.SepRec mpred := alg_seplog.algSepRec rmap.
Definition guard (p: program) (G: funspecs) (vars: varset) (P : assert) (k: control) : pred nat :=
ALL s:env, P s && funassert G >=> assert_safe p vars k s.
Record semaxArg :Type := SemaxArg {
sa_vars: varset;
sa_P: assert;
sa_c: control
}.
Definition believe (semax: semaxArg -> pred nat)
(p: program) (P: funspec) (f: adr) : pred nat :=
EX k: list var * control,
!!(table_get p f = Some k /\ length (fst k) = length (fst P) /\ list_norepet (fst k)) &&
|> semax (SemaxArg (fst k) (fun s => call P (map s (fst k))) (snd k)).
Definition believe_all (semax: semaxArg -> pred nat) (G: funspecs) (p: program) (G': funspecs) : pred nat :=
ALL v:adr, ALL args: list var, ALL P: assert,
!! (table_get G' v = Some (args,P)) -->
believe semax p (args, fun s => P s && funassert G) v.
Definition semax_ (semax: semaxArg -> pred nat) (a: semaxArg) : pred nat :=
match a with SemaxArg vars P c =>
ALL p: program, ALL G: funspecs, believe_all semax G p G --> guard p G vars P c
end.

(* Specifications: *)
Lemma prop_imp {A}{agA: ageable A}:
forall (P: Prop) (Q: pred A) w, (P -> app_pred Q w) -> app_pred (!!P --> Q) w.
Lemma HOcontractive_semax_ : HOcontractive semax_.
Definition semax'  := HORec semax_.
Lemma semax'_unfold: forall vars P c,
semax' (SemaxArg vars P c) =
ALL p: program, ALL G:funspecs, believe_all semax' G p G --> guard p G vars P c.