Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 4fe734d

Browse files
committed
fix(algebra/indicator_function): add missing decidable instances to lemma statements (#13834)
This keeps the definition of `set.indicator` as non-computable, but ensures that when lemmas are applied they generalize to any decidable instances.
1 parent cf5fa84 commit 4fe734d

File tree

8 files changed

+67
-40
lines changed

8 files changed

+67
-40
lines changed

src/algebra/indicator_function.lean

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ But since it is usually used to restrict a function to a certain set `s`,
2121
we let the indicator function take the value `f x` for some function `f`, instead of `1`.
2222
If the usual indicator function is needed, just set `f` to be the constant function `λx, 1`.
2323
24+
The indicator function is implemented non-computably, to avoid having to pass around `decidable`
25+
arguments. This is in contrast with the design of `pi.single` or `set.piecewise`.
26+
2427
## Tags
2528
indicator, characteristic
2629
-/
2730

28-
noncomputable theory
29-
open_locale classical big_operators
31+
open_locale big_operators
3032
open function
3133

3234
variables {α β ι M N : Type*}
@@ -37,30 +39,40 @@ section has_one
3739
variables [has_one M] [has_one N] {s t : set α} {f g : α → M} {a : α}
3840

3941
/-- `indicator s f a` is `f a` if `a ∈ s`, `0` otherwise. -/
40-
def indicator {M} [has_zero M] (s : set α) (f : α → M) : α → M := λ x, if x ∈ s then f x else 0
42+
noncomputable def indicator {M} [has_zero M] (s : set α) (f : α → M) : α → M
43+
| x := by haveI := classical.dec_pred (∈ s); exact if x ∈ s then f x else 0
4144

4245
/-- `mul_indicator s f a` is `f a` if `a ∈ s`, `1` otherwise. -/
4346
@[to_additive]
44-
def mul_indicator (s : set α) (f : α → M) : α → M := λ x, if x ∈ s then f x else 1
47+
noncomputable def mul_indicator (s : set α) (f : α → M) : α → M
48+
| x := by haveI := classical.dec_pred (∈ s); exact if x ∈ s then f x else 1
4549

46-
@[simp, to_additive] lemma piecewise_eq_mul_indicator : s.piecewise f 1 = s.mul_indicator f := rfl
50+
@[simp, to_additive] lemma piecewise_eq_mul_indicator [decidable_pred (∈ s)] :
51+
s.piecewise f 1 = s.mul_indicator f :=
52+
funext $ λ x, @if_congr _ _ _ _ (id _) _ _ _ _ iff.rfl rfl rfl
4753

48-
@[to_additive] lemma mul_indicator_apply (s : set α) (f : α → M) (a : α) :
49-
mul_indicator s f a = if a ∈ s then f a else 1 := rfl
54+
@[to_additive] lemma mul_indicator_apply (s : set α) (f : α → M) (a : α) [decidable (a ∈ s)] :
55+
mul_indicator s f a = if a ∈ s then f a else 1 := by convert rfl
5056

5157
@[simp, to_additive] lemma mul_indicator_of_mem (h : a ∈ s) (f : α → M) :
52-
mul_indicator s f a = f a := if_pos h
58+
mul_indicator s f a = f a :=
59+
by { letI := classical.dec (a ∈ s), exact if_pos h }
5360

5461
@[simp, to_additive] lemma mul_indicator_of_not_mem (h : a ∉ s) (f : α → M) :
55-
mul_indicator s f a = 1 := if_neg h
62+
mul_indicator s f a = 1 :=
63+
by { letI := classical.dec (a ∈ s), exact if_neg h }
5664

5765
@[to_additive] lemma mul_indicator_eq_one_or_self (s : set α) (f : α → M) (a : α) :
5866
mul_indicator s f a = 1 ∨ mul_indicator s f a = f a :=
59-
if h : a ∈ s then or.inr (mul_indicator_of_mem h f) else or.inl (mul_indicator_of_not_mem h f)
67+
begin
68+
by_cases h : a ∈ s,
69+
{ exact or.inr (mul_indicator_of_mem h f) },
70+
{ exact or.inl (mul_indicator_of_not_mem h f) }
71+
end
6072

6173
@[simp, to_additive] lemma mul_indicator_apply_eq_self :
6274
s.mul_indicator f a = f a ↔ (a ∉ s → f a = 1) :=
63-
ite_eq_left_iff.trans $ by rw [@eq_comm _ (f a)]
75+
by letI := classical.dec (a ∈ s); exact ite_eq_left_iff.trans (by rw [@eq_comm _ (f a)])
6476

6577
@[simp, to_additive] lemma mul_indicator_eq_self : s.mul_indicator f = f ↔ mul_support f ⊆ s :=
6678
by simp only [funext_iff, subset_def, mem_mul_support, mul_indicator_apply_eq_self, not_imp_comm]
@@ -71,7 +83,7 @@ by { rw mul_indicator_eq_self at h1 ⊢, exact subset.trans h1 h2 }
7183

7284
@[simp, to_additive] lemma mul_indicator_apply_eq_one :
7385
mul_indicator s f a = 1 ↔ (a ∈ s → f a = 1) :=
74-
ite_eq_right_iff
86+
by letI := classical.dec (a ∈ s); exact ite_eq_right_iff
7587

7688
@[simp, to_additive] lemma mul_indicator_eq_one :
7789
mul_indicator s f = (λ x, 1) ↔ disjoint (mul_support f) s :=
@@ -108,7 +120,7 @@ mul_indicator_eq_self.2 subset.rfl
108120

109121
@[simp, to_additive] lemma mul_indicator_range_comp {ι : Sort*} (f : ι → α) (g : α → M) :
110122
mul_indicator (range f) g ∘ f = g ∘ f :=
111-
piecewise_range_comp _ _ _
123+
by letI := classical.dec_pred (∈ range f); exact piecewise_range_comp _ _ _
112124

113125
@[to_additive] lemma mul_indicator_congr (h : eq_on f g s) :
114126
mul_indicator s f = mul_indicator s g :=
@@ -142,9 +154,10 @@ funext $ λx, by { simp only [mul_indicator], split_ifs, repeat {simp * at * {co
142154
mul_indicator (s ∩ mul_support f) f = mul_indicator s f :=
143155
by rw [← mul_indicator_mul_indicator, mul_indicator_mul_support]
144156

145-
@[to_additive] lemma comp_mul_indicator (h : M → β) (f : α → M) {s : set α} {x : α} :
157+
@[to_additive] lemma comp_mul_indicator (h : M → β) (f : α → M) {s : set α} {x : α}
158+
[decidable_pred (∈ s)] :
146159
h (s.mul_indicator f x) = s.piecewise (h ∘ f) (const α (h 1)) x :=
147-
s.apply_piecewise _ _ (λ _, h)
160+
by letI := classical.dec_pred (∈ s); convert s.apply_piecewise f (const α 1) (λ _, h)
148161

149162
@[to_additive] lemma mul_indicator_comp_right {s : set α} (f : β → α) {g : α → M} {x : β} :
150163
mul_indicator (f ⁻¹' s) (g ∘ f) x = mul_indicator s g (f x) :=
@@ -168,7 +181,7 @@ end
168181

169182
@[to_additive] lemma mul_indicator_preimage (s : set α) (f : α → M) (B : set M) :
170183
(mul_indicator s f)⁻¹' B = s.ite (f ⁻¹' B) (1 ⁻¹' B) :=
171-
piecewise_preimage s f 1 B
184+
by letI := classical.dec_pred (∈ s); exact piecewise_preimage s f 1 B
172185

173186
@[to_additive] lemma mul_indicator_preimage_of_not_mem (s : set α) (f : α → M)
174187
{t : set M} (ht : (1:M) ∉ t) :
@@ -264,7 +277,7 @@ end
264277

265278
/-- `set.mul_indicator` as a `monoid_hom`. -/
266279
@[to_additive "`set.indicator` as an `add_monoid_hom`."]
267-
def mul_indicator_hom {α} (M) [mul_one_class M] (s : set α) : (α → M) →* (α → M) :=
280+
noncomputable def mul_indicator_hom {α} (M) [mul_one_class M] (s : set α) : (α → M) →* (α → M) :=
268281
{ to_fun := mul_indicator s,
269282
map_one' := mul_indicator_one M s,
270283
map_mul' := mul_indicator_mul s }
@@ -374,7 +387,7 @@ lemma prod_mul_indicator_subset (f : α → M) {s t : finset α} (h : s ⊆ t) :
374387
prod_mul_indicator_subset_of_eq_one _ (λ a b, b) h (λ _, rfl)
375388

376389
@[to_additive] lemma _root_.finset.prod_mul_indicator_eq_prod_filter
377-
(s : finset ι) (f : ι → α → M) (t : ι → set α) (g : ι → α) :
390+
(s : finset ι) (f : ι → α → M) (t : ι → set α) (g : ι → α) [decidable_pred (λ i, g i ∈ t i)]:
378391
∏ i in s, mul_indicator (t i) (f i) (g i) = ∏ i in s.filter (λ i, g i ∈ t i), f i (g i) :=
379392
begin
380393
refine (finset.prod_filter_mul_prod_filter_not s (λ i, g i ∈ t i) _).symm.trans _,
@@ -392,6 +405,7 @@ end
392405
(s : ι → set α) {f : α → M} : (∀ (i ∈ I) (j ∈ I), i ≠ j → disjoint (s i) (s j)) →
393406
mul_indicator (⋃ i ∈ I, s i) f = λ a, ∏ i in I, mul_indicator (s i) f a :=
394407
begin
408+
classical,
395409
refine finset.induction_on I _ _,
396410
{ intro h, funext, simp },
397411
assume a I haI ih hI,
@@ -439,7 +453,11 @@ funext (λ _, by simpa only [← inter_indicator_mul, pi.mul_apply, pi.one_apply
439453

440454
lemma indicator_prod_one {s : set α} {t : set β} {x : α} {y : β} :
441455
(s ×ˢ t : set _).indicator (1 : _ → M) (x, y) = s.indicator 1 x * t.indicator 1 y :=
442-
by simp [indicator, ← ite_and]
456+
begin
457+
letI := classical.dec_pred (∈ s),
458+
letI := classical.dec_pred (∈ t),
459+
simp [indicator_apply, ← ite_and],
460+
end
443461

444462
end mul_zero_one_class
445463

@@ -452,7 +470,11 @@ variables [has_le M]
452470

453471
@[to_additive] lemma mul_indicator_apply_le' (hfg : a ∈ s → f a ≤ y) (hg : a ∉ s → 1 ≤ y) :
454472
mul_indicator s f a ≤ y :=
455-
if ha : a ∈ s then by simpa [ha] using hfg ha else by simpa [ha] using hg ha
473+
begin
474+
by_cases ha : a ∈ s,
475+
{ simpa [ha] using hfg ha },
476+
{ simpa [ha] using hg ha },
477+
end
456478

457479
@[to_additive] lemma mul_indicator_le' (hfg : ∀ a ∈ s, f a ≤ g a) (hg : ∀ a ∉ s, 1 ≤ g a) :
458480
mul_indicator s f ≤ g :=
@@ -540,6 +562,7 @@ lemma indicator_le_indicator_nonneg {β} [linear_order β] [has_zero β] (s : se
540562
s.indicator f ≤ {x | 0 ≤ f x}.indicator f :=
541563
begin
542564
intro x,
565+
classical,
543566
simp_rw indicator_apply,
544567
split_ifs,
545568
{ exact le_rfl, },

src/combinatorics/simple_graph/inc_matrix.lean

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ incidence matrix for each `simple_graph α` has the same type.
4040
arbitrary orientation of a simple graph.
4141
-/
4242

43-
noncomputable theory
44-
4543
open finset matrix simple_graph sym2
4644
open_locale big_operators matrix
4745

@@ -50,7 +48,7 @@ variables (R : Type*) {α : Type*} (G : simple_graph α)
5048

5149
/-- `G.inc_matrix R` is the `α × sym2 α` matrix whose `(a, e)`-entry is `1` if `e` is incident to
5250
`a` and `0` otherwise. -/
53-
def inc_matrix [has_zero R] [has_one R] : matrix α (sym2 α) R :=
51+
noncomputable def inc_matrix [has_zero R] [has_one R] : matrix α (sym2 α) R :=
5452
λ a, (G.incidence_set a).indicator 1
5553

5654
variables {R}
@@ -70,6 +68,7 @@ variables [mul_zero_one_class R] {a b : α} {e : sym2 α}
7068
lemma inc_matrix_apply_mul_inc_matrix_apply :
7169
G.inc_matrix R a e * G.inc_matrix R b e = (G.incidence_set a ∩ G.incidence_set b).indicator 1 e :=
7270
begin
71+
classical,
7372
simp only [inc_matrix, set.indicator_apply, ←ite_and_mul_zero,
7473
pi.one_apply, mul_one, set.mem_inter_eq],
7574
congr,
@@ -162,6 +161,7 @@ variables [fintype (sym2 α)] [semiring R] {a b : α} {e : sym2 α}
162161
lemma inc_matrix_mul_transpose_apply_of_adj (h : G.adj a b) :
163162
(G.inc_matrix R ⬝ (G.inc_matrix R)ᵀ) a b = (1 : R) :=
164163
begin
164+
classical,
165165
simp_rw [matrix.mul_apply, matrix.transpose_apply, inc_matrix_apply_mul_inc_matrix_apply,
166166
set.indicator_apply, pi.one_apply, sum_boole],
167167
convert nat.cast_one,

src/geometry/euclidean/circumcenter.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ begin
615615
fs.subset_univ
616616
(λ i, zero_smul ℝ _),
617617
set.indicator_apply],
618-
congr, funext, congr' 2
618+
congr,
619619
end
620620

621621
omit V

src/measure_theory/function/conditional_expectation.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,7 @@ begin
853853
{ refine lintegral_congr_ae (ae_restrict_of_ae _),
854854
refine (@indicator_const_Lp_coe_fn _ _ _ 2 _ _ _ hs hμs (1 : ℝ)).mono (λ x hx, _),
855855
rw hx,
856+
classical,
856857
simp_rw set.indicator_apply,
857858
split_ifs; simp, },
858859
rw [h_eq, lintegral_indicator _ hs, lintegral_const, measure.restrict_restrict hs],

src/measure_theory/function/uniform_integrable.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ begin
809809
((hf i).nnnorm.measurable_set_lt strongly_measurable_const)))
810810
(strongly_measurable.ae_strongly_measurable ((hf i).indicator
811811
(strongly_measurable_const.measurable_set_le (hf i).nnnorm))) hp),
812-
{ rw [indicator, pi.add_apply],
812+
{ rw [pi.add_apply, indicator_apply],
813813
split_ifs with hx,
814814
{ rw [indicator_of_not_mem, add_zero],
815815
simpa using hx },

src/measure_theory/integral/bochner.lean

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ Bochner integral, simple function, function space, Lebesgue dominated convergenc
142142
-/
143143

144144
noncomputable theory
145-
open_locale classical topological_space big_operators nnreal ennreal measure_theory
145+
open_locale topological_space big_operators nnreal ennreal measure_theory
146146
open set filter topological_space ennreal emetric
147147

148148
namespace measure_theory
@@ -294,12 +294,13 @@ lemma integral_eq {m : measurable_space α} (μ : measure α) (f : α →ₛ F)
294294
f.integral μ = ∑ x in f.range, (μ (f ⁻¹' {x})).to_real • x :=
295295
by simp [integral, set_to_simple_func, weighted_smul_apply]
296296

297-
lemma integral_eq_sum_filter {m : measurable_space α} (f : α →ₛ F) (μ : measure α) :
297+
lemma integral_eq_sum_filter [decidable_pred (λ x : F, x ≠ 0)] {m : measurable_space α} (f : α →ₛ F)
298+
(μ : measure α) :
298299
f.integral μ = ∑ x in f.range.filter (λ x, x ≠ 0), (μ (f ⁻¹' {x})).to_real • x :=
299-
by { rw [integral_def, set_to_simple_func_eq_sum_filter], simp_rw weighted_smul_apply, }
300+
by { rw [integral_def, set_to_simple_func_eq_sum_filter], simp_rw weighted_smul_apply, congr }
300301

301302
/-- The Bochner integral is equal to a sum over any set that includes `f.range` (except `0`). -/
302-
lemma integral_eq_sum_of_subset {f : α →ₛ F} {s : finset F}
303+
lemma integral_eq_sum_of_subset [decidable_pred (λ x : F, x ≠ 0)] {f : α →ₛ F} {s : finset F}
303304
(hs : f.range.filter (λ x, x ≠ 0) ⊆ s) : f.integral μ = ∑ x in s, (μ (f ⁻¹' {x})).to_real • x :=
304305
begin
305306
rw [simple_func.integral_eq_sum_filter, finset.sum_subset hs],
@@ -310,14 +311,15 @@ end
310311

311312
@[simp] lemma integral_const {m : measurable_space α} (μ : measure α) (y : F) :
312313
(const α y).integral μ = (μ univ).to_real • y :=
313-
calc (const α y).integral μ = ∑ z in {y}, (μ ((const α y) ⁻¹' {z})).to_real • z :
314+
by classical; calc (const α y).integral μ = ∑ z in {y}, (μ ((const α y) ⁻¹' {z})).to_real • z :
314315
integral_eq_sum_of_subset $ (filter_subset _ _).trans (range_const_subset _ _)
315316
... = (μ univ).to_real • y : by simp
316317

317318
@[simp] lemma integral_piecewise_zero {m : measurable_space α} (f : α →ₛ F) (μ : measure α)
318319
{s : set α} (hs : measurable_set s) :
319320
(piecewise s hs f 0).integral μ = f.integral (μ.restrict s) :=
320321
begin
322+
classical,
321323
refine (integral_eq_sum_of_subset _).trans
322324
((sum_congr rfl $ λ y hy, _).trans (integral_eq_sum_filter _ _).symm),
323325
{ intros y hy,
@@ -326,7 +328,8 @@ begin
326328
rcases hy with ⟨⟨rfl, -⟩|⟨x, hxs, rfl⟩, h₀⟩,
327329
exacts [(h₀ rfl).elim, ⟨set.mem_range_self _, h₀⟩] },
328330
{ dsimp,
329-
rw [indicator_preimage_of_not_mem, measure.restrict_apply (f.measurable_set_preimage _)],
331+
rw [set.piecewise_eq_indicator, indicator_preimage_of_not_mem,
332+
measure.restrict_apply (f.measurable_set_preimage _)],
330333
exact λ h₀, (mem_filter.1 hy).2 (eq.symm h₀) }
331334
end
332335

@@ -687,10 +690,15 @@ variables [normed_group E] [normed_space ℝ E] [complete_space E]
687690
[nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [smul_comm_class ℝ 𝕜 E]
688691
[normed_group F] [normed_space ℝ F] [complete_space F]
689692

693+
section
694+
open_locale classical
695+
690696
/-- The Bochner integral -/
691697
def integral {m : measurable_space α} (μ : measure α) (f : α → E) : E :=
692698
if hf : integrable f μ then L1.integral (hf.to_L1 f) else 0
693699

700+
end
701+
694702
/-! In the notation for integrals, an expression like `∫ x, g ∥x∥ ∂μ` will not be parsed correctly,
695703
and needs parentheses. We do not set the binding power of `r` to `0`, because then
696704
`∫ x, f x = 0` will be parsed incorrectly. -/
@@ -707,7 +715,7 @@ variables {f g : α → E} {m : measurable_space α} {μ : measure α}
707715

708716
lemma integral_eq (f : α → E) (hf : integrable f μ) :
709717
∫ a, f a ∂μ = L1.integral (hf.to_L1 f) :=
710-
dif_pos hf
718+
@dif_pos _ (id _) hf _ _ _
711719

712720
lemma integral_eq_set_to_fun (f : α → E) :
713721
∫ a, f a ∂μ = set_to_fun μ (weighted_smul μ) (dominated_fin_meas_additive_weighted_smul μ) f :=
@@ -717,7 +725,7 @@ lemma L1.integral_eq_integral (f : α →₁[μ] E) : L1.integral f = ∫ a, f a
717725
(L1.set_to_fun_eq_set_to_L1 (dominated_fin_meas_additive_weighted_smul μ) f).symm
718726

719727
lemma integral_undef (h : ¬ integrable f μ) : ∫ a, f a ∂μ = 0 :=
720-
dif_neg h
728+
@dif_neg _ (id _) h _ _ _
721729

722730
lemma integral_non_ae_strongly_measurable (h : ¬ ae_strongly_measurable f μ) : ∫ a, f a ∂μ = 0 :=
723731
integral_undef $ not_and_of_not_left _ h

src/measure_theory/probability_mass_function/monad.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ calc (p.bind f).to_outer_measure s
147147
... = ∑' (a : α), ↑(p a) * ∑' (b : β), if b ∈ s then ↑(f a b) else (0 : ℝ≥0∞) :
148148
tsum_congr (λ a, congr_arg (λ x, ↑(p a) * x) $ tsum_congr (λ b, by split_ifs; refl))
149149
... = ∑' (a : α), ↑(p a) * (f a).to_outer_measure s :
150-
tsum_congr (λ a, by rw [to_outer_measure_apply, set.indicator])
150+
tsum_congr (λ a, by simp only [to_outer_measure_apply, set.indicator_apply])
151151

152152
/-- The measure of a set under `p.bind f` is the sum over `a : α`
153153
of the probability of `a` under `p` times the measure of the set under `f a` -/

src/topology/instances/ennreal.lean

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -841,12 +841,7 @@ lemma tsum_mono_subtype (f : α → ℝ≥0∞) {s t : set α} (h : s ⊆ t) :
841841
begin
842842
simp only [tsum_subtype],
843843
apply ennreal.tsum_le_tsum,
844-
assume x,
845-
split_ifs,
846-
{ exact le_rfl },
847-
{ exact (h_2 (h h_1)).elim },
848-
{ exact zero_le _ },
849-
{ exact le_rfl }
844+
exact indicator_le_indicator_of_subset h (λ _, zero_le _),
850845
end
851846

852847
lemma tsum_union_le (f : α → ℝ≥0∞) (s t : set α) :

0 commit comments

Comments
 (0)