(*+ Definition of safety *)
(* We define safety based on specification of externals (acquire and release) *)
(* no need for an oracle, so it is unit *)
Definition Z := unit.
Record ext : Type := mkext {
ext_type : Type;
Pre : ext_type -> Z -> map -> Prop;
Post : ext_type -> Z -> map -> Prop
}.
Definition after_external : C -> option C :=
fun c =>
match c with
| acquire _ k => Some k
| release _ k => Some k
| _ => None
end.
(* [Hrel] is related to step indexing levels, and specify that the PURE of the maps coincide, which is always implied by joinability *)
Variable Hrel : nat -> map -> map -> Prop.

(* Specifications: *)
Axiom join_Hrel1 : forall m1 m2 m3 n, join m1 m2 m3 -> Hrel n m3 m1.
Axiom join_Hrel2 : forall m1 m2 m3 n, join m1 m2 m3 -> Hrel n m1 m3.
Inductive safeN_ (at_ext : C -> option ext) : nat -> Z -> C -> map -> Prop :=
safeN_0 : forall (z : Z) (c : C) (m : map), safeN_ at_ext 0 z c m
| safeN_step : forall (n : nat) (z : Z) (c c' : C') (m m' : map),
corestep c m c' m' ->
safeN_ at_ext n z (normal c') m' ->
safeN_ at_ext (S n) z (normal c) m
| safeN_external : forall (n : nat) (z : Z) (c : C) (m : map) (e : ext) (x : ext_type e),
at_ext c = Some e ->
Pre e x z m ->
(forall (m' : map) (z' : Z) (n' : nat),
n' <= n ->
Hrel n' m m' ->
Post e x z' m' ->
exists c' : C,
after_external c = Some c' /\
safeN_ at_ext n' z' c' m') ->
safeN_ at_ext (S n) z c m.
Lemma safeN_S at_ext n z c m : safeN_ at_ext (S n) z c m -> safeN_ at_ext n z c m.
Lemma strong_nat_ind (P : nat -> Prop) (IH : forall n, (forall i, i < n -> P i) -> P n) n : P n.
Definition acquire_spec l : ext :=
mkext
(nat * (map -> Prop))
(fun x Ω m =>
match x with
| (lx, Rx) =>
lx = l /\
islock l Rx m
end)
(fun x Ω m =>
exists m1 m2,
join m1 m2 m /\
match x with
| (lx, Rx) =>
islock lx Rx m1 /\
Rx m2
end).