Record SM_Injection :=
  { locBlocksSrc : block -> bool;
                     (* The blocks allocated by THIS module in the
                        source language SRC*)
    locBlocksTgt : block -> bool;
                     (* The blocks allocated by THIS module in the
                        target language TGT*)
    pubBlocksSrc : block -> bool; (*subset of locBlocksSrc that have been
                        made public. Must be mapped by pubInj.*)
    pubBlocksTgt : block -> bool; (*subset of locBlocksTgt that have been
                        made public. Contains the image of pubInj.*)
    local_of: meminj; (* meminj on blocks allocated by THIS module.
                        Remains unchanged by external steps,
                        and is partitioned by pubBlocksSrc/Tgt into
                        exported (public)
                        and non-exporrted (private) component.  *)

    extBlocksSrc: block -> bool; (*blocks allocated by OTHER modules in SRC *)
    extBlocksTgt: block -> bool; (*blocks allocated by OTHER modules in TGT *)

    frgnBlocksSrc : block -> bool; (*subset of extBlocksSrc that have been
                        made visible to THIS module. Must be apped by foreign.*)
    frgnBlocksTgt : block -> bool; (*subset of extBlocksTgt that have been
                        made visible to THIS module. Contains image of foreign*)

    extern_of: meminj (* a meminj 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*)
}.Record SM_Injection :=
  { locBlocksSrc : block -> bool;
                     (* The blocks allocated by THIS module in the
                        source language SRC*)
    locBlocksTgt : block -> bool;
                     (* The blocks allocated by THIS module in the
                        target language TGT*)
    pubBlocksSrc : block -> bool; (*subset of locBlocksSrc that have been
                        made public. Must be mapped by pubInj.*)
    pubBlocksTgt : block -> bool; (*subset of locBlocksTgt that have been
                        made public. Contains the image of pubInj.*)
    local_of: meminj; (* meminj on blocks allocated by THIS module.
                        Remains unchanged by external steps,
                        and is partitioned by pubBlocksSrc/Tgt into
                        exported (public)
                        and non-exporrted (private) component.  *)

    extBlocksSrc: block -> bool; (*blocks allocated by OTHER modules in SRC *)
    extBlocksTgt: block -> bool; (*blocks allocated by OTHER modules in TGT *)

    frgnBlocksSrc : block -> bool; (*subset of extBlocksSrc that have been
                        made visible to THIS module. Must be apped by foreign.*)
    frgnBlocksTgt : block -> bool; (*subset of extBlocksTgt that have been
                        made visible to THIS module. Contains image of foreign*)

    extern_of: meminj (* a meminj 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*)
}.Record SM_Injection :=
  { locBlocksSrc : block -> bool;
                     (* The blocks allocated by THIS module in the
                        source language SRC*)
    locBlocksTgt : block -> bool;
                     (* The blocks allocated by THIS module in the
                        target language TGT*)
    pubBlocksSrc : block -> bool; (*subset of locBlocksSrc that have been
                        made public. Must be mapped by pubInj.*)
    pubBlocksTgt : block -> bool; (*subset of locBlocksTgt that have been
                        made public. Contains the image of pubInj.*)
    local_of: meminj; (* meminj on blocks allocated by THIS module.
                        Remains unchanged by external steps,
                        and is partitioned by pubBlocksSrc/Tgt into
                        exported (public)
                        and non-exporrted (private) component.  *)

    extBlocksSrc: block -> bool; (*blocks allocated by OTHER modules in SRC *)
    extBlocksTgt: block -> bool; (*blocks allocated by OTHER modules in TGT *)

    frgnBlocksSrc : block -> bool; (*subset of extBlocksSrc that have been
                        made visible to THIS module. Must be apped by foreign.*)
    frgnBlocksTgt : block -> bool; (*subset of extBlocksTgt that have been
                        made visible to THIS module. Contains image of foreign*)

    extern_of: meminj (* a meminj 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*)
}.Record SM_Injection :=
  { locBlocksSrc : block -> bool;
                     (* The blocks allocated by THIS module in the
                        source language SRC*)
    locBlocksTgt : block -> bool;
                     (* The blocks allocated by THIS module in the
                        target language TGT*)
    pubBlocksSrc : block -> bool; (*subset of locBlocksSrc that have been
                        made public. Must be mapped by pubInj.*)
    pubBlocksTgt : block -> bool; (*subset of locBlocksTgt that have been
                        made public. Contains the image of pubInj.*)
    local_of: meminj; (* meminj on blocks allocated by THIS module.
                        Remains unchanged by external steps,
                        and is partitioned by pubBlocksSrc/Tgt into
                        exported (public)
                        and non-exporrted (private) component.  *)

    extBlocksSrc: block -> bool; (*blocks allocated by OTHER modules in SRC *)
    extBlocksTgt: block -> bool; (*blocks allocated by OTHER modules in TGT *)

    frgnBlocksSrc : block -> bool; (*subset of extBlocksSrc that have been
                        made visible to THIS module. Must be apped by foreign.*)
    frgnBlocksTgt : block -> bool; (*subset of extBlocksTgt that have been
                        made visible to THIS module. Contains image of foreign*)

    extern_of: meminj (* a meminj 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*)
}.Record SM_Injection :=
  { locBlocksSrc : block -> bool;
                     (* The blocks allocated by THIS module in the
                        source language SRC*)
    locBlocksTgt : block -> bool;
                     (* The blocks allocated by THIS module in the
                        target language TGT*)
    pubBlocksSrc : block -> bool; (*subset of locBlocksSrc that have been
                        made public. Must be mapped by pubInj.*)
    pubBlocksTgt : block -> bool; (*subset of locBlocksTgt that have been
                        made public. Contains the image of pubInj.*)
    local_of: meminj; (* meminj on blocks allocated by THIS module.
                        Remains unchanged by external steps,
                        and is partitioned by pubBlocksSrc/Tgt into
                        exported (public)
                        and non-exporrted (private) component.  *)

    extBlocksSrc: block -> bool; (*blocks allocated by OTHER modules in SRC *)
    extBlocksTgt: block -> bool; (*blocks allocated by OTHER modules in TGT *)

    frgnBlocksSrc : block -> bool; (*subset of extBlocksSrc that have been
                        made visible to THIS module. Must be apped by foreign.*)
    frgnBlocksTgt : block -> bool; (*subset of extBlocksTgt that have been
                        made visible to THIS module. Contains image of foreign*)

    extern_of: meminj (* a meminj 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*)
}.Record SM_Injection :=
  { locBlocksSrc : block -> bool;
                     (* The blocks allocated by THIS module in the
                        source language SRC*)
    locBlocksTgt : block -> bool;
                     (* The blocks allocated by THIS module in the
                        target language TGT*)
    pubBlocksSrc : block -> bool; (*subset of locBlocksSrc that have been
                        made public. Must be mapped by pubInj.*)
    pubBlocksTgt : block -> bool; (*subset of locBlocksTgt that have been
                        made public. Contains the image of pubInj.*)
    local_of: meminj; (* meminj on blocks allocated by THIS module.
                        Remains unchanged by external steps,
                        and is partitioned by pubBlocksSrc/Tgt into
                        exported (public)
                        and non-exporrted (private) component.  *)

    extBlocksSrc: block -> bool; (*blocks allocated by OTHER modules in SRC *)
    extBlocksTgt: block -> bool; (*blocks allocated by OTHER modules in TGT *)

    frgnBlocksSrc : block -> bool; (*subset of extBlocksSrc that have been
                        made visible to THIS module. Must be apped by foreign.*)
    frgnBlocksTgt : block -> bool; (*subset of extBlocksTgt that have been
                        made visible to THIS module. Contains image of foreign*)

    extern_of: meminj (* a meminj 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*)
}.Record SM_Injection :=
  { locBlocksSrc : block -> bool;
                     (* The blocks allocated by THIS module in the
                        source language SRC*)
    locBlocksTgt : block -> bool;
                     (* The blocks allocated by THIS module in the
                        target language TGT*)
    pubBlocksSrc : block -> bool; (*subset of locBlocksSrc that have been
                        made public. Must be mapped by pubInj.*)
    pubBlocksTgt : block -> bool; (*subset of locBlocksTgt that have been
                        made public. Contains the image of pubInj.*)
    local_of: meminj; (* meminj on blocks allocated by THIS module.
                        Remains unchanged by external steps,
                        and is partitioned by pubBlocksSrc/Tgt into
                        exported (public)
                        and non-exporrted (private) component.  *)

    extBlocksSrc: block -> bool; (*blocks allocated by OTHER modules in SRC *)
    extBlocksTgt: block -> bool; (*blocks allocated by OTHER modules in TGT *)

    frgnBlocksSrc : block -> bool; (*subset of extBlocksSrc that have been
                        made visible to THIS module. Must be apped by foreign.*)
    frgnBlocksTgt : block -> bool; (*subset of extBlocksTgt that have been
                        made visible to THIS module. Contains image of foreign*)

    extern_of: meminj (* a meminj 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*)
}.Record SM_Injection :=
  { locBlocksSrc : block -> bool;
                     (* The blocks allocated by THIS module in the
                        source language SRC*)
    locBlocksTgt : block -> bool;
                     (* The blocks allocated by THIS module in the
                        target language TGT*)
    pubBlocksSrc : block -> bool; (*subset of locBlocksSrc that have been
                        made public. Must be mapped by pubInj.*)
    pubBlocksTgt : block -> bool; (*subset of locBlocksTgt that have been
                        made public. Contains the image of pubInj.*)
    local_of: meminj; (* meminj on blocks allocated by THIS module.
                        Remains unchanged by external steps,
                        and is partitioned by pubBlocksSrc/Tgt into
                        exported (public)
                        and non-exporrted (private) component.  *)

    extBlocksSrc: block -> bool; (*blocks allocated by OTHER modules in SRC *)
    extBlocksTgt: block -> bool; (*blocks allocated by OTHER modules in TGT *)

    frgnBlocksSrc : block -> bool; (*subset of extBlocksSrc that have been
                        made visible to THIS module. Must be apped by foreign.*)
    frgnBlocksTgt : block -> bool; (*subset of extBlocksTgt that have been
                        made visible to THIS module. Contains image of foreign*)

    extern_of: meminj (* a meminj 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*)
}.Record SM_Injection :=
  { locBlocksSrc : block -> bool;
                     (* The blocks allocated by THIS module in the
                        source language SRC*)
    locBlocksTgt : block -> bool;
                     (* The blocks allocated by THIS module in the
                        target language TGT*)
    pubBlocksSrc : block -> bool; (*subset of locBlocksSrc that have been
                        made public. Must be mapped by pubInj.*)
    pubBlocksTgt : block -> bool; (*subset of locBlocksTgt that have been
                        made public. Contains the image of pubInj.*)
    local_of: meminj; (* meminj on blocks allocated by THIS module.
                        Remains unchanged by external steps,
                        and is partitioned by pubBlocksSrc/Tgt into
                        exported (public)
                        and non-exporrted (private) component.  *)

    extBlocksSrc: block -> bool; (*blocks allocated by OTHER modules in SRC *)
    extBlocksTgt: block -> bool; (*blocks allocated by OTHER modules in TGT *)

    frgnBlocksSrc : block -> bool; (*subset of extBlocksSrc that have been
                        made visible to THIS module. Must be apped by foreign.*)
    frgnBlocksTgt : block -> bool; (*subset of extBlocksTgt that have been
                        made visible to THIS module. Contains image of foreign*)

    extern_of: meminj (* a meminj 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*)
}.Record SM_Injection :=
  { locBlocksSrc : block -> bool;
                     (* The blocks allocated by THIS module in the
                        source language SRC*)
    locBlocksTgt : block -> bool;
                     (* The blocks allocated by THIS module in the
                        target language TGT*)
    pubBlocksSrc : block -> bool; (*subset of locBlocksSrc that have been
                        made public. Must be mapped by pubInj.*)
    pubBlocksTgt : block -> bool; (*subset of locBlocksTgt that have been
                        made public. Contains the image of pubInj.*)
    local_of: meminj; (* meminj on blocks allocated by THIS module.
                        Remains unchanged by external steps,
                        and is partitioned by pubBlocksSrc/Tgt into
                        exported (public)
                        and non-exporrted (private) component.  *)

    extBlocksSrc: block -> bool; (*blocks allocated by OTHER modules in SRC *)
    extBlocksTgt: block -> bool; (*blocks allocated by OTHER modules in TGT *)

    frgnBlocksSrc : block -> bool; (*subset of extBlocksSrc that have been
                        made visible to THIS module. Must be apped by foreign.*)
    frgnBlocksTgt : block -> bool; (*subset of extBlocksTgt that have been
                        made visible to THIS module. Contains image of foreign*)

    extern_of: meminj (* a meminj 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*)
}.Record SM_Injection :=
  { locBlocksSrc : block -> bool;
                     (* The blocks allocated by THIS module in the
                        source language SRC*)
    locBlocksTgt : block -> bool;
                     (* The blocks allocated by THIS module in the
                        target language TGT*)
    pubBlocksSrc : block -> bool; (*subset of locBlocksSrc that have been
                        made public. Must be mapped by pubInj.*)
    pubBlocksTgt : block -> bool; (*subset of locBlocksTgt that have been
                        made public. Contains the image of pubInj.*)
    local_of: meminj; (* meminj on blocks allocated by THIS module.
                        Remains unchanged by external steps,
                        and is partitioned by pubBlocksSrc/Tgt into
                        exported (public)
                        and non-exporrted (private) component.  *)

    extBlocksSrc: block -> bool; (*blocks allocated by OTHER modules in SRC *)
    extBlocksTgt: block -> bool; (*blocks allocated by OTHER modules in TGT *)

    frgnBlocksSrc : block -> bool; (*subset of extBlocksSrc that have been
                        made visible to THIS module. Must be apped by foreign.*)
    frgnBlocksTgt : block -> bool; (*subset of extBlocksTgt that have been
                        made visible to THIS module. Contains image of foreign*)

    extern_of: meminj (* a meminj 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*)
}.(*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.

(* Specifications: *)
Lemma local_pubpriv: forall mu, local_of mu = join (pub_of mu) (priv_of mu).