@@ -53,6 +53,7 @@ Require Import ASCommon.Common.
5353Require Import ASCommon.Exec.
5454Require Import ASCommon.Effects.
5555Require Import ASCommon.FMon.
56+ Require Import ASCommon.HVec.
5657Require Import ASCommon.StateT.
5758
5859Require Import Relations.
@@ -182,27 +183,38 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
182183 it generic *)
183184 Structure BasicExecutablePM := {
184185 pModel :> PromisingModel;
185- (** try to compute ALL allowed promises, if that is not possible (not
186- enough fuel) then fail with error message.
187186
188- Soundness and completeness proofs are required to show that when not
189- failing, promise_select effectively computes the allowed_promises
190- set. *)
191- promise_select :
187+ enumerate_promises_and_terminal_states :
192188 (* fuel *) nat → (* tid *) nat →
193189 (* termination condition *) (registerMap → bool) →
194190 memoryMap → pModel.(tState) → PromMemory.t pModel.(mEvent) →
195- Exec.res string pModel.(mEvent);
191+ result string (list pModel.(mEvent) * list pModel.(tState) );
196192
197193 promise_select_sound :
198- ∀ fuel tid term initMem ts mem,
199- ∀ ev ∈ (promise_select fuel tid term initMem ts mem),
200- ev ∈ pModel.(allowed_promises) tid initMem ts mem;
194+ ∀ fuel tid term initMem ts mem promises tstates,
195+ Ok (promises, tstates) =
196+ enumerate_promises_and_terminal_states fuel tid term initMem ts mem →
197+ ∀ ev ∈ promises, ev ∈ pModel.(allowed_promises) tid initMem ts mem;
198+
201199 promise_select_complete :
202- ∀ fuel tid term initMem ts mem,
203- ¬ Exec.has_error (promise_select fuel tid term initMem ts mem) →
204- ∀ ev ∈ pModel.(allowed_promises) tid initMem ts mem,
205- ev ∈ promise_select fuel tid term initMem ts mem
200+ ∀ fuel tid term initMem ts mem promises tstates,
201+ Ok (promises, tstates) =
202+ enumerate_promises_and_terminal_states fuel tid term initMem ts mem →
203+ ∀ ev ∈ pModel.(allowed_promises) tid initMem ts mem, ev ∈ promises;
204+
205+ terminal_state_no_outstanding_promise :
206+ ∀ fuel tid term initMem ts mem promises tstates,
207+ Ok (promises, tstates) =
208+ enumerate_promises_and_terminal_states fuel tid term initMem ts mem →
209+ ∀ tts ∈ tstates, pModel.(tState_nopromises) tts;
210+
211+ terminal_state_is_terminated :
212+ ∀ fuel tid term initMem ts mem promises tstates,
213+ Ok (promises, tstates) =
214+ enumerate_promises_and_terminal_states fuel tid term initMem ts mem →
215+ ∀ tts ∈ tstates, term (pModel.(tState_regs) tts);
216+
217+ (* TODO: add terminal_state_is_reachable *)
206218 }.
207219 Arguments BasicExecutablePM : clear implicits.
208220
@@ -340,10 +352,24 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
340352 Local Notation mEvent := (mEvent prom).
341353 Local Notation t := (t tState mEvent n).
342354
355+ (** The type of final promising state return by run *)
356+ Definition final := { x : t | terminated prom term x }.
357+
358+ Definition make_final (p : t) := exist (terminated prom term) p.
359+
360+ (** Convert a final promising state to a generic final state *)
361+ Program Definition to_final_archState (f : final) :
362+ {s & archState.is_terminated term s} :=
363+ existT (to_archState prom f) _.
364+ Solve All Obligations with
365+ hauto unfold:terminated unfold:archState.is_terminated l:on db:vec, brefl.
366+
343367 (** Get a list of possible promises for a thread by tid *)
344368 Definition promise_select_tid (fuel : nat) (st : t)
345369 (tid : fin n) : Exec.res string mEvent :=
346- prom.(promise_select) fuel tid (term tid) (initmem st) (tstate tid st) (events st).
370+ '(promises, _) ← mlift $ prom.(enumerate_promises_and_terminal_states)
371+ fuel tid (term tid) (initmem st) (tstate tid st) (events st);
372+ mchoosel promises.
347373
348374 (** Take any promising step for that tid and promise it *)
349375 Definition cpromise_tid (fuel : nat) (tid : fin n)
@@ -367,19 +393,6 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
367393 promise ← mchoosel (enum bool);
368394 if (promise : bool) then cpromise_tid fuel tid else run_tid isem prom tid.
369395
370- (** The type of final promising state return by run *)
371- Definition final := { x : t | terminated prom term x }.
372-
373- Definition make_final (p : t) := exist (terminated prom term) p.
374-
375-
376- (** Convert a final promising state to a generic final state *)
377- Program Definition to_final_archState (f : final) :
378- {s & archState.is_terminated term s} :=
379- existT (to_archState prom f) _.
380- Solve All Obligations with
381- hauto unfold:terminated unfold:archState.is_terminated l:on db:vec, brefl.
382-
383396 (** Computational evaluate all the possible allowed final states according
384397 to the promising model prom starting from st *)
385398 Fixpoint run (fuel : nat) : Exec.t t string final :=
@@ -390,19 +403,79 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
390403 run_step (S fuel);;
391404 run fuel
392405 else mthrow "Could not finish running within the size of the fuel".
406+
407+ (** Explore all possible promise-based executions across all threads. *)
408+ Fixpoint prune_promises_and_states (fuel_per_tid fuel : nat)
409+ (finals : list final) : Exec.t t string (list final) :=
410+ if fuel is S fuel then
411+ st ← mGet;
412+ (* Find out next possible promises or terminating states at the current thread *)
413+ executions ←
414+ for (tid : fin n) in enum (fin n) do
415+ '(promises_per_tid, tstates_per_tid) ←
416+ mlift $ prom.(enumerate_promises_and_terminal_states)
417+ fuel_per_tid tid (term tid) (initmem st) (tstate tid st) (events st);
418+ mret (map (λ ev, (ev, tid)) promises_per_tid, tstates_per_tid)
419+ end ;
420+
421+ (* Compute cartesian products of the possible thread states *)
422+ let tstates_sys :=
423+ fold_left (λ partial_sts tstates_tid,
424+ List.flat_map (λ tstate,
425+ if is_emptyb partial_sts then [[tstate]]
426+ else map (λ partial_st, partial_st ++ [tstate]) partial_sts
427+ ) tstates_tid
428+ ) (map snd executions) [] in
429+ let new_finals :=
430+ omap (λ tstates,
431+ if (list_to_vec_n n tstates) is Some tstates_vec then
432+ let st := Make tstates_vec st.(PState.initmem) st.(PState.events) in
433+ if decide $ terminated prom term st is left pt
434+ then Some (make_final st pt)
435+ else None
436+ else None
437+ ) tstates_sys in
438+
439+ (* Non-deterministically choose the next promise and the tid for pruning *)
440+ let promises_all := List.concat (map fst executions) in
441+ if is_emptyb promises_all then
442+ mret (new_finals ++ finals)
443+ else
444+ '(next_ev, tid) ← mchoosel promises_all;
445+ mSet (λ st, promise_tid prom st tid next_ev);;
446+ prune_promises_and_states fuel_per_tid fuel (new_finals ++ finals)
447+ else mret finals.
448+
449+ (** Computational evaluate all the possible allowed final states according
450+ to the promising model prom starting from st
451+ with promise-first optimization *)
452+ Definition run_promise_first (fuel : nat) : Exec.t t string final :=
453+ finals ← prune_promises_and_states fuel fuel [];
454+ mchoosel finals.
455+
393456 End CPS.
394457 Arguments to_final_archState {_ _ _}.
395458 End CPState.
396459
397460 (** Create a computational model from an ISA model and promising model *)
398461 Definition Promising_to_Modelc (isem : iMon ()) (prom : BasicExecutablePM)
399462 (fuel : nat) : archModel.c ∅ :=
400- fun n term (initMs : archState n) =>
463+ λ n term (initMs : archState n),
401464 PState.from_archState prom initMs |>
402465 archModel.Res.from_exec
403466 $ CPState.to_final_archState
404467 <$> CPState.run isem prom term fuel.
405468
469+ (** Create a computational model from an ISA model and promising model
470+ with promise-free optimization *)
471+ Definition Promising_to_Modelc_pf (isem : iMon ()) (prom : BasicExecutablePM)
472+ (fuel : nat) : archModel.c ∅ :=
473+ λ n term (initMs : archState n),
474+ PState.from_archState prom initMs |>
475+ archModel.Res.from_exec
476+ $ CPState.to_final_archState
477+ <$> CPState.run_promise_first prom term fuel.
478+
406479 (* TODO state some soundness lemma between Promising_to_Modelnc and
407480 Promising_Modelc *)
408481
0 commit comments