Library prosa.classic.model.arrival.jitter.arrival_bounds

Require Import prosa.classic.util.all.
Require Import prosa.classic.model.arrival.basic.task prosa.classic.model.priority.
Require Import prosa.classic.model.arrival.jitter.job
               prosa.classic.model.arrival.jitter.arrival_sequence
               prosa.classic.model.arrival.jitter.task_arrival.
From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq path div.

Module ArrivalBounds.

  Import JobWithJitter ArrivalSequenceWithJitter SporadicTaskset Priority
         TaskArrivalWithJitter.

  Section BoundingActualArrivals.

    Context {Task: eqType}.
    Variable task_period: Task time.
    Variable task_jitter: Task time.

    Context {Job: eqType}.
    Variable job_arrival: Job time.
    Variable job_cost: Job time.
    Variable job_jitter: Job time.
    Variable job_task: Job Task.

    Variable arr_seq: arrival_sequence Job.
    Hypothesis H_arrival_times_are_consistent: arrival_times_are_consistent job_arrival arr_seq.
    Hypothesis H_arrival_sequence_is_a_set: arrival_sequence_is_a_set arr_seq.

    Hypothesis H_job_jitter_bounded:
       j,
        arrives_in arr_seq j
        job_jitter_leq_task_jitter task_jitter job_jitter job_task j.

    Let actual_job_arrival := actual_arrival job_arrival job_jitter.

    Section UpperBoundOn.

      Hypothesis H_sporadic_tasks: sporadic_task_model task_period job_arrival job_task arr_seq.

      Variable t1 t2: time.

      Variable tsk: Task.
      Hypothesis H_period_gt_zero: task_period tsk > 0.

      Let actual_arrivals := actual_arrivals_of_task_between job_arrival job_jitter
                                                             job_task arr_seq tsk t1 t2.
      Let num_actual_arrivals := num_actual_arrivals_of_task job_arrival job_jitter job_task
                                                             arr_seq tsk t1 t2.


      Section NoJobs.

        Hypothesis H_no_jobs: num_actual_arrivals = 0.

        Lemma sporadic_arrival_bound_no_jobs:
          num_actual_arrivals div_ceil (t2 + task_jitter tsk - t1) (task_period tsk).

      End NoJobs.

      Section OneJob.

        Lemma sporadic_arrival_bound_more_than_one_point:
          num_actual_arrivals > 0
          t1 < t2.

        Hypothesis H_no_jobs: num_actual_arrivals = 1.

        Lemma sporadic_arrival_bound_one_job:
          num_actual_arrivals div_ceil (t2 + task_jitter tsk - t1) (task_period tsk).

      End OneJob.

      Section AtLeastTwoJobs.

        Hypothesis H_at_least_two_jobs: num_actual_arrivals 2.

        Section DerivingContradiction.

          Hypothesis H_many_arrivals:
            div_ceil (t2 + task_jitter tsk - t1) (task_period tsk) < num_actual_arrivals.

          Let by_arrival_time j j' := job_arrival j job_arrival j'.
          Let sorted_jobs := sort by_arrival_time actual_arrivals.

          Variable elem: Job.
          Let nth_job := nth elem sorted_jobs.

          Let j_first := nth_job 0.
          Let j_last := nth_job (num_actual_arrivals.-1).
          Let a_first := job_arrival j_first.
          Let a_last := job_arrival j_last.

          Corollary sporadic_arrival_bound_properties_of_nth:
             idx,
              idx < num_actual_arrivals
              t1 actual_job_arrival (nth_job idx) < t2
              job_task (nth_job idx) = tsk
              arrives_in arr_seq (nth_job idx).

          Corollary sporadic_arrival_bound_distance_between_first_and_last:
            a_last a_first + (num_actual_arrivals - 1) × task_period tsk.

          Lemma sporadic_arrival_bound_last_job_too_far:
            a_first + t2 + task_jitter tsk - t1 a_last.

          Lemma sporadic_arrival_bound_last_arrives_too_late:
            a_last t2.

          Lemma sporadic_arrival_bound_case_3_contradiction: False.

        End DerivingContradiction.

        Lemma sporadic_task_arrival_bound_at_least_two_jobs:
          num_actual_arrivals div_ceil (t2 + task_jitter tsk - t1) (task_period tsk).

      End AtLeastTwoJobs.

      Theorem sporadic_task_with_jitter_arrival_bound:
        num_actual_arrivals div_ceil (t2 + task_jitter tsk - t1) (task_period tsk).

    End UpperBoundOn.

  End BoundingActualArrivals.

End ArrivalBounds.