Library prosa.classic.model.schedule.uni.limited.busy_interval

Require Import prosa.classic.util.all.
Require Import prosa.classic.model.arrival.basic.task
               prosa.classic.model.arrival.basic.job
               prosa.classic.model.arrival.basic.arrival_sequence
               prosa.classic.model.priority
               prosa.classic.model.arrival.basic.task_arrival.
Require Import prosa.classic.model.schedule.uni.service
               prosa.classic.model.schedule.uni.workload
               prosa.classic.model.schedule.uni.schedule.
Require Import prosa.classic.model.schedule.uni.limited.platform.definitions.

From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq fintype bigop.

Busy Interval for JLFP-models

In this module we define the notion of busy intervals for uniprocessor for JLFP schedulers.
Module BusyIntervalJLFP.

  Import Job Priority UniprocessorSchedule LimitedPreemptionPlatform Service Workload TaskArrival.

  Section Definitions.

    Context {Task: eqType}.
    Context {Job: eqType}.
    Variable job_arrival: Job time.
    Variable job_cost: 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.

    Variable sched: schedule Job.
    Hypothesis H_jobs_come_from_arrival_sequence:
      jobs_come_from_arrival_sequence sched arr_seq.

    Variable higher_eq_priority: JLFP_policy Job.

    Let job_pending_at := pending job_arrival job_cost sched.
    Let job_scheduled_at := scheduled_at sched.
    Let job_completed_by := completed_by job_cost sched.
    Let job_remaining_cost j t := remaining_cost job_cost sched j t.
    Let arrivals_between := jobs_arrived_between arr_seq.

    Section BusyInterval.

      Variable tsk: Task.

      Variable j: Job.
      Hypothesis H_from_arrival_sequence: arrives_in arr_seq j.
      Hypothesis H_job_task: job_task j = tsk.

      Definition quiet_time (t: time) :=
         j_hp,
          arrives_in arr_seq j_hp
          higher_eq_priority j_hp j
          arrived_before job_arrival j_hp t
          job_completed_by j_hp t.

      Definition busy_interval_prefix (t1 t_busy: time) :=
        t1 < t_busy
        quiet_time t1
        ( t, t1 < t < t_busy ¬ quiet_time t)
        t1 job_arrival j < t_busy.

      Definition busy_interval (t1 t2: time) :=
        busy_interval_prefix t1 t2
        quiet_time t2.

    End BusyInterval.

    Section JobPriorityInversionBound.

      Variable tsk: Task.

      Variable j: Job.
      Hypothesis H_from_arrival_sequence: arrives_in arr_seq j.
      Hypothesis H_job_task: job_task j = tsk.

      Definition is_priority_inversion t :=
        if sched t is Some jlp then
          ~~ higher_eq_priority jlp j
        else false.

      Definition cumulative_priority_inversion t1 t2 :=
        \sum_(t1 t < t2) is_priority_inversion t.

      Definition priority_inversion_of_job_is_bounded_by (B: time) :=
         (t1 t2: time),
          busy_interval_prefix j t1 t2
          cumulative_priority_inversion t1 t2 B.

    End JobPriorityInversionBound.

    Section TaskPriorityInversionBound.

      Variable tsk: Task.

      Definition priority_inversion_is_bounded_by (B: time) :=
         (j: Job),
          arrives_in arr_seq j
          job_task j = tsk
          job_cost j > 0
          priority_inversion_of_job_is_bounded_by j B.

    End TaskPriorityInversionBound.

    Section DecidableQuietTime.

      Definition quiet_time_dec (j : Job) (t : time) :=
        all
          (fun j_hphigher_eq_priority j_hp j ==> (completed_by job_cost sched j_hp t))
          (jobs_arrived_before arr_seq t).

      Lemma quiet_time_P :
         j t, reflect (quiet_time j t) (quiet_time_dec j t).

    End DecidableQuietTime.

    Section Lemmas.

      Variable tsk: Task.

      Variable j: Job.
      Hypothesis H_from_arrival_sequence: arrives_in arr_seq j.
      Hypothesis H_job_task: job_task j = tsk.
      Hypothesis H_job_cost_positive: job_cost_positive job_cost j.

      Let quiet_time t1 := quiet_time j t1.
      Let busy_interval_prefix t1 t2 := busy_interval_prefix j t1 t2.
      Let busy_interval t1 t2 := busy_interval j t1 t2.
      Let is_priority_inversion_bounded_by K := priority_inversion_of_job_is_bounded_by j K.

      Section BasicLemma.

        Hypothesis H_priority_is_reflexive: FP_is_reflexive higher_eq_priority.

        Variable t1 t2: time.
        Hypothesis H_busy_interval: busy_interval t1 t2.

        Lemma job_completes_within_busy_interval:
          job_completed_by j t2.

      End BasicLemma.

      Section ExistsPendingJob.

        Hypothesis H_completed_jobs_dont_execute:
          completed_jobs_dont_execute job_cost sched.

        Variable t1 t2: time.
        Hypothesis H_interval: t1 t2.
        Hypothesis H_quiet: quiet_time t1.
        Hypothesis H_not_quiet: ¬ quiet_time t2.

        Lemma not_quiet_implies_exists_pending_job:
           j_hp,
            arrives_in arr_seq j_hp
            arrived_between job_arrival j_hp t1 t2
            higher_eq_priority j_hp j
            ¬ job_completed_by j_hp t2.

      End ExistsPendingJob.

      Section ProcessorAlwaysBusy.

        Hypothesis H_work_conserving: work_conserving job_arrival job_cost arr_seq sched.
        Hypothesis H_completed_jobs_dont_execute: completed_jobs_dont_execute job_cost sched.
        Hypothesis H_jobs_must_arrive_to_execute: jobs_must_arrive_to_execute job_arrival sched.

        Hypothesis H_priority_is_reflexive: JLFP_is_reflexive higher_eq_priority.
        Hypothesis H_priority_is_transitive: JLFP_is_transitive higher_eq_priority.

        Variable t1 t2: time.
        Hypothesis H_busy_interval_prefix: busy_interval_prefix t1 t2.

        Lemma idle_time_implies_quiet_time_at_the_next_time_instant:
           t,
            is_idle sched t
            quiet_time t.+1.

         Lemma pending_hp_job_exists:
           t,
            t1 t < t2
             jhp,
              arrives_in arr_seq jhp
              job_pending_at jhp t
              higher_eq_priority jhp j.

        Lemma not_quiet_implies_not_idle:
           t,
            t1 t < t2
            ¬ is_idle sched t.

      End ProcessorAlwaysBusy.

      Section QuietTimeAndServiceOfJobs.

        Hypothesis H_arrival_sequence_is_a_set:
          arrival_sequence_is_a_set arr_seq.

        Hypothesis H_jobs_must_arrive_to_execute: jobs_must_arrive_to_execute job_arrival sched.
        Hypothesis H_completed_jobs_dont_execute: completed_jobs_dont_execute job_cost sched.

        Hypothesis H_work_conserving: work_conserving job_arrival job_cost arr_seq sched.

        Variable t1: time.
        Hypothesis H_quiet_time: quiet_time t1.

        Variable Δ: time.
        Hypothesis H_no_quiet_time: t, t1 < t t1 + Δ ¬ quiet_time t.

        Let service_received_by_hep_jobs_released_during t_beg t_end :=
          service_of_higher_or_equal_priority_jobs
            sched (arrivals_between t_beg t_end) higher_eq_priority j t1 (t1 + Δ).

        Lemma hep_jobs_receive_no_service_before_quiet_time:
            service_received_by_hep_jobs_released_during t1 (t1 + Δ) =
            service_received_by_hep_jobs_released_during 0 (t1 + Δ).

        Lemma no_idle_time_within_non_quiet_time_interval:
          service_of_jobs sched (arrivals_between 0 (t1 + Δ)) predT t1 (t1 + Δ) = Δ.
      End QuietTimeAndServiceOfJobs.

      Section BoundingBusyInterval.

        Hypothesis H_arrival_sequence_is_a_set:
          arrival_sequence_is_a_set arr_seq.

        Hypothesis H_jobs_must_arrive_to_execute: jobs_must_arrive_to_execute job_arrival sched.
        Hypothesis H_completed_jobs_dont_execute: completed_jobs_dont_execute job_cost sched.

        Hypothesis H_work_conserving: work_conserving job_arrival job_cost arr_seq sched.

        Hypothesis H_priority_is_reflexive: JLFP_is_reflexive higher_eq_priority.
        Hypothesis H_priority_is_transitive: JLFP_is_transitive higher_eq_priority.

        Let hp_workload t1 t2 :=
          workload_of_higher_or_equal_priority_jobs
            job_cost (arrivals_between t1 t2) higher_eq_priority j.

        Let hp_service t1 t2 :=
          service_of_higher_or_equal_priority_jobs
            sched (arrivals_between t1 t2) higher_eq_priority j t1 t2.

        Section BoundingBusyInterval.

          Variable t_busy: time.
          Hypothesis H_j_is_pending: job_pending_at j t_busy.

          Section LowerBound.

            Lemma exists_busy_interval_prefix:
               t1,
                busy_interval_prefix t1 t_busy.+1
                t1 job_arrival j t_busy.

          End LowerBound.

          Section UpperBound.

            Variable t1: time.
            Hypothesis H_is_busy_prefix: busy_interval_prefix t1 t_busy.+1.

            Variable priority_inversion_bound: time.
            Hypothesis H_priority_inversion_is_bounded:
              is_priority_inversion_bounded_by priority_inversion_bound.

            Variable delta: time.
            Hypothesis H_delta_positive: delta > 0.
            Hypothesis H_workload_is_bounded:
              priority_inversion_bound + hp_workload t1 (t1 + delta) delta.

            Section CannotBeBusyForSoLong.

              Hypothesis H_no_quiet_time:
                 t, t1 < t t1 + delta ¬ quiet_time t.

              Lemma busy_interval_has_uninterrupted_service:
                delta priority_inversion_bound + hp_service t1 (t1 + delta).

              Lemma busy_interval_too_much_workload:
                hp_workload t1 (t1 + delta) > hp_service t1 (t1 + delta).

              Corollary busy_interval_workload_larger_than_interval:
                priority_inversion_bound + hp_workload t1 (t1 + delta) > delta.

            End CannotBeBusyForSoLong.

            Lemma busy_interval_is_bounded:
               t2,
                t2 t1 + delta
                busy_interval t1 t2.

          End UpperBound.

        End BoundingBusyInterval.

        Section BusyIntervalFromWorkloadBound.

          Variable priority_inversion_bound: time.
          Hypothesis H_priority_inversion_is_bounded:
            is_priority_inversion_bounded_by priority_inversion_bound.

          Variable delta: time.
          Hypothesis H_delta_positive: delta > 0.
          Hypothesis H_workload_is_bounded:
             t, priority_inversion_bound + hp_workload t (t + delta) delta.

          Hypothesis H_positive_cost: job_cost j > 0.

          Corollary exists_busy_interval:
             t1 t2,
              t1 job_arrival j < t2
              t2 t1 + delta
              busy_interval t1 t2.

        End BusyIntervalFromWorkloadBound.

        Section ResponseTimeBoundFromBusyInterval.

          Variable priority_inversion_bound: time.
          Hypothesis H_priority_inversion_is_bounded:
            is_priority_inversion_bounded_by priority_inversion_bound.

          Variable delta: time.
          Hypothesis H_delta_positive: delta > 0.
          Hypothesis H_workload_is_bounded:
             t, priority_inversion_bound + hp_workload t (t + delta) delta.

          Lemma busy_interval_bounds_response_time:
            job_completed_by j (job_arrival j + delta).

        End ResponseTimeBoundFromBusyInterval.

      End BoundingBusyInterval.

    End Lemmas.

    Section NonOverloadedProcessor.

      Definition no_carry_in (t: time) :=
         j_o,
          arrives_in arr_seq j_o
          arrived_before job_arrival j_o t
          job_completed_by j_o t.

      Lemma no_carry_in_implies_quiet_time :
         j t,
          no_carry_in t
          quiet_time j t.

      Hypothesis H_arrival_sequence_is_a_set:
        arrival_sequence_is_a_set arr_seq.

      Hypothesis H_work_conserving: work_conserving job_arrival job_cost arr_seq sched.
      Hypothesis H_completed_jobs_dont_execute: completed_jobs_dont_execute job_cost sched.
      Hypothesis H_jobs_must_arrive_to_execute: jobs_must_arrive_to_execute job_arrival sched.

      Lemma idle_instant_implies_no_carry_in_at_t :
         t,
          is_idle sched t
          no_carry_in t.

      Lemma idle_instant_implies_no_carry_in_at_t_pl_1 :
         t,
          is_idle sched t
          no_carry_in t.+1.

      Hypothesis H_priority_is_reflexive: JLFP_is_reflexive higher_eq_priority.

      Let total_workload t1 t2 :=
        workload_of_jobs job_cost (arrivals_between t1 t2) predT.

      Let total_service t1 t2 :=
        service_of_jobs sched (arrivals_between 0 t2) predT t1 t2.

      Variable Δ: time.
      Hypothesis H_delta_positive: Δ > 0.
      Hypothesis H_workload_is_bounded: t, total_workload t (t + Δ) Δ.

      Section ProcessorIsNotTooBusy.

        Lemma no_carry_in_at_the_beginning :
          no_carry_in 0.

        Section ProcessorIsNotTooBusyInduction.

          Variable t: time.

          Hypothesis H_no_carry_in: no_carry_in t.

          Lemma total_service_is_bounded_by_Δ :
            total_service t (t + Δ) Δ.


          Lemma low_total_service_implies_existence_of_time_with_no_carry_in :
            total_service t (t + Δ) < Δ
             δ, δ < Δ no_carry_in (t.+1 + δ).

          Lemma completion_of_all_jobs_implies_no_carry_in :
            total_service t (t + Δ) = Δ
            no_carry_in (t + Δ).

        End ProcessorIsNotTooBusyInduction.

        Lemma processor_is_not_too_busy :
           t, δ, δ < Δ no_carry_in (t + δ).

      End ProcessorIsNotTooBusy.

      Variable j: Job.
      Hypothesis H_from_arrival_sequence: arrives_in arr_seq j.
      Hypothesis H_job_cost_positive: job_cost_positive job_cost j.

      Corollary exists_busy_interval_from_total_workload_bound :
         t1 t2,
          t1 job_arrival j < t2
          t2 t1 + Δ
          busy_interval j t1 t2.

    End NonOverloadedProcessor.

  End Definitions.

End BusyIntervalJLFP.