Class SemAxioms :=
        { (** If the [Cur] permission is below [Writable] on some location then
              a thread step cannot change the contents at this location *)
          corestep_unchanged_on:
            forall  c m c' m' b ofs
              (Hstep: corestep (msem semSem) c m c' m')
              (Hvalid: Mem.valid_block m b)
              (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));          
          (** Memories between thread steps are related by [decay] of permissions*)
          corestep_decay:
            forall c c' m m',
              corestep semSem c m c' m' ->
              decay m m';
          (** [Mem.nextblock] is monotonic with respect to thread steps*)
          corestep_nextblock:
            forall c m c' m',
              corestep semSem c m c' m' ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
          (** A core cannot be both at external and halted *)
          at_external_halted_excl:
            forall q m, at_external semSem q m = None \/ forall i, ~ halted semSem q i;
          (** If the [Cur] permission is below [Writable] on some location then
              [initial_core] cannot change the contents at this location *)
          initial_core_unchanged_on:
            forall  i v args c m m' b ofs
               (Hstep: initial_core semSem i m c m' v args)
               (Hvalid: Mem.valid_block m b)
               (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));
          (** Memories after [initial_core] are related by [decay] of permissions*)
          initial_core_decay:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              strong_decay m m';
          (** [Mem.nextblock] is monotonic with respect to [initial_core]*)
          initial_core_nextblock:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
        }.Class SemAxioms :=
        { (** If the [Cur] permission is below [Writable] on some location then
              a thread step cannot change the contents at this location *)
          corestep_unchanged_on:
            forall  c m c' m' b ofs
              (Hstep: corestep (msem semSem) c m c' m')
              (Hvalid: Mem.valid_block m b)
              (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));          
          (** Memories between thread steps are related by [decay] of permissions*)
          corestep_decay:
            forall c c' m m',
              corestep semSem c m c' m' ->
              decay m m';
          (** [Mem.nextblock] is monotonic with respect to thread steps*)
          corestep_nextblock:
            forall c m c' m',
              corestep semSem c m c' m' ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
          (** A core cannot be both at external and halted *)
          at_external_halted_excl:
            forall q m, at_external semSem q m = None \/ forall i, ~ halted semSem q i;
          (** If the [Cur] permission is below [Writable] on some location then
              [initial_core] cannot change the contents at this location *)
          initial_core_unchanged_on:
            forall  i v args c m m' b ofs
               (Hstep: initial_core semSem i m c m' v args)
               (Hvalid: Mem.valid_block m b)
               (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));
          (** Memories after [initial_core] are related by [decay] of permissions*)
          initial_core_decay:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              strong_decay m m';
          (** [Mem.nextblock] is monotonic with respect to [initial_core]*)
          initial_core_nextblock:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
        }.Class SemAxioms :=
        { (** If the [Cur] permission is below [Writable] on some location then
              a thread step cannot change the contents at this location *)
          corestep_unchanged_on:
            forall  c m c' m' b ofs
              (Hstep: corestep (msem semSem) c m c' m')
              (Hvalid: Mem.valid_block m b)
              (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));          
          (** Memories between thread steps are related by [decay] of permissions*)
          corestep_decay:
            forall c c' m m',
              corestep semSem c m c' m' ->
              decay m m';
          (** [Mem.nextblock] is monotonic with respect to thread steps*)
          corestep_nextblock:
            forall c m c' m',
              corestep semSem c m c' m' ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
          (** A core cannot be both at external and halted *)
          at_external_halted_excl:
            forall q m, at_external semSem q m = None \/ forall i, ~ halted semSem q i;
          (** If the [Cur] permission is below [Writable] on some location then
              [initial_core] cannot change the contents at this location *)
          initial_core_unchanged_on:
            forall  i v args c m m' b ofs
               (Hstep: initial_core semSem i m c m' v args)
               (Hvalid: Mem.valid_block m b)
               (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));
          (** Memories after [initial_core] are related by [decay] of permissions*)
          initial_core_decay:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              strong_decay m m';
          (** [Mem.nextblock] is monotonic with respect to [initial_core]*)
          initial_core_nextblock:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
        }.Class SemAxioms :=
        { (** If the [Cur] permission is below [Writable] on some location then
              a thread step cannot change the contents at this location *)
          corestep_unchanged_on:
            forall  c m c' m' b ofs
              (Hstep: corestep (msem semSem) c m c' m')
              (Hvalid: Mem.valid_block m b)
              (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));          
          (** Memories between thread steps are related by [decay] of permissions*)
          corestep_decay:
            forall c c' m m',
              corestep semSem c m c' m' ->
              decay m m';
          (** [Mem.nextblock] is monotonic with respect to thread steps*)
          corestep_nextblock:
            forall c m c' m',
              corestep semSem c m c' m' ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
          (** A core cannot be both at external and halted *)
          at_external_halted_excl:
            forall q m, at_external semSem q m = None \/ forall i, ~ halted semSem q i;
          (** If the [Cur] permission is below [Writable] on some location then
              [initial_core] cannot change the contents at this location *)
          initial_core_unchanged_on:
            forall  i v args c m m' b ofs
               (Hstep: initial_core semSem i m c m' v args)
               (Hvalid: Mem.valid_block m b)
               (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));
          (** Memories after [initial_core] are related by [decay] of permissions*)
          initial_core_decay:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              strong_decay m m';
          (** [Mem.nextblock] is monotonic with respect to [initial_core]*)
          initial_core_nextblock:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
        }.Class SemAxioms :=
        { (** If the [Cur] permission is below [Writable] on some location then
              a thread step cannot change the contents at this location *)
          corestep_unchanged_on:
            forall  c m c' m' b ofs
              (Hstep: corestep (msem semSem) c m c' m')
              (Hvalid: Mem.valid_block m b)
              (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));          
          (** Memories between thread steps are related by [decay] of permissions*)
          corestep_decay:
            forall c c' m m',
              corestep semSem c m c' m' ->
              decay m m';
          (** [Mem.nextblock] is monotonic with respect to thread steps*)
          corestep_nextblock:
            forall c m c' m',
              corestep semSem c m c' m' ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
          (** A core cannot be both at external and halted *)
          at_external_halted_excl:
            forall q m, at_external semSem q m = None \/ forall i, ~ halted semSem q i;
          (** If the [Cur] permission is below [Writable] on some location then
              [initial_core] cannot change the contents at this location *)
          initial_core_unchanged_on:
            forall  i v args c m m' b ofs
               (Hstep: initial_core semSem i m c m' v args)
               (Hvalid: Mem.valid_block m b)
               (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));
          (** Memories after [initial_core] are related by [decay] of permissions*)
          initial_core_decay:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              strong_decay m m';
          (** [Mem.nextblock] is monotonic with respect to [initial_core]*)
          initial_core_nextblock:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
        }.Class SemAxioms :=
        { (** If the [Cur] permission is below [Writable] on some location then
              a thread step cannot change the contents at this location *)
          corestep_unchanged_on:
            forall  c m c' m' b ofs
              (Hstep: corestep (msem semSem) c m c' m')
              (Hvalid: Mem.valid_block m b)
              (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));          
          (** Memories between thread steps are related by [decay] of permissions*)
          corestep_decay:
            forall c c' m m',
              corestep semSem c m c' m' ->
              decay m m';
          (** [Mem.nextblock] is monotonic with respect to thread steps*)
          corestep_nextblock:
            forall c m c' m',
              corestep semSem c m c' m' ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
          (** A core cannot be both at external and halted *)
          at_external_halted_excl:
            forall q m, at_external semSem q m = None \/ forall i, ~ halted semSem q i;
          (** If the [Cur] permission is below [Writable] on some location then
              [initial_core] cannot change the contents at this location *)
          initial_core_unchanged_on:
            forall  i v args c m m' b ofs
               (Hstep: initial_core semSem i m c m' v args)
               (Hvalid: Mem.valid_block m b)
               (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));
          (** Memories after [initial_core] are related by [decay] of permissions*)
          initial_core_decay:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              strong_decay m m';
          (** [Mem.nextblock] is monotonic with respect to [initial_core]*)
          initial_core_nextblock:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
        }.Class SemAxioms :=
        { (** If the [Cur] permission is below [Writable] on some location then
              a thread step cannot change the contents at this location *)
          corestep_unchanged_on:
            forall  c m c' m' b ofs
              (Hstep: corestep (msem semSem) c m c' m')
              (Hvalid: Mem.valid_block m b)
              (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));          
          (** Memories between thread steps are related by [decay] of permissions*)
          corestep_decay:
            forall c c' m m',
              corestep semSem c m c' m' ->
              decay m m';
          (** [Mem.nextblock] is monotonic with respect to thread steps*)
          corestep_nextblock:
            forall c m c' m',
              corestep semSem c m c' m' ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
          (** A core cannot be both at external and halted *)
          at_external_halted_excl:
            forall q m, at_external semSem q m = None \/ forall i, ~ halted semSem q i;
          (** If the [Cur] permission is below [Writable] on some location then
              [initial_core] cannot change the contents at this location *)
          initial_core_unchanged_on:
            forall  i v args c m m' b ofs
               (Hstep: initial_core semSem i m c m' v args)
               (Hvalid: Mem.valid_block m b)
               (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));
          (** Memories after [initial_core] are related by [decay] of permissions*)
          initial_core_decay:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              strong_decay m m';
          (** [Mem.nextblock] is monotonic with respect to [initial_core]*)
          initial_core_nextblock:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
        }.Class SemAxioms :=
        { (** If the [Cur] permission is below [Writable] on some location then
              a thread step cannot change the contents at this location *)
          corestep_unchanged_on:
            forall  c m c' m' b ofs
              (Hstep: corestep (msem semSem) c m c' m')
              (Hvalid: Mem.valid_block m b)
              (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));          
          (** Memories between thread steps are related by [decay] of permissions*)
          corestep_decay:
            forall c c' m m',
              corestep semSem c m c' m' ->
              decay m m';
          (** [Mem.nextblock] is monotonic with respect to thread steps*)
          corestep_nextblock:
            forall c m c' m',
              corestep semSem c m c' m' ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
          (** A core cannot be both at external and halted *)
          at_external_halted_excl:
            forall q m, at_external semSem q m = None \/ forall i, ~ halted semSem q i;
          (** If the [Cur] permission is below [Writable] on some location then
              [initial_core] cannot change the contents at this location *)
          initial_core_unchanged_on:
            forall  i v args c m m' b ofs
               (Hstep: initial_core semSem i m c m' v args)
               (Hvalid: Mem.valid_block m b)
               (Hstable: ~ Mem.perm m b ofs Cur Writable),
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m)) =
              Maps.ZMap.get ofs (Maps.PMap.get b (Mem.mem_contents m'));
          (** Memories after [initial_core] are related by [decay] of permissions*)
          initial_core_decay:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              strong_decay m m';
          (** [Mem.nextblock] is monotonic with respect to [initial_core]*)
          initial_core_nextblock:
            forall i v args c m m',
              initial_core semSem i m c m' v args ->
              (Mem.nextblock m <= Mem.nextblock m')%positive;
        }.Class SemDet :=
        { (** The thread semantics are deterministic*)
          corestep_det: corestep_fun semSem;
          (** [initial_core] is deterministic *)
          initial_core_det:
            forall i m v args c c' m' m'',
              initial_core semSem i m c m' v args ->
              initial_core semSem i m c' m'' v args ->
              c = c' /\ m' = m''
        }.Class SemDet :=
        { (** The thread semantics are deterministic*)
          corestep_det: corestep_fun semSem;
          (** [initial_core] is deterministic *)
          initial_core_det:
            forall i m v args c c' m' m'',
              initial_core semSem i m c m' v args ->
              initial_core semSem i m c' m'' v args ->
              c = c' /\ m' = m''
        }.Class SemDet :=
        { (** The thread semantics are deterministic*)
          corestep_det: corestep_fun semSem;
          (** [initial_core] is deterministic *)
          initial_core_det:
            forall i m v args c c' m' m'',
              initial_core semSem i m c m' v args ->
              initial_core semSem i m c' m'' v args ->
              c = c' /\ m' = m''
        }.

Lemma corestep_validblock: forall c m c' m', corestep semSem c m c' m' -> forall b, Mem.valid_block m b -> Mem.valid_block m' b.