(*Require Import ExtAxioms.*)
(*Will need : *)
Require Export Coq.Logic.FunctionalExtensionality.
Notation val_inject:= Val.inject.
(** * Structured Injections *)
Record SM_Injection :=
{ (** The blocks allocated by *this* module in the source language. *)
locBlocksSrc : block -> bool
(** The blocks allocated by *this* module in the target language. *)
; locBlocksTgt : block -> bool
(** The subset of local source blocks that have been made public. Must be mapped. *)
; pubBlocksSrc : block -> bool
(** The subset of local target blocks that have been made public. Contains the image of the public source blocks. *)
; pubBlocksTgt : block -> bool
(** Memory injection on blocks allocated by *this* module. *)
; local_of: meminj
(** The blocks allocated by *other* modules at the source level. *)
; extBlocksSrc: block -> bool
(** The blocks allocated by *other* modules at the target level. *)
; extBlocksTgt: block -> bool
(** The subset of extern source blocks that have been made public. Must be mapped. *)
; frgnBlocksSrc : block -> bool
(** The subset of extern source blocks that have been made public. Must be mapped. *)
; frgnBlocksTgt : block -> bool
(** Memory injection on blocks allocated by OTHER modules; the injection is not modified by coresteps, and is partitioned by frgnBlocksSrc/Tgt into foreign (leaked to this module) and unknown (non-leaked) components, where the former blocks are accessible by *this* module. This module behaves uniformly over block mentioned by frgnInj, and assumes that blocks in frgnInj remain mapped. Compilation of *this* module neither merges nor unmaps blocks from here, nor does it spill into them. *)
; extern_of: meminj }.
(** The four projections: *)
Definition unknown_of (mu: SM_Injection) : meminj :=
match mu with
Build_SM_Injection locBSrc locBTgt pSrc pTgt local extBSrc extBTgt fSrc fTgt extern =>
fun b => if locBSrc b then None else if fSrc b then None else extern b
end.
Definition foreign_of (mu: SM_Injection) : meminj :=
match mu with
Build_SM_Injection locBSrc locBTgt pSrc pTgt local extBSrc extBTgt fSrc fTgt extern =>
fun b => if fSrc b then extern b else None
end.
Definition pub_of (mu: SM_Injection) : meminj :=
match mu with
Build_SM_Injection locBSrc locBTgt pSrc pTgt local extBSrc extBTgt fSrc fTgt extern =>
fun b => if pSrc b then local b else None
end.
Definition priv_of (mu: SM_Injection) : meminj :=
match mu with
Build_SM_Injection locBSrc locBTgt pSrc pTgt local extBSrc extBTgt fSrc fTgt extern =>
fun b => if pSrc b then None else local b
end.
(** * Lemmas *)
Definition join (j k:meminj):meminj := fun b =>
match j b with
Some (b1, delta) => Some (b1,delta)
| None => k b
end.
Definition disjoint (j k:meminj):Prop :=
forall b, j b = None \/ k b = None.
Definition shared_of (mu: SM_Injection) : meminj :=
join (foreign_of mu) (pub_of mu).
Record SM_wd (mu:SM_Injection):Prop := {
disjoint_extern_local_Src: forall b, locBlocksSrc mu b = false \/ extBlocksSrc mu b = false;
disjoint_extern_local_Tgt: forall b, locBlocksTgt mu b = false \/ extBlocksTgt mu b = false;
local_DomRng: forall b1 b2 z, local_of mu b1 = Some(b2,z) ->
(locBlocksSrc mu b1 = true /\ locBlocksTgt mu b2 = true);
extern_DomRng: forall b1 b2 z, extern_of mu b1 = Some(b2,z) ->
(extBlocksSrc mu b1 = true /\ extBlocksTgt mu b2 = true);
pubSrcAx: forall b1, pubBlocksSrc mu b1 = true ->
exists b2 z, local_of mu b1 = Some(b2,z) /\
pubBlocksTgt mu b2 = true;
frgnSrcAx: forall b1, frgnBlocksSrc mu b1 = true ->
exists b2 z, extern_of mu b1 = Some(b2,z) /\
frgnBlocksTgt mu b2 = true;
pubBlocksLocalTgt: forall b, pubBlocksTgt mu b = true ->
locBlocksTgt mu b = true;
frgnBlocksExternTgt: forall b, frgnBlocksTgt mu b = true ->
extBlocksTgt mu b = true
}.

Lemma pubTgtContra: forall mu (WD: SM_wd mu) b2, pubBlocksTgt mu b2 = false ->
~ exists b1 d, pub_of mu b1 = Some(b2,d).