← Visual paper

HardnessBilevel/Hardness/Analysis.lean

d1032f4c70da9b037605c2f444ce2450900e5a76 · GitHub

  1. import HardnessBilevel.Hardness.Construction
  2. import HardnessBilevel.Framework.Basic
  3. import HardnessBilevel.Framework.Value
  4. import HardnessBilevel.Framework.Separable
  5. /-!
  6. # Analysis of the Lemma 3.3 construction (blueprint §4.I.2, `s3.L0`–`s3.L8`, `s3.lemma33`)
  7. Lean names (all in `Bilevel.SSI`):
  8. * `s3.L0`: `isMinOn_cons_iff` (pointwise), `argminSet_cons` (set form), on
  9. `{y | y 0 ∈ A ∧ Fin.tail y ∈ B}`; `box_eq`, `mem_box_iff` rewrite `I.box` into that shape.
  10. * `s3.L1`: `IsBinary`, `Lfun_nonneg` (a), `Lfun_zero` (b), `Lfun_eq_zero_iff` (c),
  11. `isMinOn_Lfun_iff` (d), `Zset`, `mem_Zset_iff`, `Zset_eq` (e).
  12. * `s3.L2`: `Hfun_nonneg` (a), `Hfun_eq_zero_iff` (b), `continuous_Hfun` (c), `Tset`,
  13. `Tset_nonempty` (d, compactness), `mval`, `Hfun_eq_mval` (H constant on `T x`), `mval_le`,
  14. `mval_nonneg`, `mval_eq_zero_iff` (e).
  15. * `s3.L3`: `argminSet_Qfun`, `mem_argminSet_Qfun_iff`, `cons_mem_argminSet_Qfun`,
  16. `argminSet_Qfun_nonempty`.
  17. * `s3.L4`: `isBinary_iff_exists_fin_two` (a), `Ffun_fin_two`, `exists_nat_of_isBinary` (b),
  18. `exists_isBinary_Ffun_eq` (c) — via `finFunctionFinEquiv` with `m = 2`.
  19. * `s3.L5`: `tInd`, `tInd_mem_cube`, `isBinary_tInd`, `Gfun_tInd` (a), `Gfun_of_isBinary` (b).
  20. * `s3.L6`: `valueFun_eq` (+ `valueFun_of_isBinary`, `valueFun_of_not_isBinary`).
  21. * `s3.L7`: `optVal_lt_zero_of_yes`. `s3.L8`: `valueFun_nonneg_of_not_yes`,
  22. `valueFun_zero_of_not_yes`, `lemma33_no`. `s3.lemma33`: `lemma33`.
  23. Choices (no change of meaning): `Zset x := argminSet Lfun (Icc 0 1) x` and
  24. `Tset x := argminSet Hfun (cube k) x`, which by `mem_argminSet_iff` are the blueprint's
  25. `{z ∈ Icc 0 1 | IsMinOn (L x) (Icc 0 1) z}` / `{t ∈ box | IsMinOn (H x) box t}`;
  26. `mval x := sInf (H x '' cube k)`, shown to be the attained minimum. `IsBinary` gets a
  27. (noncomputable, via `Real.decidableEq`) `DecidablePred` instance so the `if` in `Zset_eq` /
  28. `valueFun_eq` elaborates without `open Classical`. The lower box is `I.box` (= blueprint
  29. `box I.k`, the cube `[0,1]^(k+1)`).
  30. -/
  31. namespace Bilevel
  32. namespace SSI
  33. /-! ### s3.L0: separable argmin on a head/tail split -/
  34. /-- `s3.L0` (pointwise form). -/
  35. theorem isMinOn_cons_iff {k : ℕ} {f : ℝ → ℝ} {g : (Fin k → ℝ) → ℝ} {A : Set ℝ}
  36. {B : Set (Fin k → ℝ)} {y : Fin (k + 1) → ℝ} (hy : y 0 ∈ A ∧ Fin.tail y ∈ B) :
  37. IsMinOn (fun y : Fin (k + 1) → ℝ => f (y 0) + g (Fin.tail y))
  38. {y : Fin (k + 1) → ℝ | y 0 ∈ A ∧ Fin.tail y ∈ B} y ↔
  39. IsMinOn f A (y 0) ∧ IsMinOn g B (Fin.tail y) := by
  40. simp only [isMinOn_iff]
  41. constructor
  42. · intro h
  43. refine ⟨fun a ha => ?_, fun b hb => ?_⟩
  44. · have := h (Fin.cons a (Fin.tail y)) ⟨by simpa using ha, by simpa using hy.2⟩
  45. simp only [Fin.cons_zero, Fin.tail_cons] at this
  46. linarith
  47. · have := h (Fin.cons (y 0) b) ⟨by simpa using hy.1, by simpa using hb⟩
  48. simp only [Fin.cons_zero, Fin.tail_cons] at this
  49. linarith
  50. · rintro ⟨h1, h2⟩ y' hy'
  51. have := h1 _ hy'.1
  52. have := h2 _ hy'.2
  53. linarith
  54. /-- `s3.L0` (set form, unconditional). -/
  55. theorem argminSet_cons {X : Type*} {k : ℕ} (A : X → ℝ → ℝ) (B : X → (Fin k → ℝ) → ℝ)
  56. (S₁ : Set ℝ) (S₂ : Set (Fin k → ℝ)) (x : X) :
  57. argminSet (fun x (y : Fin (k + 1) → ℝ) => A x (y 0) + B x (Fin.tail y))
  58. {y : Fin (k + 1) → ℝ | y 0 ∈ S₁ ∧ Fin.tail y ∈ S₂} x =
  59. {y : Fin (k + 1) → ℝ | y 0 ∈ argminSet A S₁ x ∧ Fin.tail y ∈ argminSet B S₂ x} := by
  60. ext y
  61. rw [mem_argminSet_iff]
  62. constructor
  63. · rintro ⟨hy, h⟩
  64. have h' := (isMinOn_cons_iff (f := A x) (g := B x) hy).1 h
  65. exact ⟨mem_argminSet_iff.2 ⟨hy.1, h'.1⟩, mem_argminSet_iff.2 ⟨hy.2, h'.2⟩⟩
  66. · rintro ⟨h1, h2⟩
  67. rw [mem_argminSet_iff] at h1 h2
  68. exact ⟨⟨h1.1, h2.1⟩, (isMinOn_cons_iff (f := A x) (g := B x) ⟨h1.1, h2.1⟩).2 ⟨h1.2, h2.2⟩⟩
  69. theorem mem_cube_iff {n : ℕ} {t : Fin n → ℝ} : t ∈ cube n ↔ ∀ i, t i ∈ Set.Icc (0 : ℝ) 1 := by
  70. simp only [cube, Set.mem_univ_pi]
  71. theorem zero_mem_cube (n : ℕ) : (0 : Fin n → ℝ) ∈ cube n := by
  72. simp [mem_cube_iff]
  73. theorem isCompact_cube (n : ℕ) : IsCompact (cube n) :=
  74. isCompact_univ_pi fun _ => isCompact_Icc
  75. theorem mem_box_iff (I : SSI) {y : Fin (I.k + 1) → ℝ} :
  76. y ∈ I.box ↔ y 0 ∈ Set.Icc (0 : ℝ) 1 ∧ Fin.tail y ∈ cube I.k := by
  77. simp only [box, cube, Set.mem_univ_pi, Fin.forall_fin_succ, Fin.tail]
  78. theorem box_eq (I : SSI) :
  79. I.box = {y : Fin (I.k + 1) → ℝ | y 0 ∈ Set.Icc (0 : ℝ) 1 ∧ Fin.tail y ∈ cube I.k} := by
  80. ext y; exact I.mem_box_iff
  81. /-! ### s3.L1: analysis of `L` -/
  82. /-- `x` is a 0/1 vector. -/
  83. def IsBinary {n : ℕ} (x : Fin n → ℝ) : Prop := ∀ j, x j = 0 ∨ x j = 1
  84. noncomputable instance {n : ℕ} : DecidablePred (IsBinary (n := n)) :=
  85. fun x => inferInstanceAs (Decidable (∀ j, x j = 0 ∨ x j = 1))
  86. theorem mul_one_sub_eq_zero_iff {a : ℝ} : a * (1 - a) = 0 ↔ a = 0 ∨ a = 1 := by
  87. rw [mul_eq_zero, sub_eq_zero, eq_comm (a := (1 : ℝ))]
  88. theorem one_sub_mul_eq_zero_iff {a : ℝ} : (1 - a) * a = 0 ↔ a = 0 ∨ a = 1 := by
  89. rw [mul_comm, mul_one_sub_eq_zero_iff]
  90. theorem sum_sq_eq_zero_iff' {n : ℕ} (a : Fin n → ℝ) : ∑ j, a j ^ 2 = 0 ↔ ∀ j, a j = 0 := by
  91. rw [Finset.sum_eq_zero_iff_of_nonneg (fun j _ => sq_nonneg (a j))]
  92. simp
  93. /-- `s3.L1(a)` -/
  94. theorem Lfun_nonneg {r : ℕ} (x : Fin r → ℝ) {z : ℝ} (hz : z ∈ Set.Icc (0 : ℝ) 1) :
  95. 0 ≤ Lfun x z :=
  96. mul_nonneg hz.1 (by positivity)
  97. /-- `s3.L1(b)` -/
  98. @[simp] theorem Lfun_zero {r : ℕ} (x : Fin r → ℝ) : Lfun x 0 = 0 := by simp [Lfun]
  99. /-- `s3.L1(c)` -/
  100. theorem Lfun_eq_zero_iff {r : ℕ} (x : Fin r → ℝ) (z : ℝ) :
  101. Lfun x z = 0 ↔ z = 0 ∨ (z = 1 ∧ IsBinary x) := by
  102. unfold Lfun
  103. rw [mul_eq_zero, add_eq_zero_iff_of_nonneg (sq_nonneg _) (by positivity),
  104. sum_sq_eq_zero_iff', sq_eq_zero_iff, sub_eq_zero]
  105. simp only [one_sub_mul_eq_zero_iff, IsBinary]
  106. /-- `s3.L1(d)` -/
  107. theorem isMinOn_Lfun_iff {r : ℕ} (x : Fin r → ℝ) {z : ℝ} (hz : z ∈ Set.Icc (0 : ℝ) 1) :
  108. IsMinOn (Lfun x) (Set.Icc 0 1) z ↔ Lfun x z = 0 := by
  109. rw [isMinOn_iff]
  110. constructor
  111. · intro h
  112. have := h 0 ⟨le_rfl, zero_le_one⟩
  113. rw [Lfun_zero] at this
  114. exact le_antisymm this (Lfun_nonneg x hz)
  115. · intro h z' hz'
  116. rw [h]; exact Lfun_nonneg x hz'
  117. /-- The `z`-part of the lower-level argmin. -/
  118. noncomputable def Zset {r : ℕ} (x : Fin r → ℝ) : Set ℝ := argminSet (fun x z => Lfun (r := r) x z) (Set.Icc 0 1) x
  119. theorem mem_Zset_iff {r : ℕ} (x : Fin r → ℝ) (z : ℝ) :
  120. z ∈ Zset x ↔ z = 0 ∨ (z = 1 ∧ IsBinary x) := by
  121. unfold Zset
  122. rw [mem_argminSet_iff]
  123. constructor
  124. · rintro ⟨hz, h⟩
  125. exact (Lfun_eq_zero_iff x z).1 ((isMinOn_Lfun_iff x hz).1 h)
  126. · intro h
  127. have hz : z ∈ Set.Icc (0 : ℝ) 1 := by
  128. rcases h with rfl | ⟨rfl, -⟩ <;> simp
  129. exact ⟨hz, (isMinOn_Lfun_iff x hz).2 ((Lfun_eq_zero_iff x z).2 h)⟩
  130. /-- `s3.L1(e)` -/
  131. theorem Zset_eq {r : ℕ} (x : Fin r → ℝ) :
  132. Zset x = if IsBinary x then ({0, 1} : Set ℝ) else {0} := by
  133. ext z
  134. rw [mem_Zset_iff]
  135. split_ifs with hb <;> simp [hb]
  136. /-! ### s3.L2: analysis of `H` -/
  137. section H
  138. variable (I : SSI)
  139. /-- `s3.L2(a)` -/
  140. theorem Hfun_nonneg (x : Fin I.r → ℝ) (t : Fin I.k → ℝ) : 0 ≤ I.Hfun x t := by
  141. unfold Hfun; positivity
  142. /-- `s3.L2(b)` -/
  143. theorem Hfun_eq_zero_iff (x : Fin I.r → ℝ) (t : Fin I.k → ℝ) :
  144. I.Hfun x t = 0 ↔ IsBinary t ∧ I.Ffun x = I.Gfun t := by
  145. unfold Hfun
  146. rw [add_eq_zero_iff_of_nonneg (by positivity) (sq_nonneg _), sum_sq_eq_zero_iff', sq_eq_zero_iff,
  147. sub_eq_zero]
  148. simp only [mul_one_sub_eq_zero_iff, IsBinary]
  149. /-- `s3.L2(c)` -/
  150. theorem continuous_Hfun (x : Fin I.r → ℝ) : Continuous (I.Hfun x) := by
  151. unfold Hfun Gfun; fun_prop
  152. /-- The `t`-part of the lower-level argmin: minimisers of `H x` over the cube. -/
  153. noncomputable def Tset (x : Fin I.r → ℝ) : Set (Fin I.k → ℝ) := argminSet I.Hfun (cube I.k) x
  154. /-- `s3.L2(d)`: a minimiser of `H x` over the compact cube exists. -/
  155. theorem Tset_nonempty (x : Fin I.r → ℝ) : (I.Tset x).Nonempty := by
  156. obtain ⟨t, ht, hmin⟩ := (isCompact_cube I.k).exists_isMinOn ⟨0, zero_mem_cube I.k⟩
  157. (I.continuous_Hfun x).continuousOn
  158. exact ⟨t, mem_argminSet_iff.2 ⟨ht, hmin⟩⟩
  159. theorem Tset_subset (x : Fin I.r → ℝ) : I.Tset x ⊆ cube I.k := argminSet_subset
  160. /-- `m x := min_{t ∈ [0,1]^k} H x t`. -/
  161. noncomputable def mval (x : Fin I.r → ℝ) : ℝ := sInf (I.Hfun x '' cube I.k)
  162. theorem isLeast_of_mem_Tset {x : Fin I.r → ℝ} {t : Fin I.k → ℝ} (ht : t ∈ I.Tset x) :
  163. IsLeast (I.Hfun x '' cube I.k) (I.Hfun x t) := by
  164. rw [Tset, mem_argminSet_iff, isMinOn_iff] at ht
  165. exact ⟨⟨t, ht.1, rfl⟩, by rintro _ ⟨t', ht', rfl⟩; exact ht.2 t' ht'⟩
  166. /-- `H x` is constant (`= m x`) on the argmin `T x`. -/
  167. theorem Hfun_eq_mval {x : Fin I.r → ℝ} {t : Fin I.k → ℝ} (ht : t ∈ I.Tset x) :
  168. I.Hfun x t = I.mval x :=
  169. (I.isLeast_of_mem_Tset ht).csInf_eq.symm
  170. theorem mval_le {x : Fin I.r → ℝ} {t : Fin I.k → ℝ} (ht : t ∈ cube I.k) :
  171. I.mval x ≤ I.Hfun x t := by
  172. obtain ⟨t₀, h₀⟩ := I.Tset_nonempty x
  173. exact (I.Hfun_eq_mval h₀) ▸ (I.isLeast_of_mem_Tset h₀).2 ⟨t, ht, rfl⟩
  174. /-- `s3.L2(e)` -/
  175. theorem mval_nonneg (x : Fin I.r → ℝ) : 0 ≤ I.mval x := by
  176. obtain ⟨t₀, h₀⟩ := I.Tset_nonempty x
  177. rw [← I.Hfun_eq_mval h₀]; exact I.Hfun_nonneg x t₀
  178. /-- `s3.L2(e)` -/
  179. theorem mval_eq_zero_iff (x : Fin I.r → ℝ) :
  180. I.mval x = 0 ↔ ∃ t ∈ cube I.k, I.Hfun x t = 0 := by
  181. constructor
  182. · intro h
  183. obtain ⟨t₀, h₀⟩ := I.Tset_nonempty x
  184. exact ⟨t₀, I.Tset_subset x h₀, (I.Hfun_eq_mval h₀).trans h⟩
  185. · rintro ⟨t, ht, h⟩
  186. exact le_antisymm (h ▸ I.mval_le ht) (I.mval_nonneg x)
  187. end H
  188. /-! ### s3.L3: separability (paper eq. (20)) -/
  189. theorem argminSet_Qfun (I : SSI) (x : Fin I.r → ℝ) :
  190. argminSet I.Qfun I.box x = {y : Fin (I.k + 1) → ℝ | y 0 ∈ Zset x ∧ Fin.tail y ∈ I.Tset x} := by
  191. rw [box_eq]
  192. exact argminSet_cons (fun x z => Lfun x z) I.Hfun (Set.Icc 0 1) (cube I.k) x
  193. /-- `s3.L3` -/
  194. theorem mem_argminSet_Qfun_iff (I : SSI) (x : Fin I.r → ℝ) (y : Fin (I.k + 1) → ℝ) :
  195. y ∈ argminSet I.Qfun I.box x ↔ y ∈ I.box ∧ y 0 ∈ Zset x ∧ Fin.tail y ∈ I.Tset x := by
  196. rw [argminSet_Qfun]
  197. refine ⟨fun h => ⟨I.mem_box_iff.2 ⟨argminSet_subset h.1, I.Tset_subset x h.2⟩, h⟩,
  198. fun h => h.2⟩
  199. theorem cons_mem_argminSet_Qfun (I : SSI) {x : Fin I.r → ℝ} {z : ℝ} {t : Fin I.k → ℝ}
  200. (hz : z ∈ Zset x) (ht : t ∈ I.Tset x) :
  201. (Fin.cons z t : Fin (I.k + 1) → ℝ) ∈ argminSet I.Qfun I.box x := by
  202. rw [argminSet_Qfun]
  203. exact ⟨by simpa using hz, by simpa using ht⟩
  204. /-- Corollary of `s3.L3`: the lower-level argmin is never empty. -/
  205. theorem argminSet_Qfun_nonempty (I : SSI) (x : Fin I.r → ℝ) :
  206. (argminSet I.Qfun I.box x).Nonempty := by
  207. obtain ⟨t, ht⟩ := I.Tset_nonempty x
  208. exact ⟨_, I.cons_mem_argminSet_Qfun ((mem_Zset_iff x 0).2 (Or.inl rfl)) ht⟩
  209. /-! ### s3.L4: binary expansions -/
  210. /-- `s3.L4(a)` -/
  211. theorem isBinary_iff_exists_fin_two {n : ℕ} (x : Fin n → ℝ) :
  212. IsBinary x ↔ ∃ f : Fin n → Fin 2, x = fun j => ((f j : ℕ) : ℝ) := by
  213. constructor
  214. · intro h
  215. refine ⟨fun j => if x j = 0 then 0 else 1, funext fun j => ?_⟩
  216. rcases h j with h | h <;> simp [h]
  217. · rintro ⟨f, rfl⟩ j
  218. have : ((f j : ℕ)) = 0 ∨ (f j : ℕ) = 1 := by omega
  219. rcases this with h | h <;> simp [h]
  220. /-- `s3.L4(b)` -/
  221. theorem Ffun_fin_two (I : SSI) (f : Fin I.r → Fin 2) :
  222. I.Ffun (fun j => ((f j : ℕ) : ℝ)) = ((I.R + (finFunctionFinEquiv f : ℕ) : ℕ) : ℝ) := by
  223. rw [finFunctionFinEquiv_apply, Ffun]
  224. push_cast
  225. simp only [mul_comm]
  226. /-- `s3.L4(b)`: on binary points `F x` is a natural number in `[R, R + 2^r)`. -/
  227. theorem exists_nat_of_isBinary (I : SSI) {x : Fin I.r → ℝ} (hx : IsBinary x) :
  228. ∃ S : ℕ, I.Ffun x = S ∧ I.R ≤ S ∧ S < I.R + 2 ^ I.r := by
  229. obtain ⟨f, rfl⟩ := (isBinary_iff_exists_fin_two x).1 hx
  230. refine ⟨I.R + (finFunctionFinEquiv f : ℕ), I.Ffun_fin_two f, Nat.le_add_right _ _, ?_⟩
  231. have := (finFunctionFinEquiv f).isLt
  232. omega
  233. /-- `s3.L4(c)` -/
  234. theorem exists_isBinary_Ffun_eq (I : SSI) {S : ℕ} (h1 : I.R ≤ S) (h2 : S < I.R + 2 ^ I.r) :
  235. ∃ x : Fin I.r → ℝ, IsBinary x ∧ I.Ffun x = S := by
  236. have hn : S - I.R < 2 ^ I.r := by omega
  237. set f : Fin I.r → Fin 2 := (finFunctionFinEquiv : (Fin I.r → Fin 2) ≃ Fin (2 ^ I.r)).symm
  238. ⟨S - I.R, hn⟩ with hf
  239. refine ⟨fun j => ((f j : ℕ) : ℝ), (isBinary_iff_exists_fin_two _).2 ⟨f, rfl⟩, ?_⟩
  240. rw [I.Ffun_fin_two f, hf, Equiv.apply_symm_apply]
  241. congr 1
  242. simp only
  243. omega
  244. /-! ### s3.L5: subset sums and binary `t` -/
  245. /-- The indicator vector of `T`. -/
  246. noncomputable def tInd {k : ℕ} (T : Finset (Fin k)) : Fin k → ℝ := fun i => if i ∈ T then 1 else 0
  247. /-- `s3.L5(a)` -/
  248. theorem tInd_mem_cube {k : ℕ} (T : Finset (Fin k)) : tInd T ∈ cube k := by
  249. rw [mem_cube_iff]; intro i; unfold tInd; split_ifs <;> simp
  250. /-- `s3.L5(a)` -/
  251. theorem isBinary_tInd {k : ℕ} (T : Finset (Fin k)) : IsBinary (tInd T) := by
  252. intro i; unfold tInd; split_ifs <;> simp
  253. /-- `s3.L5(a)` -/
  254. theorem Gfun_tInd (I : SSI) (T : Finset (Fin I.k)) :
  255. I.Gfun (tInd T) = ((∑ i ∈ T, I.q i : ℕ) : ℝ) := by
  256. simp only [Gfun, tInd, ite_mul, one_mul, zero_mul, Finset.sum_ite_mem, Finset.univ_inter,
  257. Nat.cast_sum]
  258. /-- `s3.L5(b)` -/
  259. theorem Gfun_of_isBinary (I : SSI) {t : Fin I.k → ℝ} (ht : IsBinary t) :
  260. I.Gfun t = ((∑ i ∈ Finset.univ.filter (fun i => t i = 1), I.q i : ℕ) : ℝ) := by
  261. rw [Nat.cast_sum, Finset.sum_filter, Gfun]
  262. refine Finset.sum_congr rfl fun i _ => ?_
  263. rcases ht i with h | h <;> simp [h]
  264. /-! ### s3.L6: the value function (paper eq. (21)) -/
  265. theorem Pfun_of_mem_argminSet (I : SSI) {x : Fin I.r → ℝ} {y : Fin (I.k + 1) → ℝ}
  266. (hy : y ∈ argminSet I.Qfun I.box x) : I.Pfun x y = 1 - y 0 * (I.mval x + 1) := by
  267. rw [Pfun, I.Hfun_eq_mval ((I.mem_argminSet_Qfun_iff x y).1 hy).2.2]
  268. /-- `s3.L6`: `φ x = -m x` on binary `x`, `φ x = 1` otherwise. -/
  269. theorem valueFun_eq (I : SSI) (x : Fin I.r → ℝ) :
  270. valueFun I.Pfun I.Qfun I.box x = ((if IsBinary x then -(I.mval x) else 1 : ℝ) : EReal) := by
  271. obtain ⟨t, ht⟩ := I.Tset_nonempty x
  272. split_ifs with hb
  273. · apply valueFun_eq_of_isLeast
  274. have hmem := I.cons_mem_argminSet_Qfun ((mem_Zset_iff x 1).2 (Or.inr ⟨rfl, hb⟩)) ht
  275. refine ⟨⟨_, hmem, ?_⟩, ?_⟩
  276. · rw [I.Pfun_of_mem_argminSet hmem, Fin.cons_zero]; ring
  277. · rintro _ ⟨y, hy, rfl⟩
  278. rw [I.Pfun_of_mem_argminSet hy]
  279. have hm := I.mval_nonneg x
  280. rcases (mem_Zset_iff x (y 0)).1 ((I.mem_argminSet_Qfun_iff x y).1 hy).2.1 with h | ⟨h, -⟩
  281. · rw [h]; linarith
  282. · rw [h]; linarith
  283. · apply valueFun_eq_of_const (I.argminSet_Qfun_nonempty x)
  284. intro y hy
  285. rw [I.Pfun_of_mem_argminSet hy]
  286. rcases (mem_Zset_iff x (y 0)).1 ((I.mem_argminSet_Qfun_iff x y).1 hy).2.1 with h | ⟨-, h⟩
  287. · rw [h]; ring
  288. · exact absurd h hb
  289. /-- `φ` is real-valued and `≤ 0` on binary points, `= 1` elsewhere. -/
  290. theorem valueFun_of_isBinary (I : SSI) {x : Fin I.r → ℝ} (hx : IsBinary x) :
  291. valueFun I.Pfun I.Qfun I.box x = ((-(I.mval x) : ℝ) : EReal) := by
  292. rw [valueFun_eq, ite_eq_left hx]
  293. theorem valueFun_of_not_isBinary (I : SSI) {x : Fin I.r → ℝ} (hx : ¬ IsBinary x) :
  294. valueFun I.Pfun I.Qfun I.box x = ((1 : ℝ) : EReal) := by
  295. rw [valueFun_eq, ite_eq_right hx]
  296. /-! ### s3.L7: YES ⇒ optimal value < 0 -/
  297. /-- `s3.L7` -/
  298. theorem optVal_lt_zero_of_yes (I : SSI) (h : I.Yes) :
  299. optVal I.Pfun I.Qfun I.box < (0 : EReal) := by
  300. obtain ⟨S, h1, h2, hS⟩ := h
  301. obtain ⟨x, hx, hFx⟩ := I.exists_isBinary_Ffun_eq h1 h2
  302. have hm : I.mval x ≠ 0 := by
  303. intro hm0
  304. obtain ⟨t, -, hHt⟩ := (I.mval_eq_zero_iff x).1 hm0
  305. obtain ⟨htb, hFG⟩ := (I.Hfun_eq_zero_iff x t).1 hHt
  306. apply hS
  307. refine ⟨Finset.univ.filter (fun i => t i = 1), ?_⟩
  308. have := hFx.symm.trans (hFG.trans (I.Gfun_of_isBinary htb))
  309. exact_mod_cast this.symm
  310. have hpos : 0 < I.mval x := lt_of_le_of_ne (I.mval_nonneg x) (Ne.symm hm)
  311. unfold optVal
  312. rw [iInf_lt_iff]
  313. refine ⟨x, ?_⟩
  314. rw [I.valueFun_of_isBinary hx, ← EReal.coe_zero, EReal.coe_lt_coe_iff]
  315. linarith
  316. /-! ### s3.L8: NO ⇒ optimal value = 0, attained -/
  317. theorem valueFun_nonneg_of_not_yes (I : SSI) (h : ¬ I.Yes) (x : Fin I.r → ℝ) :
  318. (0 : EReal) ≤ valueFun I.Pfun I.Qfun I.box x := by
  319. by_cases hx : IsBinary x
  320. · rw [I.valueFun_of_isBinary hx]
  321. obtain ⟨S, hFS, h1, h2⟩ := I.exists_nat_of_isBinary hx
  322. have hsub : I.subsetSum S := by
  323. by_contra hc; exact h ⟨S, h1, h2, hc⟩
  324. obtain ⟨T, hT⟩ := hsub
  325. have hH : I.Hfun x (tInd T) = 0 :=
  326. (I.Hfun_eq_zero_iff x _).2 ⟨isBinary_tInd T, by rw [hFS, I.Gfun_tInd, hT]⟩
  327. have hm : I.mval x = 0 := (I.mval_eq_zero_iff x).2 ⟨_, tInd_mem_cube T, hH⟩
  328. rw [hm, neg_zero, EReal.coe_zero]
  329. · rw [I.valueFun_of_not_isBinary hx, ← EReal.coe_zero, EReal.coe_le_coe_iff]
  330. exact zero_le_one
  331. theorem isBinary_zero {n : ℕ} : IsBinary (0 : Fin n → ℝ) := fun _ => Or.inl rfl
  332. /-- `s3.L8` (attained at `x = 0`). -/
  333. theorem valueFun_zero_of_not_yes (I : SSI) (h : ¬ I.Yes) :
  334. valueFun I.Pfun I.Qfun I.box 0 = 0 := by
  335. refine le_antisymm ?_ (I.valueFun_nonneg_of_not_yes h 0)
  336. rw [I.valueFun_of_isBinary isBinary_zero]
  337. have hm := I.mval_nonneg 0
  338. rw [← EReal.coe_zero, EReal.coe_le_coe_iff]
  339. linarith
  340. /-- `s3.lemma33_no` (`s3.L8`): on NO-instances the optimal value is `0`. -/
  341. theorem lemma33_no (I : SSI) (h : ¬ I.Yes) : optVal I.Pfun I.Qfun I.box = 0 :=
  342. le_antisymm (iInf_le_of_le 0 (I.valueFun_zero_of_not_yes h).le)
  343. (le_iInf (I.valueFun_nonneg_of_not_yes h))
  344. /-- `s3.lemma33` (Lemma 3.3 (b),(c)): the optimal value is `< 0` iff `I` is a YES-instance. -/
  345. theorem lemma33 (I : SSI) : optVal I.Pfun I.Qfun I.box < (0 : EReal) ↔ I.Yes := by
  346. refine ⟨fun hlt => ?_, I.optVal_lt_zero_of_yes⟩
  347. by_contra h
  348. rw [I.lemma33_no h] at hlt
  349. exact lt_irrefl _ hlt
  350. end SSI
  351. end Bilevel