Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
cc68bd4
v1 start
Aug 15, 2026
e1f75c4
progress
Aug 15, 2026
86a2bb5
more progress
Aug 16, 2026
66ab987
linter
Aug 16, 2026
72e17ff
more progress
Aug 17, 2026
c2ed4e0
mk_all
Aug 17, 2026
5cd47fa
minor updates
Aug 20, 2026
b2381e5
almost ready
Aug 24, 2026
b6c9661
linter
Aug 24, 2026
8051708
Merge remote-tracking branch 'upstream/master' into inclusion-v1
Aug 25, 2026
df9c3db
fix(Inclusion): adapt option deprecation to Lean 4.34
Aug 25, 2026
fc93189
try fix
Aug 25, 2026
c5c31ef
actual fix
Aug 25, 2026
f2f52b9
minor cleanup
Aug 26, 2026
53556b9
rename
Aug 26, 2026
fbe6dd8
remove coe
Aug 28, 2026
80c2c74
Update Mathlib/Tactic/Inclusion/Core/Elab.lean
DavidLedvinka Aug 29, 2026
32d6348
Update Mathlib/Tactic/Inclusion/Core/Expr.lean
DavidLedvinka Aug 29, 2026
faf14a5
Update Mathlib/Tactic/Inclusion/Core/Inclusion.lean
DavidLedvinka Aug 29, 2026
01c0481
suggestions
Aug 29, 2026
cf0ce72
lower_snake
Aug 29, 2026
0dddb00
Merge remote-tracking branch 'upstream/master' into inclusion-v1
Aug 31, 2026
9faceca
move discr_tree_ext
Aug 31, 2026
25f0cdf
mk_all
Aug 31, 2026
146d994
Update Mathlib/Tactic/Inclusion/Core/Elab.lean
DavidLedvinka Sep 2, 2026
81f8eaa
Update Mathlib/Tactic/Inclusion/Core/Elab.lean
DavidLedvinka Sep 2, 2026
0d60740
Update Mathlib/Tactic/Inclusion/Core/Elab.lean
DavidLedvinka Sep 2, 2026
482b619
Update Mathlib/Tactic/Inclusion/Core/Elab.lean
DavidLedvinka Sep 2, 2026
e906938
Update Mathlib/Tactic/Inclusion/Extension/IntervalDyadicReal/Tactic.lean
DavidLedvinka Sep 2, 2026
55a7f50
Update Mathlib/Tactic/Inclusion/Core/Elab.lean
DavidLedvinka Sep 2, 2026
e7be09f
fix
Sep 2, 2026
7508dcb
fix
Sep 2, 2026
754ae62
docs
Sep 2, 2026
23ce40b
minor reword
Sep 2, 2026
ffaf176
Add interval multiplication support to inclusion tactic
Sep 6, 2026
1f20a6a
draft
Sep 7, 2026
8c84c49
chore: keep local inclusion files out of the PR
Sep 7, 2026
a1fc9b8
Merge remote-tracking branch 'upstream/master' into inclusion-multipl…
Sep 7, 2026
5d3c995
improve
Sep 7, 2026
c8db13c
fix tests
Sep 8, 2026
3dab67e
test
Sep 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ theorem mul_le_mul_of_nonpos_of_nonneg' [ExistsAddOfLE R] [PosMulMono R] [MulPos
(hca : c ≤ a) (hbd : b ≤ d) (ha : 0 ≤ a) (hd : d ≤ 0) : a * b ≤ c * d :=
(mul_le_mul_of_nonneg_left hbd ha).trans <| mul_le_mul_of_nonpos_right hca hd

theorem mul_le_mul_of_nonpos_of_nonneg'' [ExistsAddOfLE R] [PosMulMono R] [MulPosMono R]
[AddRightMono R] [AddRightReflectLE R]
(hac : a ≤ c) (hdb : d ≤ b) (ha : a ≤ 0) (hd : 0 ≤ d) : a * b ≤ c * d :=
(mul_le_mul_of_nonpos_left hdb ha).trans <| mul_le_mul_of_nonneg_right hac hd

theorem mul_le_mul_of_nonpos_of_nonpos [ExistsAddOfLE R] [MulPosMono R] [PosMulMono R]
[AddRightMono R] [AddRightReflectLE R]
(hca : c ≤ a) (hdb : d ≤ b) (hc : c ≤ 0) (hb : b ≤ 0) : a * b ≤ c * d :=
Expand Down
6 changes: 3 additions & 3 deletions Mathlib/Tactic/Inclusion/Core/ToSet.lean
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ def IntervalBool.toPropSet : IntervalBool → Set Prop

instance : ToSet IntervalBool Prop := ⟨IntervalBool.toPropSet⟩

@[simp]
@[simp, grind =]
theorem IntervalBool.mem_true_iff {p : Prop} : p ∈ IntervalBool.true ↔ p := by
simp [ToSet.mem_def, ToSet.toSet, IntervalBool.toPropSet]

@[simp]
@[simp, grind =]
theorem IntervalBool.mem_false_iff {p : Prop} : p ∈ IntervalBool.false ↔ ¬p := by
simp [ToSet.mem_def, ToSet.toSet, IntervalBool.toPropSet]

Expand All @@ -123,7 +123,7 @@ theorem IntervalBool.mem_true {p : Prop} (hp : p) : p ∈ IntervalBool.true :=
theorem IntervalBool.mem_false {p : Prop} (hp : ¬p) : p ∈ IntervalBool.false :=
IntervalBool.mem_false_iff.mpr hp

@[simp]
@[simp, grind ←]
theorem IntervalBool.mem_undetermined (p : Prop) : p ∈ IntervalBool.undetermined := by
simpa [ToSet.mem_def, ToSet.toSet, IntervalBool.toPropSet] using Classical.em p

Expand Down
131 changes: 105 additions & 26 deletions Mathlib/Tactic/Inclusion/Extension/Interval.lean
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module
public import Mathlib.Algebra.Order.Group.Unbundled.Basic
public import Mathlib.Algebra.Order.Monoid.Defs
public import Mathlib.Algebra.Order.Monoid.Unbundled.WithTop
public import Mathlib.Algebra.Order.Ring.Defs
public import Mathlib.Order.Hom.Basic
public import Mathlib.Order.Interval.Set.Defs
public import Mathlib.Tactic.Inclusion.Core.ToSet
Expand All @@ -23,6 +24,15 @@ type represents a possibly unbounded interval with closed endpoints.

namespace Inclusion

-- local `grind` rules
attribute [local grind unfold] WithBot.some WithTop.some
attribute [local grind norm ←] WithBot.coe_zero WithTop.coe_zero
WithBot.none_eq_bot WithTop.none_eq_top
attribute [local grind norm] WithBot.coe_le_coe WithTop.coe_le_coe
attribute [local grind =] WithBot.coe_le_iff WithTop.le_coe_iff

local grind_pattern OrderEmbedding.le_iff_le => a ≤ b, f a, f b

variable {α β : Type*}

/-- An `Interval` represents a possibly unbounded interval with closed endpoints. -/
Expand All @@ -46,6 +56,13 @@ theorem Interval.mem_def [Preorder α] {x : α} {I : Interval α} :
def Interval.map (I : Interval α) (f : α → β) : Interval β :=
⟨WithBot.map f I.lb, WithTop.map f I.ub⟩

@[grind =]
theorem Interval.mem_map_iff [Preorder β] (f : α → β) {x : β} {I : Interval α} :
x ∈ I.map f ↔ (∀ a : α, I.lb = ↑a → f a ≤ x) ∧
(∀ a : α, I.ub = ↑a → x ≤ f a) := by
simp [Interval.map, WithBot.le_coe_iff, WithTop.coe_le_iff,
WithBot.map_eq_some_iff, WithTop.map_eq_some_iff]

/-- The interval unbounded on both sides. -/
def Interval.univ (α : Type*) : Interval α := ⟨⊥, ⊤⟩

Expand Down Expand Up @@ -85,16 +102,16 @@ def Interval.Ici (lb : WithBot α) : Interval α := ⟨lb, ⊤⟩

theorem Interval.mem_Iic_of_le [Preorder α] {x y : α} {I : Interval α}
(hxy : x ≤ y) (hy : y ∈ I) : x ∈ Interval.Iic I.ub := by
grind [Iic, bot_le, WithTop.coe_le_coe.mpr hxy]
grind [Interval.Iic, WithBot.le_coe_iff, WithTop.coe_le_iff]

theorem Interval.mem_Ici_of_le [Preorder α] {x y : α} {I : Interval α}
(hxy : x ≤ y) (hx : x ∈ I) : y ∈ Interval.Ici I.lb := by
grind [Ici, le_top, WithBot.coe_le_coe.mpr hxy]
grind [Interval.Ici, WithBot.le_coe_iff, WithTop.coe_le_iff]

theorem Interval.mem_Icc_of_le [Preorder α] {a b x : α} {I J : Interval α}
(ha : a ∈ I) (hax : a ≤ x) (hxb : x ≤ b) (hb : b ∈ J) :
x ∈ Interval.Icc I.lb J.ub := by
grind [Icc, WithBot.coe_le_coe.mpr hax, WithTop.coe_le_coe.mpr hxb]
grind [Interval.Icc, WithBot.le_coe_iff, WithTop.coe_le_iff]

theorem Interval.mem_Iic_of_lt [Preorder α] {x y : α} {I : Interval α}
(hxy : x < y) (hy : y ∈ I) : x ∈ Interval.Iic I.ub :=
Expand Down Expand Up @@ -148,6 +165,7 @@ instance [LinearOrder α] : Refine (Interval α) α where
refine := Interval.inter
mem_refine hs ht := ⟨max_le hs.1 ht.1, le_min hs.2 ht.2⟩

@[simp, grind =]
theorem Interval.map_inter [LinearOrder α] [LinearOrder β] (f : α ↪o β) (I J : Interval α) :
(I.inter J).map f = (I.map f).inter (J.map f) := by
simp [f.monotone.withBot_map.map_max, f.monotone.withTop_map.map_min,
Expand All @@ -156,40 +174,38 @@ theorem Interval.map_inter [LinearOrder α] [LinearOrder β] (f : α ↪o β) (I
theorem Interval.inter_mem [LinearOrder α] [LinearOrder β] (f : α ↪o β)
{x : β} {I J : Interval α} (hxI : x ∈ I.map f) (hxJ : x ∈ J.map f) :
x ∈ (I.inter J).map f := by
rw [Interval.map_inter]
exact Refine.mem_refine hxI hxJ
grind [Interval.inter, max_le, le_min]

/-- The convex hull of two intervals. -/
def Interval.hull [LinearOrder α] (I J : Interval α) : Interval α :=
⟨min I.lb J.lb, max I.ub J.ub⟩

theorem Interval.mem_hull_left [LinearOrder α] {x : α} {I J : Interval α} (hx : x ∈ I) :
x ∈ I.hull J := by
grind [Interval.hull]
grind [Interval.hull, min_le_left, le_max_left]

theorem Interval.mem_hull_right [LinearOrder α] {x : α} {I J : Interval α} (hx : x ∈ J) :
x ∈ I.hull J := by
grind [Interval.hull]
grind [Interval.hull, min_le_right, le_max_right]

instance [LinearOrder α] : Coarsen (Interval α) α where
coarsen := Interval.hull
mem_coarsen_left := Interval.mem_hull_left
mem_coarsen_right := Interval.mem_hull_right

@[simp, grind =]
theorem Interval.map_hull [LinearOrder α] [LinearOrder β] (f : α ↪o β) (I J : Interval α) :
(I.hull J).map f = (I.map f).hull (J.map f) := by
simp [f.monotone.withBot_map.map_min, f.monotone.withTop_map.map_max,
Interval.hull, Interval.map]

theorem Interval.hull_mem_left [LinearOrder α] [LinearOrder β] (f : α ↪o β)
{x : β} {I J : Interval α} (hx : x ∈ I.map f) : x ∈ (I.hull J).map f := by
rw [Interval.map_hull]
exact Interval.mem_hull_left hx
simpa using Interval.mem_hull_left hx

theorem Interval.hull_mem_right [LinearOrder α] [LinearOrder β] (f : α ↪o β)
{x : β} {I J : Interval α} (hx : x ∈ J.map f) : x ∈ (I.hull J).map f := by
rw [Interval.map_hull]
exact Interval.mem_hull_right hx
simpa using Interval.mem_hull_right hx

/-- Add two intervals. -/
def Interval.add [Add α] (I J : Interval α) : Interval α where
Expand All @@ -211,9 +227,7 @@ theorem Interval.add_ub [AddZero α] (I J : Interval α) : (I.add J).ub = I.ub +
theorem Interval.add_mem [AddZero α] [AddCommMonoid β] [Preorder β] [IsOrderedAddMonoid β]
(f : α →+ β) {x y : β} {I J : Interval α} (hx : x ∈ I.map f) (hy : y ∈ J.map f) :
x + y ∈ (I.add J).map f := by
constructor
· simpa [Interval.map] using add_le_add hx.1 hy.1
· simpa [Interval.map] using add_le_add hx.2 hy.2
grind [Interval.add, add_le_add]

/-- Negate an interval. -/
def Interval.neg [Neg α] (I : Interval α) : Interval α where
Expand All @@ -226,15 +240,7 @@ def Interval.neg [Neg α] (I : Interval α) : Interval α where

theorem Interval.neg_mem [AddGroup α] [AddCommGroup β] [Preorder β] [IsOrderedAddMonoid β]
(f : α →+ β) {x : β} {I : Interval α} (hx : x ∈ I.map f) : -x ∈ I.neg.map f := by
constructor
· rcases I with ⟨il, _ | iu⟩
· simp [Interval.neg, Interval.map]
apply WithBot.coe_le_coe.mpr
simpa using neg_le_neg_iff.mpr (WithTop.coe_le_coe.mp hx.2)
· rcases I with ⟨_ | il, iu⟩
· simp [Interval.neg, Interval.map]
apply WithTop.coe_le_coe.mpr
simpa using neg_le_neg_iff.mpr (WithBot.coe_le_coe.mp hx.1)
grind [Interval.neg, neg_le_neg_iff]

/-- Subtract one interval from another. -/
def Interval.sub [Sub α] (I J : Interval α) : Interval α where
Expand All @@ -246,16 +252,89 @@ def Interval.sub [Sub α] (I J : Interval α) : Interval α where
| _, _ => ⊤

theorem Interval.sub_eq_add_neg [AddGroup α] (I J : Interval α) : I.sub J = I.add J.neg := by
rcases I with ⟨_ | il, _ | iu⟩ <;>
rcases J with ⟨_ | jl, _ | ju⟩ <;>
simp [Interval.sub, Interval.add, Interval.neg, _root_.sub_eq_add_neg]
grind [Interval.sub, Interval.add, Interval.neg, _root_.sub_eq_add_neg]

theorem Interval.sub_mem [AddGroup α] [AddCommGroup β] [Preorder β] [IsOrderedAddMonoid β]
(f : α →+ β) {x y : β} {I J : Interval α}
(hx : x ∈ I.map f) (hy : y ∈ J.map f) : x - y ∈ (I.sub J).map f := by
rw [_root_.sub_eq_add_neg, Interval.sub_eq_add_neg]
exact Interval.add_mem f hx (Interval.neg_mem f hy)

/-- Multiply two finite or infinite interval bounds. -/
def Interval.mulBound [Mul α] [Zero α] [DecidableEq α] :
Option α → Option α → Option α
| some a, some b => some (a * b)
| some a, none => if a = 0 then some 0 else none
| none, some b => if b = 0 then some 0 else none
| none, none => none

@[to_dual le_map_mulBound]
theorem Interval.map_mulBound_le [Mul α] [Zero α] [DecidableEq α] [LE β]
(f : α → β) (a b : Option α) {z : β}
(hmul : ∀ x y, a = some x → b = some y → f (x * y) ≤ z)
(hzero : (a = none ∧ b = some 0 ∨ a = some 0 ∧ b = none) → f 0 ≤ z) :
WithBot.map f (Interval.mulBound a b : WithBot α) ≤ z := by
cases a <;> cases b <;>
grind [Interval.mulBound, WithBot.map_eq_some_iff, WithBot.le_coe_iff]

/-- Multiply two intervals. -/
def Interval.mul [Mul α] [Zero α] [LinearOrder α] (I J : Interval α) : Interval α :=
if 0 ≤ I.lb then
if 0 ≤ J.lb then
⟨Interval.mulBound I.lb J.lb, Interval.mulBound I.ub J.ub⟩
else if J.ub ≤ 0 then
⟨Interval.mulBound I.ub J.lb, Interval.mulBound I.lb J.ub⟩
else
⟨Interval.mulBound I.ub J.lb, Interval.mulBound I.ub J.ub⟩
else if I.ub ≤ 0 then
if 0 ≤ J.lb then
⟨Interval.mulBound I.lb J.ub, Interval.mulBound I.ub J.lb⟩
else if J.ub ≤ 0 then
⟨Interval.mulBound I.ub J.ub, Interval.mulBound I.lb J.lb⟩
else
⟨Interval.mulBound I.lb J.ub, Interval.mulBound I.lb J.lb⟩
else
if 0 ≤ J.lb then
⟨Interval.mulBound I.lb J.ub, Interval.mulBound I.ub J.ub⟩
else if J.ub ≤ 0 then
⟨Interval.mulBound I.ub J.lb, Interval.mulBound I.lb J.lb⟩
else
⟨min (Interval.mulBound I.lb J.ub) (Interval.mulBound I.ub J.lb),
max (Interval.mulBound I.lb J.lb) (Interval.mulBound I.ub J.ub)⟩

theorem Interval.mul_mem [Mul α] [Zero α] [LinearOrder α] [Ring β] [LinearOrder β]
[IsStrictOrderedRing β] (f : α ↪o β) (map_zero : f 0 = 0)
(map_mul : ∀ a b, f (a * b) = f a * f b) {x y : β} {I J : Interval α}
(hx : x ∈ I.map f) (hy : y ∈ J.map f) : x * y ∈ (I.mul J).map f := by
unfold Interval.mul
split_ifs <;> constructor
· apply Interval.map_mulBound_le <;> grind [mul_le_mul]
· apply Interval.le_map_mulBound <;> grind [mul_le_mul]
· apply Interval.map_mulBound_le <;> grind [mul_le_mul_of_nonneg_of_nonpos]
· apply Interval.le_map_mulBound <;> grind [mul_le_mul_of_nonneg_of_nonpos]
· apply Interval.map_mulBound_le <;> grind [mul_le_mul_of_nonneg_of_nonpos]
· apply Interval.le_map_mulBound <;> grind [mul_le_mul_of_nonneg]
· apply Interval.map_mulBound_le <;> grind [mul_le_mul_of_nonpos_of_nonneg]
· apply Interval.le_map_mulBound <;> grind [mul_le_mul_of_nonpos_of_nonneg]
· apply Interval.map_mulBound_le <;> grind [mul_le_mul_of_nonpos_of_nonpos']
· apply Interval.le_map_mulBound <;> grind [mul_le_mul_of_nonpos_of_nonpos]
· apply Interval.map_mulBound_le <;> grind [mul_le_mul_of_nonpos_of_nonneg]
· apply Interval.le_map_mulBound <;> grind [mul_le_mul_of_nonpos_of_nonpos']
· apply Interval.map_mulBound_le <;> grind [mul_le_mul_of_nonpos_of_nonneg'']
· apply Interval.le_map_mulBound <;> grind [mul_le_mul]
· apply Interval.map_mulBound_le <;> grind [mul_le_mul_of_nonneg_of_nonpos']
· apply Interval.le_map_mulBound <;> grind [mul_le_mul_of_nonpos_of_nonpos]
· by_cases hy0 : 0 ≤ y
· apply (f.monotone.withBot_map (min_le_left _ _)).trans
apply Interval.map_mulBound_le <;> grind [mul_le_mul_of_nonpos_of_nonneg'']
· apply (f.monotone.withBot_map (min_le_right _ _)).trans
apply Interval.map_mulBound_le <;> grind [mul_le_mul_of_nonneg_of_nonpos']
· by_cases hy0 : 0 ≤ y
· apply (f.monotone.withTop_map (le_max_right _ _)).trans'
apply Interval.le_map_mulBound <;> grind [mul_le_mul_of_nonneg']
· apply (f.monotone.withTop_map (le_max_left _ _)).trans'
apply Interval.le_map_mulBound <;> grind [mul_le_mul_of_nonpos_of_nonpos]

/-- Check if `r x y` is false is implied by `x ∈ I` and `y ∈ J` -/
def Interval.orderRelFalse (r : α → α → Prop) [DecidableRel r]
(I J : Interval α) : IntervalBool :=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ theorem neg_mem {x : ℝ} {I : Interval Dyadic} (hx : x ∈ I) : -x ∈ I.neg :=
theorem sub_mem {x y : ℝ} {I J : Interval Dyadic} (hx : x ∈ I) (hy : y ∈ J) : x - y ∈ I.sub J :=
Interval.sub_mem Dyadic.toRealAddMonoidHom hx hy

@[inclusion_op interval_dyadic_real]
theorem mul_mem {x y : ℝ} {I J : Interval Dyadic} (hx : x ∈ I) (hy : y ∈ J) : x * y ∈ I.mul J :=
Interval.mul_mem Dyadic.toRealOrderEmbedding (map_zero Dyadic.toRealAddMonoidHom)
Dyadic.toReal_mul hx hy

end Arithmetic

section Props
Expand Down
14 changes: 14 additions & 0 deletions MathlibTest/Tactic/Inclusion/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ example {x : ℝ} (hx : x ∈ (⟨1, 2⟩ : Interval Dyadic)) : x + x ≤ 4 := b
example {x y : ℝ} (hx : x ∈ Set.Icc 1 2) (hy : y ∈ Set.Icc 3 4) :
x + y ∈ Set.Icc 4 6 := by dyadic_interval

example {x y : ℝ} (hx : x ∈ Set.Icc 1 2) (hy : y ∈ Set.Icc 3 4) :
x * y ∈ Set.Icc 3 8 := by dyadic_interval

example {x y : ℝ} (hx : x ∈ Set.Icc (-2) 3) (hy : y ∈ Set.Icc (-5) 7) :
x * y ∈ Set.Icc (-15) 21 := by dyadic_interval

example {x y : ℝ} (hx : 3 ≤ x) (hy : 2 ≤ y) : 6 ≤ x * y := by dyadic_interval

example {x : ℝ} (hx : x ∈ Set.Icc (-2) 1) : -x ∈ Set.Icc (-1) 2 := by dyadic_interval

example {x y : ℝ} (hx₀ : 2 ≤ x) (hx₁ : x ≤ 3) (hy₀ : 0 ≤ y) (hy₁ : y ≤ 1) :
Expand All @@ -118,6 +126,9 @@ example {x y z : ℝ} (hx : x ∈ Set.Ico 0 1) (hy : y ∈ Set.Ioc 1 2)
example {x y z : ℝ} (hx₀ : -2 ≤ x) (hx₁ : x ≤ 1) (hy₀ : 1 ≤ y) (hy₁ : y ≤ 3)
(hz₀ : 4 ≤ z) (hz₁ : z ≤ 5) : x + y - z ∈ Set.Icc (-6) 0 := by dyadic_interval

example {x y z : ℝ} (hx₀ : -2 ≤ x) (hx₁ : x ≤ 3) (hy : y ∈ Set.Icc 1 4)
(hz : z ∈ Set.Icc (-1) 2) : x * y + z ∈ Set.Icc (-9) 14 := by dyadic_interval

example {x y : ℝ} (hx₀ : x ≤ 3) (hx₁ : x ≤ 2) (hy₀ : 0 ≤ y) (hy₁ : 1 ≤ y) :
x - y ≤ 1 := by dyadic_interval

Expand All @@ -127,6 +138,9 @@ example {x : ℝ} (hx₀ : 1 ≤ x) (hx₁ : x ≤ 2) :
example {x y : ℝ} (hx : x ≤ 1.25) (hy : 0.5 ≤ y) :
x - y + 2.5 ≤ 3.25 := by dyadic_interval [prec := 2]

example {x y : ℝ} (hx₀ : 1 ≤ x) (hx₁ : x ≤ 2) (hy : y ∈ Set.Icc 0.5 1.25) :
x * y + ((1 / 3 : ℚ) : ℝ) ∈ Set.Icc 0.8 2.9 := by dyadic_interval [prec := 12]

end Arithmetic

section Splitting
Expand Down
Loading