Definition functions_safe G F :=
  forall f, match funspecs G f, F f with
       | Some P, Some p =>
         forall m oracle, P m -> safe step (G, oracle, m, p)
       | None, None => True
       | _, _ => False
       end.Ltac funspecs_inv :=
  match goal with
  | FF : functions_safe ?G ?F |- _ =>
    match goal with
    | FSf : funspecs G ?f = Some _ |- _ =>
      let H := fresh "Hsafe" in
      let p := fresh "p" in
      let E := fresh "E" in
      pose proof FF f as H;
      destruct (F f) as [p|] eqn:E;
      rewrite FSf in H; [|tauto]
    | Ff : F ?f = Some _ |- _ =>
      let H := fresh "Hsafe" in
      let P := fresh "PRE" in
      let E := fresh "E" in
      pose proof FF f as H;
      destruct (funspecs G f) as [P|] eqn:E;
      rewrite Ff in H; [|tauto]
    end
  end.(* Our invariant:
 - resource invariants are precise (no need for them to be positive)
 - all the functions are safe (given a precondition)
 - lock pool maps and threads maps are disjoint
 - lock pool maps match the resource invariants
 - all threads are safe for n steps
*)

Definition P (x : config) :=
  match x with (_, F, G, thd, pool) =>
    (forall l, precise (resinvs G l)) /\
    functions_safe G F /\
    selfjoins (reindex thd pool) /\
    lockpool_matches pool (resinvs G) /\
    (forall i oracle m p,
        nth thd i = Some (m, p) ->
        safe step (G, oracle, m, p))
  end.

(* Specifications: *)
Theorem progress x : P x -> exists y, x ===> y.
Theorem subject_reduction x y : x ===> y -> P x -> P y.
Lemma P_safe x : P x -> safe machine x.
Theorem soundness sch F G thd pool : (forall l, precise (resinvs G l)) -> selfjoins (reindex thd pool) -> lockpool_matches pool (resinvs G) -> functions_safe G F -> (forall i oracle m p, nth thd i = Some (m, p) -> safe step (G, oracle, m, p)) -> safe machine (sch, F, G, thd, pool).
Lemma semax_app G P Q R c1 c2 : semax G P c1 Q -> semax G Q c2 R -> semax G P (c1++c2) R.
Lemma semax_nil G P : semax G P nil P.
Lemma semax_cons G P Q R i c : semax G P (i :: nil) Q -> semax G Q c R -> semax G P (i :: c) R.
Lemma updatemap_mapsto_ x n' n m : (mapsto_ x m \/ mapsto x n' m) -> exists m', updatemap m x n = Some m' /\ mapsto x n m'.
Lemma semax_set G x e : semax G (mapsto_ x) (set x e :: nil) (mapsto x e).
Lemma semax_assert G x n : n <> 0 -> semax G (mapsto x n) (assert x :: nil) (mapsto x n).
Lemma safe_onethread_implies G (P P' : pred) c : imp P' P -> safe_onethread G P c -> safe_onethread G P' c.
Lemma semax_acquire' G l : (forall P, P \/ ~P) -> semax G emp (acquire l :: nil) (resinvs G l).
Lemma semax_pre G (P P' : pred) c Q : imp P' P -> semax G P c Q -> semax G P' c Q.
Lemma semax_post G P c (Q Q' : pred) : imp Q Q' -> semax G P c Q -> semax G P c Q'.
Lemma semax_release' G l : precise (resinvs G l) -> semax G (resinvs G l) (release l :: nil) emp.
Lemma safe_nil G P : safe_onethread G P nil.
Lemma semax_safe G P c : semax G P c TT -> safe_onethread G P c.