l3lab/ntp-mathlib huggingface dataset:
lemma comap_injective (f : X → Y) (hf: Continuous f) (hfs : f.Surjective) :
    (comap (Z := Z) f).Injective := by
  intro a b h
  

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
f : X → Y
hf : Continuous f
hfs : Function.Surjective f
a b : LocallyConstant Y Z
h : comap f a = comap f b
⊢ a = b

Next tactic:
rw [LocallyConstant.ext_iff] at h
lemma comap_injective (f : X → Y) (hf: Continuous f) (hfs : f.Surjective) :
    (comap (Z := Z) f).Injective := by
  intro a b h
  rw [LocallyConstant.ext_iff] at h
  

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
f : X → Y
hf : Continuous f
hfs : Function.Surjective f
a b : LocallyConstant Y Z
h : ∀ (x : X), (comap f a) x = (comap f b) x
⊢ a = b

Next tactic:
ext y
lemma comap_injective (f : X → Y) (hf: Continuous f) (hfs : f.Surjective) :
    (comap (Z := Z) f).Injective := by
  intro a b h
  rw [LocallyConstant.ext_iff] at h
  ext y
  

Proof state:
case h
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
f : X → Y
hf : Continuous f
hfs : Function.Surjective f
a b : LocallyConstant Y Z
h : ∀ (x : X), (comap f a) x = (comap f b) x
y : Y
⊢ a y = b y

Next tactic:
obtain ⟨x, hx⟩ := hfs y
lemma comap_injective (f : X → Y) (hf: Continuous f) (hfs : f.Surjective) :
    (comap (Z := Z) f).Injective := by
  intro a b h
  rw [LocallyConstant.ext_iff] at h
  ext y
  obtain ⟨x, hx⟩ := hfs y
  

Proof state:
case h.intro
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
f : X → Y
hf : Continuous f
hfs : Function.Surjective f
a b : LocallyConstant Y Z
h : ∀ (x : X), (comap f a) x = (comap f b) x
y : Y
x : X
hx : f x = y
⊢ a y = b y

Next tactic:
specialize h x
lemma comap_injective (f : X → Y) (hf: Continuous f) (hfs : f.Surjective) :
    (comap (Z := Z) f).Injective := by
  intro a b h
  rw [LocallyConstant.ext_iff] at h
  ext y
  obtain ⟨x, hx⟩ := hfs y
  specialize h x
  

Proof state:
case h.intro
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
f : X → Y
hf : Continuous f
hfs : Function.Surjective f
a b : LocallyConstant Y Z
y : Y
x : X
hx : f x = y
h : (comap f a) x = (comap f b) x
⊢ a y = b y

Next tactic:
rwa [coe_comap_apply _ _ hf, coe_comap_apply _ _ hf, hx] at h
/-- Given a clopen set `U` and a locally constant function `f`, `LocallyConstant.mulIndicator`
  returns the locally constant function that is `f` on `U` and `1` otherwise. -/
@[to_additive (attr := simps) "Given a clopen set `U` and a locally constant function `f`,
  `LocallyConstant.indicator` returns the locally constant function that is `f` on `U` and `0`
  otherwise. "]
noncomputable def mulIndicator (hU : IsClopen U) : LocallyConstant X R where
  toFun := Set.mulIndicator U f
  isLocallyConstant := fun s => by
    

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
R : Type u_5
inst✝ : One R
U : Set X
f : LocallyConstant X R
hU : IsClopen U
s : Set R
⊢ IsOpen (Set.mulIndicator U ⇑f ⁻¹' s)

Next tactic:
rw [mulIndicator_preimage, Set.ite, Set.diff_eq]
/-- Given a clopen set `U` and a locally constant function `f`, `LocallyConstant.mulIndicator`
  returns the locally constant function that is `f` on `U` and `1` otherwise. -/
@[to_additive (attr := simps) "Given a clopen set `U` and a locally constant function `f`,
  `LocallyConstant.indicator` returns the locally constant function that is `f` on `U` and `0`
  otherwise. "]
noncomputable def mulIndicator (hU : IsClopen U) : LocallyConstant X R where
  toFun := Set.mulIndicator U f
  isLocallyConstant := fun s => by
    rw [mulIndicator_preimage, Set.ite, Set.diff_eq]
    

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
R : Type u_5
inst✝ : One R
U : Set X
f : LocallyConstant X R
hU : IsClopen U
s : Set R
⊢ IsOpen (⇑f ⁻¹' s ∩ U ∪ 1 ⁻¹' s ∩ Uᶜ)

Next tactic:
exact ((f.2 s).inter hU.isOpen).union ((IsLocallyConstant.const 1 s).inter hU.compl.isOpen)
/-- The equivalence between `LocallyConstant X Z` and `LocallyConstant Y Z` given a
    homeomorphism `X ≃ₜ Y` -/
@[simps]
noncomputable
def congrLeft [TopologicalSpace Y] (e : X ≃ₜ Y) : LocallyConstant X Z ≃ LocallyConstant Y Z where
  toFun := comap e.symm
  invFun := comap e
  left_inv := by
    

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
e : X ≃ₜ Y
⊢ Function.LeftInverse (comap ⇑e) (comap ⇑(Homeomorph.symm e))

Next tactic:
intro
/-- The equivalence between `LocallyConstant X Z` and `LocallyConstant Y Z` given a
    homeomorphism `X ≃ₜ Y` -/
@[simps]
noncomputable
def congrLeft [TopologicalSpace Y] (e : X ≃ₜ Y) : LocallyConstant X Z ≃ LocallyConstant Y Z where
  toFun := comap e.symm
  invFun := comap e
  left_inv := by
    intro
    

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
e : X ≃ₜ Y
x✝ : LocallyConstant X Z
⊢ comap (⇑e) (comap (⇑(Homeomorph.symm e)) x✝) = x✝

Next tactic:
rw [comap_comap _ _ e.continuous e.symm.continuous]
/-- The equivalence between `LocallyConstant X Z` and `LocallyConstant Y Z` given a
    homeomorphism `X ≃ₜ Y` -/
@[simps]
noncomputable
def congrLeft [TopologicalSpace Y] (e : X ≃ₜ Y) : LocallyConstant X Z ≃ LocallyConstant Y Z where
  toFun := comap e.symm
  invFun := comap e
  left_inv := by
    intro
    rw [comap_comap _ _ e.continuous e.symm.continuous]
    

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
e : X ≃ₜ Y
x✝ : LocallyConstant X Z
⊢ comap (⇑(Homeomorph.symm e) ∘ ⇑e) x✝ = x✝

Next tactic:
simp
/-- The equivalence between `LocallyConstant X Z` and `LocallyConstant Y Z` given a
    homeomorphism `X ≃ₜ Y` -/
@[simps]
noncomputable
def congrLeft [TopologicalSpace Y] (e : X ≃ₜ Y) : LocallyConstant X Z ≃ LocallyConstant Y Z where
  toFun := comap e.symm
  invFun := comap e
  left_inv := by
    intro
    rw [comap_comap _ _ e.continuous e.symm.continuous]
    simp
  right_inv := by
    

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
e : X ≃ₜ Y
⊢ Function.RightInverse (comap ⇑e) (comap ⇑(Homeomorph.symm e))

Next tactic:
intro
/-- The equivalence between `LocallyConstant X Z` and `LocallyConstant Y Z` given a
    homeomorphism `X ≃ₜ Y` -/
@[simps]
noncomputable
def congrLeft [TopologicalSpace Y] (e : X ≃ₜ Y) : LocallyConstant X Z ≃ LocallyConstant Y Z where
  toFun := comap e.symm
  invFun := comap e
  left_inv := by
    intro
    rw [comap_comap _ _ e.continuous e.symm.continuous]
    simp
  right_inv := by
    intro
    

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
e : X ≃ₜ Y
x✝ : LocallyConstant Y Z
⊢ comap (⇑(Homeomorph.symm e)) (comap (⇑e) x✝) = x✝

Next tactic:
rw [comap_comap _ _ e.symm.continuous e.continuous]
/-- The equivalence between `LocallyConstant X Z` and `LocallyConstant Y Z` given a
    homeomorphism `X ≃ₜ Y` -/
@[simps]
noncomputable
def congrLeft [TopologicalSpace Y] (e : X ≃ₜ Y) : LocallyConstant X Z ≃ LocallyConstant Y Z where
  toFun := comap e.symm
  invFun := comap e
  left_inv := by
    intro
    rw [comap_comap _ _ e.continuous e.symm.continuous]
    simp
  right_inv := by
    intro
    rw [comap_comap _ _ e.symm.continuous e.continuous]
    

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
e : X ≃ₜ Y
x✝ : LocallyConstant Y Z
⊢ comap (⇑e ∘ ⇑(Homeomorph.symm e)) x✝ = x✝

Next tactic:
simp
/-- Given two closed sets covering a topological space, and locally constant maps on these two sets,
    then if these two locally constant maps agree on the intersection, we get a piecewise defined
    locally constant map on the whole space.

TODO: Generalise this construction to `ContinuousMap`. -/
def piecewise {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) (h : C₁ ∪ C₂ = Set.univ)
    (f : LocallyConstant C₁ Z) (g : LocallyConstant C₂ Z)
    (hfg : ∀ (x : X) (hx : x ∈ C₁ ∩ C₂), f ⟨x, hx.1⟩ = g ⟨x, hx.2⟩)
    [DecidablePred (· ∈ C₁)] : LocallyConstant X Z where
  toFun i := if hi : i ∈ C₁ then f ⟨i, hi⟩ else g ⟨i, (Set.compl_subset_iff_union.mpr h) hi⟩
  isLocallyConstant := by
    

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
C₁ C₂ : Set X
h₁ : IsClosed C₁
h₂ : IsClosed C₂
h : C₁ ∪ C₂ = univ
f : LocallyConstant (↑C₁) Z
g : LocallyConstant (↑C₂) Z
hfg : ∀ (x : X) (hx : x ∈ C₁ ∩ C₂), f { val := x, property := (_ : x ∈ C₁) } = g { val := x, property := (_ : x ∈ C₂) }
inst✝ : DecidablePred fun x => x ∈ C₁
⊢ IsLocallyConstant fun i =>
    if hi : i ∈ C₁ then f { val := i, property := hi } else g { val := i, property := (_ : i ∈ C₂) }

Next tactic:
let dZ : TopologicalSpace Z := ⊥
/-- Given two closed sets covering a topological space, and locally constant maps on these two sets,
    then if these two locally constant maps agree on the intersection, we get a piecewise defined
    locally constant map on the whole space.

TODO: Generalise this construction to `ContinuousMap`. -/
def piecewise {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) (h : C₁ ∪ C₂ = Set.univ)
    (f : LocallyConstant C₁ Z) (g : LocallyConstant C₂ Z)
    (hfg : ∀ (x : X) (hx : x ∈ C₁ ∩ C₂), f ⟨x, hx.1⟩ = g ⟨x, hx.2⟩)
    [DecidablePred (· ∈ C₁)] : LocallyConstant X Z where
  toFun i := if hi : i ∈ C₁ then f ⟨i, hi⟩ else g ⟨i, (Set.compl_subset_iff_union.mpr h) hi⟩
  isLocallyConstant := by
    let dZ : TopologicalSpace Z := ⊥
    

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
C₁ C₂ : Set X
h₁ : IsClosed C₁
h₂ : IsClosed C₂
h : C₁ ∪ C₂ = univ
f : LocallyConstant (↑C₁) Z
g : LocallyConstant (↑C₂) Z
hfg : ∀ (x : X) (hx : x ∈ C₁ ∩ C₂), f { val := x, property := (_ : x ∈ C₁) } = g { val := x, property := (_ : x ∈ C₂) }
inst✝ : DecidablePred fun x => x ∈ C₁
dZ : TopologicalSpace Z := ⊥
⊢ IsLocallyConstant fun i =>
    if hi : i ∈ C₁ then f { val := i, property := hi } else g { val := i, property := (_ : i ∈ C₂) }

Next tactic:
haveI : DiscreteTopology Z := discreteTopology_bot Z
/-- Given two closed sets covering a topological space, and locally constant maps on these two sets,
    then if these two locally constant maps agree on the intersection, we get a piecewise defined
    locally constant map on the whole space.

TODO: Generalise this construction to `ContinuousMap`. -/
def piecewise {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) (h : C₁ ∪ C₂ = Set.univ)
    (f : LocallyConstant C₁ Z) (g : LocallyConstant C₂ Z)
    (hfg : ∀ (x : X) (hx : x ∈ C₁ ∩ C₂), f ⟨x, hx.1⟩ = g ⟨x, hx.2⟩)
    [DecidablePred (· ∈ C₁)] : LocallyConstant X Z where
  toFun i := if hi : i ∈ C₁ then f ⟨i, hi⟩ else g ⟨i, (Set.compl_subset_iff_union.mpr h) hi⟩
  isLocallyConstant := by
    let dZ : TopologicalSpace Z := ⊥
    haveI : DiscreteTopology Z := discreteTopology_bot Z
    

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
C₁ C₂ : Set X
h₁ : IsClosed C₁
h₂ : IsClosed C₂
h : C₁ ∪ C₂ = univ
f : LocallyConstant (↑C₁) Z
g : LocallyConstant (↑C₂) Z
hfg : ∀ (x : X) (hx : x ∈ C₁ ∩ C₂), f { val := x, property := (_ : x ∈ C₁) } = g { val := x, property := (_ : x ∈ C₂) }
inst✝ : DecidablePred fun x => x ∈ C₁
dZ : TopologicalSpace Z := ⊥
this : DiscreteTopology Z
⊢ IsLocallyConstant fun i =>
    if hi : i ∈ C₁ then f { val := i, property := hi } else g { val := i, property := (_ : i ∈ C₂) }

Next tactic:
obtain ⟨f, hf⟩ := f
/-- Given two closed sets covering a topological space, and locally constant maps on these two sets,
    then if these two locally constant maps agree on the intersection, we get a piecewise defined
    locally constant map on the whole space.

TODO: Generalise this construction to `ContinuousMap`. -/
def piecewise {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) (h : C₁ ∪ C₂ = Set.univ)
    (f : LocallyConstant C₁ Z) (g : LocallyConstant C₂ Z)
    (hfg : ∀ (x : X) (hx : x ∈ C₁ ∩ C₂), f ⟨x, hx.1⟩ = g ⟨x, hx.2⟩)
    [DecidablePred (· ∈ C₁)] : LocallyConstant X Z where
  toFun i := if hi : i ∈ C₁ then f ⟨i, hi⟩ else g ⟨i, (Set.compl_subset_iff_union.mpr h) hi⟩
  isLocallyConstant := by
    let dZ : TopologicalSpace Z := ⊥
    haveI : DiscreteTopology Z := discreteTopology_bot Z
    obtain ⟨f, hf⟩ := f
    

Proof state:
case mk
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
C₁ C₂ : Set X
h₁ : IsClosed C₁
h₂ : IsClosed C₂
h : C₁ ∪ C₂ = univ
g : LocallyConstant (↑C₂) Z
inst✝ : DecidablePred fun x => x ∈ C₁
dZ : TopologicalSpace Z := ⊥
this : DiscreteTopology Z
f : ↑C₁ → Z
hf : IsLocallyConstant f
hfg :
  ∀ (x : X) (hx : x ∈ C₁ ∩ C₂),
    { toFun := f, isLocallyConstant := hf } { val := x, property := (_ : x ∈ C₁) } =
      g { val := x, property := (_ : x ∈ C₂) }
⊢ IsLocallyConstant fun i =>
    if hi : i ∈ C₁ then { toFun := f, isLocallyConstant := hf } { val := i, property := hi }
    else g { val := i, property := (_ : i ∈ C₂) }

Next tactic:
obtain ⟨g, hg⟩ := g
/-- Given two closed sets covering a topological space, and locally constant maps on these two sets,
    then if these two locally constant maps agree on the intersection, we get a piecewise defined
    locally constant map on the whole space.

TODO: Generalise this construction to `ContinuousMap`. -/
def piecewise {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) (h : C₁ ∪ C₂ = Set.univ)
    (f : LocallyConstant C₁ Z) (g : LocallyConstant C₂ Z)
    (hfg : ∀ (x : X) (hx : x ∈ C₁ ∩ C₂), f ⟨x, hx.1⟩ = g ⟨x, hx.2⟩)
    [DecidablePred (· ∈ C₁)] : LocallyConstant X Z where
  toFun i := if hi : i ∈ C₁ then f ⟨i, hi⟩ else g ⟨i, (Set.compl_subset_iff_union.mpr h) hi⟩
  isLocallyConstant := by
    let dZ : TopologicalSpace Z := ⊥
    haveI : DiscreteTopology Z := discreteTopology_bot Z
    obtain ⟨f, hf⟩ := f
    obtain ⟨g, hg⟩ := g
    

Proof state:
case mk.mk
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
C₁ C₂ : Set X
h₁ : IsClosed C₁
h₂ : IsClosed C₂
h : C₁ ∪ C₂ = univ
inst✝ : DecidablePred fun x => x ∈ C₁
dZ : TopologicalSpace Z := ⊥
this : DiscreteTopology Z
f : ↑C₁ → Z
hf : IsLocallyConstant f
g : ↑C₂ → Z
hg : IsLocallyConstant g
hfg :
  ∀ (x : X) (hx : x ∈ C₁ ∩ C₂),
    { toFun := f, isLocallyConstant := hf } { val := x, property := (_ : x ∈ C₁) } =
      { toFun := g, isLocallyConstant := hg } { val := x, property := (_ : x ∈ C₂) }
⊢ IsLocallyConstant fun i =>
    if hi : i ∈ C₁ then { toFun := f, isLocallyConstant := hf } { val := i, property := hi }
    else { toFun := g, isLocallyConstant := hg } { val := i, property := (_ : i ∈ C₂) }

Next tactic:
rw [IsLocallyConstant.iff_continuous] at hf hg ⊢
/-- Given two closed sets covering a topological space, and locally constant maps on these two sets,
    then if these two locally constant maps agree on the intersection, we get a piecewise defined
    locally constant map on the whole space.

TODO: Generalise this construction to `ContinuousMap`. -/
def piecewise {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) (h : C₁ ∪ C₂ = Set.univ)
    (f : LocallyConstant C₁ Z) (g : LocallyConstant C₂ Z)
    (hfg : ∀ (x : X) (hx : x ∈ C₁ ∩ C₂), f ⟨x, hx.1⟩ = g ⟨x, hx.2⟩)
    [DecidablePred (· ∈ C₁)] : LocallyConstant X Z where
  toFun i := if hi : i ∈ C₁ then f ⟨i, hi⟩ else g ⟨i, (Set.compl_subset_iff_union.mpr h) hi⟩
  isLocallyConstant := by
    let dZ : TopologicalSpace Z := ⊥
    haveI : DiscreteTopology Z := discreteTopology_bot Z
    obtain ⟨f, hf⟩ := f
    obtain ⟨g, hg⟩ := g
    rw [IsLocallyConstant.iff_continuous] at hf hg ⊢
    

Proof state:
case mk.mk
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
C₁ C₂ : Set X
h₁ : IsClosed C₁
h₂ : IsClosed C₂
h : C₁ ∪ C₂ = univ
inst✝ : DecidablePred fun x => x ∈ C₁
dZ : TopologicalSpace Z := ⊥
this : DiscreteTopology Z
f : ↑C₁ → Z
hf✝ : IsLocallyConstant f
hf : Continuous f
g : ↑C₂ → Z
hg✝ : IsLocallyConstant g
hg : Continuous g
hfg :
  ∀ (x : X) (hx : x ∈ C₁ ∩ C₂),
    { toFun := f, isLocallyConstant := hf✝ } { val := x, property := (_ : x ∈ C₁) } =
      { toFun := g, isLocallyConstant := hg✝ } { val := x, property := (_ : x ∈ C₂) }
⊢ Continuous fun i =>
    if hi : i ∈ C₁ then { toFun := f, isLocallyConstant := hf✝ } { val := i, property := hi }
    else { toFun := g, isLocallyConstant := hg✝ } { val := i, property := (_ : i ∈ C₂) }

Next tactic:
dsimp only [coe_mk]
/-- Given two closed sets covering a topological space, and locally constant maps on these two sets,
    then if these two locally constant maps agree on the intersection, we get a piecewise defined
    locally constant map on the whole space.

TODO: Generalise this construction to `ContinuousMap`. -/
def piecewise {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) (h : C₁ ∪ C₂ = Set.univ)
    (f : LocallyConstant C₁ Z) (g : LocallyConstant C₂ Z)
    (hfg : ∀ (x : X) (hx : x ∈ C₁ ∩ C₂), f ⟨x, hx.1⟩ = g ⟨x, hx.2⟩)
    [DecidablePred (· ∈ C₁)] : LocallyConstant X Z where
  toFun i := if hi : i ∈ C₁ then f ⟨i, hi⟩ else g ⟨i, (Set.compl_subset_iff_union.mpr h) hi⟩
  isLocallyConstant := by
    let dZ : TopologicalSpace Z := ⊥
    haveI : DiscreteTopology Z := discreteTopology_bot Z
    obtain ⟨f, hf⟩ := f
    obtain ⟨g, hg⟩ := g
    rw [IsLocallyConstant.iff_continuous] at hf hg ⊢
    dsimp only [coe_mk]
    

Proof state:
case mk.mk
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
C₁ C₂ : Set X
h₁ : IsClosed C₁
h₂ : IsClosed C₂
h : C₁ ∪ C₂ = univ
inst✝ : DecidablePred fun x => x ∈ C₁
dZ : TopologicalSpace Z := ⊥
this : DiscreteTopology Z
f : ↑C₁ → Z
hf✝ : IsLocallyConstant f
hf : Continuous f
g : ↑C₂ → Z
hg✝ : IsLocallyConstant g
hg : Continuous g
hfg :
  ∀ (x : X) (hx : x ∈ C₁ ∩ C₂),
    { toFun := f, isLocallyConstant := hf✝ } { val := x, property := (_ : x ∈ C₁) } =
      { toFun := g, isLocallyConstant := hg✝ } { val := x, property := (_ : x ∈ C₂) }
⊢ Continuous fun i => if hi : i ∈ C₁ then f { val := i, property := hi } else g { val := i, property := (_ : i ∈ C₂) }

Next tactic:
rw [Set.union_eq_iUnion] at h
/-- Given two closed sets covering a topological space, and locally constant maps on these two sets,
    then if these two locally constant maps agree on the intersection, we get a piecewise defined
    locally constant map on the whole space.

TODO: Generalise this construction to `ContinuousMap`. -/
def piecewise {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) (h : C₁ ∪ C₂ = Set.univ)
    (f : LocallyConstant C₁ Z) (g : LocallyConstant C₂ Z)
    (hfg : ∀ (x : X) (hx : x ∈ C₁ ∩ C₂), f ⟨x, hx.1⟩ = g ⟨x, hx.2⟩)
    [DecidablePred (· ∈ C₁)] : LocallyConstant X Z where
  toFun i := if hi : i ∈ C₁ then f ⟨i, hi⟩ else g ⟨i, (Set.compl_subset_iff_union.mpr h) hi⟩
  isLocallyConstant := by
    let dZ : TopologicalSpace Z := ⊥
    haveI : DiscreteTopology Z := discreteTopology_bot Z
    obtain ⟨f, hf⟩ := f
    obtain ⟨g, hg⟩ := g
    rw [IsLocallyConstant.iff_continuous] at hf hg ⊢
    dsimp only [coe_mk]
    rw [Set.union_eq_iUnion] at h
    

Proof state:
case mk.mk
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
C₁ C₂ : Set X
h₁ : IsClosed C₁
h₂ : IsClosed C₂
h✝ : C₁ ∪ C₂ = univ
h : (⋃ b, bif b then C₁ else C₂) = univ
inst✝ : DecidablePred fun x => x ∈ C₁
dZ : TopologicalSpace Z := ⊥
this : DiscreteTopology Z
f : ↑C₁ → Z
hf✝ : IsLocallyConstant f
hf : Continuous f
g : ↑C₂ → Z
hg✝ : IsLocallyConstant g
hg : Continuous g
hfg :
  ∀ (x : X) (hx : x ∈ C₁ ∩ C₂),
    { toFun := f, isLocallyConstant := hf✝ } { val := x, property := (_ : x ∈ C₁) } =
      { toFun := g, isLocallyConstant := hg✝ } { val := x, property := (_ : x ∈ C₂) }
⊢ Continuous fun i => if hi : i ∈ C₁ then f { val := i, property := hi } else g { val := i, property := (_ : i ∈ C₂) }

Next tactic:
refine' (locallyFinite_of_finite _).continuous h (fun i ↦ _) (fun i ↦ _)
/-- Given two closed sets covering a topological space, and locally constant maps on these two sets,
    then if these two locally constant maps agree on the intersection, we get a piecewise defined
    locally constant map on the whole space.

TODO: Generalise this construction to `ContinuousMap`. -/
def piecewise {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) (h : C₁ ∪ C₂ = Set.univ)
    (f : LocallyConstant C₁ Z) (g : LocallyConstant C₂ Z)
    (hfg : ∀ (x : X) (hx : x ∈ C₁ ∩ C₂), f ⟨x, hx.1⟩ = g ⟨x, hx.2⟩)
    [DecidablePred (· ∈ C₁)] : LocallyConstant X Z where
  toFun i := if hi : i ∈ C₁ then f ⟨i, hi⟩ else g ⟨i, (Set.compl_subset_iff_union.mpr h) hi⟩
  isLocallyConstant := by
    let dZ : TopologicalSpace Z := ⊥
    haveI : DiscreteTopology Z := discreteTopology_bot Z
    obtain ⟨f, hf⟩ := f
    obtain ⟨g, hg⟩ := g
    rw [IsLocallyConstant.iff_continuous] at hf hg ⊢
    dsimp only [coe_mk]
    rw [Set.union_eq_iUnion] at h
    refine' (locallyFinite_of_finite _).continuous h (fun i ↦ _) (fun i ↦ _)
    · 

Proof state:
case mk.mk.refine'_1
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
C₁ C₂ : Set X
h₁ : IsClosed C₁
h₂ : IsClosed C₂
h✝ : C₁ ∪ C₂ = univ
h : (⋃ b, bif b then C₁ else C₂) = univ
inst✝ : DecidablePred fun x => x ∈ C₁
dZ : TopologicalSpace Z := ⊥
this : DiscreteTopology Z
f : ↑C₁ → Z
hf✝ : IsLocallyConstant f
hf : Continuous f
g : ↑C₂ → Z
hg✝ : IsLocallyConstant g
hg : Continuous g
hfg :
  ∀ (x : X) (hx : x ∈ C₁ ∩ C₂),
    { toFun := f, isLocallyConstant := hf✝ } { val := x, property := (_ : x ∈ C₁) } =
      { toFun := g, isLocallyConstant := hg✝ } { val := x, property := (_ : x ∈ C₂) }
i : Bool
⊢ IsClosed (bif i then C₁ else C₂)

Next tactic:
cases i <;> [exact h₂; exact h₁]
/-- Given two closed sets covering a topological space, and locally constant maps on these two sets,
    then if these two locally constant maps agree on the intersection, we get a piecewise defined
    locally constant map on the whole space.

TODO: Generalise this construction to `ContinuousMap`. -/
def piecewise {C₁ C₂ : Set X} (h₁ : IsClosed C₁) (h₂ : IsClosed C₂) (h : C₁ ∪ C₂ = Set.univ)
    (f : LocallyConstant C₁ Z) (g : LocallyConstant C₂ Z)
    (hfg : ∀ (x : X) (hx : x ∈ C₁ ∩ C₂), f ⟨x, hx.1⟩ = g ⟨x, hx.2⟩)
    [DecidablePred (· ∈ C₁)] : LocallyConstant X Z where
  toFun i := if hi : i ∈ C₁ then f ⟨i, hi⟩ else g ⟨i, (Set.compl_subset_iff_union.mpr h) hi⟩
  isLocallyConstant := by
    let dZ : TopologicalSpace Z := ⊥
    haveI : DiscreteTopology Z := discreteTopology_bot Z
    obtain ⟨f, hf⟩ := f
    obtain ⟨g, hg⟩ := g
    rw [IsLocallyConstant.iff_continuous] at hf hg ⊢
    dsimp only [coe_mk]
    rw [Set.union_eq_iUnion] at h
    refine' (locallyFinite_of_finite _).continuous h (fun i ↦ _) (fun i ↦ _)
    · 

Proof state:
case mk.mk.refine'_1
X : Type u_1
Y : Type u_2
Z : Type u_3
α : Type u_4
inst✝¹ : TopologicalSpace X
C₁ C₂ : Set X
h₁ : IsClosed C₁
h₂ : IsClosed C₂
h✝ : C₁ ∪ C₂ = univ
h : (⋃ b, bif b then C₁ else C₂) = univ
inst✝ : DecidablePred fun x => x ∈ C₁
dZ : TopologicalSpace Z := ⊥
this : DiscreteTopology Z
f : ↑C₁ → Z
hf✝ : IsLocallyConstant f
hf : Continuous f
g : ↑C₂ → Z
hg✝ : IsLocallyConstant g
hg : Continuous g
hfg :
  ∀ (x : X) (hx : x ∈ C₁ ∩ C₂),
    { toFun := f, isLocallyConstant := hf✝ } { val := x, property := (_ : x ∈ C₁) } =
      { toFun := g, isLocallyConstant := hg✝ } { val := x, property := (_ : x ∈ C₂) }
i : Bool
⊢ IsClosed (bif i then C₁ else C₂)

Next tactic:
cases i