diff --git a/analysis/abstract/ideal/iw_instantiation.v b/analysis/abstract/ideal/iw_instantiation.v
index 9a457e483d8908895b2cf2715929dbfa9b1f08c8..0c1ea4168a1ce71c6701f072f1afbdb589f33e05 100644
--- a/analysis/abstract/ideal/iw_instantiation.v
+++ b/analysis/abstract/ideal/iw_instantiation.v
@@ -2,7 +2,7 @@ Require Export prosa.analysis.abstract.ideal.abstract_seq_rta.
 Require Export prosa.analysis.definitions.priority_inversion.
 Require Export prosa.analysis.definitions.work_bearing_readiness.
 Require Export prosa.analysis.definitions.interference.
-Require Export prosa.analysis.facts.busy_interval.carry_in.
+Require Export prosa.analysis.facts.busy_interval.ideal.carry_in.
 Require Export prosa.analysis.abstract.iw_auxiliary.
 Require Export prosa.analysis.facts.priority.classes.
 
diff --git a/analysis/facts/busy_interval/carry_in.v b/analysis/facts/busy_interval/carry_in.v
index 8639d679a6755e8fb667ec5d3b2d7bcaa13daaf0..55a066a64a162b63abf02ef5b8ab10bd91d73df7 100644
--- a/analysis/facts/busy_interval/carry_in.v
+++ b/analysis/facts/busy_interval/carry_in.v
@@ -1,11 +1,9 @@
 Require Export prosa.analysis.facts.model.workload.
 Require Export prosa.analysis.definitions.carry_in.
 Require Export prosa.analysis.facts.busy_interval.busy_interval.
-
-(** Throughout this file, we assume ideal uniprocessor schedules. *)
-Require Import prosa.model.processor.ideal.
 Require Export prosa.analysis.facts.model.ideal.service_of_jobs.
 
+
 (** * Existence of No Carry-In Instant *)
 
 (** In this section, we derive an alternative condition for the
@@ -27,12 +25,17 @@ Section ExistsNoCarryIn.
   Context {Arrival: JobArrival Job}.
   Context {Cost : JobCost Job}.
 
-  (** Consider any arrival sequence with consistent arrivals. *)
+  (** Consider any valid arrival sequence. *)
   Variable arr_seq : arrival_sequence Job.
-  Variable H_valid_arr_seq : valid_arrival_sequence arr_seq.
+  Hypothesis H_valid_arr_seq : valid_arrival_sequence arr_seq.
 
-  (** Next, consider any ideal uniprocessor schedule of this arrival sequence ... *)
-  Variable sched : schedule (ideal.processor_state Job).
+  (** Allow for any uniprocessor model that ensures ideal progress. *)
+  Context {PState : ProcessorState Job}.
+  Hypothesis H_ideal_progress_proc_model : ideal_progress_proc_model PState.
+  Hypothesis H_uniproc : uniprocessor_model PState.
+
+  (** Next, consider any schedule of the arrival sequence ... *)
+  Variable sched : schedule PState.
   Hypothesis H_jobs_come_from_arrival_sequence:
     jobs_come_from_arrival_sequence sched arr_seq.
 
@@ -50,80 +53,69 @@ Section ExistsNoCarryIn.
   Let no_carry_in := no_carry_in arr_seq sched.
   Let quiet_time := quiet_time arr_seq sched.
 
-  (** Further, allow for any work-bearing notion of job readiness. *)
-  Context `{@JobReady Job (ideal.processor_state Job) Cost Arrival}.
+  (** Further, allow for any work-bearing notion of job readiness ... *)
+  Context `{@JobReady Job PState Cost Arrival}.
   Hypothesis H_job_ready : work_bearing_readiness arr_seq sched.
 
-  (** Assume that the schedule is work-conserving, ... *)
+  (** ... and assume that the schedule is work-conserving. *)
   Hypothesis H_work_conserving : work_conserving arr_seq sched.
 
-  (** ... and there are no duplicate job arrivals. *)
-  Hypothesis H_arrival_sequence_is_a_set:
-    arrival_sequence_uniq arr_seq.
-
   (** The fact that there is no carry-in at time instant [t] trivially
       implies that [t] is a quiet time. *)
   Lemma no_carry_in_implies_quiet_time :
     forall j t,
       no_carry_in t ->
       quiet_time j t.
+  Proof. by move=> j t + j_hp ARR HP BEF; apply. Qed.
+
+  (** Conversely, the presence of a pending job implies that the processor isn't
+      idle due to work-conservation. *)
+  Lemma pending_job_implies_not_idle :
+    forall j t,
+      arrives_in arr_seq j ->
+      pending sched j t ->
+      ~ is_idle arr_seq sched t.
   Proof.
-    by intros j t FQT j_hp ARR HP BEF; apply FQT.
+    move=> j t ARR PEND IDLE.
+    apply H_job_ready in PEND => //; move: PEND => [jhp [ARRhp [READYhp _]]].
+    move: IDLE; rewrite is_idle_iff => /eqP; rewrite scheduled_job_at_none; rt_eauto => IDLE.
+    have [j_other SCHED]:  exists j_other : Job, scheduled_at sched j_other t
+      by apply: H_work_conserving; rt_eauto; apply/andP; split => //.
+    by move: (IDLE j_other) => /negP.
   Qed.
 
-
   (** We show that an idle time implies no carry in at this time instant. *)
   Lemma idle_instant_implies_no_carry_in_at_t :
     forall t,
-      ideal_is_idle sched t ->
+      is_idle arr_seq sched t ->
       no_carry_in t.
   Proof.
     move=> t IDLE j ARR HA.
-    apply/negPn/negP; intros NCOMP.
-    have PEND : job_pending_at j t.
-    { apply/andP; split.
-      - by rewrite /has_arrived ltnW.
-      - by move: NCOMP; apply contra, completion_monotonic.
-    }
-    apply H_job_ready in PEND => //; destruct PEND as [jhp [ARRhp [READYhp _]]].
-    move: IDLE => /eqP IDLE.
-    move: (H_work_conserving _ t ARRhp) => NIDLE.
-    feed NIDLE.
-    { apply/andP; split; first by done.
-      by rewrite scheduled_at_def IDLE.
-    }
-    move: NIDLE => [j' SCHED].
-    by rewrite scheduled_at_def IDLE in SCHED.
+    apply/negPn/negP =>  NCOMP.
+    have PEND : job_pending_at j t by apply/andP; split; rt_eauto; rewrite /has_arrived ltnW.
+    by apply: (pending_job_implies_not_idle j t).
   Qed.
 
   (** Moreover, an idle time implies no carry in at the next time instant. *)
   Lemma idle_instant_implies_no_carry_in_at_t_pl_1 :
     forall t,
-      ideal_is_idle sched t ->
+      is_idle arr_seq sched t ->
       no_carry_in t.+1.
   Proof.
     move=> t IDLE j ARR HA.
     apply/negPn/negP; intros NCOMP.
     have PEND : job_pending_at j t.
-    { apply/andP; split.
-      - by rewrite /has_arrived.
-      - by move: NCOMP; apply contra, completion_monotonic.
-    }
-    apply H_job_ready in PEND => //; destruct PEND as [jhp [ARRhp [READYhp _]]].
-    move: IDLE => /eqP IDLE.
-    move: (H_work_conserving _ t ARRhp) => NIDLE.
-    feed NIDLE.
-    { apply/andP; split; first by done.
-      by rewrite scheduled_at_def IDLE.
-    }
-    move: NIDLE => [j' SCHED].
-    by rewrite scheduled_at_def IDLE in SCHED.
+    { apply/andP; split; rt_eauto; rewrite /has_arrived.
+      apply/contra; last exact NCOMP.
+      by apply/completion_monotonic. }
+    by apply: (pending_job_implies_not_idle j t).
   Qed.
 
   (** Let the priority relation be reflexive. *)
   Hypothesis H_priority_is_reflexive: reflexive_job_priorities JLFP.
 
-  (** Recall the notion of workload of all jobs released in a given interval <<[t1, t2)>>... *)
+  (** Recall the notion of workload of all jobs released in a given interval
+      <<[t1, t2)>>... *)
   Let total_workload t1 t2 :=
     workload_of_jobs predT (arrivals_between t1 t2).
 
@@ -139,6 +131,10 @@ Section ExistsNoCarryIn.
   Hypothesis H_delta_positive : Δ > 0.
   Hypothesis H_workload_is_bounded : forall t, total_workload t (t + Δ) <= Δ.
 
+  (** In the following, we also require the processor to be a unit-speed
+      processor. *)
+  Hypothesis H_unit_service_proc_model : unit_service_proc_model PState.
+
   (** Next we prove that, since for any time instant [t] there is a
       point where the total workload is upper-bounded by the supply,
       the processor encounters no-carry-in instants at least every [Δ]
@@ -165,8 +161,9 @@ Section ExistsNoCarryIn.
       (** ...such that the processor has no carry-in at time [t]. *)
       Hypothesis H_no_carry_in : no_carry_in t.
 
-      (** First, recall that the total service is bounded by the total workload. Therefore
-             the total service of jobs in the interval <<[t, t + Δ)>> is bounded by [Δ]. *)
+      (** First, recall that the total service is bounded by the total
+          workload. Therefore the total service of jobs in the interval <<[t, t
+          + Δ)>> is bounded by [Δ]. *)
       Lemma total_service_is_bounded_by_Δ :
         total_service t (t + Δ) <= Δ.
       Proof.
@@ -191,7 +188,6 @@ Section ExistsNoCarryIn.
         rewrite -{3}[Δ]addn0 -{2}(subnn t) addnBA // [Δ + t]addnC in LT.
         eapply low_service_implies_existence_of_idle_time in LT; rt_eauto.
         move: LT => [t_idle [/andP [LEt GTe] IDLE]].
-        rewrite is_idle_def in IDLE; rt_eauto.
         move: LEt; rewrite leq_eqVlt; move => /orP [/eqP EQ|LT].
         { exists 0; split => //.
           rewrite addn0; subst t_idle => s ARR BEF.
@@ -252,7 +248,8 @@ Section ExistsNoCarryIn.
 
     End ProcessorIsNotTooBusyInduction.
 
-    (** Finally, we show that any interval of length [Δ] contains a time instant with no carry-in. *)
+    (** Finally, we show that any interval of length [Δ] contains a time instant
+        with no carry-in. *)
     Lemma processor_is_not_too_busy :
       forall t, exists δ, δ < Δ /\ no_carry_in (t + δ).
     Proof.
@@ -274,53 +271,5 @@ Section ExistsNoCarryIn.
 
   End ProcessorIsNotTooBusy.
 
-  (** Consider an arbitrary job [j] with positive cost. *)
-  Variable j : Job.
-  Hypothesis H_from_arrival_sequence : arrives_in arr_seq j.
-  Hypothesis H_job_cost_positive : job_cost_positive j.
-
-  (** We show that there must exist a busy interval <<[t1, t2)>> that
-      contains the arrival time of [j]. *)
-  Corollary exists_busy_interval_from_total_workload_bound :
-    exists t1 t2,
-      t1 <= job_arrival j < t2 /\
-      t2 <= t1 + Δ /\
-      busy_interval arr_seq sched j t1 t2.
-  Proof.
-    rename H_from_arrival_sequence into ARR, H_job_cost_positive into POS.
-    have CONSIST: consistent_arrival_times arr_seq by rt_eauto.
-    edestruct (exists_busy_interval_prefix
-                 arr_seq CONSIST
-                 sched j ARR H_priority_is_reflexive (job_arrival j))
-      as [t1 [PREFIX GE]]; first by apply job_pending_at_arrival.
-    move: GE => /andP [GE1 _].
-    exists t1; move: (processor_is_not_too_busy t1.+1) => [δ [LE QT]].
-    apply no_carry_in_implies_quiet_time with (j := j) in QT.
-    have EX: exists t2, ((t1 < t2 <= t1.+1 + δ) && quiet_time_dec arr_seq sched j t2).
-    { exists (t1.+1 + δ); apply/andP; split.
-      - by apply/andP; split; first rewrite addSn ltnS leq_addr.
-      - by apply/quiet_time_P. }
-    move: (ex_minnP EX) => [t2 /andP [/andP [GTt2 LEt2] QUIET] MIN]; clear EX.
-    have NEQ: t1 <= job_arrival j < t2.
-    { apply/andP; split; first by done.
-      rewrite ltnNge; apply/negP; intros CONTR.
-      move: (PREFIX) => [_ [_ [NQT _]]].
-      move: (NQT t2); clear NQT; move  => NQT.
-      feed NQT; first by (apply/andP; split; [|rewrite ltnS]).
-      by apply: NQT; apply/quiet_time_P.
-    }
-    exists t2; split; last split; first by done.
-    { apply leq_trans with (t1.+1 + δ); [by done | by rewrite addSn ltn_add2l]. }
-    { move: PREFIX => [_ [QTt1 [NQT _]]]; repeat split; try done.
-      - move => t /andP [GEt LTt] QTt.
-        feed (MIN t).
-        { apply/andP; split.
-          + by apply/andP; split; last (apply leq_trans with t2; [apply ltnW | ]).
-          + by apply/quiet_time_P.
-        }
-        by move: LTt; rewrite ltnNge; move => /negP LTt; apply: LTt.
-      - by apply/quiet_time_P.
-    }
-  Qed.
 
 End ExistsNoCarryIn.
diff --git a/analysis/facts/busy_interval/ideal/carry_in.v b/analysis/facts/busy_interval/ideal/carry_in.v
new file mode 100644
index 0000000000000000000000000000000000000000..7555b42af55aad689cd42c63489929a7886fca8f
--- /dev/null
+++ b/analysis/facts/busy_interval/ideal/carry_in.v
@@ -0,0 +1,108 @@
+Require Export prosa.analysis.facts.busy_interval.carry_in.
+
+(** The following lemma conceptually belongs in
+    [prosa.analysis.facts.busy_interval.carry_in], but still has dependencies
+    with a baked-in ideal uniprocessor assumption. When these dependencies get
+    generalized, then this lemma should be generalized as well and moved elsewhere. *)
+
+Section BusyWindowExistence.
+
+  (** Consider any type of tasks ... *)
+  Context {Task : TaskType}.
+  Context `{TaskCost Task}.
+
+  (**  ... and any type of jobs associated with these tasks. *)
+  Context {Job : JobType}.
+  Context `{JobTask Job Task}.
+  Context {Arrival: JobArrival Job}.
+  Context {Cost : JobCost Job}.
+
+  (** Consider any valid arrival sequence. *)
+  Variable arr_seq : arrival_sequence Job.
+  Hypothesis H_valid_arr_seq : valid_arrival_sequence arr_seq.
+
+  (** Next, consider any well-behaved ideal uni-processor schedule of this
+      arrival sequence. *)
+  Variable sched : schedule (ideal.processor_state Job).
+  Hypothesis H_jobs_come_from_arrival_sequence:
+    jobs_come_from_arrival_sequence sched arr_seq.
+  Hypothesis H_jobs_must_arrive_to_execute : jobs_must_arrive_to_execute sched.
+  Hypothesis H_completed_jobs_dont_execute : completed_jobs_dont_execute sched.
+
+    (** Assume a given reflexive JLFP policy. *)
+  Context {JLFP : JLFP_policy Job}.
+  Hypothesis H_priority_is_reflexive: reflexive_job_priorities JLFP.
+
+  (** Further, allow for any work-bearing notion of job readiness ... *)
+  Context `{@JobReady Job (ideal.processor_state Job) Cost Arrival}.
+  Hypothesis H_job_ready : work_bearing_readiness arr_seq sched.
+
+  (** ... and assume that the schedule is work-conserving. *)
+  Hypothesis H_work_conserving : work_conserving arr_seq sched.
+
+  (** Recall the notion of workload of all jobs released in a given interval
+       <<[t1, t2)>>. *)
+  Let total_workload t1 t2 :=
+    workload_of_jobs predT (arrivals_between arr_seq t1 t2).
+
+  (** Assume that for some positive [Δ], the sum of requested workload
+      at time [t + Δ] is bounded by [Δ] (i.e., the supply). Note that
+      this assumption bounds the total workload of jobs released in a
+      time interval <<[t, t + Δ)>> regardless of their priorities. *)
+  Variable Δ : duration.
+  Hypothesis H_delta_positive : Δ > 0.
+  Hypothesis H_workload_is_bounded : forall t, total_workload t (t + Δ) <= Δ.
+
+  (** Consider an arbitrary job [j] with positive cost. *)
+  Variable j : Job.
+  Hypothesis H_from_arrival_sequence : arrives_in arr_seq j.
+  Hypothesis H_job_cost_positive : job_cost_positive j.
+
+  (** We show that there must exist a busy interval <<[t1, t2)>> that
+      contains the arrival time of [j]. *)
+  Corollary exists_busy_interval_from_total_workload_bound :
+    exists t1 t2,
+      t1 <= job_arrival j < t2 /\
+      t2 <= t1 + Δ /\
+      busy_interval arr_seq sched j t1 t2.
+  Proof.
+    rename H_from_arrival_sequence into ARR, H_job_cost_positive into POS.
+    have CONSIST: consistent_arrival_times arr_seq by rt_eauto.
+    edestruct (exists_busy_interval_prefix
+                 arr_seq CONSIST
+                 sched j ARR H_priority_is_reflexive (job_arrival j))
+      as [t1 [PREFIX GE]]; first by apply job_pending_at_arrival.
+    move: GE => /andP [GE1 _].
+    exists t1.
+    have [δ [LE QT]]:  exists δ : nat, δ < Δ /\ no_carry_in arr_seq sched (t1.+1 + δ)
+      by apply: processor_is_not_too_busy; rt_eauto.
+    eapply no_carry_in_implies_quiet_time with (j := j) in QT.
+    have EX: exists t2, ((t1 < t2 <= t1.+1 + δ) && quiet_time_dec arr_seq sched j t2).
+    { exists (t1.+1 + δ); apply/andP; split.
+      - by apply/andP; split; first rewrite addSn ltnS leq_addr.
+      - by apply/quiet_time_P; rt_eauto. }
+    move: (ex_minnP EX) => [t2 /andP [/andP [GTt2 LEt2] QUIET] MIN]; clear EX.
+    have NEQ: t1 <= job_arrival j < t2.
+    { apply/andP; split; first by done.
+      rewrite ltnNge; apply/negP; intros CONTR.
+      move: (PREFIX) => [_ [_ [NQT _]]].
+      move: (NQT t2); clear NQT; move  => NQT.
+      feed NQT; first by (apply/andP; split; [|rewrite ltnS]).
+      by apply: NQT; apply/quiet_time_P.
+    }
+    exists t2; split; last split; first by done.
+    { apply leq_trans with (t1.+1 + δ); [by done | by rewrite addSn ltn_add2l]. }
+    { move: PREFIX => [_ [QTt1 [NQT _]]]; repeat split; try done.
+      - move => t /andP [GEt LTt] QTt.
+        feed (MIN t).
+        { apply/andP; split.
+          + by apply/andP; split; last (apply leq_trans with t2; [apply ltnW | ]).
+          + by apply/quiet_time_P.
+        }
+        by move: LTt; rewrite ltnNge; move => /negP LTt; apply: LTt.
+      - by apply/quiet_time_P.
+    }
+  Qed.
+
+
+End BusyWindowExistence.