← Visual paper

HardnessBilevel/Semialgebraic/Ext.lean

d1032f4c70da9b037605c2f444ce2450900e5a76 · GitHub

  1. /-
  2. Copyright: HardnessBilevel project.
  3. # Extended-real-valued semialgebraic functions (paper Def 2.2)
  4. Implements blueprint §4.B.2: `IsExtSemialgebraic` (fields `top`, `bot`, `graph`), `sa.ext_dom`
  5. (`IsExtSemialgebraic.dom`), `sa.ext_coe` (`isExtSemialgebraic_coe_iff`), `sa.ext_neg`
  6. (`IsExtSemialgebraic.neg`, proved without Tarski–Seidenberg: the graph of `-h` is a polynomial preimage of
  7. the graph of `h`), plus `IsExtSemialgebraic.const` and the optional `sa.ext_graph_equiv`
  8. (`isExtSemialgebraic_iff_extGraph`, with the encoding set `extGraph h ⊆ ι ⊕ Fin 2 → ℝ`).
  9. Deviations: none.
  10. -/
  11. import HardnessBilevel.Semialgebraic.Poly
  12. open MeasureTheory Function MvPolynomial
  13. namespace Bilevel
  14. /-- Def 2.2. The domain is derived (`IsExtSemialgebraic.dom`), not a field. The graph is the graph of
  15. `h` restricted to its domain, in `ι ⊕ Unit → ℝ`. -/
  16. structure IsExtSemialgebraic {ι : Type*} (h : (ι → ℝ) → EReal) : Prop where
  17. top : IsSemialgebraic {x | h x = ⊤}
  18. bot : IsSemialgebraic {x | h x = ⊥}
  19. graph : IsSemialgebraic {z : ι ⊕ Unit → ℝ | h (z ∘ Sum.inl) = ((z (Sum.inr ()) : ℝ) : EReal)}
  20. variable {ι : Type*}
  21. /-- `sa.ext_dom`: the (real) domain of an extended-real semialgebraic function is semialgebraic. -/
  22. theorem IsExtSemialgebraic.dom {h : (ι → ℝ) → EReal} (hh : IsExtSemialgebraic h) :
  23. IsSemialgebraic {x | ∃ r : ℝ, h x = r} := by
  24. refine (hh.top.union hh.bot).compl.of_eq ?_
  25. ext x
  26. simp only [Set.mem_compl_iff, Set.mem_union, Set.mem_ofPred_eq, not_or]
  27. induction h x using EReal.rec with
  28. | bot => simp
  29. | top => simp
  30. | coe r => simp
  31. /-- `sa.ext_coe`: a real function, viewed as extended-real, is semialgebraic iff its graph is. -/
  32. theorem isExtSemialgebraic_coe_iff (f : (ι → ℝ) → ℝ) :
  33. IsExtSemialgebraic (fun x => (f x : EReal)) ↔ IsSemialgebraicMap f := by
  34. have hg : {z : ι ⊕ Unit → ℝ | ((f (z ∘ Sum.inl) : ℝ) : EReal) = ((z (Sum.inr ()) : ℝ) : EReal)} =
  35. graphSet f := by
  36. ext z; simp only [Set.mem_ofPred_eq, EReal.coe_eq_coe_iff, mem_graphSet]
  37. constructor
  38. · intro hh
  39. have := hh.graph
  40. rw [hg] at this
  41. exact this
  42. · intro hf
  43. refine ⟨isSemialgebraic_empty.of_eq (by ext x; simp),
  44. isSemialgebraic_empty.of_eq (by ext x; simp), ?_⟩
  45. rw [hg]; exact hf
  46. theorem IsSemialgebraicMap.isExtSemialgebraic {f : (ι → ℝ) → ℝ} (hf : IsSemialgebraicMap f) :
  47. IsExtSemialgebraic (fun x => (f x : EReal)) :=
  48. (isExtSemialgebraic_coe_iff f).2 hf
  49. /-- Constant extended-real functions are semialgebraic. -/
  50. theorem IsExtSemialgebraic.const (c : EReal) : IsExtSemialgebraic (fun _ : ι → ℝ => c) := by
  51. induction c using EReal.rec with
  52. | bot =>
  53. exact ⟨isSemialgebraic_empty.of_eq (by ext x; simp), isSemialgebraic_univ.of_eq (by ext x; simp),
  54. isSemialgebraic_empty.of_eq (by ext z; simp)⟩
  55. | top =>
  56. exact ⟨isSemialgebraic_univ.of_eq (by ext x; simp), isSemialgebraic_empty.of_eq (by ext x; simp),
  57. isSemialgebraic_empty.of_eq (by ext z; simp)⟩
  58. | coe r =>
  59. refine IsSemialgebraicMap.isExtSemialgebraic (f := fun _ => r) ?_
  60. exact (isSemialgebraicMap_eval (C r)).of_eq (by ext z; simp [graphSet])
  61. /-- `sa.ext_neg`: negation preserves extended-real semialgebraicity (no Tarski–Seidenberg needed). -/
  62. theorem IsExtSemialgebraic.neg {h : (ι → ℝ) → EReal} (hh : IsExtSemialgebraic h) :
  63. IsExtSemialgebraic (fun x => -h x) := by
  64. refine ⟨hh.bot.of_eq (by ext x; simp [EReal.neg_eq_top_iff]),
  65. hh.top.of_eq (by ext x; simp [EReal.neg_eq_bot_iff]), ?_⟩
  66. have := hh.graph.preimage_of_poly
  67. (φ := fun z : ι ⊕ Unit → ℝ => Sum.elim (z ∘ Sum.inl) (fun _ => -z (Sum.inr ())))
  68. (Sum.elim (fun j => X (Sum.inl j)) (fun _ => -X (Sum.inr ())))
  69. (fun z i => by cases i <;> simp)
  70. refine this.of_eq ?_
  71. ext z
  72. simp only [Set.mem_preimage, Set.mem_ofPred_eq, Sum.elim_comp_inl, Sum.elim_inr, EReal.coe_neg]
  73. rw [neg_eq_iff_eq_neg]
  74. theorem isExtSemialgebraic_neg_iff {h : (ι → ℝ) → EReal} :
  75. IsExtSemialgebraic (fun x => -h x) ↔ IsExtSemialgebraic h := by
  76. refine ⟨fun hh => ?_, IsExtSemialgebraic.neg⟩
  77. simpa only [neg_neg] using hh.neg
  78. /-- Encoding of the full extended-real graph of `h` in `ι ⊕ Fin 2 → ℝ`: an extended real is encoded as a
  79. pair `(value, tag)` with tag `0` (finite, value `= h`), `1` (`h = ⊤`, value `0`) or `-1` (`h = ⊥`, value `0`). -/
  80. def extGraph (h : (ι → ℝ) → EReal) : Set (ι ⊕ Fin 2 → ℝ) :=
  81. {z | (z (Sum.inr 1) = 0 ∧ h (z ∘ Sum.inl) = ((z (Sum.inr 0) : ℝ) : EReal)) ∨
  82. (z (Sum.inr 1) = 1 ∧ z (Sum.inr 0) = 0 ∧ h (z ∘ Sum.inl) = ⊤) ∨
  83. (z (Sum.inr 1) = -1 ∧ z (Sum.inr 0) = 0 ∧ h (z ∘ Sum.inl) = ⊥)}
  84. /-- `sa.ext_graph_equiv` (optional): Def 2.2 agrees with semialgebraicity of the encoded graph. -/
  85. theorem isExtSemialgebraic_iff_extGraph (h : (ι → ℝ) → EReal) :
  86. IsExtSemialgebraic h ↔ IsSemialgebraic (extGraph h) := by
  87. constructor
  88. · intro hh
  89. have h1 : IsSemialgebraic {z : ι ⊕ Fin 2 → ℝ | z (Sum.inr 1) = 0 ∧
  90. h (z ∘ Sum.inl) = ((z (Sum.inr 0) : ℝ) : EReal)} := by
  91. refine isSemialgebraic_setOf_and (isSemialgebraic_coord_eq_const _ _) ?_
  92. refine (hh.graph.preimage_of_poly
  93. (φ := fun z : ι ⊕ Fin 2 → ℝ => Sum.elim (z ∘ Sum.inl) (fun _ => z (Sum.inr 0)))
  94. (Sum.elim (fun j => X (Sum.inl j)) (fun _ => X (Sum.inr 0)))
  95. (fun z i => by cases i <;> simp)).of_eq ?_
  96. ext z; simp
  97. have h2 : IsSemialgebraic {z : ι ⊕ Fin 2 → ℝ | z (Sum.inr 1) = 1 ∧ z (Sum.inr 0) = 0 ∧
  98. h (z ∘ Sum.inl) = ⊤} :=
  99. isSemialgebraic_setOf_and (isSemialgebraic_coord_eq_const _ _)
  100. (isSemialgebraic_setOf_and (isSemialgebraic_coord_eq_const _ _) (hh.top.reindex Sum.inl))
  101. have h3 : IsSemialgebraic {z : ι ⊕ Fin 2 → ℝ | z (Sum.inr 1) = -1 ∧ z (Sum.inr 0) = 0 ∧
  102. h (z ∘ Sum.inl) = ⊥} :=
  103. isSemialgebraic_setOf_and (isSemialgebraic_coord_eq_const _ _)
  104. (isSemialgebraic_setOf_and (isSemialgebraic_coord_eq_const _ _) (hh.bot.reindex Sum.inl))
  105. exact isSemialgebraic_setOf_or h1 (isSemialgebraic_setOf_or h2 h3)
  106. · intro hE
  107. refine ⟨?_, ?_, ?_⟩
  108. · refine (hE.preimage_of_poly (φ := fun x : ι → ℝ => Sum.elim x ![0, 1])
  109. (Sum.elim X ![C 0, C 1]) (fun x i => by
  110. rcases i with j | j
  111. · simp
  112. · fin_cases j <;> simp)).of_eq ?_
  113. ext x; simp [extGraph]; norm_num
  114. · refine (hE.preimage_of_poly (φ := fun x : ι → ℝ => Sum.elim x ![0, -1])
  115. (Sum.elim X ![C 0, C (-1)]) (fun x i => by
  116. rcases i with j | j
  117. · simp
  118. · fin_cases j <;> simp)).of_eq ?_
  119. ext x; simp [extGraph]; norm_num
  120. · refine (hE.preimage_of_poly
  121. (φ := fun z : ι ⊕ Unit → ℝ => Sum.elim (z ∘ Sum.inl) ![z (Sum.inr ()), 0])
  122. (Sum.elim (fun j => X (Sum.inl j)) ![X (Sum.inr ()), C 0]) (fun z i => by
  123. rcases i with j | j
  124. · simp
  125. · fin_cases j <;> simp)).of_eq ?_
  126. ext z; simp [extGraph]
  127. end Bilevel