l3lab/ntp-mathlib huggingface dataset:
theorem treesOfNumNodesEq_card_eq_catalan (n : ℕ) : (treesOfNumNodesEq n).card = catalan n := by
  induction' n using Nat.case_strong_induction_on with n ih
  · simp
  rw [treesOfNumNodesEq_succ, card_biUnion, catalan_succ']
  · apply sum_congr rfl
    rintro ⟨i, j⟩ H
    rw [card_map, card_product, ih _ (fst_le H), ih _ (snd_le H)]
  · simp_rw [disjoint_left]
    rintro ⟨i, j⟩ _ ⟨i', j'⟩ _
    -- Porting note: was clear * -; tidy
    intros h a
    cases' a with a l r
    · intro h; simp at h
    · intro h1 h2
      apply h
      trans (numNodes l, numNodes r)
      · simp at h1; simp [h1]
      · simp at h2; 

Proof state:
n : ℕ
ih : ∀ m ≤ n, card (treesOfNumNodesEq m) = catalan m
i j : ℕ
a✝¹ : (i, j) ∈ antidiagonal n
i' j' : ℕ
a✝ : (i', j') ∈ antidiagonal n
h : (i, j) ≠ (i', j')
a : Unit
l r : Tree Unit
h1 : node a l r ∈ pairwiseNode (treesOfNumNodesEq (i, j).1) (treesOfNumNodesEq (i, j).2)
h2 : numNodes l = i' ∧ numNodes r = j'
⊢ (numNodes l, numNodes r) = (i', j')

Next tactic:
simp [h2]
theorem integralSum_biUnionTagged (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) (π : Prepartition I)
    (πi : ∀ J, TaggedPrepartition J) :
    integralSum f vol (π.biUnionTagged πi) = ∑ J in π.boxes, integralSum f vol (πi J) := by
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
I J : Box ι
π✝ : TaggedPrepartition I
f : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
π : Prepartition I
πi : (J : Box ι) → TaggedPrepartition J
⊢ integralSum f vol (Prepartition.biUnionTagged π πi) = ∑ J in π.boxes, integralSum f vol (πi J)

Next tactic:
refine (π.sum_biUnion_boxes _ _).trans <| sum_congr rfl fun J hJ => sum_congr rfl fun J' hJ' => ?_
theorem integralSum_biUnionTagged (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) (π : Prepartition I)
    (πi : ∀ J, TaggedPrepartition J) :
    integralSum f vol (π.biUnionTagged πi) = ∑ J in π.boxes, integralSum f vol (πi J) := by
  refine (π.sum_biUnion_boxes _ _).trans <| sum_congr rfl fun J hJ => sum_congr rfl fun J' hJ' => ?_
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
I J✝ : Box ι
π✝ : TaggedPrepartition I
f : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
π : Prepartition I
πi : (J : Box ι) → TaggedPrepartition J
J : Box ι
hJ : J ∈ π.boxes
J' : Box ι
hJ' : J' ∈ (πi J).boxes
⊢ (vol J') (f (tag (Prepartition.biUnionTagged π πi) J')) = (vol J') (f (tag (πi J) J'))

Next tactic:
rw [π.tag_biUnionTagged hJ hJ']
theorem integralSum_biUnion_partition (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F)
    (π : TaggedPrepartition I) (πi : ∀ J, Prepartition J) (hπi : ∀ J ∈ π, (πi J).IsPartition) :
    integralSum f vol (π.biUnionPrepartition πi) = integralSum f vol π := by
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
I J : Box ι
π✝ : TaggedPrepartition I
f : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
π : TaggedPrepartition I
πi : (J : Box ι) → Prepartition J
hπi : ∀ J ∈ π, Prepartition.IsPartition (πi J)
⊢ integralSum f vol (biUnionPrepartition π πi) = integralSum f vol π

Next tactic:
refine' (π.sum_biUnion_boxes _ _).trans (sum_congr rfl fun J hJ => _)
theorem integralSum_biUnion_partition (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F)
    (π : TaggedPrepartition I) (πi : ∀ J, Prepartition J) (hπi : ∀ J ∈ π, (πi J).IsPartition) :
    integralSum f vol (π.biUnionPrepartition πi) = integralSum f vol π := by
  refine' (π.sum_biUnion_boxes _ _).trans (sum_congr rfl fun J hJ => _)
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
I J✝ : Box ι
π✝ : TaggedPrepartition I
f : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
π : TaggedPrepartition I
πi : (J : Box ι) → Prepartition J
hπi : ∀ J ∈ π, Prepartition.IsPartition (πi J)
J : Box ι
hJ : J ∈ π.boxes
⊢ ∑ J' in (πi J).boxes, (vol J') (f (tag (biUnionPrepartition π πi) J')) = (vol J) (f (tag π J))

Next tactic:
calc
    (∑ J' in (πi J).boxes, vol J' (f (π.tag <| π.toPrepartition.biUnionIndex πi J'))) =
        ∑ J' in (πi J).boxes, vol J' (f (π.tag J)) :=
      sum_congr rfl fun J' hJ' => by rw [Prepartition.biUnionIndex_of_mem _ hJ hJ']
    _ = vol J (f (π.tag J)) :=
      (vol.map ⟨⟨fun g : E →L[ℝ] F => g (f (π.tag J)), rfl⟩, fun _ _ => rfl⟩).sum_partition_boxes
        le_top (hπi J hJ)
theorem integralSum_biUnion_partition (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F)
    (π : TaggedPrepartition I) (πi : ∀ J, Prepartition J) (hπi : ∀ J ∈ π, (πi J).IsPartition) :
    integralSum f vol (π.biUnionPrepartition πi) = integralSum f vol π := by
  refine' (π.sum_biUnion_boxes _ _).trans (sum_congr rfl fun J hJ => _)
  calc
    (∑ J' in (πi J).boxes, vol J' (f (π.tag <| π.toPrepartition.biUnionIndex πi J'))) =
        ∑ J' in (πi J).boxes, vol J' (f (π.tag J)) :=
      sum_congr rfl fun J' hJ' => by 

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
I J✝ : Box ι
π✝ : TaggedPrepartition I
f : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
π : TaggedPrepartition I
πi : (J : Box ι) → Prepartition J
hπi : ∀ J ∈ π, Prepartition.IsPartition (πi J)
J : Box ι
hJ : J ∈ π.boxes
J' : Box ι
hJ' : J' ∈ (πi J).boxes
⊢ (vol J') (f (tag π (Prepartition.biUnionIndex π.toPrepartition πi J'))) = (vol J') (f (tag π J))

Next tactic:
rw [Prepartition.biUnionIndex_of_mem _ hJ hJ']
theorem integralSum_sub_partitions (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F)
    {π₁ π₂ : TaggedPrepartition I} (h₁ : π₁.IsPartition) (h₂ : π₂.IsPartition) :
    integralSum f vol π₁ - integralSum f vol π₂ =
      ∑ J in (π₁.toPrepartition ⊓ π₂.toPrepartition).boxes,
        (vol J (f <| (π₁.infPrepartition π₂.toPrepartition).tag J) -
          vol J (f <| (π₂.infPrepartition π₁.toPrepartition).tag J)) := by
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
I J : Box ι
π : TaggedPrepartition I
f : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
π₁ π₂ : TaggedPrepartition I
h₁ : IsPartition π₁
h₂ : IsPartition π₂
⊢ integralSum f vol π₁ - integralSum f vol π₂ =
    ∑ J in (π₁.toPrepartition ⊓ π₂.toPrepartition).boxes,
      ((vol J) (f (tag (infPrepartition π₁ π₂.toPrepartition) J)) -
        (vol J) (f (tag (infPrepartition π₂ π₁.toPrepartition) J)))

Next tactic:
rw [← integralSum_inf_partition f vol π₁ h₂, ← integralSum_inf_partition f vol π₂ h₁,
    integralSum, integralSum, Finset.sum_sub_distrib]
theorem integralSum_sub_partitions (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F)
    {π₁ π₂ : TaggedPrepartition I} (h₁ : π₁.IsPartition) (h₂ : π₂.IsPartition) :
    integralSum f vol π₁ - integralSum f vol π₂ =
      ∑ J in (π₁.toPrepartition ⊓ π₂.toPrepartition).boxes,
        (vol J (f <| (π₁.infPrepartition π₂.toPrepartition).tag J) -
          vol J (f <| (π₂.infPrepartition π₁.toPrepartition).tag J)) := by
  rw [← integralSum_inf_partition f vol π₁ h₂, ← integralSum_inf_partition f vol π₂ h₁,
    integralSum, integralSum, Finset.sum_sub_distrib]
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
I J : Box ι
π : TaggedPrepartition I
f : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
π₁ π₂ : TaggedPrepartition I
h₁ : IsPartition π₁
h₂ : IsPartition π₂
⊢ ∑ J in (infPrepartition π₁ π₂.toPrepartition).toPrepartition.boxes,
        (vol J) (f (tag (infPrepartition π₁ π₂.toPrepartition) J)) -
      ∑ J in (infPrepartition π₂ π₁.toPrepartition).toPrepartition.boxes,
        (vol J) (f (tag (infPrepartition π₂ π₁.toPrepartition) J)) =
    ∑ x in (π₁.toPrepartition ⊓ π₂.toPrepartition).boxes, (vol x) (f (tag (infPrepartition π₁ π₂.toPrepartition) x)) -
      ∑ x in (π₁.toPrepartition ⊓ π₂.toPrepartition).boxes, (vol x) (f (tag (infPrepartition π₂ π₁.toPrepartition) x))

Next tactic:
simp only [infPrepartition_toPrepartition, inf_comm]
@[simp]
theorem integralSum_disjUnion (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) {π₁ π₂ : TaggedPrepartition I}
    (h : Disjoint π₁.iUnion π₂.iUnion) :
    integralSum f vol (π₁.disjUnion π₂ h) = integralSum f vol π₁ + integralSum f vol π₂ := by
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
I J : Box ι
π : TaggedPrepartition I
f : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
π₁ π₂ : TaggedPrepartition I
h : Disjoint (TaggedPrepartition.iUnion π₁) (TaggedPrepartition.iUnion π₂)
⊢ integralSum f vol (TaggedPrepartition.disjUnion π₁ π₂ h) = integralSum f vol π₁ + integralSum f vol π₂

Next tactic:
refine' (Prepartition.sum_disj_union_boxes h _).trans
      (congr_arg₂ (· + ·) (sum_congr rfl fun J hJ => _) (sum_congr rfl fun J hJ => _))
@[simp]
theorem integralSum_disjUnion (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) {π₁ π₂ : TaggedPrepartition I}
    (h : Disjoint π₁.iUnion π₂.iUnion) :
    integralSum f vol (π₁.disjUnion π₂ h) = integralSum f vol π₁ + integralSum f vol π₂ := by
  refine' (Prepartition.sum_disj_union_boxes h _).trans
      (congr_arg₂ (· + ·) (sum_congr rfl fun J hJ => _) (sum_congr rfl fun J hJ => _))
  · 

Proof state:
case refine'_1
ι : Type u
E : Type v
F : Type w
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
I J✝ : Box ι
π : TaggedPrepartition I
f : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
π₁ π₂ : TaggedPrepartition I
h : Disjoint (TaggedPrepartition.iUnion π₁) (TaggedPrepartition.iUnion π₂)
J : Box ι
hJ : J ∈ π₁.boxes
⊢ (vol J) (f (tag (TaggedPrepartition.disjUnion π₁ π₂ h) J)) = (vol J) (f (tag π₁ J))

Next tactic:
rw [disjUnion_tag_of_mem_left _ hJ]
@[simp]
theorem integralSum_disjUnion (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) {π₁ π₂ : TaggedPrepartition I}
    (h : Disjoint π₁.iUnion π₂.iUnion) :
    integralSum f vol (π₁.disjUnion π₂ h) = integralSum f vol π₁ + integralSum f vol π₂ := by
  refine' (Prepartition.sum_disj_union_boxes h _).trans
      (congr_arg₂ (· + ·) (sum_congr rfl fun J hJ => _) (sum_congr rfl fun J hJ => _))
  · rw [disjUnion_tag_of_mem_left _ hJ]
  · 

Proof state:
case refine'_2
ι : Type u
E : Type v
F : Type w
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
I J✝ : Box ι
π : TaggedPrepartition I
f : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
π₁ π₂ : TaggedPrepartition I
h : Disjoint (TaggedPrepartition.iUnion π₁) (TaggedPrepartition.iUnion π₂)
J : Box ι
hJ : J ∈ π₂.boxes
⊢ (vol J) (f (tag (TaggedPrepartition.disjUnion π₁ π₂ h) J)) = (vol J) (f (tag π₂ J))

Next tactic:
rw [disjUnion_tag_of_mem_right _ hJ]
@[simp]
theorem integralSum_add (f g : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) (π : TaggedPrepartition I) :
    integralSum (f + g) vol π = integralSum f vol π + integralSum g vol π := by
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
I J : Box ι
π✝ : TaggedPrepartition I
f g : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
π : TaggedPrepartition I
⊢ integralSum (f + g) vol π = integralSum f vol π + integralSum g vol π

Next tactic:
simp only [integralSum, Pi.add_apply, (vol _).map_add, Finset.sum_add_distrib]
@[simp]
theorem integralSum_neg (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) (π : TaggedPrepartition I) :
    integralSum (-f) vol π = -integralSum f vol π := by
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
I J : Box ι
π✝ : TaggedPrepartition I
f : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
π : TaggedPrepartition I
⊢ integralSum (-f) vol π = -integralSum f vol π

Next tactic:
simp only [integralSum, Pi.neg_apply, (vol _).map_neg, Finset.sum_neg_distrib]
@[simp]
theorem integralSum_smul (c : ℝ) (f : ℝⁿ → E) (vol : ι →ᵇᵃ E →L[ℝ] F) (π : TaggedPrepartition I) :
    integralSum (c • f) vol π = c • integralSum f vol π := by
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
I J : Box ι
π✝ : TaggedPrepartition I
c : ℝ
f : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
π : TaggedPrepartition I
⊢ integralSum (c • f) vol π = c • integralSum f vol π

Next tactic:
simp only [integralSum, Finset.smul_sum, Pi.smul_apply, ContinuousLinearMap.map_smul]
/-- The `ε`-`δ` definition of `BoxIntegral.HasIntegral`. -/
theorem hasIntegral_iff : HasIntegral I l f vol y ↔
    ∀ ε > (0 : ℝ), ∃ r : ℝ≥0 → ℝⁿ → Ioi (0 : ℝ), (∀ c, l.RCond (r c)) ∧
      ∀ c π, l.MemBaseSet I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ ε :=
  ((l.hasBasis_toFilteriUnion_top I).tendsto_iff nhds_basis_closedBall).trans <| by
    

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : NormedAddCommGroup F
inst✝¹ : NormedSpace ℝ F
I J : Box ι
π : TaggedPrepartition I
inst✝ : Fintype ι
l : IntegrationParams
f g : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
y y' : F
⊢ (∀ (ib : ℝ),
      0 < ib →
        ∃ ia,
          (∀ (c : ℝ≥0), RCond l (ia c)) ∧
            ∀ x ∈ {π | ∃ c, MemBaseSet l I c (ia c) π ∧ IsPartition π}, integralSum f vol x ∈ closedBall y ib) ↔
    ∀ ε > 0,
      ∃ r,
        (∀ (c : ℝ≥0), RCond l (r c)) ∧
          ∀ (c : ℝ≥0) (π : TaggedPrepartition I),
            MemBaseSet l I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ ε

Next tactic:
simp [@forall_swap ℝ≥0 (TaggedPrepartition I)]
/-- Quite often it is more natural to prove an estimate of the form `a * ε`, not `ε` in the RHS of
`BoxIntegral.hasIntegral_iff`, so we provide this auxiliary lemma.  -/
theorem HasIntegral.of_mul (a : ℝ)
    (h : ∀ ε : ℝ, 0 < ε → ∃ r : ℝ≥0 → ℝⁿ → Ioi (0 : ℝ), (∀ c, l.RCond (r c)) ∧ ∀ c π,
      l.MemBaseSet I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ a * ε) :
    HasIntegral I l f vol y := by
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : NormedAddCommGroup F
inst✝¹ : NormedSpace ℝ F
I J : Box ι
π : TaggedPrepartition I
inst✝ : Fintype ι
l : IntegrationParams
f g : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
y y' : F
a : ℝ
h :
  ∀ (ε : ℝ),
    0 < ε →
      ∃ r,
        (∀ (c : ℝ≥0), RCond l (r c)) ∧
          ∀ (c : ℝ≥0) (π : TaggedPrepartition I),
            MemBaseSet l I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ a * ε
⊢ HasIntegral I l f vol y

Next tactic:
refine' hasIntegral_iff.2 fun ε hε => _
/-- Quite often it is more natural to prove an estimate of the form `a * ε`, not `ε` in the RHS of
`BoxIntegral.hasIntegral_iff`, so we provide this auxiliary lemma.  -/
theorem HasIntegral.of_mul (a : ℝ)
    (h : ∀ ε : ℝ, 0 < ε → ∃ r : ℝ≥0 → ℝⁿ → Ioi (0 : ℝ), (∀ c, l.RCond (r c)) ∧ ∀ c π,
      l.MemBaseSet I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ a * ε) :
    HasIntegral I l f vol y := by
  refine' hasIntegral_iff.2 fun ε hε => _
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : NormedAddCommGroup F
inst✝¹ : NormedSpace ℝ F
I J : Box ι
π : TaggedPrepartition I
inst✝ : Fintype ι
l : IntegrationParams
f g : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
y y' : F
a : ℝ
h :
  ∀ (ε : ℝ),
    0 < ε →
      ∃ r,
        (∀ (c : ℝ≥0), RCond l (r c)) ∧
          ∀ (c : ℝ≥0) (π : TaggedPrepartition I),
            MemBaseSet l I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ a * ε
ε : ℝ
hε : ε > 0
⊢ ∃ r,
    (∀ (c : ℝ≥0), RCond l (r c)) ∧
      ∀ (c : ℝ≥0) (π : TaggedPrepartition I),
        MemBaseSet l I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ ε

Next tactic:
rcases exists_pos_mul_lt hε a with ⟨ε', hε', ha⟩
/-- Quite often it is more natural to prove an estimate of the form `a * ε`, not `ε` in the RHS of
`BoxIntegral.hasIntegral_iff`, so we provide this auxiliary lemma.  -/
theorem HasIntegral.of_mul (a : ℝ)
    (h : ∀ ε : ℝ, 0 < ε → ∃ r : ℝ≥0 → ℝⁿ → Ioi (0 : ℝ), (∀ c, l.RCond (r c)) ∧ ∀ c π,
      l.MemBaseSet I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ a * ε) :
    HasIntegral I l f vol y := by
  refine' hasIntegral_iff.2 fun ε hε => _
  rcases exists_pos_mul_lt hε a with ⟨ε', hε', ha⟩
  

Proof state:
case intro.intro
ι : Type u
E : Type v
F : Type w
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : NormedAddCommGroup F
inst✝¹ : NormedSpace ℝ F
I J : Box ι
π : TaggedPrepartition I
inst✝ : Fintype ι
l : IntegrationParams
f g : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
y y' : F
a : ℝ
h :
  ∀ (ε : ℝ),
    0 < ε →
      ∃ r,
        (∀ (c : ℝ≥0), RCond l (r c)) ∧
          ∀ (c : ℝ≥0) (π : TaggedPrepartition I),
            MemBaseSet l I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ a * ε
ε : ℝ
hε : ε > 0
ε' : ℝ
hε' : 0 < ε'
ha : a * ε' < ε
⊢ ∃ r,
    (∀ (c : ℝ≥0), RCond l (r c)) ∧
      ∀ (c : ℝ≥0) (π : TaggedPrepartition I),
        MemBaseSet l I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ ε

Next tactic:
rcases h ε' hε' with ⟨r, hr, H⟩
/-- Quite often it is more natural to prove an estimate of the form `a * ε`, not `ε` in the RHS of
`BoxIntegral.hasIntegral_iff`, so we provide this auxiliary lemma.  -/
theorem HasIntegral.of_mul (a : ℝ)
    (h : ∀ ε : ℝ, 0 < ε → ∃ r : ℝ≥0 → ℝⁿ → Ioi (0 : ℝ), (∀ c, l.RCond (r c)) ∧ ∀ c π,
      l.MemBaseSet I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ a * ε) :
    HasIntegral I l f vol y := by
  refine' hasIntegral_iff.2 fun ε hε => _
  rcases exists_pos_mul_lt hε a with ⟨ε', hε', ha⟩
  rcases h ε' hε' with ⟨r, hr, H⟩
  

Proof state:
case intro.intro.intro.intro
ι : Type u
E : Type v
F : Type w
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : NormedAddCommGroup F
inst✝¹ : NormedSpace ℝ F
I J : Box ι
π : TaggedPrepartition I
inst✝ : Fintype ι
l : IntegrationParams
f g : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
y y' : F
a : ℝ
h :
  ∀ (ε : ℝ),
    0 < ε →
      ∃ r,
        (∀ (c : ℝ≥0), RCond l (r c)) ∧
          ∀ (c : ℝ≥0) (π : TaggedPrepartition I),
            MemBaseSet l I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ a * ε
ε : ℝ
hε : ε > 0
ε' : ℝ
hε' : 0 < ε'
ha : a * ε' < ε
r : ℝ≥0 → (ι → ℝ) → ↑(Set.Ioi 0)
hr : ∀ (c : ℝ≥0), RCond l (r c)
H :
  ∀ (c : ℝ≥0) (π : TaggedPrepartition I),
    MemBaseSet l I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ a * ε'
⊢ ∃ r,
    (∀ (c : ℝ≥0), RCond l (r c)) ∧
      ∀ (c : ℝ≥0) (π : TaggedPrepartition I),
        MemBaseSet l I c (r c) π → IsPartition π → dist (integralSum f vol π) y ≤ ε

Next tactic:
exact ⟨r, hr, fun c π hπ hπp => (H c π hπ hπp).trans ha.le⟩
/-- In a complete space, a function is integrable if and only if its integral sums form a Cauchy
net. Here we restate this fact in terms of `∀ ε > 0, ∃ r, ...`. -/
theorem integrable_iff_cauchy_basis [CompleteSpace F] : Integrable I l f vol ↔
    ∀ ε > (0 : ℝ), ∃ r : ℝ≥0 → ℝⁿ → Ioi (0 : ℝ), (∀ c, l.RCond (r c)) ∧
      ∀ c₁ c₂ π₁ π₂, l.MemBaseSet I c₁ (r c₁) π₁ → π₁.IsPartition → l.MemBaseSet I c₂ (r c₂) π₂ →
        π₂.IsPartition → dist (integralSum f vol π₁) (integralSum f vol π₂) ≤ ε := by
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : NormedSpace ℝ E
inst✝³ : NormedAddCommGroup F
inst✝² : NormedSpace ℝ F
I J : Box ι
π : TaggedPrepartition I
inst✝¹ : Fintype ι
l : IntegrationParams
f g : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
y y' : F
inst✝ : CompleteSpace F
⊢ Integrable I l f vol ↔
    ∀ ε > 0,
      ∃ r,
        (∀ (c : ℝ≥0), RCond l (r c)) ∧
          ∀ (c₁ c₂ : ℝ≥0) (π₁ π₂ : TaggedPrepartition I),
            MemBaseSet l I c₁ (r c₁) π₁ →
              IsPartition π₁ →
                MemBaseSet l I c₂ (r c₂) π₂ → IsPartition π₂ → dist (integralSum f vol π₁) (integralSum f vol π₂) ≤ ε

Next tactic:
rw [integrable_iff_cauchy, cauchy_map_iff',
    (l.hasBasis_toFilteriUnion_top _).prod_self.tendsto_iff uniformity_basis_dist_le]
/-- In a complete space, a function is integrable if and only if its integral sums form a Cauchy
net. Here we restate this fact in terms of `∀ ε > 0, ∃ r, ...`. -/
theorem integrable_iff_cauchy_basis [CompleteSpace F] : Integrable I l f vol ↔
    ∀ ε > (0 : ℝ), ∃ r : ℝ≥0 → ℝⁿ → Ioi (0 : ℝ), (∀ c, l.RCond (r c)) ∧
      ∀ c₁ c₂ π₁ π₂, l.MemBaseSet I c₁ (r c₁) π₁ → π₁.IsPartition → l.MemBaseSet I c₂ (r c₂) π₂ →
        π₂.IsPartition → dist (integralSum f vol π₁) (integralSum f vol π₂) ≤ ε := by
  rw [integrable_iff_cauchy, cauchy_map_iff',
    (l.hasBasis_toFilteriUnion_top _).prod_self.tendsto_iff uniformity_basis_dist_le]
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : NormedSpace ℝ E
inst✝³ : NormedAddCommGroup F
inst✝² : NormedSpace ℝ F
I J : Box ι
π : TaggedPrepartition I
inst✝¹ : Fintype ι
l : IntegrationParams
f g : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
y y' : F
inst✝ : CompleteSpace F
⊢ (∀ (ib : ℝ),
      0 < ib →
        ∃ ia,
          (∀ (c : ℝ≥0), RCond l (ia c)) ∧
            ∀
              x ∈
                {π | ∃ c, MemBaseSet l I c (ia c) π ∧ IsPartition π} ×ˢ
                  {π | ∃ c, MemBaseSet l I c (ia c) π ∧ IsPartition π},
              (integralSum f vol x.1, integralSum f vol x.2) ∈ {p | dist p.1 p.2 ≤ ib}) ↔
    ∀ ε > 0,
      ∃ r,
        (∀ (c : ℝ≥0), RCond l (r c)) ∧
          ∀ (c₁ c₂ : ℝ≥0) (π₁ π₂ : TaggedPrepartition I),
            MemBaseSet l I c₁ (r c₁) π₁ →
              IsPartition π₁ →
                MemBaseSet l I c₂ (r c₂) π₂ → IsPartition π₂ → dist (integralSum f vol π₁) (integralSum f vol π₂) ≤ ε

Next tactic:
refine' forall₂_congr fun ε _ => exists_congr fun r => _
/-- In a complete space, a function is integrable if and only if its integral sums form a Cauchy
net. Here we restate this fact in terms of `∀ ε > 0, ∃ r, ...`. -/
theorem integrable_iff_cauchy_basis [CompleteSpace F] : Integrable I l f vol ↔
    ∀ ε > (0 : ℝ), ∃ r : ℝ≥0 → ℝⁿ → Ioi (0 : ℝ), (∀ c, l.RCond (r c)) ∧
      ∀ c₁ c₂ π₁ π₂, l.MemBaseSet I c₁ (r c₁) π₁ → π₁.IsPartition → l.MemBaseSet I c₂ (r c₂) π₂ →
        π₂.IsPartition → dist (integralSum f vol π₁) (integralSum f vol π₂) ≤ ε := by
  rw [integrable_iff_cauchy, cauchy_map_iff',
    (l.hasBasis_toFilteriUnion_top _).prod_self.tendsto_iff uniformity_basis_dist_le]
  refine' forall₂_congr fun ε _ => exists_congr fun r => _
  

Proof state:
ι : Type u
E : Type v
F : Type w
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : NormedSpace ℝ E
inst✝³ : NormedAddCommGroup F
inst✝² : NormedSpace ℝ F
I J : Box ι
π : TaggedPrepartition I
inst✝¹ : Fintype ι
l : IntegrationParams
f g : (ι → ℝ) → E
vol : ι →ᵇᵃ[⊤] E →L[ℝ] F
y y' : F
inst✝ : CompleteSpace F
ε : ℝ
x✝ : 0 < ε
r : ℝ≥0 → (ι → ℝ) → ↑(Set.Ioi 0)
⊢ ((∀ (c : ℝ≥0), RCond l (r c)) ∧
      ∀ x ∈ {π | ∃ c, MemBaseSet l I c (r c) π ∧ IsPartition π} ×ˢ {π | ∃ c, MemBaseSet l I c (r c) π ∧ IsPartition π},
        (integralSum f vol x.1, integralSum f vol x.2) ∈ {p | dist p.1 p.2 ≤ ε}) ↔
    (∀ (c : ℝ≥0), RCond l (r c)) ∧
      ∀ (c₁ c₂ : ℝ≥0) (π₁ π₂ : TaggedPrepartition I),
        MemBaseSet l I c₁ (r c₁) π₁ →
          IsPartition π₁ →
            MemBaseSet l I c₂ (r c₂) π₂ → IsPartition π₂ → dist (integralSum f vol π₁) (integralSum f vol π₂) ≤ ε

Next tactic:
simp only [exists_prop, Prod.forall, Set.mem_iUnion, exists_imp, prod_mk_mem_set_prod_eq, and_imp,
    mem_inter_iff, mem_setOf_eq]