(** * Definitions and properties of machine executions *)
From mathcomp.ssreflect Require Import ssreflect ssrbool ssrnat ssrfun eqtype seq fintype finfun.
Set Implicit Arguments.
(*NOTE: because of redefinition of [val], these imports must appear after Ssreflect eqtype.*)
(* Require Import VST.concurrency.common.ClightSemanticsForMachines. *)
Set Bullet Behavior "None".
Set Bullet Behavior "Strict Subproofs".
Module Executions.
Section Executions.
Context
{Sem : Semantics}
{initU : seq.seq nat}
{SemAx : CoreLanguage.SemAxioms}
{SemD : CoreLanguage.SemDet}
{DilMem : DiluteMem}
{Res: Resources}.
(* Existing Instance FineDilMem. *)
Existing Instance HybridFineMachine.scheduler.
Existing Instance OrdinalPool.OrdinalThreadPool.
Context {Hbs : MachineSig}.
(** Reflexive-transitive closure of machine step relation*)
Inductive multi_step :
MachState -> mem -> MachState -> mem -> Prop :=
| Step_refl : forall ms (m : mem),
multi_step ms m ms m
| Step_trans : forall i U U'
(tp tp' tp'' : t)
tr tr' tr''
(m m' m'' : mem),
MachStep (i :: U, tr, tp) m (U, tr ++ tr', tp') m' ->
multi_step (U, tr ++ tr', tp') m' (U', tr ++ tr' ++ tr'', tp'') m'' ->
multi_step (i :: U,tr,tp) m (U',tr ++ tr' ++ tr'',tp'') m''.
(** Complete executions (until the schedule is empty) of the FineConc machine*)
Inductive fine_execution :
MachState -> mem -> MachState -> mem -> Prop :=
| fine_completed : forall ms (m : mem),
halted_machine ms ->
fine_execution ms m ms m
| fine_exec : forall i U U'
tp tp' tp''
tr tr' tr''
(m m' m'' : mem),
MachStep (i :: U, tr, tp) m (U, tr ++ tr', tp') m' ->
fine_execution (U, tr ++ tr', tp') m' (U', tr ++ tr' ++ tr'', tp'') m'' ->
fine_execution (i :: U,tr,tp) m (U',tr ++ tr' ++ tr'',tp'') m''.
(** ** Generic Properties of executions and steps *)

(* Specifications: *)
(** Connection between [multi_step] and [fine_execution]*)
Lemma fine_execution_multi_step:
forall U  tr tr' tp m tp' m',
fine_execution (U, tr, tp) m ([::], tr', tp') m' ->
multi_step (U, tr, tp) m ([::], tr', tp') m'.
(** [fine_execution] has empty schedules*)
Lemma fine_execution_schedule:
forall U U' tr tr' tp m tp' m',
fine_execution (U, tr, tp) m (U', tr', tp') m' ->
U' = [::].
(** A property of steps is that any sequence of events added by one external step is a singleton *)
Lemma step_ext_trace:
forall a U
(i : nat) tr tr' tp tp'
(m m' : mem) (ev : machine_event),
is_external ev ->
nth_error tr' i = Some ev ->
MachStep ((a :: U)%SEQ, tr, tp) m
(U, tr ++ tr', tp') m' ->
tr' = [:: ev].
Lemma step_event_tid:
forall U tr tp m U' tr' tp' m'
(Hstep: MachStep (U, tr, tp) m
(U', tr ++ tr', tp') m'),
forall ev ev', List.In ev tr' ->
List.In ev' tr' ->
thread_id ev = thread_id ev'.
Lemma step_trace_monotone:
forall U tp m tr U' tp' m' tr'
(Hstep: MachStep (U, tr, tp) m
(U', tr', tp') m'),
exists tr'',
tr' = tr ++ tr''.
Lemma multi_step_trace_monotone:
forall U tr tp m U' tr' tp' m'
(Hexec: multi_step (U, tr, tp) m (U', tr', tp') m'),
exists tr'',
tr' = tr ++ tr''.
(** Decomposing steps based on an external event*)
Lemma multi_step_inv_ext:
forall U U' i tr tr' tp m tp' m' ev
(Hext: is_external ev)
(Hi: nth_error tr' i = Some ev)
(Hexec: multi_step (U, tr, tp) m (U', tr ++ tr', tp') m'),
exists U'' U''' tp'' m'' tr'' tp''' m''',
multi_step (U, tr, tp) m (U'', tr ++ tr'', tp'') m'' /\
MachStep (U'', tr ++ tr'', tp'') m''
(U''', tr ++ tr'' ++ [:: ev], tp''') m''' /\
multi_step (U''', tr ++ tr'' ++ [:: ev], tp''') m'''
(U', tr ++ tr', tp') m' /\
length tr'' = i.
(** Decomposing steps on any kind of event. This theorem is stronger than the previous one *)
Lemma multi_step_inv:
forall U U' i tr tr' tp m tp' m' ev
(Hi: nth_error tr' i = Some ev)
(Hexec: multi_step (U, tr, tp) m (U', tr ++ tr', tp') m'),
exists U'' U''' tp'' m'' tr'' pre_ev post_ev  tp''' m''',
multi_step (U, tr, tp) m (U'', tr ++ tr'', tp'') m'' /\
MachStep (U'', tr ++ tr'', tp'') m''
(U''', tr ++ tr'' ++ pre_ev ++ [:: ev] ++ post_ev, tp''') m''' /\
multi_step (U''', tr ++ tr'' ++ pre_ev ++ [:: ev] ++ post_ev , tp''') m'''
(U', tr ++ tr', tp') m' /\
length (tr'' ++ pre_ev) = i.
Lemma step_sched_inv:
forall i U tp m tr U' tp' m' tr'
(Hstep: MachStep (i :: U, tr, tp) m
(U', tr', tp') m'),
U' = U.
Lemma multi_step_snoc:
forall U U' U'' tr tr' tr'' tp m tp' m' tp'' m''
(Hexec: multi_step (U, tr, tp) m (U', tr ++ tr', tp') m')
(Hstep: MachStep (U', tr ++ tr', tp') m' (U'', tr ++ tr' ++ tr'', tp'') m''),
multi_step (U, tr, tp) m (U'', tr ++ tr' ++ tr'', tp'') m''.
(** The trace is irrelevant to further execution of the machine. It's just a history of the memory operations *)
Lemma step_trace_irr:
forall U i tp m tp' m' tr tr'
(Hstep: MachStep (i :: U, tr, tp) m (U, tr', tp') m'),
forall tr'', exists ev,
MachStep (i :: U, tr'', tp) m (U, tr'' ++ ev, tp') m'.
Lemma  multi_step_contra:
forall U U' tr tp m tr' tp' m'
(HU': U' <> [::])
(Hexec: multi_step (U, tr, tp) m (U' ++ U, tr', tp') m'),
False.
Lemma  multi_step_refl:
forall U tr tp m tr' tp' m'
(Hexec: multi_step (U, tr, tp) m (U, tr', tp') m'),
tp = tp' /\ m = m' /\ tr = tr'.