Definition obox (Delta: tycontext) (i: ident) (P: environ -> mpred): environ -> mpred :=
ALL v: _,
match ((temp_types Delta) ! i) with
| Some t => !! (tc_val' t v) --> subst i (`v) P
| _ => TT
end.
Definition odia (Delta: tycontext) (i: ident) (P: environ -> mpred): environ -> mpred :=
EX v: _,
match ((temp_types Delta) ! i) with
| Some t => !! (tc_val' t v) && subst i (`v) P
| _ => FF
end.

(* Specifications: *)
Lemma obox_closed_wrt: forall Delta id P, closed_wrt_vars (eq id) (obox Delta id P).
Lemma odia_closed_wrt: forall Delta id P, closed_wrt_vars (eq id) (odia Delta id P).
Lemma subst_obox: forall Delta id v (P: environ -> mpred), subst id (`v) (obox Delta id P) = obox Delta id P.
Lemma subst_odia: forall Delta id v (P: environ -> mpred), subst id (`v) (odia Delta id P) = odia Delta id P.
Definition temp_guard (Delta : tycontext) (i: ident): Prop :=
(temp_types Delta) ! i <> None.
Lemma obox_closed: forall Delta i P, temp_guard Delta i -> closed_wrt_vars (eq i) P -> obox Delta i P = P.
Lemma obox_odia: forall Delta i P, temp_guard Delta i -> obox Delta i (odia Delta i P) = odia Delta i P.
Lemma obox_K: forall Delta i P Q, P |-- Q -> obox Delta i P |-- obox Delta i Q.
Lemma obox_T: forall Delta i (P: environ -> mpred),
temp_guard Delta i ->
local (tc_environ Delta) && obox Delta i P |-- P.
Lemma odia_D: forall Delta i (P: environ -> mpred),
temp_guard Delta i ->
local (tc_environ Delta) && P |-- odia Delta i P.
Lemma odia_derives_EX_subst: forall Delta i P,
odia Delta i P |-- EX v : val, subst i (` v) P.
Lemma obox_left2: forall Delta i P Q,
temp_guard Delta i ->
local (tc_environ Delta) && P |-- Q ->
local (tc_environ Delta) && obox Delta i P |-- obox Delta i Q.
Lemma obox_left2': forall Delta i P Q,
temp_guard Delta i ->
local (tc_environ Delta) && (allp_fun_id Delta && P) |-- Q ->
local (tc_environ Delta) && (allp_fun_id Delta && obox Delta i P) |-- obox Delta i Q.
Lemma obox_sepcon: forall Delta i P Q,
obox Delta i P * obox Delta i Q |-- obox Delta i (P * Q).