l3lab/ntp-mathlib huggingface dataset:
/-- The derivation on `MvPolynomial σ R` that takes value `f i` on `X i`. -/
def mkDerivation (f : σ → A) : Derivation R (MvPolynomial σ R) A where
  toLinearMap := mkDerivationₗ R f
  map_one_eq_zero' := mkDerivationₗ_C _ 1
  leibniz' :=
    (leibniz_iff_X (mkDerivationₗ R f) (mkDerivationₗ_C _ 1)).2 fun s i => by
      simp only [mkDerivationₗ_monomial, X, monomial_mul, one_smul, one_mul]
      rw [Finsupp.sum_add_index'] <;>
        [skip; simp; (intros; simp only [Nat.cast_add, (monomial _).map_add, add_smul])]
      rw [Finsupp.sum_single_index, Finsupp.sum_single_index] <;> [skip; simp; simp]
      rw [tsub_self, add_tsub_cancel_right, Nat.cast_one, ← C_apply, C_1, one_smul, add_comm,
        Finsupp.smul_sum]
      

Proof state:
σ : Type u_1
R : Type u_2
A : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid A
inst✝² : Module R A
inst✝¹ : Module (MvPolynomial σ R) A
inst✝ : IsScalarTower R (MvPolynomial σ R) A
f : σ → A
s : σ →₀ ℕ
i : σ
⊢ ((monomial s) 1 • f i + Finsupp.sum s fun i_1 k => (monomial ((s + fun₀ | i => 1) - fun₀ | i_1 => 1)) ↑k • f i_1) =
    (monomial s) 1 • f i + Finsupp.sum s fun a b => (monomial fun₀ | i => 1) 1 • (monomial (s - fun₀ | a => 1)) ↑b • f a

Next tactic:
refine' congr_arg₂ (· + ·) rfl (Finset.sum_congr rfl fun j hj => _)
/-- The derivation on `MvPolynomial σ R` that takes value `f i` on `X i`. -/
def mkDerivation (f : σ → A) : Derivation R (MvPolynomial σ R) A where
  toLinearMap := mkDerivationₗ R f
  map_one_eq_zero' := mkDerivationₗ_C _ 1
  leibniz' :=
    (leibniz_iff_X (mkDerivationₗ R f) (mkDerivationₗ_C _ 1)).2 fun s i => by
      simp only [mkDerivationₗ_monomial, X, monomial_mul, one_smul, one_mul]
      rw [Finsupp.sum_add_index'] <;>
        [skip; simp; (intros; simp only [Nat.cast_add, (monomial _).map_add, add_smul])]
      rw [Finsupp.sum_single_index, Finsupp.sum_single_index] <;> [skip; simp; simp]
      rw [tsub_self, add_tsub_cancel_right, Nat.cast_one, ← C_apply, C_1, one_smul, add_comm,
        Finsupp.smul_sum]
      refine' congr_arg₂ (· + ·) rfl (Finset.sum_congr rfl fun j hj => _); 

Proof state:
σ : Type u_1
R : Type u_2
A : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid A
inst✝² : Module R A
inst✝¹ : Module (MvPolynomial σ R) A
inst✝ : IsScalarTower R (MvPolynomial σ R) A
f : σ → A
s : σ →₀ ℕ
i j : σ
hj : j ∈ s.support
⊢ (fun i_1 k => (monomial ((s + fun₀ | i => 1) - fun₀ | i_1 => 1)) ↑k • f i_1) j (s j) =
    (fun a b => (monomial fun₀ | i => 1) 1 • (monomial (s - fun₀ | a => 1)) ↑b • f a) j (s j)

Next tactic:
dsimp only
/-- The derivation on `MvPolynomial σ R` that takes value `f i` on `X i`. -/
def mkDerivation (f : σ → A) : Derivation R (MvPolynomial σ R) A where
  toLinearMap := mkDerivationₗ R f
  map_one_eq_zero' := mkDerivationₗ_C _ 1
  leibniz' :=
    (leibniz_iff_X (mkDerivationₗ R f) (mkDerivationₗ_C _ 1)).2 fun s i => by
      simp only [mkDerivationₗ_monomial, X, monomial_mul, one_smul, one_mul]
      rw [Finsupp.sum_add_index'] <;>
        [skip; simp; (intros; simp only [Nat.cast_add, (monomial _).map_add, add_smul])]
      rw [Finsupp.sum_single_index, Finsupp.sum_single_index] <;> [skip; simp; simp]
      rw [tsub_self, add_tsub_cancel_right, Nat.cast_one, ← C_apply, C_1, one_smul, add_comm,
        Finsupp.smul_sum]
      refine' congr_arg₂ (· + ·) rfl (Finset.sum_congr rfl fun j hj => _); dsimp only
      

Proof state:
σ : Type u_1
R : Type u_2
A : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid A
inst✝² : Module R A
inst✝¹ : Module (MvPolynomial σ R) A
inst✝ : IsScalarTower R (MvPolynomial σ R) A
f : σ → A
s : σ →₀ ℕ
i j : σ
hj : j ∈ s.support
⊢ (monomial ((s + fun₀ | i => 1) - fun₀ | j => 1)) ↑(s j) • f j =
    (monomial fun₀ | i => 1) 1 • (monomial (s - fun₀ | j => 1)) ↑(s j) • f j

Next tactic:
rw [smul_smul, monomial_mul, one_mul, add_comm s, add_tsub_assoc_of_le]
/-- The derivation on `MvPolynomial σ R` that takes value `f i` on `X i`. -/
def mkDerivation (f : σ → A) : Derivation R (MvPolynomial σ R) A where
  toLinearMap := mkDerivationₗ R f
  map_one_eq_zero' := mkDerivationₗ_C _ 1
  leibniz' :=
    (leibniz_iff_X (mkDerivationₗ R f) (mkDerivationₗ_C _ 1)).2 fun s i => by
      simp only [mkDerivationₗ_monomial, X, monomial_mul, one_smul, one_mul]
      rw [Finsupp.sum_add_index'] <;>
        [skip; simp; (intros; simp only [Nat.cast_add, (monomial _).map_add, add_smul])]
      rw [Finsupp.sum_single_index, Finsupp.sum_single_index] <;> [skip; simp; simp]
      rw [tsub_self, add_tsub_cancel_right, Nat.cast_one, ← C_apply, C_1, one_smul, add_comm,
        Finsupp.smul_sum]
      refine' congr_arg₂ (· + ·) rfl (Finset.sum_congr rfl fun j hj => _); dsimp only
      rw [smul_smul, monomial_mul, one_mul, add_comm s, add_tsub_assoc_of_le]
      

Proof state:
case h
σ : Type u_1
R : Type u_2
A : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid A
inst✝² : Module R A
inst✝¹ : Module (MvPolynomial σ R) A
inst✝ : IsScalarTower R (MvPolynomial σ R) A
f : σ → A
s : σ →₀ ℕ
i j : σ
hj : j ∈ s.support
⊢ (fun₀ | j => 1) ≤ s

Next tactic:
rwa [Finsupp.single_le_iff, Nat.succ_le_iff, pos_iff_ne_zero, ← Finsupp.mem_support_iff]
theorem isOpenImmersion_iff_stalk {f : X ⟶ Y} : IsOpenImmersion f ↔
    OpenEmbedding f.1.base ∧ ∀ x, IsIso (PresheafedSpace.stalkMap f.1 x) := by
  

Proof state:
X Y Z : Scheme
f✝ : X ⟶ Y
g : Y ⟶ Z
f : X ⟶ Y
⊢ IsOpenImmersion f ↔
    OpenEmbedding ⇑f.val.base ∧ ∀ (x : ↑↑X.toPresheafedSpace), IsIso (PresheafedSpace.stalkMap f.val x)

Next tactic:
constructor
theorem isOpenImmersion_iff_stalk {f : X ⟶ Y} : IsOpenImmersion f ↔
    OpenEmbedding f.1.base ∧ ∀ x, IsIso (PresheafedSpace.stalkMap f.1 x) := by
  constructor
  · 

Proof state:
case mp
X Y Z : Scheme
f✝ : X ⟶ Y
g : Y ⟶ Z
f : X ⟶ Y
⊢ IsOpenImmersion f →
    OpenEmbedding ⇑f.val.base ∧ ∀ (x : ↑↑X.toPresheafedSpace), IsIso (PresheafedSpace.stalkMap f.val x)

Next tactic:
intro h
theorem isOpenImmersion_iff_stalk {f : X ⟶ Y} : IsOpenImmersion f ↔
    OpenEmbedding f.1.base ∧ ∀ x, IsIso (PresheafedSpace.stalkMap f.1 x) := by
  constructor
  · intro h; 

Proof state:
case mp
X Y Z : Scheme
f✝ : X ⟶ Y
g : Y ⟶ Z
f : X ⟶ Y
h : IsOpenImmersion f
⊢ OpenEmbedding ⇑f.val.base ∧ ∀ (x : ↑↑X.toPresheafedSpace), IsIso (PresheafedSpace.stalkMap f.val x)

Next tactic:
exact ⟨h.1, inferInstance⟩
theorem isOpenImmersion_iff_stalk {f : X ⟶ Y} : IsOpenImmersion f ↔
    OpenEmbedding f.1.base ∧ ∀ x, IsIso (PresheafedSpace.stalkMap f.1 x) := by
  constructor
  · intro h; exact ⟨h.1, inferInstance⟩
  · 

Proof state:
case mpr
X Y Z : Scheme
f✝ : X ⟶ Y
g : Y ⟶ Z
f : X ⟶ Y
⊢ (OpenEmbedding ⇑f.val.base ∧ ∀ (x : ↑↑X.toPresheafedSpace), IsIso (PresheafedSpace.stalkMap f.val x)) →
    IsOpenImmersion f

Next tactic:
rintro ⟨h₁, h₂⟩
theorem isOpenImmersion_iff_stalk {f : X ⟶ Y} : IsOpenImmersion f ↔
    OpenEmbedding f.1.base ∧ ∀ x, IsIso (PresheafedSpace.stalkMap f.1 x) := by
  constructor
  · intro h; exact ⟨h.1, inferInstance⟩
  · rintro ⟨h₁, h₂⟩; 

Proof state:
case mpr.intro
X Y Z : Scheme
f✝ : X ⟶ Y
g : Y ⟶ Z
f : X ⟶ Y
h₁ : OpenEmbedding ⇑f.val.base
h₂ : ∀ (x : ↑↑X.toPresheafedSpace), IsIso (PresheafedSpace.stalkMap f.val x)
⊢ IsOpenImmersion f

Next tactic:
exact IsOpenImmersion.of_stalk_iso f h₁
theorem isOpenImmersion_stableUnderComposition :
    MorphismProperty.StableUnderComposition @IsOpenImmersion := by
  

Proof state:
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
⊢ MorphismProperty.StableUnderComposition @IsOpenImmersion

Next tactic:
intro X Y Z f g h₁ h₂
theorem isOpenImmersion_stableUnderComposition :
    MorphismProperty.StableUnderComposition @IsOpenImmersion := by
  intro X Y Z f g h₁ h₂; 

Proof state:
X✝ Y✝ Z✝ : Scheme
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
h₁ : IsOpenImmersion f
h₂ : IsOpenImmersion g
⊢ IsOpenImmersion (f ≫ g)

Next tactic:
exact LocallyRingedSpace.IsOpenImmersion.comp f g
theorem isOpenImmersion_respectsIso : MorphismProperty.RespectsIso @IsOpenImmersion := by
  

Proof state:
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
⊢ MorphismProperty.RespectsIso @IsOpenImmersion

Next tactic:
apply isOpenImmersion_stableUnderComposition.respectsIso
theorem isOpenImmersion_respectsIso : MorphismProperty.RespectsIso @IsOpenImmersion := by
  apply isOpenImmersion_stableUnderComposition.respectsIso
  

Proof state:
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
⊢ ∀ {X Y : Scheme} (e : X ≅ Y), IsOpenImmersion e.hom

Next tactic:
intro _ _ _
theorem isOpenImmersion_respectsIso : MorphismProperty.RespectsIso @IsOpenImmersion := by
  apply isOpenImmersion_stableUnderComposition.respectsIso
  intro _ _ _; 

Proof state:
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
X✝ Y✝ : Scheme
e✝ : X✝ ≅ Y✝
⊢ IsOpenImmersion e✝.hom

Next tactic:
infer_instance
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  

Proof state:
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
⊢ PropertyIsLocalAtTarget @IsOpenImmersion

Next tactic:
constructor
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · 

Proof state:
case RespectsIso
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
⊢ MorphismProperty.RespectsIso @IsOpenImmersion

Next tactic:
exact isOpenImmersion_respectsIso
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · 

Proof state:
case restrict
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
⊢ ∀ {X Y : Scheme} (f : X ⟶ Y) (U : Opens ↑↑Y.toPresheafedSpace), IsOpenImmersion f → IsOpenImmersion (f ∣_ U)

Next tactic:
intros
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · intros; 

Proof state:
case restrict
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
X✝ Y✝ : Scheme
f✝ : X✝ ⟶ Y✝
U✝ : Opens ↑↑Y✝.toPresheafedSpace
a✝ : IsOpenImmersion f✝
⊢ IsOpenImmersion (f✝ ∣_ U✝)

Next tactic:
infer_instance
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · intros; infer_instance
  · 

Proof state:
case of_openCover
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
⊢ ∀ {X Y : Scheme} (f : X ⟶ Y) (𝒰 : Scheme.OpenCover Y), (∀ (i : 𝒰.J), IsOpenImmersion pullback.snd) → IsOpenImmersion f

Next tactic:
intro X Y f 𝒰 H
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · intros; infer_instance
  · intro X Y f 𝒰 H
    

Proof state:
case of_openCover
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Y✝
g : Y✝ ⟶ Z
X Y : Scheme
f : X ⟶ Y
𝒰 : Scheme.OpenCover Y
H : ∀ (i : 𝒰.J), IsOpenImmersion pullback.snd
⊢ IsOpenImmersion f

Next tactic:
rw [isOpenImmersion_iff_stalk]
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · intros; infer_instance
  · intro X Y f 𝒰 H
    rw [isOpenImmersion_iff_stalk]
    

Proof state:
case of_openCover
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Y✝
g : Y✝ ⟶ Z
X Y : Scheme
f : X ⟶ Y
𝒰 : Scheme.OpenCover Y
H : ∀ (i : 𝒰.J), IsOpenImmersion pullback.snd
⊢ OpenEmbedding ⇑f.val.base ∧ ∀ (x : ↑↑X.toPresheafedSpace), IsIso (PresheafedSpace.stalkMap f.val x)

Next tactic:
constructor
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · intros; infer_instance
  · intro X Y f 𝒰 H
    rw [isOpenImmersion_iff_stalk]
    constructor
    · 

Proof state:
case of_openCover.left
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Y✝
g : Y✝ ⟶ Z
X Y : Scheme
f : X ⟶ Y
𝒰 : Scheme.OpenCover Y
H : ∀ (i : 𝒰.J), IsOpenImmersion pullback.snd
⊢ OpenEmbedding ⇑f.val.base

Next tactic:
apply (openEmbedding_iff_openEmbedding_of_iSup_eq_top 𝒰.iSup_opensRange f.1.base.2).mpr
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · intros; infer_instance
  · intro X Y f 𝒰 H
    rw [isOpenImmersion_iff_stalk]
    constructor
    · apply (openEmbedding_iff_openEmbedding_of_iSup_eq_top 𝒰.iSup_opensRange f.1.base.2).mpr
      

Proof state:
case of_openCover.left
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Y✝
g : Y✝ ⟶ Z
X Y : Scheme
f : X ⟶ Y
𝒰 : Scheme.OpenCover Y
H : ∀ (i : 𝒰.J), IsOpenImmersion pullback.snd
⊢ ∀ (i : 𝒰.J),
    OpenEmbedding (Set.restrictPreimage (Scheme.Hom.opensRange (Scheme.OpenCover.map 𝒰 i)).carrier f.val.base.toFun)

Next tactic:
intro i
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · intros; infer_instance
  · intro X Y f 𝒰 H
    rw [isOpenImmersion_iff_stalk]
    constructor
    · apply (openEmbedding_iff_openEmbedding_of_iSup_eq_top 𝒰.iSup_opensRange f.1.base.2).mpr
      intro i
      

Proof state:
case of_openCover.left
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Y✝
g : Y✝ ⟶ Z
X Y : Scheme
f : X ⟶ Y
𝒰 : Scheme.OpenCover Y
H : ∀ (i : 𝒰.J), IsOpenImmersion pullback.snd
i : 𝒰.J
⊢ OpenEmbedding (Set.restrictPreimage (Scheme.Hom.opensRange (Scheme.OpenCover.map 𝒰 i)).carrier f.val.base.toFun)

Next tactic:
have := ((isOpenImmersion_respectsIso.arrow_iso_iff
        (morphismRestrictOpensRange f (𝒰.map i))).mpr (H i)).1
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · intros; infer_instance
  · intro X Y f 𝒰 H
    rw [isOpenImmersion_iff_stalk]
    constructor
    · apply (openEmbedding_iff_openEmbedding_of_iSup_eq_top 𝒰.iSup_opensRange f.1.base.2).mpr
      intro i
      have := ((isOpenImmersion_respectsIso.arrow_iso_iff
        (morphismRestrictOpensRange f (𝒰.map i))).mpr (H i)).1
      

Proof state:
case of_openCover.left
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Y✝
g : Y✝ ⟶ Z
X Y : Scheme
f : X ⟶ Y
𝒰 : Scheme.OpenCover Y
H : ∀ (i : 𝒰.J), IsOpenImmersion pullback.snd
i : 𝒰.J
this : OpenEmbedding ⇑(Arrow.mk (f ∣_ Scheme.Hom.opensRange (Scheme.OpenCover.map 𝒰 i))).hom.val.base
⊢ OpenEmbedding (Set.restrictPreimage (Scheme.Hom.opensRange (Scheme.OpenCover.map 𝒰 i)).carrier f.val.base.toFun)

Next tactic:
erw [Arrow.mk_hom, morphismRestrict_val_base] at this
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · intros; infer_instance
  · intro X Y f 𝒰 H
    rw [isOpenImmersion_iff_stalk]
    constructor
    · apply (openEmbedding_iff_openEmbedding_of_iSup_eq_top 𝒰.iSup_opensRange f.1.base.2).mpr
      intro i
      have := ((isOpenImmersion_respectsIso.arrow_iso_iff
        (morphismRestrictOpensRange f (𝒰.map i))).mpr (H i)).1
      erw [Arrow.mk_hom, morphismRestrict_val_base] at this
      

Proof state:
case of_openCover.left
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Y✝
g : Y✝ ⟶ Z
X Y : Scheme
f : X ⟶ Y
𝒰 : Scheme.OpenCover Y
H : ∀ (i : 𝒰.J), IsOpenImmersion pullback.snd
i : 𝒰.J
this : OpenEmbedding (Set.restrictPreimage (Scheme.Hom.opensRange (Scheme.OpenCover.map 𝒰 i)).carrier ⇑f.val.base)
⊢ OpenEmbedding (Set.restrictPreimage (Scheme.Hom.opensRange (Scheme.OpenCover.map 𝒰 i)).carrier f.val.base.toFun)

Next tactic:
norm_cast
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · intros; infer_instance
  · intro X Y f 𝒰 H
    rw [isOpenImmersion_iff_stalk]
    constructor
    · apply (openEmbedding_iff_openEmbedding_of_iSup_eq_top 𝒰.iSup_opensRange f.1.base.2).mpr
      intro i
      have := ((isOpenImmersion_respectsIso.arrow_iso_iff
        (morphismRestrictOpensRange f (𝒰.map i))).mpr (H i)).1
      erw [Arrow.mk_hom, morphismRestrict_val_base] at this
      norm_cast
    · 

Proof state:
case of_openCover.right
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Y✝
g : Y✝ ⟶ Z
X Y : Scheme
f : X ⟶ Y
𝒰 : Scheme.OpenCover Y
H : ∀ (i : 𝒰.J), IsOpenImmersion pullback.snd
⊢ ∀ (x : ↑↑X.toPresheafedSpace), IsIso (PresheafedSpace.stalkMap f.val x)

Next tactic:
intro x
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · intros; infer_instance
  · intro X Y f 𝒰 H
    rw [isOpenImmersion_iff_stalk]
    constructor
    · apply (openEmbedding_iff_openEmbedding_of_iSup_eq_top 𝒰.iSup_opensRange f.1.base.2).mpr
      intro i
      have := ((isOpenImmersion_respectsIso.arrow_iso_iff
        (morphismRestrictOpensRange f (𝒰.map i))).mpr (H i)).1
      erw [Arrow.mk_hom, morphismRestrict_val_base] at this
      norm_cast
    · intro x
      

Proof state:
case of_openCover.right
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Y✝
g : Y✝ ⟶ Z
X Y : Scheme
f : X ⟶ Y
𝒰 : Scheme.OpenCover Y
H : ∀ (i : 𝒰.J), IsOpenImmersion pullback.snd
x : ↑↑X.toPresheafedSpace
⊢ IsIso (PresheafedSpace.stalkMap f.val x)

Next tactic:
have := Arrow.iso_w (morphismRestrictStalkMap
        f (Scheme.Hom.opensRange (𝒰.map <| 𝒰.f <| f.1.base x)) ⟨x, 𝒰.Covers _⟩)
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · intros; infer_instance
  · intro X Y f 𝒰 H
    rw [isOpenImmersion_iff_stalk]
    constructor
    · apply (openEmbedding_iff_openEmbedding_of_iSup_eq_top 𝒰.iSup_opensRange f.1.base.2).mpr
      intro i
      have := ((isOpenImmersion_respectsIso.arrow_iso_iff
        (morphismRestrictOpensRange f (𝒰.map i))).mpr (H i)).1
      erw [Arrow.mk_hom, morphismRestrict_val_base] at this
      norm_cast
    · intro x
      have := Arrow.iso_w (morphismRestrictStalkMap
        f (Scheme.Hom.opensRange (𝒰.map <| 𝒰.f <| f.1.base x)) ⟨x, 𝒰.Covers _⟩)
      

Proof state:
case of_openCover.right
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Y✝
g : Y✝ ⟶ Z
X Y : Scheme
f : X ⟶ Y
𝒰 : Scheme.OpenCover Y
H : ∀ (i : 𝒰.J), IsOpenImmersion pullback.snd
x : ↑↑X.toPresheafedSpace
this :
  (Arrow.mk
        (PresheafedSpace.stalkMap f.val
          ↑{ val := x,
              property :=
                (_ :
                  f.val.base x ∈
                    Set.range ⇑(Scheme.OpenCover.map 𝒰 (Scheme.OpenCover.f 𝒰 (f.val.base x))).val.base) })).hom =
    (morphismRestrictStalkMap f (Scheme.Hom.opensRange (Scheme.OpenCover.map 𝒰 (Scheme.OpenCover.f 𝒰 (f.val.base x))))
            { val := x,
              property :=
                (_ :
                  f.val.base x ∈
                    Set.range ⇑(Scheme.OpenCover.map 𝒰 (Scheme.OpenCover.f 𝒰 (f.val.base x))).val.base) }).inv.left ≫
      (Arrow.mk
            (PresheafedSpace.stalkMap
              (f ∣_ Scheme.Hom.opensRange (Scheme.OpenCover.map 𝒰 (Scheme.OpenCover.f 𝒰 (f.val.base x)))).val
              { val := x,
                property :=
                  (_ :
                    f.val.base x ∈
                      Set.range ⇑(Scheme.OpenCover.map 𝒰 (Scheme.OpenCover.f 𝒰 (f.val.base x))).val.base) })).hom ≫
        (morphismRestrictStalkMap f
              (Scheme.Hom.opensRange (Scheme.OpenCover.map 𝒰 (Scheme.OpenCover.f 𝒰 (f.val.base x))))
              { val := x,
                property :=
                  (_ :
                    f.val.base x ∈
                      Set.range ⇑(Scheme.OpenCover.map 𝒰 (Scheme.OpenCover.f 𝒰 (f.val.base x))).val.base) }).hom.right
⊢ IsIso (PresheafedSpace.stalkMap f.val x)

Next tactic:
dsimp only [Arrow.mk_hom] at this
theorem isOpenImmersion_is_local_at_target : PropertyIsLocalAtTarget @IsOpenImmersion := by
  constructor
  · exact isOpenImmersion_respectsIso
  · intros; infer_instance
  · intro X Y f 𝒰 H
    rw [isOpenImmersion_iff_stalk]
    constructor
    · apply (openEmbedding_iff_openEmbedding_of_iSup_eq_top 𝒰.iSup_opensRange f.1.base.2).mpr
      intro i
      have := ((isOpenImmersion_respectsIso.arrow_iso_iff
        (morphismRestrictOpensRange f (𝒰.map i))).mpr (H i)).1
      erw [Arrow.mk_hom, morphismRestrict_val_base] at this
      norm_cast
    · intro x
      have := Arrow.iso_w (morphismRestrictStalkMap
        f (Scheme.Hom.opensRange (𝒰.map <| 𝒰.f <| f.1.base x)) ⟨x, 𝒰.Covers _⟩)
      dsimp only [Arrow.mk_hom] at this
      

Proof state:
case of_openCover.right
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Y✝
g : Y✝ ⟶ Z
X Y : Scheme
f : X ⟶ Y
𝒰 : Scheme.OpenCover Y
H : ∀ (i : 𝒰.J), IsOpenImmersion pullback.snd
x : ↑↑X.toPresheafedSpace
this :
  PresheafedSpace.stalkMap f.val x =
    (morphismRestrictStalkMap f (Scheme.Hom.opensRange (Scheme.OpenCover.map 𝒰 (Scheme.OpenCover.f 𝒰 (f.val.base x))))
            { val := x,
              property :=
                (_ :
                  f.val.base x ∈
                    Set.range ⇑(Scheme.OpenCover.map 𝒰 (Scheme.OpenCover.f 𝒰 (f.val.base x))).val.base) }).inv.left ≫
      PresheafedSpace.stalkMap
          (f ∣_ Scheme.Hom.opensRange (Scheme.OpenCover.map 𝒰 (Scheme.OpenCover.f 𝒰 (f.val.base x)))).val
          { val := x,
            property :=
              (_ :
                f.val.base x ∈ Set.range ⇑(Scheme.OpenCover.map 𝒰 (Scheme.OpenCover.f 𝒰 (f.val.base x))).val.base) } ≫
        (morphismRestrictStalkMap f
              (Scheme.Hom.opensRange (Scheme.OpenCover.map 𝒰 (Scheme.OpenCover.f 𝒰 (f.val.base x))))
              { val := x,
                property :=
                  (_ :
                    f.val.base x ∈
                      Set.range ⇑(Scheme.OpenCover.map 𝒰 (Scheme.OpenCover.f 𝒰 (f.val.base x))).val.base) }).hom.right
⊢ IsIso (PresheafedSpace.stalkMap f.val x)

Next tactic:
rw [this]
theorem isOpenImmersion_stableUnderBaseChange :
    MorphismProperty.StableUnderBaseChange @IsOpenImmersion :=
  MorphismProperty.StableUnderBaseChange.mk isOpenImmersion_respectsIso <| by
    

Proof state:
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
⊢ ∀ (X Y S : Scheme) (f : X ⟶ S) (g : Y ⟶ S), IsOpenImmersion g → IsOpenImmersion pullback.fst

Next tactic:
intro X Y Z f g H
theorem isOpenImmersion_stableUnderBaseChange :
    MorphismProperty.StableUnderBaseChange @IsOpenImmersion :=
  MorphismProperty.StableUnderBaseChange.mk isOpenImmersion_respectsIso <| by
    intro X Y Z f g H; 

Proof state:
X✝ Y✝ Z✝ : Scheme
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion g
⊢ IsOpenImmersion pullback.fst

Next tactic:
infer_instance
/-- The downward **local LYM inequality**, with cancelled denominators. `𝒜` takes up less of `α^(r)`
(the finsets of card `r`) than `∂𝒜` takes up of `α^(r - 1)`. -/
theorem card_mul_le_card_shadow_mul (h𝒜 : (𝒜 : Set (Finset α)).Sized r) :
    𝒜.card * r ≤ (∂ 𝒜).card * (Fintype.card α - r + 1) := by
  

Proof state:
𝕜 : Type u_1
α : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
inst✝ : Fintype α
𝒜 : Finset (Finset α)
r : ℕ
h𝒜 : Set.Sized r ↑𝒜
⊢ card 𝒜 * r ≤ card (∂ 𝒜) * (Fintype.card α - r + 1)

Next tactic:
let i : DecidableRel ((· ⊆ ·) : Finset α → Finset α → Prop) := fun _ _ => Classical.dec _
/-- The downward **local LYM inequality**, with cancelled denominators. `𝒜` takes up less of `α^(r)`
(the finsets of card `r`) than `∂𝒜` takes up of `α^(r - 1)`. -/
theorem card_mul_le_card_shadow_mul (h𝒜 : (𝒜 : Set (Finset α)).Sized r) :
    𝒜.card * r ≤ (∂ 𝒜).card * (Fintype.card α - r + 1) := by
  let i : DecidableRel ((· ⊆ ·) : Finset α → Finset α → Prop) := fun _ _ => Classical.dec _
  

Proof state:
𝕜 : Type u_1
α : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
inst✝ : Fintype α
𝒜 : Finset (Finset α)
r : ℕ
h𝒜 : Set.Sized r ↑𝒜
i : DecidableRel fun x x_1 => x ⊆ x_1 := fun x x_1 => Classical.dec ((fun x x_2 => x ⊆ x_2) x x_1)
⊢ card 𝒜 * r ≤ card (∂ 𝒜) * (Fintype.card α - r + 1)

Next tactic:
refine' card_mul_le_card_mul' (· ⊆ ·) (fun s hs => _) (fun s hs => _)
/-- The downward **local LYM inequality**, with cancelled denominators. `𝒜` takes up less of `α^(r)`
(the finsets of card `r`) than `∂𝒜` takes up of `α^(r - 1)`. -/
theorem card_mul_le_card_shadow_mul (h𝒜 : (𝒜 : Set (Finset α)).Sized r) :
    𝒜.card * r ≤ (∂ 𝒜).card * (Fintype.card α - r + 1) := by
  let i : DecidableRel ((· ⊆ ·) : Finset α → Finset α → Prop) := fun _ _ => Classical.dec _
  refine' card_mul_le_card_mul' (· ⊆ ·) (fun s hs => _) (fun s hs => _)
  · 

Proof state:
case refine'_1
𝕜 : Type u_1
α : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
inst✝ : Fintype α
𝒜 : Finset (Finset α)
r : ℕ
h𝒜 : Set.Sized r ↑𝒜
i : DecidableRel fun x x_1 => x ⊆ x_1 := fun x x_1 => Classical.dec ((fun x x_2 => x ⊆ x_2) x x_1)
s : Finset α
hs : s ∈ 𝒜
⊢ r ≤ card (bipartiteBelow (fun x x_1 => x ⊆ x_1) (∂ 𝒜) s)

Next tactic:
rw [← h𝒜 hs, ← card_image_of_injOn s.erase_injOn]