l3lab/ntp-mathlib huggingface dataset:
theorem openCover_TFAE {X Y : Scheme.{u}} [IsAffine Y] (f : X ⟶ Y) :
    List.TFAE
      [sourceAffineLocally (@P) f,
        ∃ 𝒰 : Scheme.OpenCover.{u} X, ∀ i : 𝒰.J, sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ (𝒰 : Scheme.OpenCover.{u} X) (i : 𝒰.J), sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ {U : Scheme} (g : U ⟶ X) [IsOpenImmersion g], sourceAffineLocally (@P) (g ≫ f)] := by
  tfae_have 1 → 4
  · intro H U g hg V
    skip
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 3
    rw [this] at H
    haveI : IsAffine _ := V.2
    rw [← Category.assoc]
    -- Porting note: Lean could find this previously
    have : IsOpenImmersion <| (Scheme.ofRestrict U (Opens.openEmbedding V.val)) ≫ g :=
      LocallyRingedSpace.IsOpenImmersion.comp _ _
    apply H
  tfae_have 4 → 3
  · intro H 𝒰 _ i; skip; apply H
  tfae_have 3 → 2
  · intro H; refine' ⟨X.affineCover, H _⟩
  tfae_have 2 → 1
  · rintro ⟨𝒰, h𝒰⟩
    -- Porting note: this has metavariable if I put it directly into rw
    

Proof state:
case tfae_2_to_1.intro
P : {R S : Type u} → [inst : CommRing R] → [inst_1 : CommRing S] → (R →+* S) → Prop
hP : PropertyIsLocal P
X Y : Scheme
inst✝ : IsAffine Y
f : X ⟶ Y
tfae_1_to_4 :
  sourceAffineLocally P f → ∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)
tfae_4_to_3 :
  (∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)) →
    ∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
tfae_3_to_2 :
  (∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)) →
    ∃ 𝒰, ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
𝒰 : Scheme.OpenCover X
h𝒰 : ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
⊢ sourceAffineLocally P f

Next tactic:
have := (hP.affine_openCover_TFAE f).out 0 1
theorem openCover_TFAE {X Y : Scheme.{u}} [IsAffine Y] (f : X ⟶ Y) :
    List.TFAE
      [sourceAffineLocally (@P) f,
        ∃ 𝒰 : Scheme.OpenCover.{u} X, ∀ i : 𝒰.J, sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ (𝒰 : Scheme.OpenCover.{u} X) (i : 𝒰.J), sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ {U : Scheme} (g : U ⟶ X) [IsOpenImmersion g], sourceAffineLocally (@P) (g ≫ f)] := by
  tfae_have 1 → 4
  · intro H U g hg V
    skip
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 3
    rw [this] at H
    haveI : IsAffine _ := V.2
    rw [← Category.assoc]
    -- Porting note: Lean could find this previously
    have : IsOpenImmersion <| (Scheme.ofRestrict U (Opens.openEmbedding V.val)) ≫ g :=
      LocallyRingedSpace.IsOpenImmersion.comp _ _
    apply H
  tfae_have 4 → 3
  · intro H 𝒰 _ i; skip; apply H
  tfae_have 3 → 2
  · intro H; refine' ⟨X.affineCover, H _⟩
  tfae_have 2 → 1
  · rintro ⟨𝒰, h𝒰⟩
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 1
    

Proof state:
case tfae_2_to_1.intro
P : {R S : Type u} → [inst : CommRing R] → [inst_1 : CommRing S] → (R →+* S) → Prop
hP : PropertyIsLocal P
X Y : Scheme
inst✝ : IsAffine Y
f : X ⟶ Y
tfae_1_to_4 :
  sourceAffineLocally P f → ∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)
tfae_4_to_3 :
  (∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)) →
    ∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
tfae_3_to_2 :
  (∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)) →
    ∃ 𝒰, ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
𝒰 : Scheme.OpenCover X
h𝒰 : ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
this :
  sourceAffineLocally P f ↔
    ∃ 𝒰,
      ∃ (_ : ∀ (i : 𝒰.J), IsAffine (Scheme.OpenCover.obj 𝒰 i)),
        ∀ (i : 𝒰.J), P (Scheme.Γ.map (Scheme.OpenCover.map 𝒰 i ≫ f).op)
⊢ sourceAffineLocally P f

Next tactic:
rw [this]
theorem openCover_TFAE {X Y : Scheme.{u}} [IsAffine Y] (f : X ⟶ Y) :
    List.TFAE
      [sourceAffineLocally (@P) f,
        ∃ 𝒰 : Scheme.OpenCover.{u} X, ∀ i : 𝒰.J, sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ (𝒰 : Scheme.OpenCover.{u} X) (i : 𝒰.J), sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ {U : Scheme} (g : U ⟶ X) [IsOpenImmersion g], sourceAffineLocally (@P) (g ≫ f)] := by
  tfae_have 1 → 4
  · intro H U g hg V
    skip
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 3
    rw [this] at H
    haveI : IsAffine _ := V.2
    rw [← Category.assoc]
    -- Porting note: Lean could find this previously
    have : IsOpenImmersion <| (Scheme.ofRestrict U (Opens.openEmbedding V.val)) ≫ g :=
      LocallyRingedSpace.IsOpenImmersion.comp _ _
    apply H
  tfae_have 4 → 3
  · intro H 𝒰 _ i; skip; apply H
  tfae_have 3 → 2
  · intro H; refine' ⟨X.affineCover, H _⟩
  tfae_have 2 → 1
  · rintro ⟨𝒰, h𝒰⟩
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 1
    rw [this]
    

Proof state:
case tfae_2_to_1.intro
P : {R S : Type u} → [inst : CommRing R] → [inst_1 : CommRing S] → (R →+* S) → Prop
hP : PropertyIsLocal P
X Y : Scheme
inst✝ : IsAffine Y
f : X ⟶ Y
tfae_1_to_4 :
  sourceAffineLocally P f → ∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)
tfae_4_to_3 :
  (∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)) →
    ∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
tfae_3_to_2 :
  (∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)) →
    ∃ 𝒰, ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
𝒰 : Scheme.OpenCover X
h𝒰 : ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
this :
  sourceAffineLocally P f ↔
    ∃ 𝒰,
      ∃ (_ : ∀ (i : 𝒰.J), IsAffine (Scheme.OpenCover.obj 𝒰 i)),
        ∀ (i : 𝒰.J), P (Scheme.Γ.map (Scheme.OpenCover.map 𝒰 i ≫ f).op)
⊢ ∃ 𝒰,
    ∃ (_ : ∀ (i : 𝒰.J), IsAffine (Scheme.OpenCover.obj 𝒰 i)),
      ∀ (i : 𝒰.J), P (Scheme.Γ.map (Scheme.OpenCover.map 𝒰 i ≫ f).op)

Next tactic:
refine' ⟨𝒰.bind fun _ => Scheme.affineCover _, _, _⟩
theorem openCover_TFAE {X Y : Scheme.{u}} [IsAffine Y] (f : X ⟶ Y) :
    List.TFAE
      [sourceAffineLocally (@P) f,
        ∃ 𝒰 : Scheme.OpenCover.{u} X, ∀ i : 𝒰.J, sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ (𝒰 : Scheme.OpenCover.{u} X) (i : 𝒰.J), sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ {U : Scheme} (g : U ⟶ X) [IsOpenImmersion g], sourceAffineLocally (@P) (g ≫ f)] := by
  tfae_have 1 → 4
  · intro H U g hg V
    skip
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 3
    rw [this] at H
    haveI : IsAffine _ := V.2
    rw [← Category.assoc]
    -- Porting note: Lean could find this previously
    have : IsOpenImmersion <| (Scheme.ofRestrict U (Opens.openEmbedding V.val)) ≫ g :=
      LocallyRingedSpace.IsOpenImmersion.comp _ _
    apply H
  tfae_have 4 → 3
  · intro H 𝒰 _ i; skip; apply H
  tfae_have 3 → 2
  · intro H; refine' ⟨X.affineCover, H _⟩
  tfae_have 2 → 1
  · rintro ⟨𝒰, h𝒰⟩
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 1
    rw [this]
    refine' ⟨𝒰.bind fun _ => Scheme.affineCover _, _, _⟩
    · 

Proof state:
case tfae_2_to_1.intro.refine'_1
P : {R S : Type u} → [inst : CommRing R] → [inst_1 : CommRing S] → (R →+* S) → Prop
hP : PropertyIsLocal P
X Y : Scheme
inst✝ : IsAffine Y
f : X ⟶ Y
tfae_1_to_4 :
  sourceAffineLocally P f → ∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)
tfae_4_to_3 :
  (∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)) →
    ∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
tfae_3_to_2 :
  (∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)) →
    ∃ 𝒰, ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
𝒰 : Scheme.OpenCover X
h𝒰 : ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
this :
  sourceAffineLocally P f ↔
    ∃ 𝒰,
      ∃ (_ : ∀ (i : 𝒰.J), IsAffine (Scheme.OpenCover.obj 𝒰 i)),
        ∀ (i : 𝒰.J), P (Scheme.Γ.map (Scheme.OpenCover.map 𝒰 i ≫ f).op)
⊢ ∀ (i : (Scheme.OpenCover.bind 𝒰 fun x => Scheme.affineCover (Scheme.OpenCover.obj 𝒰 x)).J),
    IsAffine (Scheme.OpenCover.obj (Scheme.OpenCover.bind 𝒰 fun x => Scheme.affineCover (Scheme.OpenCover.obj 𝒰 x)) i)

Next tactic:
intro i
theorem openCover_TFAE {X Y : Scheme.{u}} [IsAffine Y] (f : X ⟶ Y) :
    List.TFAE
      [sourceAffineLocally (@P) f,
        ∃ 𝒰 : Scheme.OpenCover.{u} X, ∀ i : 𝒰.J, sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ (𝒰 : Scheme.OpenCover.{u} X) (i : 𝒰.J), sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ {U : Scheme} (g : U ⟶ X) [IsOpenImmersion g], sourceAffineLocally (@P) (g ≫ f)] := by
  tfae_have 1 → 4
  · intro H U g hg V
    skip
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 3
    rw [this] at H
    haveI : IsAffine _ := V.2
    rw [← Category.assoc]
    -- Porting note: Lean could find this previously
    have : IsOpenImmersion <| (Scheme.ofRestrict U (Opens.openEmbedding V.val)) ≫ g :=
      LocallyRingedSpace.IsOpenImmersion.comp _ _
    apply H
  tfae_have 4 → 3
  · intro H 𝒰 _ i; skip; apply H
  tfae_have 3 → 2
  · intro H; refine' ⟨X.affineCover, H _⟩
  tfae_have 2 → 1
  · rintro ⟨𝒰, h𝒰⟩
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 1
    rw [this]
    refine' ⟨𝒰.bind fun _ => Scheme.affineCover _, _, _⟩
    · intro i; 

Proof state:
case tfae_2_to_1.intro.refine'_1
P : {R S : Type u} → [inst : CommRing R] → [inst_1 : CommRing S] → (R →+* S) → Prop
hP : PropertyIsLocal P
X Y : Scheme
inst✝ : IsAffine Y
f : X ⟶ Y
tfae_1_to_4 :
  sourceAffineLocally P f → ∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)
tfae_4_to_3 :
  (∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)) →
    ∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
tfae_3_to_2 :
  (∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)) →
    ∃ 𝒰, ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
𝒰 : Scheme.OpenCover X
h𝒰 : ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
this :
  sourceAffineLocally P f ↔
    ∃ 𝒰,
      ∃ (_ : ∀ (i : 𝒰.J), IsAffine (Scheme.OpenCover.obj 𝒰 i)),
        ∀ (i : 𝒰.J), P (Scheme.Γ.map (Scheme.OpenCover.map 𝒰 i ≫ f).op)
i : (Scheme.OpenCover.bind 𝒰 fun x => Scheme.affineCover (Scheme.OpenCover.obj 𝒰 x)).J
⊢ IsAffine (Scheme.OpenCover.obj (Scheme.OpenCover.bind 𝒰 fun x => Scheme.affineCover (Scheme.OpenCover.obj 𝒰 x)) i)

Next tactic:
dsimp
theorem openCover_TFAE {X Y : Scheme.{u}} [IsAffine Y] (f : X ⟶ Y) :
    List.TFAE
      [sourceAffineLocally (@P) f,
        ∃ 𝒰 : Scheme.OpenCover.{u} X, ∀ i : 𝒰.J, sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ (𝒰 : Scheme.OpenCover.{u} X) (i : 𝒰.J), sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ {U : Scheme} (g : U ⟶ X) [IsOpenImmersion g], sourceAffineLocally (@P) (g ≫ f)] := by
  tfae_have 1 → 4
  · intro H U g hg V
    skip
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 3
    rw [this] at H
    haveI : IsAffine _ := V.2
    rw [← Category.assoc]
    -- Porting note: Lean could find this previously
    have : IsOpenImmersion <| (Scheme.ofRestrict U (Opens.openEmbedding V.val)) ≫ g :=
      LocallyRingedSpace.IsOpenImmersion.comp _ _
    apply H
  tfae_have 4 → 3
  · intro H 𝒰 _ i; skip; apply H
  tfae_have 3 → 2
  · intro H; refine' ⟨X.affineCover, H _⟩
  tfae_have 2 → 1
  · rintro ⟨𝒰, h𝒰⟩
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 1
    rw [this]
    refine' ⟨𝒰.bind fun _ => Scheme.affineCover _, _, _⟩
    · intro i; dsimp; 

Proof state:
case tfae_2_to_1.intro.refine'_1
P : {R S : Type u} → [inst : CommRing R] → [inst_1 : CommRing S] → (R →+* S) → Prop
hP : PropertyIsLocal P
X Y : Scheme
inst✝ : IsAffine Y
f : X ⟶ Y
tfae_1_to_4 :
  sourceAffineLocally P f → ∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)
tfae_4_to_3 :
  (∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)) →
    ∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
tfae_3_to_2 :
  (∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)) →
    ∃ 𝒰, ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
𝒰 : Scheme.OpenCover X
h𝒰 : ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
this :
  sourceAffineLocally P f ↔
    ∃ 𝒰,
      ∃ (_ : ∀ (i : 𝒰.J), IsAffine (Scheme.OpenCover.obj 𝒰 i)),
        ∀ (i : 𝒰.J), P (Scheme.Γ.map (Scheme.OpenCover.map 𝒰 i ≫ f).op)
i : (Scheme.OpenCover.bind 𝒰 fun x => Scheme.affineCover (Scheme.OpenCover.obj 𝒰 x)).J
⊢ IsAffine (Scheme.OpenCover.obj (Scheme.affineCover (Scheme.OpenCover.obj 𝒰 i.fst)) i.snd)

Next tactic:
infer_instance
theorem openCover_TFAE {X Y : Scheme.{u}} [IsAffine Y] (f : X ⟶ Y) :
    List.TFAE
      [sourceAffineLocally (@P) f,
        ∃ 𝒰 : Scheme.OpenCover.{u} X, ∀ i : 𝒰.J, sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ (𝒰 : Scheme.OpenCover.{u} X) (i : 𝒰.J), sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ {U : Scheme} (g : U ⟶ X) [IsOpenImmersion g], sourceAffineLocally (@P) (g ≫ f)] := by
  tfae_have 1 → 4
  · intro H U g hg V
    skip
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 3
    rw [this] at H
    haveI : IsAffine _ := V.2
    rw [← Category.assoc]
    -- Porting note: Lean could find this previously
    have : IsOpenImmersion <| (Scheme.ofRestrict U (Opens.openEmbedding V.val)) ≫ g :=
      LocallyRingedSpace.IsOpenImmersion.comp _ _
    apply H
  tfae_have 4 → 3
  · intro H 𝒰 _ i; skip; apply H
  tfae_have 3 → 2
  · intro H; refine' ⟨X.affineCover, H _⟩
  tfae_have 2 → 1
  · rintro ⟨𝒰, h𝒰⟩
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 1
    rw [this]
    refine' ⟨𝒰.bind fun _ => Scheme.affineCover _, _, _⟩
    · intro i; dsimp; infer_instance
    · 

Proof state:
case tfae_2_to_1.intro.refine'_2
P : {R S : Type u} → [inst : CommRing R] → [inst_1 : CommRing S] → (R →+* S) → Prop
hP : PropertyIsLocal P
X Y : Scheme
inst✝ : IsAffine Y
f : X ⟶ Y
tfae_1_to_4 :
  sourceAffineLocally P f → ∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)
tfae_4_to_3 :
  (∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)) →
    ∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
tfae_3_to_2 :
  (∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)) →
    ∃ 𝒰, ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
𝒰 : Scheme.OpenCover X
h𝒰 : ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
this :
  sourceAffineLocally P f ↔
    ∃ 𝒰,
      ∃ (_ : ∀ (i : 𝒰.J), IsAffine (Scheme.OpenCover.obj 𝒰 i)),
        ∀ (i : 𝒰.J), P (Scheme.Γ.map (Scheme.OpenCover.map 𝒰 i ≫ f).op)
⊢ ∀ (i : (Scheme.OpenCover.bind 𝒰 fun x => Scheme.affineCover (Scheme.OpenCover.obj 𝒰 x)).J),
    P
      (Scheme.Γ.map
        (Scheme.OpenCover.map (Scheme.OpenCover.bind 𝒰 fun x => Scheme.affineCover (Scheme.OpenCover.obj 𝒰 x)) i ≫
            f).op)

Next tactic:
intro i
theorem openCover_TFAE {X Y : Scheme.{u}} [IsAffine Y] (f : X ⟶ Y) :
    List.TFAE
      [sourceAffineLocally (@P) f,
        ∃ 𝒰 : Scheme.OpenCover.{u} X, ∀ i : 𝒰.J, sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ (𝒰 : Scheme.OpenCover.{u} X) (i : 𝒰.J), sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ {U : Scheme} (g : U ⟶ X) [IsOpenImmersion g], sourceAffineLocally (@P) (g ≫ f)] := by
  tfae_have 1 → 4
  · intro H U g hg V
    skip
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 3
    rw [this] at H
    haveI : IsAffine _ := V.2
    rw [← Category.assoc]
    -- Porting note: Lean could find this previously
    have : IsOpenImmersion <| (Scheme.ofRestrict U (Opens.openEmbedding V.val)) ≫ g :=
      LocallyRingedSpace.IsOpenImmersion.comp _ _
    apply H
  tfae_have 4 → 3
  · intro H 𝒰 _ i; skip; apply H
  tfae_have 3 → 2
  · intro H; refine' ⟨X.affineCover, H _⟩
  tfae_have 2 → 1
  · rintro ⟨𝒰, h𝒰⟩
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 1
    rw [this]
    refine' ⟨𝒰.bind fun _ => Scheme.affineCover _, _, _⟩
    · intro i; dsimp; infer_instance
    · intro i
      

Proof state:
case tfae_2_to_1.intro.refine'_2
P : {R S : Type u} → [inst : CommRing R] → [inst_1 : CommRing S] → (R →+* S) → Prop
hP : PropertyIsLocal P
X Y : Scheme
inst✝ : IsAffine Y
f : X ⟶ Y
tfae_1_to_4 :
  sourceAffineLocally P f → ∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)
tfae_4_to_3 :
  (∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)) →
    ∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
tfae_3_to_2 :
  (∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)) →
    ∃ 𝒰, ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
𝒰 : Scheme.OpenCover X
h𝒰 : ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
this :
  sourceAffineLocally P f ↔
    ∃ 𝒰,
      ∃ (_ : ∀ (i : 𝒰.J), IsAffine (Scheme.OpenCover.obj 𝒰 i)),
        ∀ (i : 𝒰.J), P (Scheme.Γ.map (Scheme.OpenCover.map 𝒰 i ≫ f).op)
i : (Scheme.OpenCover.bind 𝒰 fun x => Scheme.affineCover (Scheme.OpenCover.obj 𝒰 x)).J
⊢ P
    (Scheme.Γ.map
      (Scheme.OpenCover.map (Scheme.OpenCover.bind 𝒰 fun x => Scheme.affineCover (Scheme.OpenCover.obj 𝒰 x)) i ≫ f).op)

Next tactic:
specialize h𝒰 i.1
theorem openCover_TFAE {X Y : Scheme.{u}} [IsAffine Y] (f : X ⟶ Y) :
    List.TFAE
      [sourceAffineLocally (@P) f,
        ∃ 𝒰 : Scheme.OpenCover.{u} X, ∀ i : 𝒰.J, sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ (𝒰 : Scheme.OpenCover.{u} X) (i : 𝒰.J), sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ {U : Scheme} (g : U ⟶ X) [IsOpenImmersion g], sourceAffineLocally (@P) (g ≫ f)] := by
  tfae_have 1 → 4
  · intro H U g hg V
    skip
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 3
    rw [this] at H
    haveI : IsAffine _ := V.2
    rw [← Category.assoc]
    -- Porting note: Lean could find this previously
    have : IsOpenImmersion <| (Scheme.ofRestrict U (Opens.openEmbedding V.val)) ≫ g :=
      LocallyRingedSpace.IsOpenImmersion.comp _ _
    apply H
  tfae_have 4 → 3
  · intro H 𝒰 _ i; skip; apply H
  tfae_have 3 → 2
  · intro H; refine' ⟨X.affineCover, H _⟩
  tfae_have 2 → 1
  · rintro ⟨𝒰, h𝒰⟩
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 1
    rw [this]
    refine' ⟨𝒰.bind fun _ => Scheme.affineCover _, _, _⟩
    · intro i; dsimp; infer_instance
    · intro i
      specialize h𝒰 i.1
      -- Porting note: this has metavariable if I put it directly into rw
      

Proof state:
case tfae_2_to_1.intro.refine'_2
P : {R S : Type u} → [inst : CommRing R] → [inst_1 : CommRing S] → (R →+* S) → Prop
hP : PropertyIsLocal P
X Y : Scheme
inst✝ : IsAffine Y
f : X ⟶ Y
tfae_1_to_4 :
  sourceAffineLocally P f → ∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)
tfae_4_to_3 :
  (∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)) →
    ∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
tfae_3_to_2 :
  (∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)) →
    ∃ 𝒰, ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
𝒰 : Scheme.OpenCover X
this :
  sourceAffineLocally P f ↔
    ∃ 𝒰,
      ∃ (_ : ∀ (i : 𝒰.J), IsAffine (Scheme.OpenCover.obj 𝒰 i)),
        ∀ (i : 𝒰.J), P (Scheme.Γ.map (Scheme.OpenCover.map 𝒰 i ≫ f).op)
i : (Scheme.OpenCover.bind 𝒰 fun x => Scheme.affineCover (Scheme.OpenCover.obj 𝒰 x)).J
h𝒰 : sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i.fst ≫ f)
⊢ P
    (Scheme.Γ.map
      (Scheme.OpenCover.map (Scheme.OpenCover.bind 𝒰 fun x => Scheme.affineCover (Scheme.OpenCover.obj 𝒰 x)) i ≫ f).op)

Next tactic:
have := (hP.affine_openCover_TFAE (𝒰.map i.fst ≫ f)).out 0 3
theorem openCover_TFAE {X Y : Scheme.{u}} [IsAffine Y] (f : X ⟶ Y) :
    List.TFAE
      [sourceAffineLocally (@P) f,
        ∃ 𝒰 : Scheme.OpenCover.{u} X, ∀ i : 𝒰.J, sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ (𝒰 : Scheme.OpenCover.{u} X) (i : 𝒰.J), sourceAffineLocally (@P) (𝒰.map i ≫ f),
        ∀ {U : Scheme} (g : U ⟶ X) [IsOpenImmersion g], sourceAffineLocally (@P) (g ≫ f)] := by
  tfae_have 1 → 4
  · intro H U g hg V
    skip
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 3
    rw [this] at H
    haveI : IsAffine _ := V.2
    rw [← Category.assoc]
    -- Porting note: Lean could find this previously
    have : IsOpenImmersion <| (Scheme.ofRestrict U (Opens.openEmbedding V.val)) ≫ g :=
      LocallyRingedSpace.IsOpenImmersion.comp _ _
    apply H
  tfae_have 4 → 3
  · intro H 𝒰 _ i; skip; apply H
  tfae_have 3 → 2
  · intro H; refine' ⟨X.affineCover, H _⟩
  tfae_have 2 → 1
  · rintro ⟨𝒰, h𝒰⟩
    -- Porting note: this has metavariable if I put it directly into rw
    have := (hP.affine_openCover_TFAE f).out 0 1
    rw [this]
    refine' ⟨𝒰.bind fun _ => Scheme.affineCover _, _, _⟩
    · intro i; dsimp; infer_instance
    · intro i
      specialize h𝒰 i.1
      -- Porting note: this has metavariable if I put it directly into rw
      have := (hP.affine_openCover_TFAE (𝒰.map i.fst ≫ f)).out 0 3
      

Proof state:
case tfae_2_to_1.intro.refine'_2
P : {R S : Type u} → [inst : CommRing R] → [inst_1 : CommRing S] → (R →+* S) → Prop
hP : PropertyIsLocal P
X Y : Scheme
inst✝ : IsAffine Y
f : X ⟶ Y
tfae_1_to_4 :
  sourceAffineLocally P f → ∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)
tfae_4_to_3 :
  (∀ {U : Scheme} (g : U ⟶ X) [inst : IsOpenImmersion g], sourceAffineLocally P (g ≫ f)) →
    ∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
tfae_3_to_2 :
  (∀ (𝒰 : Scheme.OpenCover X) (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)) →
    ∃ 𝒰, ∀ (i : 𝒰.J), sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i ≫ f)
𝒰 : Scheme.OpenCover X
this✝ :
  sourceAffineLocally P f ↔
    ∃ 𝒰,
      ∃ (_ : ∀ (i : 𝒰.J), IsAffine (Scheme.OpenCover.obj 𝒰 i)),
        ∀ (i : 𝒰.J), P (Scheme.Γ.map (Scheme.OpenCover.map 𝒰 i ≫ f).op)
i : (Scheme.OpenCover.bind 𝒰 fun x => Scheme.affineCover (Scheme.OpenCover.obj 𝒰 x)).J
h𝒰 : sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i.fst ≫ f)
this :
  sourceAffineLocally P (Scheme.OpenCover.map 𝒰 i.fst ≫ f) ↔
    ∀ {U : Scheme} (g : U ⟶ Scheme.OpenCover.obj 𝒰 i.fst) [inst : IsAffine U] [inst : IsOpenImmersion g],
      P (Scheme.Γ.map (g ≫ Scheme.OpenCover.map 𝒰 i.fst ≫ f).op)
⊢ P
    (Scheme.Γ.map
      (Scheme.OpenCover.map (Scheme.OpenCover.bind 𝒰 fun x => Scheme.affineCover (Scheme.OpenCover.obj 𝒰 x)) i ≫ f).op)

Next tactic:
rw [this] at h𝒰