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
}.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
}.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
}.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
}.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
}.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
}.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
}.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
}.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
}.

(* Specifications: *)
Lemma pubSrc: forall mu (WD: SM_wd mu) b1, pubBlocksSrc mu b1 = true -> exists b2 z, pub_of mu b1 = Some(b2,z) /\ pubBlocksTgt mu b2 = true.
Lemma frgnSrc: forall mu (WD: SM_wd mu) b1, frgnBlocksSrc mu b1 = true -> exists b2 z, foreign_of mu b1 = Some(b2,z) /\ frgnBlocksTgt mu b2 = true.
Lemma extBlocksSrc_locBlocksSrc: forall mu (WD: SM_wd mu) b, extBlocksSrc mu b = true -> locBlocksSrc mu b = false.
Lemma extBlocksTgt_locBlocksTgt: forall mu (WD: SM_wd mu) b, extBlocksTgt mu b = true -> locBlocksTgt mu b = false.
Lemma locBlocksSrc_extBlocksSrc: forall mu (WD: SM_wd mu) b, locBlocksSrc mu b = true -> extBlocksSrc mu b = false.
Lemma locBlocksTgt_extBlocksTgt: forall mu (WD: SM_wd mu) b, locBlocksTgt mu b = true -> extBlocksTgt mu b = false.
Lemma pubBlocksLocalSrc: forall mu (WD: SM_wd mu) b, pubBlocksSrc mu b = true -> locBlocksSrc mu b = true.
Lemma frgnBlocksSrc_extBlocksSrc: forall mu (WD: SM_wd mu) b, frgnBlocksSrc mu b = true -> extBlocksSrc mu b = true.
Lemma locBlocksSrc_externNone: forall mu (WD:SM_wd mu) b (MB: locBlocksSrc mu b = true), extern_of mu b = None.
Lemma locBlocksSrc_foreignNone: forall mu (WD:SM_wd mu) b (MB: locBlocksSrc mu b = true), foreign_of mu b = None.
Lemma frgnBlocksSrc_locBlocksSrc: forall mu (WD:SM_wd mu) b (FB: frgnBlocksSrc mu b = true), locBlocksSrc mu b = false.
Lemma locBlocksSrc_frgnBlocksSrc: forall mu (WD:SM_wd mu) b (MB: locBlocksSrc mu b = true), frgnBlocksSrc mu b = false.
Lemma locBlocksTgt_frgnBlocksTgt: forall mu (WD:SM_wd mu) b (MB: locBlocksTgt mu b = true), frgnBlocksTgt mu b = false.
Lemma frgnBlocksTgt_locBlocksTgt: forall mu (WD:SM_wd mu) b (FB: frgnBlocksTgt mu b = true), locBlocksTgt mu b = false.
Lemma locBlocksTgt_frgnBlocksTgt_D: forall mu (WD:SM_wd mu) b (MB: locBlocksTgt mu b = true) (FB: frgnBlocksTgt mu b = true), False.
Lemma locBlocksSrc_unknownNone: forall mu (WD:SM_wd mu) b (MB: locBlocksSrc mu b = true), unknown_of mu b = None.
Lemma extern_foreignunknown: forall mu (WD: SM_wd mu), extern_of mu = join (foreign_of mu) (unknown_of mu).
Lemma pubChar: forall mu (WD: SM_wd mu) b1 b2 z, pub_of mu b1 = Some(b2,z) -> pubBlocksSrc mu b1 = true /\ pubBlocksTgt mu b2 = true.
Lemma privChar: forall mu b1 b2 z, priv_of mu b1 = Some(b2,z) -> pubBlocksSrc mu b1 = false.
Lemma pubSrcContra: forall mu b1, pubBlocksSrc mu b1 = false -> pub_of mu b1 = None.
Lemma pubTgtContra: forall mu (WD: SM_wd mu) b2, pubBlocksTgt mu b2 = false -> ~ exists b1 d, pub_of mu b1 = Some(b2,d).
Lemma disjoint_extern_local: forall mu (WD: SM_wd mu), disjoint (extern_of mu) (local_of mu).
Lemma disjoint_foreign_pub: forall mu (WD: SM_wd mu), disjoint (foreign_of mu) (pub_of mu).
Lemma pub_in_shared: forall mu (WD: SM_wd mu), inject_incr (pub_of mu) (shared_of mu).
Lemma pubSrc: forall mu (WD: SM_wd mu) b1, pubBlocksSrc mu b1 = true -> exists b2 z, pub_of mu b1 = Some(b2,z) /\ pubBlocksTgt mu b2 = true.
Lemma frgnSrc: forall mu (WD: SM_wd mu) b1, frgnBlocksSrc mu b1 = true -> exists b2 z, foreign_of mu b1 = Some(b2,z) /\ frgnBlocksTgt mu b2 = true.
Lemma extBlocksSrc_locBlocksSrc: forall mu (WD: SM_wd mu) b, extBlocksSrc mu b = true -> locBlocksSrc mu b = false.
Lemma extBlocksTgt_locBlocksTgt: forall mu (WD: SM_wd mu) b, extBlocksTgt mu b = true -> locBlocksTgt mu b = false.
Lemma locBlocksSrc_extBlocksSrc: forall mu (WD: SM_wd mu) b, locBlocksSrc mu b = true -> extBlocksSrc mu b = false.
Lemma locBlocksTgt_extBlocksTgt: forall mu (WD: SM_wd mu) b, locBlocksTgt mu b = true -> extBlocksTgt mu b = false.
Lemma pubBlocksLocalSrc: forall mu (WD: SM_wd mu) b, pubBlocksSrc mu b = true -> locBlocksSrc mu b = true.
Lemma frgnBlocksSrc_extBlocksSrc: forall mu (WD: SM_wd mu) b, frgnBlocksSrc mu b = true -> extBlocksSrc mu b = true.
Lemma locBlocksSrc_externNone: forall mu (WD:SM_wd mu) b (MB: locBlocksSrc mu b = true), extern_of mu b = None.
Lemma locBlocksSrc_foreignNone: forall mu (WD:SM_wd mu) b (MB: locBlocksSrc mu b = true), foreign_of mu b = None.
Lemma frgnBlocksSrc_locBlocksSrc: forall mu (WD:SM_wd mu) b (FB: frgnBlocksSrc mu b = true), locBlocksSrc mu b = false.
Lemma locBlocksSrc_frgnBlocksSrc: forall mu (WD:SM_wd mu) b (MB: locBlocksSrc mu b = true), frgnBlocksSrc mu b = false.
Lemma locBlocksTgt_frgnBlocksTgt: forall mu (WD:SM_wd mu) b (MB: locBlocksTgt mu b = true), frgnBlocksTgt mu b = false.
Lemma frgnBlocksTgt_locBlocksTgt: forall mu (WD:SM_wd mu) b (FB: frgnBlocksTgt mu b = true), locBlocksTgt mu b = false.
Lemma locBlocksTgt_frgnBlocksTgt_D: forall mu (WD:SM_wd mu) b (MB: locBlocksTgt mu b = true) (FB: frgnBlocksTgt mu b = true), False.
Lemma locBlocksSrc_unknownNone: forall mu (WD:SM_wd mu) b (MB: locBlocksSrc mu b = true), unknown_of mu b = None.
Lemma extern_foreignunknown: forall mu (WD: SM_wd mu), extern_of mu = join (foreign_of mu) (unknown_of mu).
Lemma pubChar: forall mu (WD: SM_wd mu) b1 b2 z, pub_of mu b1 = Some(b2,z) -> pubBlocksSrc mu b1 = true /\ pubBlocksTgt mu b2 = true.
Lemma privChar: forall mu b1 b2 z, priv_of mu b1 = Some(b2,z) -> pubBlocksSrc mu b1 = false.
Lemma pubSrcContra: forall mu b1, pubBlocksSrc mu b1 = false -> pub_of mu b1 = None.
Lemma pubTgtContra: forall mu (WD: SM_wd mu) b2, pubBlocksTgt mu b2 = false -> ~ exists b1 d, pub_of mu b1 = Some(b2,d).
Lemma disjoint_extern_local: forall mu (WD: SM_wd mu), disjoint (extern_of mu) (local_of mu).
Lemma disjoint_foreign_pub: forall mu (WD: SM_wd mu), disjoint (foreign_of mu) (pub_of mu).
Lemma pub_in_shared: forall mu (WD: SM_wd mu), inject_incr (pub_of mu) (shared_of mu).