@@ -388,6 +388,112 @@ theorem deadzone_mono_val (v1 v2 dz : Rat) (hv : v1 ≤ v2) (hdz0 : 0 ≤ dz) (h
388388 · -- Both inside: 0 ≤ 0
389389 rw [deadzone_in_dz v2 dz (Rat.not_lt.mp h2)]; exact Rat.le_refl
390390
391+ /-! ## No-deadzone identity (general) -/
392+
393+ /-- The negative case of the no-deadzone identity: when `dz = 0`, `deadzone x 0 = x` for `x < 0`. -/
394+ theorem deadzone_no_dz_neg (x : Rat) (hx : x < 0 ) : deadzone x 0 = x := by
395+ rw [deadzone_neg_eq x 0 (by rw [Rat.neg_zero]; exact hx) (Rat.le_refl)]
396+ rw [Rat.add_zero, Rat.sub_eq_add_neg, Rat.neg_zero, Rat.add_zero,
397+ Rat.div_def, Rat.inv_eq_of_mul_eq_one (Rat.mul_one 1 ), Rat.mul_one]
398+
399+ /-- **Identity with no deadzone** (all cases): when `dz = 0`, `deadzone x 0 = x` for all `x`.
400+
401+ Combining `deadzone_no_dz_pos`, `deadzone_no_dz_neg`, and the zero case (which is in the
402+ deadzone since `|0| = 0 = dz`), we get the full identity. -/
403+ theorem deadzone_no_dz (x : Rat) : deadzone x 0 = x := by
404+ by_cases h1 : 0 < x
405+ · exact deadzone_no_dz_pos x h1
406+ · by_cases h2 : x = 0
407+ · subst h2
408+ simp [deadzone]
409+ · exact deadzone_no_dz_neg x (Rat.lt_of_le_of_ne (Rat.not_lt.mp h1) h2)
410+
411+ /-! ## Monotonicity in the deadzone width -/
412+
413+ -- Private helpers for `deadzone_mono_dz_pos`
414+
415+ /-- Inverse anti-monotonicity: larger positive denominators give smaller inverses. -/
416+ private theorem dz_inv_anti (a b : Rat) (hba : b ≤ a) (ha : 0 < a) (hb : 0 < b) : a⁻¹ ≤ b⁻¹ := by
417+ have ha_ne : a ≠ 0 := Rat.ne_of_gt ha
418+ have hb_ne : b ≠ 0 := Rat.ne_of_gt hb
419+ rw [Rat.le_iff_sub_nonneg]
420+ have key : b⁻¹ - a⁻¹ = (a - b) * (a⁻¹ * b⁻¹) := by
421+ simp only [Rat.sub_eq_add_neg, Rat.add_mul, Rat.neg_mul]
422+ rw [show a * (a⁻¹ * b⁻¹) = b⁻¹ by
423+ rw [← Rat.mul_assoc a a⁻¹ b⁻¹, Rat.mul_inv_cancel a ha_ne, Rat.one_mul]]
424+ rw [show b * (a⁻¹ * b⁻¹) = a⁻¹ by
425+ rw [Rat.mul_comm a⁻¹ b⁻¹, ← Rat.mul_assoc b b⁻¹ a⁻¹,
426+ Rat.mul_inv_cancel b hb_ne, Rat.one_mul]]
427+ rw [key]
428+ exact Rat.mul_nonneg ((Rat.le_iff_sub_nonneg b a).mp hba)
429+ (Rat.mul_nonneg (Rat.le_of_lt (Rat.inv_pos.mpr ha)) (Rat.le_of_lt (Rat.inv_pos.mpr hb)))
430+
431+ /-- Rewrite `(x - dz) / (1 - dz)` as `1 - (1 - x) / (1 - dz)`. -/
432+ private theorem dz_div_rewrite (x dz : Rat) (h1mdz : 0 < 1 - dz) :
433+ (x - dz) / (1 - dz) = 1 - (1 - x) / (1 - dz) := by
434+ rw [Rat.div_def, Rat.div_def]
435+ have h1mdz_ne : (1 - dz) ≠ 0 := Rat.ne_of_gt h1mdz
436+ have hn : (1 - dz) - (1 - x) = x - dz := by
437+ simp only [Rat.sub_eq_add_neg, Rat.neg_add, Rat.neg_neg]
438+ rw [Rat.add_assoc, ← Rat.add_assoc (-dz) (-1 ) x, Rat.add_comm (-dz) (-1 ),
439+ Rat.add_assoc (-1 ) (-dz) x, ← Rat.add_assoc 1 (-1 ) (-dz + x),
440+ show (1 :Rat) + -1 = 0 from Rat.add_neg_cancel 1 , Rat.zero_add, Rat.add_comm (-dz) x]
441+ rw [show (x - dz) * (1 - dz)⁻¹ = ((1 - dz) - (1 - x)) * (1 - dz)⁻¹ from by rw [hn]]
442+ rw [show ((1 - dz) - (1 - x)) * (1 - dz)⁻¹ = (1 - dz) * (1 - dz)⁻¹ - (1 - x) * (1 - dz)⁻¹
443+ from by simp only [Rat.sub_eq_add_neg, Rat.add_mul, Rat.neg_mul]]
444+ rw [Rat.mul_inv_cancel _ h1mdz_ne]
445+
446+ /-- `c - b ≤ c - a` when `a ≤ b`. -/
447+ private theorem dz_sub_le_sub_l (a b c : Rat) (h : a ≤ b) : c - b ≤ c - a := by
448+ rw [Rat.le_iff_sub_nonneg (c - b) (c - a)]
449+ have key : (c - a) - (c - b) = b - a := by
450+ simp only [Rat.sub_eq_add_neg, Rat.neg_add, Rat.neg_neg]
451+ rw [Rat.add_assoc c (-a) (-c + b), ← Rat.add_assoc (-a) (-c) b, Rat.add_comm (-a) (-c),
452+ Rat.add_assoc (-c) (-a) b, ← Rat.add_assoc c (-c) (-a + b),
453+ show c + -c = (0 :Rat) from Rat.add_neg_cancel c, Rat.zero_add, Rat.add_comm (-a) b]
454+ rw [key]; exact (Rat.le_iff_sub_nonneg a b).mp h
455+
456+ /-- **Monotonicity in `dz`** (positive branch): for a fixed input `x`,
457+ increasing the deadzone width `dz` weakly decreases the output.
458+
459+ Statement: `dz₁ ≤ dz₂ < x ≤ 1`, `0 ≤ dz₁`, `dz₂ < 1` →
460+ `deadzone x dz₂ ≤ deadzone x dz₁`.
461+
462+ Proof: rewrite `(x - dz) / (1 - dz) = 1 - (1 - x) / (1 - dz)`. Since `dz₁ ≤ dz₂`,
463+ we have `1 - dz₂ ≤ 1 - dz₁`, so `(1 - dz₁)⁻¹ ≤ (1 - dz₂)⁻¹` by inverse anti-monotonicity.
464+ Multiplying by `1 - x ≥ 0` gives `(1 - x)/(1 - dz₁) ≤ (1 - x)/(1 - dz₂)`, hence the
465+ subtraction from 1 reverses the inequality. -/
466+ theorem deadzone_mono_dz_pos (x dz1 dz2 : Rat)
467+ (hx : 0 < x) (hx1 : x ≤ 1 )
468+ (h12 : dz1 ≤ dz2) (hdz0 : 0 ≤ dz1) (hdz1 : dz2 < 1 ) (hout : dz2 < x) :
469+ deadzone x dz2 ≤ deadzone x dz1 := by
470+ have hout1 : dz1 < x := Std.lt_of_le_of_lt h12 hout
471+ rw [deadzone_pos_eq x dz1 hout1 hdz0,
472+ deadzone_pos_eq x dz2 hout (Rat.le_trans hdz0 h12)]
473+ have hd1 : (0 :Rat) < 1 - dz1 := dz_one_sub_pos dz1 (Std.lt_of_le_of_lt h12 hdz1)
474+ have hd2 : (0 :Rat) < 1 - dz2 := dz_one_sub_pos dz2 hdz1
475+ -- Rewrite both sides: (x - dz) / (1 - dz) = 1 - (1 - x) / (1 - dz)
476+ rw [dz_div_rewrite x dz1 hd1, dz_div_rewrite x dz2 hd2]
477+ -- Goal: 1 - (1 - x) / (1 - dz2) ≤ 1 - (1 - x) / (1 - dz1)
478+ apply dz_sub_le_sub_l
479+ -- Goal: (1 - x) / (1 - dz1) ≤ (1 - x) / (1 - dz2)
480+ rw [Rat.div_def, Rat.div_def]
481+ have h1mx : (0 :Rat) ≤ 1 - x := (Rat.le_iff_sub_nonneg x 1 ).mp hx1
482+ -- 1 - dz2 ≤ 1 - dz1 (because dz1 ≤ dz2)
483+ have hdz12 : (1 :Rat) - dz2 ≤ 1 - dz1 := by
484+ rw [Rat.le_iff_sub_nonneg]
485+ have key : (1 - dz1) - (1 - dz2) = dz2 - dz1 := by
486+ simp only [Rat.sub_eq_add_neg, Rat.neg_add, Rat.neg_neg]
487+ rw [Rat.add_assoc 1 (-dz1) (-1 + dz2), ← Rat.add_assoc (-dz1) (-1 ) dz2,
488+ Rat.add_comm (-dz1) (-1 ), Rat.add_assoc (-1 ) (-dz1) dz2,
489+ ← Rat.add_assoc 1 (-1 ) (-dz1 + dz2),
490+ show (1 :Rat) + -1 = 0 from Rat.add_neg_cancel 1 ,
491+ Rat.zero_add, Rat.add_comm (-dz1) dz2]
492+ rw [key]; exact (Rat.le_iff_sub_nonneg dz1 dz2).mp h12
493+ -- (1 - dz1)⁻¹ ≤ (1 - dz2)⁻¹ by inverse anti-monotonicity
494+ have hinv : (1 - dz1)⁻¹ ≤ (1 - dz2)⁻¹ := dz_inv_anti (1 - dz1) (1 - dz2) hdz12 hd1 hd2
495+ exact Rat.mul_le_mul_of_nonneg_left hinv h1mx
496+
391497/-! ## Summary of proved properties
392498
393499 | Theorem | Statement | Status |
@@ -400,12 +506,15 @@ theorem deadzone_mono_val (v1 v2 dz : Rat) (hv : v1 ≤ v2) (hdz0 : 0 ≤ dz) (h
400506 | `deadzone_pos` | `x > dz ≥ 0, dz < 1 → deadzone x dz > 0` | ✅ Proved |
401507 | `deadzone_neg` | `x < -dz ≤ 0, dz < 1 → deadzone x dz < 0` | ✅ Proved |
402508 | `deadzone_no_dz_pos` | `deadzone x 0 = x` (identity, positive case) | ✅ Proved |
509+ | `deadzone_no_dz_neg` | `deadzone x 0 = x` (identity, negative case) | ✅ Proved |
510+ | `deadzone_no_dz` | `deadzone x 0 = x` (identity, all inputs) | ✅ Proved |
403511 | `deadzone_at_max` | `deadzone 1 dz = 1` (for `dz < 1`) | ✅ Proved |
404512 | `deadzone_at_min` | `deadzone (-1) dz = -1` (for `dz < 1`) | ✅ Proved |
405513 | `deadzone_le_one` | `x ≤ 1, 0 ≤ dz < 1 → deadzone x dz ≤ 1` | ✅ Proved |
406514 | `deadzone_ge_neg_one` | `-1 ≤ x, 0 ≤ dz < 1 → -1 ≤ deadzone x dz` | ✅ Proved |
407515 | `deadzone_odd` | `dz ≥ 0 → deadzone (-x) dz = -(deadzone x dz)` | ✅ Proved |
408516 | `deadzone_mono_val` | `v₁ ≤ v₂ → deadzone v₁ dz ≤ deadzone v₂ dz` | ✅ Proved |
517+ | `deadzone_mono_dz_pos` | `dz₁ ≤ dz₂ < x ≤ 1 → deadzone x dz₂ ≤ deadzone x dz₁` | ✅ Proved |
409518-/
410519
411520end PX4.Deadzone
0 commit comments