Built with Alectryon, running Coq+SerAPI v8.20.0+0.20.0. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
[Loading ML file ssrmatching_plugin.cmxs (using legacy method) ... done]
[Loading ML file ssreflect_plugin.cmxs (using legacy method) ... done]
[Loading ML file ring_plugin.cmxs (using legacy method) ... done]
Serlib plugin: coq-elpi.elpi is not available: serlib support is missing.
Incremental checking for commands in this plugin will be impacted.
[Loading ML file coq-elpi.elpi ... done]
[Loading ML file zify_plugin.cmxs (using legacy method) ... done]
[Loading ML file micromega_core_plugin.cmxs (using legacy method) ... done]
[Loading ML file micromega_plugin.cmxs (using legacy method) ... done]
[Loading ML file btauto_plugin.cmxs (using legacy method) ... done]
Notation"_ + _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ - _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ <= _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ < _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ >= _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ > _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ <= _ <= _" was already used in scope
nat_scope. [notation-overridden,parsing,default]
Notation"_ < _ <= _" was already used in scope
nat_scope. [notation-overridden,parsing,default]
Notation"_ <= _ < _" was already used in scope
nat_scope. [notation-overridden,parsing,default]
Notation"_ < _ < _" was already used in scope
nat_scope. [notation-overridden,parsing,default]
Notation"_ * _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Require Export prosa.model.processor.platform_properties.Require Export prosa.analysis.facts.behavior.service.Require Export prosa.analysis.facts.model.scheduled.Require Import prosa.model.processor.ideal.(** Note: we do not re-export the basic definitions to avoid littering the global namespace with type class instances. *)(** In this section we establish the classes to which an ideal schedule belongs. *)SectionScheduleClass.(** We assume ideal uni-processor schedules. *)#[local] Existing Instanceideal.processor_state.LocalTransparent scheduled_in scheduled_on.(** Consider any job type and the ideal processor model. *)Context {Job: JobType}.Context `{JobArrival Job}.Context `{JobCost Job}.(** We note that the ideal processor model is indeed a uni-processor model. *)
Job: JobType H: JobArrival Job H0: JobCost Job
uniprocessor_model (processor_state Job)
Job: JobType H: JobArrival Job H0: JobCost Job
uniprocessor_model (processor_state Job)
Job: JobType H: JobArrival Job H0: JobCost Job j1, j2: Job sched: schedule (processor_state Job) t: instant E1: sched t = Some j1 E2: sched t = Some j2
j1 = j2
bymove: E1 E2 =>->[].Qed.(** By definition, [service_in] is the sum of the service received in total across all cores. In the ideal uniprocessor model, however, there is only one "core," which is expressed by using [unit] as the type of cores. The type [unit] only has a single member [tt], which serves as a placeholder. Consequently, the definition of [service_in] simplifies to a single term of the sum, the service on the one core, which we note with the following lemma that relates [service_in] to [service_on]. *)
byrewrite /service_in sum_unit1.Qed.(** Furthermore, since the ideal uniprocessor state is represented by the [option Job] type, [service_in] further simplifies to a simple equality comparison, which we note next. *)
byrewrite service_in_service_on.Qed.(** We observe that the ideal processor model falls into the category of ideal-progress models, i.e., a scheduled job always receives service. *)
Job: JobType H: JobArrival Job H0: JobCost Job sched: schedule (processor_state Job) j: Job t: instant SCHED: sched t = Some j IDLE: sched t = None
False
byrewrite IDLE in SCHED; inversion SCHED.Qed.(** On a similar note, if a scheduler is idle at a time instant [t], then no job can receive service at [t]. *)
byrewrite service_at_is_scheduled_at scheduled_at_def => /eqP ->.Qed.(** In the following, we relate the ideal uniprocessor state to the generic definition [job_scheduled_at]. Specifically, the two notions are equivalent. To show this, require an arrival sequence in context. *)SectionRelationToGenericScheduledJob.(** Consider any arrival sequence ... *)Variablearr_seq : arrival_sequence Job.Context `{JobArrival Job}.(** ... and any ideal uni-processor schedule of this arrival sequence. *)Variablesched : schedule (ideal.processor_state Job).(** Suppose all jobs come from the arrival sequence and do not execute before their arrival time (which must be consistent with the arrival sequence). *)HypothesisH_jobs_come_from_arrival_sequence :
jobs_come_from_arrival_sequence sched arr_seq.HypothesisH_jobs_must_arrive_to_execute :
jobs_must_arrive_to_execute sched.HypothesisH_arrival_times_are_valid :
valid_arrival_sequence arr_seq.(** The generic notion [scheduled_job_at] coincides with our notion of ideal processor state. This observation allows cutting out the generic notion in proofs specific to ideal uniprocessor schedules. *)
bycase: (scheduled_jobs_at _ _ _).Qed.EndRelationToGenericScheduledJob.EndScheduleClass.(** * Automation *)(** We add the above lemmas into a "Hint Database" basic_rt_facts, so Coq will be able to apply them automatically. *)GlobalHint Resolve ideal_proc_model_is_a_uniprocessor_model
ideal_proc_model_provides_unit_supply
ideal_proc_model_ensures_ideal_progress
ideal_proc_model_provides_unit_service
ideal_proc_model_fully_consuming
ideal_proc_has_supply : basic_rt_facts.(** We also provide tactics for case analysis on ideal processor state. *)(** The first tactic generates two sub-goals: one with idle processor and the other with processor executing a job named [JobName]. *)Ltacideal_proc_model_sched_case_analysis sched t JobName :=
letIdle := fresh"Idle"inletSched := fresh"Sched_" JobName indestruct (ideal_proc_model_sched_case_analysis sched t) as [Idle | [JobName Sched]].(** The second tactic is similar to the first, but it additionally generates two equalities: [sched t = None] and [sched t = Some j]. *)Ltacideal_proc_model_sched_case_analysis_eq sched t JobName :=
letIdle := fresh"Idle"inletIdleEq := fresh"Eq" Idle inletSched := fresh"Sched_" JobName inletSchedEq := fresh"Eq" Sched indestruct (ideal_proc_model_sched_case_analysis sched t) as [Idle | [JobName Sched]];
[move: (Idle) => /eqP IdleEq; rewrite?IdleEq
| move: (Sched); simpl; move => /eqP SchedEq; rewrite?SchedEq].