(** * Effect Semantics *)

(** Effect semantics augment memory semantics with effects, in the form
    of a set of locations [block -> Z -> bool] associated with each internal
    step of the semantics. *)

Record EffectSem {C} :=
  { (** [sem] is a memory semantics. *)
    sem :> @MemSem C

    (** The step relation of the new semantics. *)
  ; effstep: (block -> Z -> bool) -> C -> mem -> C -> mem -> Prop

    (** The next three fields axiomatize [effstep] and its relation to the
        underlying step relation of [sem]. *)
  ; effax1: forall M c m c' m',
       effstep M c m c' m' ->
            corestep sem c m c' m'
         /\ Mem.unchanged_on (fun b ofs => M b ofs = false) m m'
  ; effax2: forall c m c' m',
       corestep sem c m c' m' ->
       exists M, effstep M c m c' m'
  ; effstep_perm: forall M c m c' m',
       effstep M c m c' m' ->
       forall b z, M b z = true -> Mem.perm m b z Cur Writable
  }.(** * Effect Semantics *)

(** Effect semantics augment memory semantics with effects, in the form
    of a set of locations [block -> Z -> bool] associated with each internal
    step of the semantics. *)

Record EffectSem {C} :=
  { (** [sem] is a memory semantics. *)
    sem :> @MemSem C

    (** The step relation of the new semantics. *)
  ; effstep: (block -> Z -> bool) -> C -> mem -> C -> mem -> Prop

    (** The next three fields axiomatize [effstep] and its relation to the
        underlying step relation of [sem]. *)
  ; effax1: forall M c m c' m',
       effstep M c m c' m' ->
            corestep sem c m c' m'
         /\ Mem.unchanged_on (fun b ofs => M b ofs = false) m m'
  ; effax2: forall c m c' m',
       corestep sem c m c' m' ->
       exists M, effstep M c m c' m'
  ; effstep_perm: forall M c m c' m',
       effstep M c m c' m' ->
       forall b z, M b z = true -> Mem.perm m b z Cur Writable
  }.(** * Effect Semantics *)

(** Effect semantics augment memory semantics with effects, in the form
    of a set of locations [block -> Z -> bool] associated with each internal
    step of the semantics. *)

Record EffectSem {C} :=
  { (** [sem] is a memory semantics. *)
    sem :> @MemSem C

    (** The step relation of the new semantics. *)
  ; effstep: (block -> Z -> bool) -> C -> mem -> C -> mem -> Prop

    (** The next three fields axiomatize [effstep] and its relation to the
        underlying step relation of [sem]. *)
  ; effax1: forall M c m c' m',
       effstep M c m c' m' ->
            corestep sem c m c' m'
         /\ Mem.unchanged_on (fun b ofs => M b ofs = false) m m'
  ; effax2: forall c m c' m',
       corestep sem c m c' m' ->
       exists M, effstep M c m c' m'
  ; effstep_perm: forall M c m c' m',
       effstep M c m c' m' ->
       forall b z, M b z = true -> Mem.perm m b z Cur Writable
  }.(** * Effect Semantics *)

(** Effect semantics augment memory semantics with effects, in the form
    of a set of locations [block -> Z -> bool] associated with each internal
    step of the semantics. *)

Record EffectSem {C} :=
  { (** [sem] is a memory semantics. *)
    sem :> @MemSem C

    (** The step relation of the new semantics. *)
  ; effstep: (block -> Z -> bool) -> C -> mem -> C -> mem -> Prop

    (** The next three fields axiomatize [effstep] and its relation to the
        underlying step relation of [sem]. *)
  ; effax1: forall M c m c' m',
       effstep M c m c' m' ->
            corestep sem c m c' m'
         /\ Mem.unchanged_on (fun b ofs => M b ofs = false) m m'
  ; effax2: forall c m c' m',
       corestep sem c m c' m' ->
       exists M, effstep M c m c' m'
  ; effstep_perm: forall M c m c' m',
       effstep M c m c' m' ->
       forall b z, M b z = true -> Mem.perm m b z Cur Writable
  }.(** * Effect Semantics *)

(** Effect semantics augment memory semantics with effects, in the form
    of a set of locations [block -> Z -> bool] associated with each internal
    step of the semantics. *)

Record EffectSem {C} :=
  { (** [sem] is a memory semantics. *)
    sem :> @MemSem C

    (** The step relation of the new semantics. *)
  ; effstep: (block -> Z -> bool) -> C -> mem -> C -> mem -> Prop

    (** The next three fields axiomatize [effstep] and its relation to the
        underlying step relation of [sem]. *)
  ; effax1: forall M c m c' m',
       effstep M c m c' m' ->
            corestep sem c m c' m'
         /\ Mem.unchanged_on (fun b ofs => M b ofs = false) m m'
  ; effax2: forall c m c' m',
       corestep sem c m c' m' ->
       exists M, effstep M c m c' m'
  ; effstep_perm: forall M c m c' m',
       effstep M c m c' m' ->
       forall b z, M b z = true -> Mem.perm m b z Cur Writable
  }.(** * Effect Semantics *)

(** Effect semantics augment memory semantics with effects, in the form
    of a set of locations [block -> Z -> bool] associated with each internal
    step of the semantics. *)

Record EffectSem {C} :=
  { (** [sem] is a memory semantics. *)
    sem :> @MemSem C

    (** The step relation of the new semantics. *)
  ; effstep: (block -> Z -> bool) -> C -> mem -> C -> mem -> Prop

    (** The next three fields axiomatize [effstep] and its relation to the
        underlying step relation of [sem]. *)
  ; effax1: forall M c m c' m',
       effstep M c m c' m' ->
            corestep sem c m c' m'
         /\ Mem.unchanged_on (fun b ofs => M b ofs = false) m m'
  ; effax2: forall c m c' m',
       corestep sem c m c' m' ->
       exists M, effstep M c m c' m'
  ; effstep_perm: forall M c m c' m',
       effstep M c m c' m' ->
       forall b z, M b z = true -> Mem.perm m b z Cur Writable
  }.

(* Specifications: *)
Lemma effstep_valid: forall M c m c' m', effstep Sem M c m c' m' -> forall b z, M b z = true -> Mem.valid_block m b.
Lemma effstep_corestep: forall M c m c' m', effstep Sem M c m c' m' -> corestep Sem c m c' m'.
Lemma effstep_unchanged: forall M c m c' m', effstep Sem M c m c' m' -> Mem.unchanged_on (fun b ofs => M b ofs = false) m m'.
Lemma effstep_mem U c m c' m' (EF: effstep Sem U c m c' m'): mem_step m m'.
Lemma effstep_fwd U c m c' m' (EF: effstep Sem U c m c' m'): mem_forward m m'.