From c8db68d09787c54c2f84f3af4f3db47b11b98d99 Mon Sep 17 00:00:00 2001
From: Felipe Cerqueira <felipec@mpi-sws.org>
Date: Sun, 7 Feb 2016 00:57:54 +0100
Subject: [PATCH] Add more implementations for basic/jitter

- Implemented concrete job and tasks.
- Added a periodic arrival sequence.
- Created examples of applying a schedulability
  test to small task sets and concluding that
  no task misses a deadline.
---
 Makefile                                     |  10 +-
 implementation/basic/arrival_sequence.v      | 114 +++++++++++++++
 implementation/basic/bertogna_edf_example.v  | 136 ++++++++++++++++++
 implementation/basic/job.v                   |  61 ++++++++
 implementation/basic/schedule.v              |   4 +-
 implementation/basic/task.v                  |  69 ++++++++++
 implementation/jitter/arrival_sequence.v     | 114 +++++++++++++++
 implementation/jitter/bertogna_edf_example.v | 138 +++++++++++++++++++
 implementation/jitter/job.v                  |  63 +++++++++
 implementation/jitter/schedule.v             |  16 +--
 implementation/jitter/task.v                 |  71 ++++++++++
 11 files changed, 784 insertions(+), 12 deletions(-)
 create mode 100644 implementation/basic/arrival_sequence.v
 create mode 100644 implementation/basic/bertogna_edf_example.v
 create mode 100644 implementation/basic/job.v
 create mode 100644 implementation/basic/task.v
 create mode 100644 implementation/jitter/arrival_sequence.v
 create mode 100644 implementation/jitter/bertogna_edf_example.v
 create mode 100644 implementation/jitter/job.v
 create mode 100644 implementation/jitter/task.v

diff --git a/Makefile b/Makefile
index 31f4cb7ec..a640af6de 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@
 
 #
 # This Makefile was generated by the command line :
-# coq_makefile -R . rt ./util/ssromega.v ./util/lemmas.v ./util/Vbase.v ./util/divround.v ./implementation/basic/schedule.v ./implementation/jitter/schedule.v ./analysis/basic/bertogna_fp_theory.v ./analysis/basic/bertogna_edf_comp.v ./analysis/basic/bertogna_fp_comp.v ./analysis/basic/bertogna_edf_theory.v ./analysis/jitter/bertogna_fp_theory.v ./analysis/jitter/bertogna_edf_comp.v ./analysis/jitter/bertogna_fp_comp.v ./analysis/jitter/bertogna_edf_theory.v ./model/basic/schedulability.v ./model/basic/interference_bound_edf.v ./model/basic/task.v ./model/basic/interference_bound_fp.v ./model/basic/task_arrival.v ./model/basic/interference_bound.v ./model/basic/platform.v ./model/basic/schedule.v ./model/basic/priority.v ./model/basic/interference_edf.v ./model/basic/interference.v ./model/basic/workload.v ./model/basic/job.v ./model/basic/arrival_sequence.v ./model/basic/response_time.v ./model/basic/platform_fp.v ./model/basic/workload_bound.v ./model/jitter/schedulability.v ./model/jitter/interference_bound_edf.v ./model/jitter/task.v ./model/jitter/interference_bound_fp.v ./model/jitter/task_arrival.v ./model/jitter/interference_bound.v ./model/jitter/platform.v ./model/jitter/schedule.v ./model/jitter/priority.v ./model/jitter/interference_edf.v ./model/jitter/interference.v ./model/jitter/workload.v ./model/jitter/job.v ./model/jitter/arrival_sequence.v ./model/jitter/response_time.v ./model/jitter/platform_fp.v ./model/jitter/workload_bound.v -o Makefile 
+# coq_makefile -R . rt ./util/ssromega.v ./util/lemmas.v ./util/Vbase.v ./util/divround.v ./implementation/basic/bertogna_edf_example.v ./implementation/basic/task.v ./implementation/basic/schedule.v ./implementation/basic/job.v ./implementation/basic/arrival_sequence.v ./implementation/jitter/bertogna_edf_example.v ./implementation/jitter/task.v ./implementation/jitter/schedule.v ./implementation/jitter/job.v ./implementation/jitter/arrival_sequence.v ./analysis/basic/bertogna_fp_theory.v ./analysis/basic/bertogna_edf_comp.v ./analysis/basic/bertogna_fp_comp.v ./analysis/basic/bertogna_edf_theory.v ./analysis/jitter/bertogna_fp_theory.v ./analysis/jitter/bertogna_edf_comp.v ./analysis/jitter/bertogna_fp_comp.v ./analysis/jitter/bertogna_edf_theory.v ./model/basic/schedulability.v ./model/basic/interference_bound_edf.v ./model/basic/task.v ./model/basic/interference_bound_fp.v ./model/basic/task_arrival.v ./model/basic/interference_bound.v ./model/basic/platform.v ./model/basic/schedule.v ./model/basic/priority.v ./model/basic/interference_edf.v ./model/basic/interference.v ./model/basic/workload.v ./model/basic/job.v ./model/basic/arrival_sequence.v ./model/basic/response_time.v ./model/basic/platform_fp.v ./model/basic/workload_bound.v ./model/jitter/schedulability.v ./model/jitter/interference_bound_edf.v ./model/jitter/task.v ./model/jitter/interference_bound_fp.v ./model/jitter/task_arrival.v ./model/jitter/interference_bound.v ./model/jitter/platform.v ./model/jitter/schedule.v ./model/jitter/priority.v ./model/jitter/interference_edf.v ./model/jitter/interference.v ./model/jitter/workload.v ./model/jitter/job.v ./model/jitter/arrival_sequence.v ./model/jitter/response_time.v ./model/jitter/platform_fp.v ./model/jitter/workload_bound.v -o Makefile 
 #
 
 .DEFAULT_GOAL := all
@@ -84,8 +84,16 @@ VFILES:=util/ssromega.v\
   util/lemmas.v\
   util/Vbase.v\
   util/divround.v\
+  implementation/basic/bertogna_edf_example.v\
+  implementation/basic/task.v\
   implementation/basic/schedule.v\
+  implementation/basic/job.v\
+  implementation/basic/arrival_sequence.v\
+  implementation/jitter/bertogna_edf_example.v\
+  implementation/jitter/task.v\
   implementation/jitter/schedule.v\
+  implementation/jitter/job.v\
+  implementation/jitter/arrival_sequence.v\
   analysis/basic/bertogna_fp_theory.v\
   analysis/basic/bertogna_edf_comp.v\
   analysis/basic/bertogna_fp_comp.v\
diff --git a/implementation/basic/arrival_sequence.v b/implementation/basic/arrival_sequence.v
new file mode 100644
index 000000000..723f77487
--- /dev/null
+++ b/implementation/basic/arrival_sequence.v
@@ -0,0 +1,114 @@
+Add LoadPath "../../" as rt.
+Require Import rt.util.Vbase.
+Require Import rt.model.basic.arrival_sequence rt.model.basic.job
+               rt.model.basic.task rt.model.basic.task_arrival.
+Require Import rt.implementation.basic.task rt.implementation.basic.job.
+Require Import ssreflect ssrbool ssrfun ssrnat eqtype seq div.
+
+Module ConcreteArrivalSequence.
+
+  Import Job ArrivalSequence ConcreteTask ConcreteJob SporadicTaskset SporadicTaskArrival.
+
+  Section PeriodicArrivals.
+
+    Variable ts: concrete_taskset.
+
+    (* At any time t, we release Some job of tsk if t is a multiple of the period,
+       otherwise we release None. *)
+    Definition add_job (t: time) (tsk: concrete_task) :=
+      if task_period tsk %| t  then
+        Some (Build_concrete_job (t %/ task_period tsk) (task_cost tsk) (task_deadline tsk) tsk)
+      else
+        None.
+
+    (* The arrival sequence at any time t is simply the partial map of add_job. *)
+    Definition periodic_arrival_sequence (t: time) := pmap (add_job t) ts.
+
+  End PeriodicArrivals.
+
+  Section Proofs.
+
+    (* Let ts be any concrete task set with valid parameters. *)
+    Variable ts: concrete_taskset.
+    Hypothesis H_valid_task_parameters:
+      valid_sporadic_taskset task_cost task_period task_deadline ts.
+    
+    (* Regarding the periodic arrival sequence built from ts, we prove that...*)
+    Let arr_seq := periodic_arrival_sequence ts.
+
+    (* ... every job comes from the task set, ... *)
+    (* TODO: It's supposed to be job_task j, but I don't know yet how to
+       fix the coercion. *)
+    Theorem periodic_arrivals_all_jobs_from_taskset:
+      forall (j: JobIn arr_seq),
+        job_task (_job_in arr_seq j) \in ts.
+    Proof.
+      intros j.
+      destruct j as [j arr ARRj]; simpl.
+      unfold arr_seq, arrives_at, periodic_arrival_sequence in *.
+      rewrite mem_pmap in ARRj.
+      move: ARRj => /mapP ARRj; destruct ARRj as [tsk IN SOME].
+      by unfold add_job in *; desf.
+    Qed.
+
+    (* ..., jobs have valid parameters, ... *)
+    Theorem periodic_arrivals_valid_job_parameters:
+      forall (j: JobIn arr_seq),
+        valid_sporadic_job task_cost task_deadline job_cost job_deadline job_task j.
+    Proof.
+      rename H_valid_task_parameters into PARAMS.
+      unfold valid_sporadic_taskset, is_valid_sporadic_task in *.
+      intros j; destruct j as [j arr ARRj]; simpl.
+      unfold arrives_at, arr_seq, periodic_arrival_sequence in ARRj.
+      rewrite mem_pmap in ARRj; move: ARRj => /mapP [tsk IN SOME].
+      unfold add_job in SOME; desf.
+      specialize (PARAMS tsk IN); des.
+      unfold valid_sporadic_job, valid_realtime_job, job_cost_positive.
+      by repeat split; try (by done); apply leqnn.
+    Qed.
+
+    (* ... job arrivals satisfy the sporadic task model, ... *)
+    Theorem periodic_arrivals_are_sporadic:
+      sporadic_task_model task_period arr_seq job_task.
+    Proof.
+      unfold sporadic_task_model; move => j j' /eqP DIFF SAMEtsk LE.
+      destruct j as [j arr ARR], j' as [j' arr' ARR']; simpl in *.
+      rewrite eqE /= /jobin_eqdef negb_and /= in DIFF.
+      unfold arrives_at, arr_seq, periodic_arrival_sequence in *.
+      rewrite 2!mem_pmap in ARR ARR'.
+      move: ARR ARR' => /mapP [tsk_j INj SOMEj] /mapP [tsk_j' INj' SOMEj'].
+      unfold add_job in *; desf; simpl in *; subst.
+      clear INj'.
+      move: Heq Heq0 => /dvdnP DIV' /dvdnP DIV; des.
+      rewrite DIV DIV' -mulSnr.
+      rewrite leq_eqVlt in LE; move: LE => /orP [/eqP EQ | LESS].
+      {
+        move: DIFF => /orP [/eqP CASE1 | /eqP CASE2].
+        - by exfalso; apply CASE1; repeat f_equal.
+        - by rewrite EQ in CASE2.
+      }
+      rewrite leq_mul2r; apply/orP; right.
+      rewrite ltn_neqAle; apply/andP; split.
+      {
+        apply/eqP; red; intro EQ; subst.
+        by rewrite ltnn in LESS.
+      }
+      rewrite leqNgt; apply/negP; red; intro LT.
+      rewrite ltnNge in LESS; move: LESS => /negP LESS; apply LESS.
+      by subst; rewrite leq_mul2r; apply/orP; right; apply ltnW.
+    Qed.
+
+    (* ... and if the task set has no duplicates, the same applies to
+       the arrival sequence. *)
+    Theorem periodic_arrivals_is_a_set:
+      uniq ts -> arrival_sequence_is_a_set arr_seq.
+    Proof.
+      intros UNIQ t.
+      unfold arr_seq, periodic_arrival_sequence.
+      apply (pmap_uniq) with (g := job_task); last by done.
+      by unfold add_job, ocancel; intro tsk; desf.
+    Qed.
+      
+  End Proofs.
+  
+End ConcreteArrivalSequence.
\ No newline at end of file
diff --git a/implementation/basic/bertogna_edf_example.v b/implementation/basic/bertogna_edf_example.v
new file mode 100644
index 000000000..ad8eaa3ea
--- /dev/null
+++ b/implementation/basic/bertogna_edf_example.v
@@ -0,0 +1,136 @@
+Add LoadPath "../../" as rt.
+Require Import rt.util.Vbase rt.util.divround.
+Require Import rt.model.basic.job rt.model.basic.task
+               rt.model.basic.schedule rt.model.basic.schedulability
+               rt.model.basic.workload_bound
+               rt.model.basic.interference_bound_edf
+               rt.model.basic.priority rt.model.basic.platform
+               rt.analysis.basic.bertogna_edf_comp.
+Require Import rt.implementation.basic.job
+               rt.implementation.basic.task
+               rt.implementation.basic.schedule
+               rt.implementation.basic.arrival_sequence.
+Require Import ssreflect ssrbool ssrnat eqtype seq bigop div.
+
+Module ResponseTimeAnalysisEDF.
+
+  Import Job Schedule SporadicTaskset Priority Schedulability Platform InterferenceBoundEDF WorkloadBound ResponseTimeIterationEDF.
+  Import ConcreteJob ConcreteTask ConcreteArrivalSequence ConcreteScheduler.
+
+  Section ExampleRTA.
+
+    Let tsk1 := {| task_id := 1; task_cost := 2; task_period := 5; task_deadline := 3|}.
+    Let tsk2 := {| task_id := 2; task_cost := 4; task_period := 6; task_deadline := 5|}.
+    Let tsk3 := {| task_id := 3; task_cost := 3; task_period := 12; task_deadline := 11|}.
+
+    (* Let ts be a task set containing these three tasks. *)
+    Let ts := [:: tsk1; tsk2; tsk3].
+
+    Section FactsAboutTaskset.
+
+      Fact ts_is_a_set: uniq ts.
+      Proof.
+        by compute.
+      Qed.
+      
+      Fact ts_has_valid_parameters:
+        valid_sporadic_taskset task_cost task_period task_deadline ts.
+      Proof.
+        intros tsk IN.
+        repeat (move: IN => /orP [/eqP EQ | IN]; subst; compute); by done.
+      Qed.
+
+      Fact ts_has_constrained_deadlines:
+        forall tsk,
+          tsk \in ts ->
+          task_deadline tsk <= task_period tsk.
+      Proof.
+        intros tsk IN.
+        repeat (move: IN => /orP [/eqP EQ | IN]; subst; compute); by done.
+      Qed.
+      
+    End FactsAboutTaskset.
+
+    (* Assume there are two processors. *)
+    Let num_cpus := 2.
+
+    (* Recall the EDF RTA schedulability test. *)
+    Let schedulability_test :=
+      edf_schedulable task_cost task_period task_deadline num_cpus.
+
+    Fact schedulability_test_succeeds :
+      schedulability_test ts = true.
+    Proof.
+      unfold schedulability_test, edf_schedulable, edf_claimed_bounds; desf.
+      apply negbT in Heq; move: Heq => /negP ALL.
+      exfalso; apply ALL; clear ALL.
+      assert (STEPS: \sum_(tsk <- ts) (task_deadline tsk - task_cost tsk) + 1 = 11).
+      {
+        by rewrite unlock; compute.
+      } rewrite STEPS; clear STEPS.
+      
+      Ltac f :=
+        unfold edf_rta_iteration; simpl;
+        unfold edf_response_time_bound, div_floor, total_interference_bound_edf, interference_bound_edf, interference_bound_generic, W; simpl;
+        repeat rewrite addnE;
+        repeat rewrite big_cons; repeat rewrite big_nil;
+        repeat rewrite addnE; simpl;
+        unfold num_cpus, divn; simpl.
+
+      rewrite [edf_rta_iteration]lock; simpl.
+
+      unfold locked at 11; destruct master_key; f.
+      unfold locked at 10; destruct master_key; f.
+      unfold locked at 9; destruct master_key; f.
+      unfold locked at 8; destruct master_key; f.
+      unfold locked at 7; destruct master_key; f.
+      unfold locked at 6; destruct master_key; f.
+      unfold locked at 5; destruct master_key; f.
+      unfold locked at 4; destruct master_key; f.
+      unfold locked at 3; destruct master_key; f.
+      unfold locked at 2; destruct master_key; f.
+      by unfold locked at 1; destruct master_key; f.
+    Qed.
+
+    (* Let arr_seq be the periodic arrival sequence from ts. *)
+    Let arr_seq := periodic_arrival_sequence ts.
+
+    (* Let sched be the work-conserving EDF scheduler. *)
+    Let sched := scheduler job_cost num_cpus arr_seq (EDF job_deadline).
+
+    (* Recall the definition of deadline miss. *)
+    Let no_deadline_missed_by :=
+      task_misses_no_deadline job_cost job_deadline job_task sched.
+
+    (* Next, we prove that ts is schedulable with the result of the test. *)
+    Corollary ts_is_schedulable:
+      forall tsk,
+        tsk \in ts ->
+        no_deadline_missed_by tsk.
+    Proof.
+      intros tsk IN.
+      have VALID := periodic_arrivals_valid_job_parameters ts ts_has_valid_parameters.
+      have EDFVALID := @edf_valid_policy _ arr_seq job_deadline.
+      unfold valid_JLDP_policy, valid_sporadic_job, valid_realtime_job in *; des.
+      apply taskset_schedulable_by_edf_rta with (task_cost := task_cost) (task_period := task_period) (task_deadline := task_deadline) (ts0 := ts).
+      - by apply ts_is_a_set.
+      - by apply ts_has_valid_parameters. 
+      - by apply ts_has_constrained_deadlines.
+      - by apply periodic_arrivals_all_jobs_from_taskset.
+      - by apply periodic_arrivals_valid_job_parameters, ts_has_valid_parameters.
+      - by apply periodic_arrivals_are_sporadic.
+      - by compute.
+      - by apply scheduler_jobs_must_arrive_to_execute.
+      - apply scheduler_completed_jobs_dont_execute; intro j'.
+        -- by specialize (VALID j'); des.
+        -- by apply periodic_arrivals_is_a_set.
+      - by apply scheduler_no_parallelism, periodic_arrivals_is_a_set.
+      - by apply scheduler_work_conserving.
+      - by apply scheduler_enforces_policy; ins.
+      - by apply schedulability_test_succeeds.
+      - by apply IN.
+    Qed.
+
+  End ExampleRTA.
+
+End ResponseTimeAnalysisEDF.
\ No newline at end of file
diff --git a/implementation/basic/job.v b/implementation/basic/job.v
new file mode 100644
index 000000000..ba32c5366
--- /dev/null
+++ b/implementation/basic/job.v
@@ -0,0 +1,61 @@
+Add LoadPath "../../" as rt.
+Require Import rt.util.Vbase.
+Require Import rt.implementation.basic.task.
+Require Import ssreflect ssrbool ssrnat eqtype seq.
+
+Module ConcreteJob.
+
+  Import ConcreteTask.
+
+  Section Defs.
+
+    (* Definition of a concrete task. *)
+    Record concrete_job :=
+    {
+      job_id: nat;
+      job_cost: nat;
+      job_deadline: nat;
+      job_task: concrete_task_eqType
+    }.
+
+    (* To make it compatible with ssreflect, we define a decidable
+       equality for concrete jobs. *)
+    Definition job_eqdef (j1 j2: concrete_job) :=
+      (job_id j1 == job_id j2) &&
+      (job_cost j1 == job_cost j2) &&
+      (job_deadline j1 == job_deadline j2) &&
+      (job_task j1 == job_task j2).
+
+    (* Next, we prove that job_eqdef is indeed an equality, ... *)
+    Lemma eqn_job : Equality.axiom job_eqdef.
+    Proof.
+      unfold Equality.axiom; intros x y.
+      destruct (job_eqdef x y) eqn:EQ.
+      {
+        apply ReflectT; unfold job_eqdef in *.
+        move: EQ => /andP [/andP [/andP [/eqP ID /eqP COST] /eqP DL] /eqP TASK].
+        by destruct x, y; simpl in *; subst.
+      }
+      {
+        apply ReflectF.
+        unfold job_eqdef, not in *; intro BUG.
+        apply negbT in EQ; rewrite negb_and in EQ.
+        destruct x, y.
+        rewrite negb_and in EQ.
+        move: EQ => /orP [EQ | /eqP TASK]; last by apply TASK; inversion BUG.
+        move: EQ => /orP [EQ | /eqP DL].
+        rewrite negb_and in EQ.
+        move: EQ => /orP [/eqP ID | /eqP COST].
+        by apply ID; inversion BUG.
+        by apply COST; inversion BUG.
+        by apply DL; inversion BUG.
+      }
+    Qed.
+
+    (* ..., which allows instantiating the canonical structure. *)
+    Canonical concrete_job_eqMixin := EqMixin eqn_job.
+    Canonical concrete_job_eqType := Eval hnf in EqType concrete_job concrete_job_eqMixin.
+
+   End Defs.
+    
+End ConcreteJob.
\ No newline at end of file
diff --git a/implementation/basic/schedule.v b/implementation/basic/schedule.v
index 71ae096b3..8435ae225 100644
--- a/implementation/basic/schedule.v
+++ b/implementation/basic/schedule.v
@@ -4,7 +4,7 @@ Require Import rt.model.basic.job rt.model.basic.arrival_sequence rt.model.basic
                rt.model.basic.platform rt.model.basic.priority.
 Require Import Program ssreflect ssrbool ssrfun eqtype ssrnat fintype bigop seq path.
 
-Module WorkConservingScheduler.
+Module ConcreteScheduler.
 
   Import Job ArrivalSequence Schedule Platform Priority.
   
@@ -336,4 +336,4 @@ Module WorkConservingScheduler.
 
   End Proofs.
     
-End WorkConservingScheduler.
\ No newline at end of file
+End ConcreteScheduler.
\ No newline at end of file
diff --git a/implementation/basic/task.v b/implementation/basic/task.v
new file mode 100644
index 000000000..30c7a8965
--- /dev/null
+++ b/implementation/basic/task.v
@@ -0,0 +1,69 @@
+Add LoadPath "../../" as rt.
+Require Import rt.util.Vbase.
+Require Import rt.model.basic.task.
+Require Import ssreflect ssrbool ssrnat eqtype seq.
+
+Module ConcreteTask.
+
+  Import SporadicTaskset.
+  
+  Section Defs.
+    
+    (* Definition of a concrete task. *)
+    Record concrete_task :=
+    {
+      task_id: nat; (* for uniqueness *)  
+      task_cost: nat;
+      task_period: nat;
+      task_deadline: nat               
+    }.
+
+    (* To make it compatible with ssreflect, we define a decidable
+       equality for concrete tasks. *)
+    Definition task_eqdef (t1 t2: concrete_task) :=
+      (task_id t1 == task_id t2) &&
+      (task_cost t1 == task_cost t2) &&
+      (task_period t1 == task_period t2) &&
+      (task_deadline t1 == task_deadline t2).
+
+    (* Next, we prove that task_eqdef is indeed an equality, ... *)
+    Lemma eqn_task : Equality.axiom task_eqdef.
+    Proof.
+      unfold Equality.axiom; intros x y.
+      destruct (task_eqdef x y) eqn:EQ.
+      {
+        apply ReflectT.
+        unfold task_eqdef in *.
+        move: EQ => /andP [/andP [/andP [/eqP ID /eqP COST] /eqP PERIOD] /eqP DL].
+        by destruct x, y; simpl in *; subst. 
+      }
+      {
+        apply ReflectF.
+        unfold task_eqdef, not in *; intro BUG.
+        apply negbT in EQ; rewrite negb_and in EQ.
+        destruct x, y.
+        rewrite negb_and in EQ.
+        move: EQ => /orP [EQ | /eqP DL]; last by apply DL; inversion BUG.
+        move: EQ => /orP [EQ | /eqP PERIOD].
+        rewrite negb_and in EQ.
+        move: EQ => /orP [/eqP ID | /eqP COST].
+        by apply ID; inversion BUG.
+        by apply COST; inversion BUG.
+        by apply PERIOD; inversion BUG.
+      }
+    Qed.
+
+    (* ..., which allows instantiating the canonical structure. *)
+    Canonical concrete_task_eqMixin := EqMixin eqn_task.
+    Canonical concrete_task_eqType := Eval hnf in EqType concrete_task concrete_task_eqMixin.
+
+  End Defs.
+
+  Section ConcreteTaskset.
+
+    Definition concrete_taskset :=
+      taskset_of concrete_task_eqType.
+
+  End ConcreteTaskset.
+  
+End ConcreteTask.
\ No newline at end of file
diff --git a/implementation/jitter/arrival_sequence.v b/implementation/jitter/arrival_sequence.v
new file mode 100644
index 000000000..e50701dc8
--- /dev/null
+++ b/implementation/jitter/arrival_sequence.v
@@ -0,0 +1,114 @@
+Add LoadPath "../../" as rt.
+Require Import rt.util.Vbase.
+Require Import rt.model.jitter.arrival_sequence rt.model.jitter.job
+               rt.model.jitter.task rt.model.jitter.task_arrival.
+Require Import rt.implementation.jitter.task rt.implementation.jitter.job.
+Require Import ssreflect ssrbool ssrfun ssrnat eqtype seq div.
+
+Module ConcreteArrivalSequence.
+
+  Import JobWithJitter ArrivalSequence ConcreteTask ConcreteJob SporadicTaskset SporadicTaskArrival.
+
+  Section PeriodicArrivals.
+
+    Variable ts: concrete_taskset.
+
+    (* At any time t, we release Some job of tsk if t is a multiple of the period,
+       otherwise we release None. *)
+    Definition add_job (t: time) (tsk: concrete_task) :=
+      if task_period tsk %| t  then
+        Some (Build_concrete_job (t %/ task_period tsk) (task_cost tsk) (task_deadline tsk) (task_jitter tsk) tsk)
+      else
+        None.
+
+    (* The arrival sequence at any time t is simply the partial map of add_job. *)
+    Definition periodic_arrival_sequence (t: time) := pmap (add_job t) ts.
+
+  End PeriodicArrivals.
+
+  Section Proofs.
+
+    (* Let ts be any concrete task set with valid parameters. *)
+    Variable ts: concrete_taskset.
+    Hypothesis H_valid_task_parameters:
+      valid_sporadic_taskset task_cost task_period task_deadline ts.
+    
+    (* Regarding the periodic arrival sequence built from ts, we prove that...*)
+    Let arr_seq := periodic_arrival_sequence ts.
+
+    (* ... every job comes from the task set, ... *)
+    (* TODO: It's supposed to be job_task j, but I don't know yet how to
+       fix the coercion. *)
+    Theorem periodic_arrivals_all_jobs_from_taskset:
+      forall (j: JobIn arr_seq),
+        job_task (_job_in arr_seq j) \in ts.
+    Proof.
+      intros j.
+      destruct j as [j arr ARRj]; simpl.
+      unfold arr_seq, arrives_at, periodic_arrival_sequence in *.
+      rewrite mem_pmap in ARRj.
+      move: ARRj => /mapP ARRj; destruct ARRj as [tsk IN SOME].
+      by unfold add_job in *; desf.
+    Qed.
+
+    (* ..., jobs have valid parameters, ... *)
+    Theorem periodic_arrivals_valid_job_parameters:
+      forall (j: JobIn arr_seq),
+        valid_sporadic_job_with_jitter task_cost task_deadline task_jitter job_cost job_deadline job_task job_jitter j.
+    Proof.
+      rename H_valid_task_parameters into PARAMS.
+      unfold valid_sporadic_taskset, is_valid_sporadic_task in *.
+      intros j; destruct j as [j arr ARRj]; simpl.
+      unfold arrives_at, arr_seq, periodic_arrival_sequence in ARRj.
+      rewrite mem_pmap in ARRj; move: ARRj => /mapP [tsk IN SOME].
+      unfold add_job in SOME; desf.
+      specialize (PARAMS tsk IN); des.
+      unfold valid_sporadic_job, valid_realtime_job, job_cost_positive.
+      by repeat split; try (by done); apply leqnn.
+    Qed.
+
+    (* ... job arrivals satisfy the sporadic task model, ... *)
+    Theorem periodic_arrivals_are_sporadic:
+      sporadic_task_model task_period arr_seq job_task.
+    Proof.
+      unfold sporadic_task_model; move => j j' /eqP DIFF SAMEtsk LE.
+      destruct j as [j arr ARR], j' as [j' arr' ARR']; simpl in *.
+      rewrite eqE /= /jobin_eqdef negb_and /= in DIFF.
+      unfold arrives_at, arr_seq, periodic_arrival_sequence in *.
+      rewrite 2!mem_pmap in ARR ARR'.
+      move: ARR ARR' => /mapP [tsk_j INj SOMEj] /mapP [tsk_j' INj' SOMEj'].
+      unfold add_job in *; desf; simpl in *; subst.
+      clear INj'.
+      move: Heq Heq0 => /dvdnP DIV' /dvdnP DIV; des.
+      rewrite DIV DIV' -mulSnr.
+      rewrite leq_eqVlt in LE; move: LE => /orP [/eqP EQ | LESS].
+      {
+        move: DIFF => /orP [/eqP CASE1 | /eqP CASE2].
+        - by exfalso; apply CASE1; repeat f_equal.
+        - by rewrite EQ in CASE2.
+      }
+      rewrite leq_mul2r; apply/orP; right.
+      rewrite ltn_neqAle; apply/andP; split.
+      {
+        apply/eqP; red; intro EQ; subst.
+        by rewrite ltnn in LESS.
+      }
+      rewrite leqNgt; apply/negP; red; intro LT.
+      rewrite ltnNge in LESS; move: LESS => /negP LESS; apply LESS.
+      by subst; rewrite leq_mul2r; apply/orP; right; apply ltnW.
+    Qed.
+
+    (* ... and if the task set has no duplicates, the same applies to
+       the arrival sequence. *)
+    Theorem periodic_arrivals_is_a_set:
+      uniq ts -> arrival_sequence_is_a_set arr_seq.
+    Proof.
+      intros UNIQ t.
+      unfold arr_seq, periodic_arrival_sequence.
+      apply (pmap_uniq) with (g := job_task); last by done.
+      by unfold add_job, ocancel; intro tsk; desf.
+    Qed.
+      
+  End Proofs.
+  
+End ConcreteArrivalSequence.
\ No newline at end of file
diff --git a/implementation/jitter/bertogna_edf_example.v b/implementation/jitter/bertogna_edf_example.v
new file mode 100644
index 000000000..0a4b32174
--- /dev/null
+++ b/implementation/jitter/bertogna_edf_example.v
@@ -0,0 +1,138 @@
+Add LoadPath "../../" as rt.
+Require Import rt.util.Vbase rt.util.divround.
+Require Import rt.model.jitter.job rt.model.jitter.task
+               rt.model.jitter.schedule rt.model.jitter.schedulability
+               rt.model.jitter.workload_bound
+               rt.model.jitter.interference_bound_edf
+               rt.model.jitter.priority rt.model.jitter.platform
+               rt.analysis.jitter.bertogna_edf_comp.
+Require Import rt.implementation.jitter.job
+               rt.implementation.jitter.task
+               rt.implementation.jitter.schedule
+               rt.implementation.jitter.arrival_sequence.
+Require Import ssreflect ssrbool ssrnat eqtype seq bigop div.
+
+Module ResponseTimeAnalysisEDF.
+
+  Import JobWithJitter ScheduleWithJitter SporadicTaskset Priority Schedulability Platform InterferenceBoundEDFJitter WorkloadBoundJitter ResponseTimeIterationEDF.
+  Import ConcreteJob ConcreteTask ConcreteArrivalSequence ConcreteScheduler.
+
+  Section ExampleRTA.
+
+    Let tsk1 := {| task_id := 1; task_cost := 2; task_period := 5; task_deadline := 3; task_jitter := 1|}.
+    Let tsk2 := {| task_id := 2; task_cost := 4; task_period := 6; task_deadline := 5; task_jitter := 0|}.
+    Let tsk3 := {| task_id := 3; task_cost := 2; task_period := 12; task_deadline := 11; task_jitter := 2|}.
+
+    (* Let ts be a task set containing these three tasks. *)
+    Let ts := [:: tsk1; tsk2; tsk3].
+
+    Section FactsAboutTaskset.
+
+      Fact ts_is_a_set: uniq ts.
+      Proof.
+        by compute.
+      Qed.
+      
+      Fact ts_has_valid_parameters:
+        valid_sporadic_taskset task_cost task_period task_deadline ts.
+      Proof.
+        intros tsk IN.
+        repeat (move: IN => /orP [/eqP EQ | IN]; subst; compute); by done.
+      Qed.
+
+      Fact ts_has_constrained_deadlines:
+        forall tsk,
+          tsk \in ts ->
+          task_deadline tsk <= task_period tsk.
+      Proof.
+        intros tsk IN.
+        repeat (move: IN => /orP [/eqP EQ | IN]; subst; compute); by done.
+      Qed.
+      
+    End FactsAboutTaskset.
+
+    (* Assume there are two processors. *)
+    Let num_cpus := 2.
+
+    (* Recall the EDF RTA schedulability test. *)
+    Let schedulability_test :=
+      edf_schedulable task_cost task_period task_deadline task_jitter num_cpus.
+
+    Fact schedulability_test_succeeds :
+      schedulability_test ts = true.
+    Proof.
+      unfold schedulability_test, edf_schedulable, edf_claimed_bounds; desf.
+      apply negbT in Heq; move: Heq => /negP ALL.
+      exfalso; apply ALL; clear ALL.
+      assert (STEPS: \sum_(tsk <- ts) (task_deadline tsk - task_cost tsk) + 1 = 12).
+      {
+        by rewrite unlock; compute.
+      } rewrite STEPS; clear STEPS.
+      
+      Ltac f :=
+        unfold edf_rta_iteration; simpl;
+        unfold edf_response_time_bound, div_floor, total_interference_bound_edf, interference_bound_edf, interference_bound_generic, W_jitter; simpl;
+        repeat rewrite addnE;
+        repeat rewrite big_cons; repeat rewrite big_nil;
+        repeat rewrite addnE; simpl;
+        unfold num_cpus, divn; simpl.
+
+      rewrite [edf_rta_iteration]lock; simpl.
+
+      unfold locked at 12; destruct master_key; f.
+      unfold locked at 11; destruct master_key; f.
+      unfold locked at 10; destruct master_key; f.
+      unfold locked at 9; destruct master_key; f.
+      unfold locked at 8; destruct master_key; f.
+      unfold locked at 7; destruct master_key; f.
+      unfold locked at 6; destruct master_key; f.
+      unfold locked at 5; destruct master_key; f.
+      unfold locked at 4; destruct master_key; f.
+      unfold locked at 3; destruct master_key; f.
+      unfold locked at 2; destruct master_key; f.
+      by unfold locked at 1; destruct master_key; f.
+    Qed.
+
+    (* Let arr_seq be the periodic arrival sequence from ts. *)
+    Let arr_seq := periodic_arrival_sequence ts.
+
+    (* Let sched be the work-conserving EDF scheduler. *)
+    Let sched := scheduler job_cost job_jitter num_cpus arr_seq (EDF job_deadline).
+
+    (* Recall the definition of deadline miss. *)
+    Let no_deadline_missed_by :=
+      task_misses_no_deadline job_cost job_deadline job_task sched.
+
+    (* Next, we prove that ts is schedulable with the result of the test. *)
+    Corollary ts_is_schedulable:
+      forall tsk,
+        tsk \in ts ->
+        no_deadline_missed_by tsk.
+    Proof.
+      intros tsk IN.
+      have VALID := periodic_arrivals_valid_job_parameters ts ts_has_valid_parameters.
+      have EDFVALID := @edf_valid_policy _ arr_seq job_deadline.
+      unfold valid_JLDP_policy, valid_sporadic_job_with_jitter,
+             valid_sporadic_job, valid_realtime_job in *; des.
+      apply taskset_schedulable_by_edf_rta with (task_cost := task_cost) (task_period := task_period) (task_deadline := task_deadline) (ts0 := ts) (task_jitter := task_jitter) (job_jitter := job_jitter).
+      - by apply ts_is_a_set.
+      - by apply ts_has_valid_parameters. 
+      - by apply ts_has_constrained_deadlines.
+      - by apply periodic_arrivals_all_jobs_from_taskset.
+      - by apply periodic_arrivals_valid_job_parameters, ts_has_valid_parameters.
+      - by apply periodic_arrivals_are_sporadic.
+      - by compute.
+      - by apply scheduler_jobs_execute_after_jitter.
+      - apply scheduler_completed_jobs_dont_execute; intro j'.
+        -- by specialize (VALID j'); des.
+        -- by apply periodic_arrivals_is_a_set.
+      - by apply scheduler_no_parallelism, periodic_arrivals_is_a_set.
+      - by apply scheduler_work_conserving.
+      - by apply scheduler_enforces_policy; ins.
+      - by apply schedulability_test_succeeds.
+      - by apply IN.
+    Qed.
+
+  End ExampleRTA.
+
+End ResponseTimeAnalysisEDF.
\ No newline at end of file
diff --git a/implementation/jitter/job.v b/implementation/jitter/job.v
new file mode 100644
index 000000000..441a6fb0e
--- /dev/null
+++ b/implementation/jitter/job.v
@@ -0,0 +1,63 @@
+Add LoadPath "../../" as rt.
+Require Import rt.util.Vbase.
+Require Import rt.implementation.jitter.task.
+Require Import ssreflect ssrbool ssrnat eqtype seq.
+
+Module ConcreteJob.
+
+  Import ConcreteTask.
+
+  Section Defs.
+
+    (* Definition of a concrete task. *)
+    Record concrete_job :=
+    {
+      job_id: nat;
+      job_cost: nat;
+      job_deadline: nat;
+      job_jitter: nat;
+      job_task: concrete_task_eqType
+    }.
+
+    (* To make it compatible with ssreflect, we define a decidable
+       equality for concrete jobs. *)
+    Definition job_eqdef (j1 j2: concrete_job) :=
+      (job_id j1 == job_id j2) &&
+      (job_cost j1 == job_cost j2) &&
+      (job_deadline j1 == job_deadline j2) &&
+      (job_jitter j1 == job_jitter j2) &&
+      (job_task j1 == job_task j2).
+
+    (* Next, we prove that job_eqdef is indeed an equality, ... *)
+    Lemma eqn_job : Equality.axiom job_eqdef.
+    Proof.
+      unfold Equality.axiom; intros x y.
+      destruct (job_eqdef x y) eqn:EQ.
+      {
+        apply ReflectT; unfold job_eqdef in *.
+        move: EQ => /andP [/andP [/andP [/andP [/eqP ID /eqP COST] /eqP DL] /eqP JITTER] /eqP TASK].
+        by destruct x, y; simpl in *; subst.
+      }
+      {
+        apply ReflectF.
+        unfold job_eqdef, not in *; intro BUG.
+        apply negbT in EQ; rewrite negb_and in EQ.
+        destruct x, y.
+        rewrite negb_and in EQ.
+        move: EQ => /orP [EQ | /eqP TASK]; last by apply TASK; inversion BUG.
+        move: EQ => /orP [EQ | /eqP JITTER]; last by apply JITTER; inversion BUG.
+        rewrite negb_and in EQ.
+        move: EQ => /orP [EQ | /eqP DL]; last by apply DL; inversion BUG.
+        rewrite negb_and in EQ.
+        move: EQ => /orP [/eqP ID | /eqP COST]; last by apply COST; inversion BUG.
+        by apply ID; inversion BUG.
+      }
+    Qed.
+
+    (* ..., which allows instantiating the canonical structure. *)
+    Canonical concrete_job_eqMixin := EqMixin eqn_job.
+    Canonical concrete_job_eqType := Eval hnf in EqType concrete_job concrete_job_eqMixin.
+
+   End Defs.
+    
+End ConcreteJob.
\ No newline at end of file
diff --git a/implementation/jitter/schedule.v b/implementation/jitter/schedule.v
index c242c70f6..21d18bb3a 100644
--- a/implementation/jitter/schedule.v
+++ b/implementation/jitter/schedule.v
@@ -4,7 +4,7 @@ Require Import rt.model.jitter.job rt.model.jitter.arrival_sequence rt.model.jit
                rt.model.jitter.platform rt.model.jitter.priority.
 Require Import Program ssreflect ssrbool ssrfun eqtype ssrnat fintype bigop seq path.
 
-Module WorkConservingScheduler.
+Module ConcreteScheduler.
 
   Import Job ArrivalSequence ScheduleWithJitter Platform Priority.
   
@@ -217,9 +217,9 @@ Module WorkConservingScheduler.
 
     (* Now, we prove the important properties about the implementation. *)
     
-    (* Jobs do not execute before they arrive, ...*)
-    Theorem scheduler_jobs_must_arrive_to_execute:
-      jobs_must_arrive_to_execute sched.
+    (* Jobs do not execute before the jitter, ...*)
+    Theorem scheduler_jobs_execute_after_jitter:
+      jobs_execute_after_jitter job_jitter sched.
     Proof.
       unfold jobs_must_arrive_to_execute.
       intros j t SCHED.
@@ -230,15 +230,13 @@ Module WorkConservingScheduler.
         rewrite /update_schedule eq_refl in SCHED.
         apply (nth_or_none_mem _ cpu j) in SCHED.
         rewrite mem_sort mem_filter in SCHED.
-        move: SCHED => /andP [_ ARR].
-        by apply JobIn_has_arrived in ARR.
+        by move: SCHED => /andP [/andP [PENDING _] _]. 
       }
       {
         unfold update_schedule at 1 in SCHED; rewrite eq_refl /= in SCHED.
         apply (nth_or_none_mem _ cpu j) in SCHED.
         rewrite mem_sort mem_filter in SCHED.
-        move: SCHED => /andP [_ ARR].
-        by apply JobIn_has_arrived in ARR.
+        by move: SCHED => /andP [/andP [PENDING _] _].
       }
     Qed.
 
@@ -340,4 +338,4 @@ Module WorkConservingScheduler.
 
   End Proofs.
     
-End WorkConservingScheduler.
\ No newline at end of file
+End ConcreteScheduler.
\ No newline at end of file
diff --git a/implementation/jitter/task.v b/implementation/jitter/task.v
new file mode 100644
index 000000000..ac1e51da3
--- /dev/null
+++ b/implementation/jitter/task.v
@@ -0,0 +1,71 @@
+Add LoadPath "../../" as rt.
+Require Import rt.util.Vbase.
+Require Import rt.model.jitter.task.
+Require Import ssreflect ssrbool ssrnat eqtype seq.
+
+Module ConcreteTask.
+
+  Import SporadicTaskset.
+  
+  Section Defs.
+    
+    (* Definition of a concrete task. *)
+    Record concrete_task :=
+    {
+      task_id: nat; (* for uniqueness *)  
+      task_cost: nat;
+      task_period: nat;
+      task_deadline: nat;
+      task_jitter: nat
+    }.
+
+    (* To make it compatible with ssreflect, we define a decidable
+       equality for concrete tasks. *)
+    Definition task_eqdef (t1 t2: concrete_task) :=
+      (task_id t1 == task_id t2) &&
+      (task_cost t1 == task_cost t2) &&
+      (task_period t1 == task_period t2) &&
+      (task_deadline t1 == task_deadline t2) &&
+      (task_jitter t1 == task_jitter t2).
+
+    (* Next, we prove that task_eqdef is indeed an equality, ... *)
+    Lemma eqn_task : Equality.axiom task_eqdef.
+    Proof.
+      unfold Equality.axiom; intros x y.
+      destruct (task_eqdef x y) eqn:EQ.
+      {
+        apply ReflectT.
+        unfold task_eqdef in *.
+        move: EQ => /andP [/andP [/andP [/andP [/eqP ID /eqP COST] /eqP PERIOD] /eqP DL] /eqP JITTER].
+        by destruct x, y; simpl in *; subst. 
+      }
+      {
+        apply ReflectF.
+        unfold task_eqdef, not in *; intro BUG.
+        apply negbT in EQ; rewrite negb_and in EQ.
+        destruct x, y.
+        rewrite negb_and in EQ.
+        move: EQ => /orP [/orP [EQ | /eqP DL] | /eqP JITTER]; last by apply JITTER; inversion BUG.
+        rewrite negb_and in EQ.
+        move: EQ => /orP [EQ | /eqP DL]; last by apply DL; inversion BUG.
+        rewrite negb_and in EQ.
+        move: EQ => /orP [/eqP ID | /eqP PERIOD]; last by apply PERIOD; inversion BUG.
+        by apply ID; inversion BUG.
+        by apply DL; inversion BUG.
+      }
+    Qed.
+
+    (* ..., which allows instantiating the canonical structure. *)
+    Canonical concrete_task_eqMixin := EqMixin eqn_task.
+    Canonical concrete_task_eqType := Eval hnf in EqType concrete_task concrete_task_eqMixin.
+
+  End Defs.
+
+  Section ConcreteTaskset.
+
+    Definition concrete_taskset :=
+      taskset_of concrete_task_eqType.
+
+  End ConcreteTaskset.
+  
+End ConcreteTask.
\ No newline at end of file
-- 
GitLab