Commit 9c541774 authored by Björn Brandenburg's avatar Björn Brandenburg
Browse files

preserve Classic Prosa upon retirement

Preserve the Classic Prosa development as it is retired from the main
development branch.

Issue: #98
parent 6c63703c
Pipeline #74388 passed with stage
in 14 minutes and 25 seconds
......@@ -77,7 +77,7 @@ compile-and-doc:
- .preferred-stable-version
script:
- !reference [.install-dependencies, script]
- ./create_makefile.sh --without-classic
- ./create_makefile.sh
- make -j ${NJOBS}
- !reference [.make-html, script]
artifacts:
......@@ -95,45 +95,13 @@ compile-and-doc-and-validate:
- .preferred-stable-version
script:
- !reference [.install-dependencies, script]
- ./create_makefile.sh --without-classic
- ./create_makefile.sh
- make -j ${NJOBS}
- !reference [.make-html, script]
- make validate 2>&1 | tee validation-results.txt
- scripts/check-validation-output.sh --accept-proof-irrelevance validation-results.txt
artifacts:
name: "prosa-spec-$CI_COMMIT_REF_NAME"
paths:
- "with-proofs/"
- "without-proofs/"
- "pretty/"
expire_in: 1 week
# Check that proof irrelevance shows up only due to refinements.
compile-and-validate:
stage: build
extends:
- .not_in_wip_branches
- .preferred-stable-version
script:
- !reference [.install-dependencies, script]
- ./create_makefile.sh --without-classic --without-refinements
- make -j ${NJOBS}
- make validate 2>&1 | tee validation-results.txt
- scripts/check-validation-output.sh validation-results.txt
classic-compile-and-doc-and-validate:
stage: build
extends:
- .preferred-stable-version
- .not_in_wip_branches
script:
- !reference [.install-dependencies, script]
- ./create_makefile.sh --only-classic
- make -j ${NJOBS}
- !reference [.make-html, script]
- make validate
artifacts:
name: "prosa-classic-spec-$CI_COMMIT_REF_NAME"
name: "prosa-spec-$CI_COMMIT_REF_NAME"
paths:
- "with-proofs/"
- "without-proofs/"
......@@ -146,42 +114,3 @@ proof-length:
script:
- scripts/proofloc.py --check --long-proofs scripts/known-long-proofs.json `find . -iname *.v`
spell-check:
extends:
- .not_in_wip_branches
stage: build
image: bbbrandenburg/aspell-ci
script:
- scripts/flag-typos-in-comments.sh `find . -iname '*.v' ! -path './classic/*'`
# mathcomp-dev with stable Coq
#coq-8.15:
# extends:
# - .build-dev
# - .not_in_wip_branches
# # it's ok to fail with an unreleased version of ssreflect
# allow_failure: true
# mathcomp-dev with coq-dev
#coq-dev:
# extends:
# - .build-dev
# - .not_in_wip_branches
# # it's ok to fail with an unreleased version of ssreflect and Coq
# allow_failure: true
proof-state:
extends:
- .not_in_wip_branches
stage: build
image: bbbrandenburg/alectryon-ci:1.14.0-coq-8.15.0
script:
- eval $(opam env "--switch=${COMPILER_EDGE}" --set-switch)
- !reference [.install-dependencies, script]
- ./create_makefile.sh --without-classic
- make -j ${NJOBS} alectryon
artifacts:
name: "prosa-proof-state-$CI_COMMIT_REF_NAME"
paths:
- "html-alectryon/"
expire_in: 1 week
# Prosa: Formally Proven Schedulability Analysis
# Classic Prosa (2015-2019)
This repository contains the main Coq specification & proof development of the [Prosa open-source project](https://prosa.mpi-sws.org), which was launched in 2016. As of 2018, Prosa is primarily being developed in the context of the [RT-Proofs research project](https://rt-proofs.inria.fr/) (kindly funded jointly by ANR and DFG, projects ANR-17-CE25-0016 and DFG-391919384, respectively).
---
<center><img alt="RT-Proofs logo" src="http://prosa.mpi-sws.org/figures/rt-proofs-logo.png" width="300px"></center>
**Deprecation warning:** Classic Prosa is no longer being maintained. Please base any new developments on "modern" Prosa.
## Documentation
---
Up-to-date documentation for all branches of the main Prosa repository is available on the Prosa homepage:
This branch preserves the *classic* version of the [Prosa open-source project](https://prosa.mpi-sws.org), as originally presented at ECRTS'16. This version of Prosa was developed from 2015 until 2019, and further maintained until 2022.
- <https://prosa.mpi-sws.org/branches>
Throughout 2018–2021, Prosa was developed in the context of the [RT-Proofs research project](https://rt-proofs.inria.fr/) (funded jointly by ANR and DFG, projects ANR-17-CE25-0016 and DFG-391919384, respectively).
## Publications
<center><img alt="RT-Proofs logo" src="http://prosa.mpi-sws.org/figures/rt-proofs-logo.png" width="300px"></center>
Please see the [list of publications](https://prosa.mpi-sws.org/publications.html) on the Prosa project's homepage.
## Directory and Module Structure
As of now, classic Prosa has been superseded by "modern Prosa" (as tracked in the main branch of this repository), which is under active development. Classic Prosa is no longer being maintained.
The directory and module structure is organized as follows. First, the main parts, of which there are currently four.
This branch serves to preserve a working snapshot based on **Coq 8.16** and **mathcomp 1.15.0**.
- [behavior/](behavior/): The `behavior` namespace collects basic definitions and properties of system behavior (i.e., it defines Prosa's **trace-based semantics**). There are *no* proofs here. This module is mandatory: *all* results in Prosa rely on the basic trace-based semantics defined in this module.
- [model/](model/): The `model` namespace collects all definitions and basic properties of various **system models** (e.g., sporadic tasks, arrival curves, various scheduling policies, etc.). There are only few proofs here. This module contains multiple, mutually exclusive alternatives (e.g., periodic vs. sporadic tasks, uni- vs. multiprocessor models, constrained vs. arbitrary deadlines, etc.), and higher-level results are expected "pick and choose" whatever definitions and assumptions are appropriate.
- [analysis/](analysis/): The `analysis` namespace collects all definitions and proof libraries needed to establish **system properties** (e.g., schedulability, response time, etc.). This includes a substantial library of *basic facts* that follow directly from the trace-based semantics or specific modelling assumptions. Virtually all intermediate steps and low-level proofs will be found here.
- [results/](results/): The `results` namespace contains all **high-level analysis results**.
## Documentation
In future work, there will also (again) be an `implementation` or `examples` namespace in which important high-level results are instantiated (i.e., applied) in an assumption-free environment for concrete job and task types to establish the absence of any contradiction in assumptions.
Up-to-date documentation for all branches of the main Prosa repository is available on the Prosa homepage:
Furthermore, there are a couple of additional folders and namespaces.
- <https://prosa.mpi-sws.org/branches>
- [classic/](classic/): This module contains the "classic" version of Prosa as first presented at ECRTS'16.
All results published prior to 2020 build on this "classic" version of Prosa.
- [util/](util/): A collection of miscellaneous "helper" lemmas and tactics. Used throughout the rest of Prosa.
- [scripts/](scripts/): Scripts and supporting resources required for continuous integration and documentation generation.
## Publications
## Installation
Please see the [list of publications](https://prosa.mpi-sws.org/publications.html) on the Prosa project's homepage.
### With OPAM
All results published prior to 2020 build on this "classic" version of Prosa.
Prosa can be installed using the [OPAM package manager](https://opam.ocaml.org/) (>= 2.0).
## Installation
```bash
opam repo add coq-released https://coq.inria.fr/opam/released
# or for the dev version (git master): https://coq.inria.fr/opam/extra-dev
opam update
opam install coq-prosa
```
First, make sure you have **Coq 8.16** and **mathcomp 1.15.0** installed.
### From Sources with `opam`
......@@ -57,32 +45,6 @@ opam pin add -n -y -k path coq-prosa .
opam install coq-prosa
```
### From Sources With `esy`
Prosa can be installed using [esy](https://esy.sh/).
#### Installing `esy`
`esy` itself can typically be installed through `npm`.
It should look something like this on most `apt`-based systems:
```bash
sudo apt install npm
sudo npm install --global esy@latest
```
#### Installing Prosa
With `esy` in place, it is easy to compile Prosa in one go. To download and compile all of Prosa's dependencies (including Coq), and then to compile Prosa itself, simply issue the command:
```bash
esy
```
Note that `esy` uses an internal compilation environment, which is not exported to the current shell.
To work within this environment, prefix any command with `esy`: for instance `esy coqide` to run your system’s coqIDE within the right environment.
Alternatively, `esy shell` opens a shell within its environment.
### Manually From Sources
#### Dependencies
......@@ -91,16 +53,13 @@ Besides on Coq itself, Prosa depends on
1. the `ssreflect` library of the [Mathematical Components project](https://math-comp.github.io),
2. the [Micromega support for the Mathematical Components library](https://github.com/math-comp/mczify) provided by `mczify`, and
3. the [The Coq Effective Algebra Library](https://github.com/coq-community/coqeal) (optional, needed only for POET-related refinements).
These dependencies can be easily installed with OPAM.
These dependencies can be easily installed with OPAM.
```bash
opam install -y coq-mathcomp-ssreflect coq-mathcomp-zify coq-coqeal
opam install -y coq-mathcomp-ssreflect<=1.15.0 coq-mathcomp-zify
```
Prosa always tracks the latest stable versions of Coq and ssreflect. We do not maintain compatibility with older versions of either Coq or ssreflect.
#### Compiling Prosa
Assuming all dependencies are available (either via OPAM or compiled from source, see the [Prosa setup instructions](http://prosa.mpi-sws.org/setup-instructions.html)), compiling Prosa consists of only two steps.
......@@ -111,18 +70,6 @@ First, create an appropriate `Makefile`.
./create_makefile.sh
```
Alternatively, to avoid compiling the older "classic" Prosa, specify the `--without-classic` option. This can speed up compilation considerably and is a good idea during development. (It's also possible to *only* compile the "classic" Prosa by specifying the `--only-classic` option, but this is rarely needed.)
```bash
./create_makefile.sh --without-classic
```
To avoid compiling the POET-related refinements (which require CoqEAL to be installed and inject a dependency on the *proof irrelevance* axiom), specify the switch `--without-refinements`. For example, to skip both "classic" Prosa and the refinements library, use the following command:
```bash
./create_makefile.sh --without-classic --without-refinements
```
Second, compile the library.
```bash
......@@ -139,29 +86,3 @@ The Coqdoc documentation (as shown on the [webpage](http://prosa.mpi-sws.org/doc
- `make gallinahtml -j` --- just the specification, without proofs,
- `make html -j` --- full specification with all proofs.
Since Coqdoc requires object files (`*.vo`) as input, please make sure that the code is compilable.
## Commit and Development Rules
We very much welcome external contributions. Please don't hesitate to [get in touch](http://prosa.mpi-sws.org/get-in-touch.html)!
To make things as smooth as possible, here are a couple of rules and guidelines that we seek to abide by.
1. Always follow the project [coding and writing guidelines](doc/guidelines.md).
2. Make sure the master branch "compiles" at each commit. This is not true for the early history of the repository, and during certain stretches of heavy refactoring, but going forward we should strive to keep it working at all times.
3. It's ok (and even recommended) to develop in a (private) dirty branch, but clean up and rebase (i.e., `git-rebase -i`) on top of the current master branch before opening a merge request.
4. Create merge requests liberally. No improvement is too small or too insignificant for a merge request. This applies to documentation fixes (e.g., typo fixes, grammar fixes, clarifications, etc.) as well.
5. If you are unsure whether a proposed change is even acceptable or the right way to go about things, create a work-in-progress (WIP) merge request as a basis for discussion. A WIP merge request is prefixed by "WIP:".
6. We strive to have only "fast-forward merges" without merge commits, so always rebase your branch to linearize the history before merging. (WIP branches do not need to be linear.)
7. Recommendation: Document the tactics that you use in the [list of tactics](doc/tactics.md), especially when introducing/using non-standard tactics.
8. If something seems confusing, please help with improving the documentation. :-)
9. If you don't know how to fix or improve something, or if you have an open-ended suggestion in need of discusion, please file a ticket.
# Prosa Analysis Library
This module provides virtually all **analysis concepts and definitions** and encapsulates the bulk of the **intermediate proofs** in Prosa.
More precisely, this module collects all definitions that are not needed to define the behavioral semantics (found in [prosa.behavior](../behavior)) and that also do not conceptually form part of the task and system model (found in [prosa.model](../model)). For example, precise notions of "schedulability," "busy window," or "response time" are clearly analysis concepts and consequently defined here.
The proofs found in this module are "intermediate proofs" in the sense that they are not an end in of themselves; rather, they are a means to enable the proofs of the high-level results provided in the [prosa.results](../results) module.
## Structure
The Prosa analysis library is currently organized as follows:
- [abstract](./abstract): This provides **abstract RTA** analysis framework, a general and extensible approach to response-time analysis (RTA).
- [definitions](./definitions): This folder currently collects all major and minor **analysis definitions** (such as schedulability, priority inversion, etc.).
- [transform](./transform): This folder contains procedures for transforming schedules, to be used in proofs that rely on modifying a given reference schedule in some way (e.g., the EDF "swapping argument").
- [facts](./facts): Currently the home of virtually all **intermediate proofs**. In particular, [facts.behavior](./facts/behavior) provides a library of basic facts that follow (mostly) directly from Prosa's trace semantics (as given in [prosa.behavior](../behavior)).
**NB**: It is expected that the analysis module will be further (re)organized and (re)structured in future versions of Prosa.
## Guidelines
- As a general rule, keep definitions and proofs separate, so that casual readers may read and understand the Prosa specification without encountering intermediate lemmas and proofs.
- Prefer subfolders with many short files over fewer, longer files.
- In each file that is specific to some system model, explicitly `Require` the specific modules that jointly constitute the assumed system model (e.g., `Require prosa.model.processor.ideal` to express that the results in a file depend on the ideal-uniprocessor assumption).
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq path fintype bigop.
Require Export prosa.model.task.concept.
(** * Definitions for Abstract Response-Time Analysis *)
(** In this module, we propose a set of definitions for the general framework for response-time analysis (RTA)
of uni-processor scheduling of real-time tasks with arbitrary arrival models. *)
Section AbstractRTADefinitions.
(** In this section, we introduce all the abstract notions required by the analysis. *)
Section Definitions.
(** Consider any type of job associated with any type of tasks... *)
Context {Job : JobType}.
Context {Task : TaskType}.
Context `{JobTask Job Task}.
(** ... with arrival times and costs. *)
Context `{JobArrival Job}.
Context `{JobCost Job}.
(** Consider any kind of processor state model. *)
Context {PState : ProcessorState Job}.
(** Consider any arrival sequence... *)
Variable arr_seq : arrival_sequence Job.
(** ... and any schedule of this arrival sequence. *)
Variable sched : schedule PState.
(** Let [tsk] be any task that is to be analyzed *)
Variable tsk : Task.
(** We are going to introduce two main variables of the analysis:
(a) interference, and (b) interfering workload. *)
(** ** (a) Interference *)
(** Execution of a job may be postponed by the environment and/or the system due to different
factors (preemption by higher-priority jobs, jitter, black-out periods in hierarchical
scheduling, lack of budget, etc.), which we call interference.
Besides, note that even the subsequent activation of a task can suffer from interference at
the beginning of its busy interval (despite the fact that this job hasn’t even arrived
at that moment!). Thus, it makes more sense (at least for the current busy-interval
analysis) to think about interference of a job as any interference within the
corresponding busy interval, and not after release of the job.
Based on that, assume a predicate that expresses whether a job [j] under consideration
incurs interference at a given time [t] (in the context of the schedule under consideration).
This will be used later to upper-bound job [j]'s response time. Note that a concrete
realization of the function may depend on the schedule, but here we do not require this
for the sake of simplicity and generality. *)
Variable interference : Job -> instant -> bool.
(** ** (b) Interfering Workload *)
(** In addition to interference, the analysis assumes that at any time [t], we know an upper
bound on the potential cumulative interference that can be incurred in the future by any
job (i.e., the total remaining potential delays). Based on that, assume a function
interfering_workload that indicates for any job [j], at any time [t], the amount of potential
interference for job [j] that is introduced into the system at time [t]. This function will be
later used to upper-bound the length of the busy window of a job.
One example of workload function is the "total cost of jobs that arrive at time [t] and
have higher-or-equal priority than job j". In some task models, this function expresses
the amount of the potential interference on job [j] that "arrives" in the system at time [t]. *)
Variable interfering_workload : Job -> instant -> duration.
(** In order to bound the response time of a job, we must to consider the cumulative
interference and cumulative interfering workload. *)
Definition cumul_interference j t1 t2 := \sum_(t1 <= t < t2) interference j t.
Definition cumul_interfering_workload j t1 t2 := \sum_(t1 <= t < t2) interfering_workload j t.
(** ** Definition of Busy Interval *)
(** Further analysis will be based on the notion of a busy interval. The overall idea of the
busy interval is to take into account the workload that cause a job under consideration to
incur interference. In this section, we provide a definition of an abstract busy interval. *)
Section BusyInterval.
(** We say that time instant [t] is a quiet time for job [j] iff two conditions hold.
First, the cumulative interference at time [t] must be equal to the cumulative
interfering workload, to indicate that the potential interference seen so far
has been fully "consumed" (i.e., there is no more higher-priority work or other
kinds of delay pending). Second, job [j] cannot be pending at any time earlier
than [t] _and_ at time instant [t] (i.e., either it was pending earlier but is no
longer pending now, or it was previously not pending and may or may not be
released now), to ensure that the busy window captures the execution of job [j]. *)
Definition quiet_time (j : Job) (t : instant) :=
cumul_interference j 0 t = cumul_interfering_workload j 0 t /\
~~ pending_earlier_and_at sched j t.
(** Based on the definition of quiet time, we say that interval <<[t1, t2)>> is
a (potentially unbounded) busy-interval prefix w.r.t. job [j] iff the
interval (a) contains the arrival of job j, (b) starts with a quiet
time and (c) remains non-quiet. *)
Definition busy_interval_prefix (j : Job) (t1 t2 : instant) :=
t1 <= job_arrival j < t2 /\
quiet_time j t1 /\
(forall t, t1 < t < t2 -> ~ quiet_time j t).
(** Next, we say that an interval <<[t1, t2)>> is a busy interval iff
[t1, t2) is a busy-interval prefix and t2 is a quiet time. *)
Definition busy_interval (j : Job) (t1 t2 : instant) :=
busy_interval_prefix j t1 t2 /\
quiet_time j t2.
(** Note that the busy interval, if it exists, is unique. *)
Lemma busy_interval_is_unique:
forall j t1 t2 t1' t2',
busy_interval j t1 t2 ->
busy_interval j t1' t2' ->
t1 = t1' /\ t2 = t2'.
Proof.
intros ? ? ? ? ? BUSY BUSY'.
have EQ: t1 = t1'.
{ apply/eqP.
apply/negPn/negP; intros CONTR.
move: BUSY => [[IN [QT1 NQ]] _].
move: BUSY' => [[IN' [QT1' NQ']] _].
move: CONTR; rewrite neq_ltn; move => /orP [LT|GT].
{ apply NQ with t1'; try done; clear NQ.
apply/andP; split; first by done.
move: IN IN' => /andP [_ T1] /andP [T2 _].
by apply leq_ltn_trans with (job_arrival j).
}
{ apply NQ' with t1; try done; clear NQ'.
apply/andP; split; first by done.
move: IN IN' => /andP [T1 _] /andP [_ T2].
by apply leq_ltn_trans with (job_arrival j).
}
} subst t1'.
have EQ: t2 = t2'.
{ apply/eqP.
apply/negPn/negP; intros CONTR.
move: BUSY => [[IN [_ NQ]] QT2].
move: BUSY' => [[IN' [_ NQ']] QT2'].
move: CONTR; rewrite neq_ltn; move => /orP [LT|GT].
{ apply NQ' with t2; try done; clear NQ'.
apply/andP; split; last by done.
move: IN IN' => /andP [_ T1] /andP [T2 _].
by apply leq_ltn_trans with (job_arrival j).
}
{ apply NQ with t2'; try done; clear NQ.
apply/andP; split; last by done.
move: IN IN' => /andP [T1 _] /andP [_ T2].
by apply leq_ltn_trans with (job_arrival j).
}
} by subst t2'.
Qed.
End BusyInterval.
(** In this section, we introduce some assumptions about the
busy interval that are fundamental for the analysis. *)
Section BusyIntervalProperties.
(** We say that a schedule is "work_conserving" iff for any job [j] from task [tsk] and
at any time [t] within a busy interval, there are only two options:
either (a) interference(j, t) holds or (b) job [j] is scheduled at time [t]. *)
Definition work_conserving :=
forall j t1 t2 t,
arrives_in arr_seq j ->
job_cost j > 0 ->
busy_interval j t1 t2 ->
t1 <= t < t2 ->
~ interference j t <-> scheduled_at sched j t.
(** Next, we say that busy intervals of task [tsk] are bounded by [L] iff,
for any job [j] of task [tsk], there exists a busy interval with
length at most [L]. Note that the existence of such a bounded busy
interval is not guaranteed if the system is overloaded. Therefore, in
the later concrete analyses, we will have to introduce an additional
condition that rules out overload. *)
Definition busy_intervals_are_bounded_by L :=
forall j,
arrives_in arr_seq j ->
job_of_task tsk j ->
job_cost j > 0 ->
exists t1 t2,
t2 <= t1 + L /\
busy_interval j t1 t2.
(** Although we have defined the notion of cumulative interference of a job, it cannot be used in
a response-time analysis because of the variability of job parameters. To address this
issue, we define the notion of an interference bound. Note that according to the definition of
a work conserving schedule, interference does _not_ include execution of a job itself. Therefore,
an interference bound is not obliged to take into account the execution of this job. We say that
the job interference is bounded by an interference_bound_function ([IBF]) iff for any job [j] of
task [tsk] the cumulative interference incurred by [j] in the sub-interval [t1, t1 + delta) of busy
interval [t1, t2) does not exceed [interference_bound_function(tsk, A, delta)], where [A] is a
relative arrival time of job [j] (with respect to time [t1]). *)
Definition job_interference_is_bounded_by (interference_bound_function: Task -> duration -> duration -> duration) :=
(** Let's examine this definition in more detail. *)
forall t1 t2 delta j,
(** First, we require [j] to be a job of task [tsk]. *)
arrives_in arr_seq j ->
job_of_task tsk j ->
(** Next, we require the IBF to bound the interference only within the interval <<[t1, t1 + delta)>>. *)
busy_interval j t1 t2 ->
t1 + delta < t2 ->
(** Next, we require the IBF to bound the interference only until the job is
completed, after which the function can behave arbitrarily. *)
~~ completed_by sched j (t1 + delta) ->
(** And finally, the IBF function might depend not only on the length
of the interval, but also on the relative arrival time of job [j] (offset). *)
(** While the first three conditions are needed for discarding excessive cases, offset adds
flexibility to the IBF, which is important, for instance, when analyzing EDF scheduling. *)
let offset := job_arrival j - t1 in
cumul_interference j t1 (t1 + delta) <= interference_bound_function tsk offset delta.
End BusyIntervalProperties.
End Definitions.
End AbstractRTADefinitions.
This diff is collapsed.
Require Export prosa.analysis.facts.model.service_of_jobs.
Require Export prosa.analysis.facts.preemption.rtc_threshold.job_preemptable.
Require Export prosa.analysis.abstract.definitions.
(** * Run-to-Completion Threshold of a job *)
(** In this module, we provide a sufficient condition under which a job
receives enough service to become non-preemptive. *)
(** Previously we defined the notion of run-to-completion threshold (see file
abstract.run_to_completion_threshold.v). Run-to-completion threshold is the
amount of service after which a job cannot be preempted until its completion.
In this section we prove that if cumulative interference inside a busy interval
is bounded by a certain constant then a job executes long enough to reach its
run-to-completion threshold and become non-preemptive. *)
Section AbstractRTARunToCompletionThreshold.
(** Consider any type of jobs. *)
Context {Job : JobType}.
Context `{JobArrival Job}.
Context `{JobCost Job}.
(** In addition, we assume existence of a function
mapping jobs to their preemption points. *)
Context `{JobPreemptable Job}.
(** Consider any kind of uni-service ideal processor state model. *)
Context {PState : ProcessorState Job}.
Hypothesis H_ideal_progress_proc_model : ideal_progress_proc_model PState.
Hypothesis H_unit_service_proc_model : unit_service_proc_model PState.
(** Consider any arrival sequence with consistent arrivals ... *)
Variable arr_seq : arrival_sequence Job.
Hypothesis H_arrival_times_are_consistent : consistent_arrival_times arr_seq.
(** ... and any schedule of this arrival sequence. *)
Variable sched : schedule PState.
(** Assume we are provided with abstract functions for interference and interfering workload. *)
Variable interference : Job -> instant -> bool.
Variable interfering_workload : Job -> instant -> duration.
(** For simplicity, let's define some local names. *)
Let work_conserving := work_conserving arr_seq sched.
Let cumul_interference := cumul_interference interference.
Let cumul_interfering_workload := cumul_interfering_workload interfering_workload.
Let busy_interval := busy_interval sched interference interfering_workload.
(** We assume that the schedule is work-conserving. *)
Hypothesis H_work_conserving: work_conserving interference interfering_workload.
(** Let [j] be any job of task [tsk] with positive cost. *)
Variable j : Job.
Hypothesis H_j_arrives : arrives_in arr_seq j.
Hypothesis H_job_cost_positive : job_cost_positive j.
(** Next, consider any busy interval <<[t1, t2)>> of job [j]. *)
Variable t1 t2 : instant.
Hypothesis H_busy_interval : busy_interval j t1 t2.
(** First, we prove that job [j] completes by the end of the busy interval.
Note that the busy interval contains the execution of job j, in addition
time instant t2 is a quiet time. Thus by the definition of a quiet time
the job should be completed before time t2. *)
Lemma job_completes_within_busy_interval:
completed_by sched j t2.
Proof.
move: (H_busy_interval) => [[/andP [_ LT] [_ _]] [_ QT2]].
unfold pending, has_arrived in QT2.
move: QT2; rewrite /pending negb_and; move => /orP [QT2|QT2].
{ by move: QT2 => /negP QT2; exfalso; apply QT2, ltnW. }
by rewrite Bool.negb_involutive in QT2.
Qed.
(** In this section we show that the cumulative interference is a complement to
the total time where job [j] is scheduled inside the busy interval. *)
Section InterferenceIsComplement.
(** Consider any sub-interval <<[t, t + delta)>> inside the busy interval [t1, t2). *)
Variables (t : instant) (delta : duration).
Hypothesis H_greater_than_or_equal : t1 <= t.
Hypothesis H_less_or_equal: t + delta <= t2.
(** We prove that sum of cumulative service and cumulative interference
in the interval <<[t, t + delta)>> is equal to delta. *)
Lemma interference_is_complement_to_schedule:
service_during sched j t (t + delta) + cumul_interference j t (t + delta) = delta.
Proof.
rewrite /service_during /cumul_interference/service_at.
rewrite -big_split //=.
rewrite -{2}(sum_of_ones t delta).
rewrite big_nat [in RHS]big_nat.