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.
Require Export prosa.behavior.time.
[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]
(** This file introduces an implementation of arrival curves via the periodic extension of finite _arrival-curve prefix_. An arrival-curve prefix is a pair comprising a horizon and a list of steps. The horizon defines the domain of the prefix, in which no extrapolation is necessary. The list of steps ([duration × value]) describes the value changes of the corresponding arrival curve within the domain. For time instances outside of an arrival-curve prefix's domain, extrapolation is necessary. Therefore, past the domain, arrival-curve values are extrapolated assuming that the arrival-curve prefix is repeated with a period equal to the horizon. Note that such a periodic extension does not necessarily give the tightest curve, and hence it is not optimal. The advantage is speed of calculation: periodic extension can be done in constant time, whereas the optimal extension takes roughly quadratic time in the number of steps. *)(** An arrival-curve prefix is defined as a pair comprised of a horizon and a list of steps ([duration × value]) that describe the value changes of the described arrival curve. For example, an arrival-curve prefix [(5, [:: (1, 3)])] describes an arrival sequence with job bursts of size [3] happening every [5] time instances. *)DefinitionArrivalCurvePrefix : Type := duration * seq (duration * nat).(** Given an inter-arrival time [p] (or period [p]), the corresponding arrival-curve prefix can be defined as [(p, [:: (1, 1)])]. *)Definitioninter_arrival_to_prefix (p : nat) : ArrivalCurvePrefix := (p, [:: (1, 1)]).(** The first component of arrival-curve prefix [ac_prefix] is called horizon. *)Definitionhorizon_of (ac_prefix : ArrivalCurvePrefix) := fst ac_prefix.(** The second component of [ac_prefix] is called steps. *)Definitionsteps_of (ac_prefix : ArrivalCurvePrefix) := snd ac_prefix.(** The time steps of [ac_prefix] are the first components of the steps. That is, these are time instances before the horizon where the corresponding arrival curve makes a step. *)Definitiontime_steps_of (ac_prefix : ArrivalCurvePrefix) :=
map fst (steps_of ac_prefix).(** The function [step_at] returns the last step ([duration × value]) such that [duration ≤ t]. *)Definitionstep_at (ac_prefix : ArrivalCurvePrefix) (t : duration) :=
last (0, 0) [ seq step <- steps_of ac_prefix | fst step <= t ].(* The function [value_at] returns the _value_ of the last step ([duration × value]) such that [duration ≤ t] *)Definitionvalue_at (ac_prefix : ArrivalCurvePrefix) (t : duration) :=
snd (step_at ac_prefix t).(** Finally, we define a function [extrapolated_arrival_curve] that performs the periodic extension of the arrival-curve prefix (and hence, defines an arrival curve). Value of [extrapolated_arrival_curve t] is defined as [t %/ h * value_at horizon] plus [value_at (t mod horizon)]. The first summand corresponds to [k] full repetitions of the arrival-curve prefix inside interval <<[0,t)>>. The second summand corresponds to the residual change inside interval <<[k*h, t)>>. *)Definitionextrapolated_arrival_curve (ac_prefix : ArrivalCurvePrefix) (t : duration) :=
leth := horizon_of ac_prefix in
t %/ h * value_at ac_prefix h + value_at ac_prefix (t %% h).(** In the following section, we define a few validity predicates. *)SectionValidArrivalCurvePrefix.(** Horizon should be positive. *)Definitionpositive_horizon (ac_prefix : ArrivalCurvePrefix) :=
horizon_of ac_prefix > 0.(** Horizon should bound time steps. *)Definitionlarge_horizon (ac_prefix : ArrivalCurvePrefix) :=
foralls, s \in time_steps_of ac_prefix -> s <= horizon_of ac_prefix.(** We define an alternative, decidable version of [large_horizon]... *)Definitionlarge_horizon_dec (ac_prefix : ArrivalCurvePrefix) : bool :=
all (funs => s <= horizon_of ac_prefix) (time_steps_of ac_prefix).(** ... and prove that the two definitions are equivalent. *)
byapply /allP.Qed.(** There should be no infinite arrivals; that is, [value_at 0 = 0]. *)Definitionno_inf_arrivals (ac_prefix : ArrivalCurvePrefix) :=
value_at ac_prefix 0 == 0.(** Bursts must be specified; that is, [steps_of] should contain a pair [(ε, b)]. *)Definitionspecified_bursts (ac_prefix : ArrivalCurvePrefix) :=
ε \in time_steps_of ac_prefix.(** Steps should be strictly increasing both in time steps and values. *)Definitionltn_stepsab := (fst a < fst b) && (snd a < snd b).Definitionsorted_ltn_steps (ac_prefix : ArrivalCurvePrefix) :=
sorted ltn_steps (steps_of ac_prefix).(** The conjunction of the 5 afore-defined properties defines a valid arrival-curve prefix. *)Definitionvalid_arrival_curve_prefix (ac_prefix : ArrivalCurvePrefix) :=
positive_horizon ac_prefix
/\ large_horizon ac_prefix
/\ no_inf_arrivals ac_prefix
/\ specified_bursts ac_prefix
/\ sorted_ltn_steps ac_prefix.(** We define an alternative, decidable version of [valid_arrival_curve_prefix]... *)Definitionvalid_arrival_curve_prefix_dec (ac_prefix : ArrivalCurvePrefix) : bool :=
(positive_horizon ac_prefix)
&& (large_horizon_dec ac_prefix)
&& (no_inf_arrivals ac_prefix)
&& (specified_bursts ac_prefix)
&& (sorted_ltn_steps ac_prefix).(** ... and prove that the two definitions are equivalent. *)
~~ valid_arrival_curve_prefix_dec ac ->
~ valid_arrival_curve_prefix ac
ac: ArrivalCurvePrefix
valid_arrival_curve_prefix ac ->
valid_arrival_curve_prefix_dec ac
ac: ArrivalCurvePrefix _a_: positive_horizon ac __view_subject_1_: large_horizon_dec ac _a1_: no_inf_arrivals ac _a2_: specified_bursts ac _b_: sorted_ltn_steps ac
valid_arrival_curve_prefix_dec ac
byrepeat (apply /andP; split => //).Qed.(** We also define a predicate for non-decreasing order that is more convenient for proving some of the claims. *)Definitionleq_stepsab := (fst a <= fst b) && (snd a <= snd b).Definitionsorted_leq_steps (ac_prefix : ArrivalCurvePrefix) :=
sorted leq_steps (steps_of ac_prefix).EndValidArrivalCurvePrefix.