l3lab/ntp-mathlib huggingface dataset:
/-- A small category with products is a thin category.

in Lean, a preorder category is one where the morphisms are in Prop, which is weaker than the usual
notion of a preorder/thin category which says that each homset is subsingleton; we show the latter
rather than providing a `Preorder C` instance.
-/
instance (priority := 100) : Quiver.IsThin C := fun X Y =>
  ⟨fun r s => by
    classical
      by_contra r_ne_s
      have z : (2 : Cardinal) ≤ #(X ⟶ Y) := by
        rw [Cardinal.two_le_iff]
        exact ⟨_, _, r_ne_s⟩
      let md := ΣZ W : C, Z ⟶ W
      let α := #md
      apply not_le_of_lt (Cardinal.cantor α)
      let yp : C := ∏ fun _ : md => Y
      refine' _root_.trans _ _
      · exact #(X ⟶ yp)
      · apply le_trans (Cardinal.power_le_power_right z)
        rw [Cardinal.power_def]
        apply le_of_eq
        rw [Cardinal.eq]
        refine' ⟨⟨Pi.lift, fun f k => f ≫ Pi.π _ k, _, _⟩⟩
        · intro f
          ext k
          simp
        · intro f
          ext ⟨j⟩
          simp
      · apply Cardinal.mk_le_of_injective _
        · intro f
          exact ⟨_, _, f⟩
        · rintro f g k
          cases k
          

Proof state:
case refl
C : Type u
inst✝¹ : SmallCategory C
inst✝ : HasProducts C
X Y : C
r s : X ⟶ Y
r_ne_s : ¬r = s
z : 2 ≤ #(X ⟶ Y)
md : Type u := (Z : C) × (W : C) × (Z ⟶ W)
α : Cardinal.{u} := #md
yp : C := ∏ fun x => Y
f : X ⟶ yp
⊢ f = f

Next tactic:
rfl
@[to_additive]
theorem IsPwo.mul [OrderedCancelCommMonoid α] (hs : s.IsPwo) (ht : t.IsPwo) : IsPwo (s * t) := by
  

Proof state:
α : Type u_1
s t : Set α
inst✝ : OrderedCancelCommMonoid α
hs : IsPwo s
ht : IsPwo t
⊢ IsPwo (s * t)

Next tactic:
rw [← image_mul_prod]
@[to_additive]
theorem IsPwo.mul [OrderedCancelCommMonoid α] (hs : s.IsPwo) (ht : t.IsPwo) : IsPwo (s * t) := by
  rw [← image_mul_prod]
  

Proof state:
α : Type u_1
s t : Set α
inst✝ : OrderedCancelCommMonoid α
hs : IsPwo s
ht : IsPwo t
⊢ IsPwo ((fun x => x.1 * x.2) '' s ×ˢ t)

Next tactic:
exact (hs.prod ht).image_of_monotone (monotone_fst.mul' monotone_snd)
@[to_additive]
theorem IsWf.min_mul (hs : s.IsWf) (ht : t.IsWf) (hsn : s.Nonempty) (htn : t.Nonempty) :
    (hs.mul ht).min (hsn.mul htn) = hs.min hsn * ht.min htn := by
  

Proof state:
α : Type u_1
s t : Set α
inst✝ : LinearOrderedCancelCommMonoid α
hs : IsWf s
ht : IsWf t
hsn : Set.Nonempty s
htn : Set.Nonempty t
⊢ min (_ : IsWf (s * t)) (_ : Set.Nonempty (s * t)) = min hs hsn * min ht htn

Next tactic:
refine' le_antisymm (IsWf.min_le _ _ (mem_mul.2 ⟨_, _, hs.min_mem _, ht.min_mem _, rfl⟩)) _
@[to_additive]
theorem IsWf.min_mul (hs : s.IsWf) (ht : t.IsWf) (hsn : s.Nonempty) (htn : t.Nonempty) :
    (hs.mul ht).min (hsn.mul htn) = hs.min hsn * ht.min htn := by
  refine' le_antisymm (IsWf.min_le _ _ (mem_mul.2 ⟨_, _, hs.min_mem _, ht.min_mem _, rfl⟩)) _
  

Proof state:
α : Type u_1
s t : Set α
inst✝ : LinearOrderedCancelCommMonoid α
hs : IsWf s
ht : IsWf t
hsn : Set.Nonempty s
htn : Set.Nonempty t
⊢ min hs hsn * min ht htn ≤ min (_ : IsWf (s * t)) (_ : Set.Nonempty (s * t))

Next tactic:
rw [IsWf.le_min_iff]
@[to_additive]
theorem IsWf.min_mul (hs : s.IsWf) (ht : t.IsWf) (hsn : s.Nonempty) (htn : t.Nonempty) :
    (hs.mul ht).min (hsn.mul htn) = hs.min hsn * ht.min htn := by
  refine' le_antisymm (IsWf.min_le _ _ (mem_mul.2 ⟨_, _, hs.min_mem _, ht.min_mem _, rfl⟩)) _
  rw [IsWf.le_min_iff]
  

Proof state:
α : Type u_1
s t : Set α
inst✝ : LinearOrderedCancelCommMonoid α
hs : IsWf s
ht : IsWf t
hsn : Set.Nonempty s
htn : Set.Nonempty t
⊢ ∀ b ∈ s * t, min hs hsn * min ht htn ≤ b

Next tactic:
rintro _ ⟨x, y, hx, hy, rfl⟩
@[to_additive]
theorem IsWf.min_mul (hs : s.IsWf) (ht : t.IsWf) (hsn : s.Nonempty) (htn : t.Nonempty) :
    (hs.mul ht).min (hsn.mul htn) = hs.min hsn * ht.min htn := by
  refine' le_antisymm (IsWf.min_le _ _ (mem_mul.2 ⟨_, _, hs.min_mem _, ht.min_mem _, rfl⟩)) _
  rw [IsWf.le_min_iff]
  rintro _ ⟨x, y, hx, hy, rfl⟩
  

Proof state:
case intro.intro.intro.intro
α : Type u_1
s t : Set α
inst✝ : LinearOrderedCancelCommMonoid α
hs : IsWf s
ht : IsWf t
hsn : Set.Nonempty s
htn : Set.Nonempty t
x y : α
hx : x ∈ s
hy : y ∈ t
⊢ min hs hsn * min ht htn ≤ (fun x x_1 => x * x_1) x y

Next tactic:
exact mul_le_mul' (hs.min_le _ hx) (ht.min_le _ hy)
@[to_additive (attr := simp)]
theorem mem_mulAntidiagonal : x ∈ mulAntidiagonal hs ht a ↔ x.1 ∈ s ∧ x.2 ∈ t ∧ x.1 * x.2 = a := by
  

Proof state:
α : Type u_1
inst✝ : OrderedCancelCommMonoid α
s t : Set α
hs : Set.IsPwo s
ht : Set.IsPwo t
a : α
u : Set α
hu : Set.IsPwo u
x : α × α
⊢ x ∈ mulAntidiagonal hs ht a ↔ x.1 ∈ s ∧ x.2 ∈ t ∧ x.1 * x.2 = a

Next tactic:
simp only [mulAntidiagonal, Set.Finite.mem_toFinset, Set.mem_mulAntidiagonal]
@[to_additive]
theorem swap_mem_mulAntidiagonal :
    x.swap ∈ Finset.mulAntidiagonal hs ht a ↔ x ∈ Finset.mulAntidiagonal ht hs a := by
  

Proof state:
α : Type u_1
inst✝ : OrderedCancelCommMonoid α
s t : Set α
hs : Set.IsPwo s
ht : Set.IsPwo t
a : α
u : Set α
hu : Set.IsPwo u
x : α × α
⊢ Prod.swap x ∈ mulAntidiagonal hs ht a ↔ x ∈ mulAntidiagonal ht hs a

Next tactic:
simp only [mem_mulAntidiagonal, Prod.fst_swap, Prod.snd_swap, Set.swap_mem_mulAntidiagonal_aux,
             Set.mem_mulAntidiagonal]
@[to_additive]
theorem support_mulAntidiagonal_subset_mul : { a | (mulAntidiagonal hs ht a).Nonempty } ⊆ s * t :=
  fun a ⟨b, hb⟩ => by
  

Proof state:
α : Type u_1
inst✝ : OrderedCancelCommMonoid α
s t : Set α
hs : Set.IsPwo s
ht : Set.IsPwo t
a✝ : α
u : Set α
hu : Set.IsPwo u
x : α × α
a : α
x✝ : a ∈ {a | Finset.Nonempty (mulAntidiagonal hs ht a)}
b : α × α
hb : b ∈ mulAntidiagonal hs ht a
⊢ a ∈ s * t

Next tactic:
rw [mem_mulAntidiagonal] at hb
@[to_additive]
theorem support_mulAntidiagonal_subset_mul : { a | (mulAntidiagonal hs ht a).Nonempty } ⊆ s * t :=
  fun a ⟨b, hb⟩ => by
  rw [mem_mulAntidiagonal] at hb
  

Proof state:
α : Type u_1
inst✝ : OrderedCancelCommMonoid α
s t : Set α
hs : Set.IsPwo s
ht : Set.IsPwo t
a✝ : α
u : Set α
hu : Set.IsPwo u
x : α × α
a : α
x✝ : a ∈ {a | Finset.Nonempty (mulAntidiagonal hs ht a)}
b : α × α
hb : b.1 ∈ s ∧ b.2 ∈ t ∧ b.1 * b.2 = a
⊢ a ∈ s * t

Next tactic:
exact ⟨b.1, b.2, hb⟩
@[to_additive]
theorem mulAntidiagonal_min_mul_min {α} [LinearOrderedCancelCommMonoid α] {s t : Set α}
    (hs : s.IsWf) (ht : t.IsWf) (hns : s.Nonempty) (hnt : t.Nonempty) :
    mulAntidiagonal hs.isPwo ht.isPwo (hs.min hns * ht.min hnt) = {(hs.min hns, ht.min hnt)} := by
  

Proof state:
α✝ : Type u_1
inst✝¹ : OrderedCancelCommMonoid α✝
s✝ t✝ : Set α✝
hs✝ : Set.IsPwo s✝
ht✝ : Set.IsPwo t✝
a : α✝
u : Set α✝
hu : Set.IsPwo u
x : α✝ × α✝
α : Type u_2
inst✝ : LinearOrderedCancelCommMonoid α
s t : Set α
hs : Set.IsWf s
ht : Set.IsWf t
hns : Set.Nonempty s
hnt : Set.Nonempty t
⊢ mulAntidiagonal (_ : Set.IsPwo s) (_ : Set.IsPwo t) (Set.IsWf.min hs hns * Set.IsWf.min ht hnt) =
    {(Set.IsWf.min hs hns, Set.IsWf.min ht hnt)}

Next tactic:
ext ⟨a, b⟩
@[to_additive]
theorem mulAntidiagonal_min_mul_min {α} [LinearOrderedCancelCommMonoid α] {s t : Set α}
    (hs : s.IsWf) (ht : t.IsWf) (hns : s.Nonempty) (hnt : t.Nonempty) :
    mulAntidiagonal hs.isPwo ht.isPwo (hs.min hns * ht.min hnt) = {(hs.min hns, ht.min hnt)} := by
  ext ⟨a, b⟩
  

Proof state:
case a.mk
α✝ : Type u_1
inst✝¹ : OrderedCancelCommMonoid α✝
s✝ t✝ : Set α✝
hs✝ : Set.IsPwo s✝
ht✝ : Set.IsPwo t✝
a✝ : α✝
u : Set α✝
hu : Set.IsPwo u
x : α✝ × α✝
α : Type u_2
inst✝ : LinearOrderedCancelCommMonoid α
s t : Set α
hs : Set.IsWf s
ht : Set.IsWf t
hns : Set.Nonempty s
hnt : Set.Nonempty t
a b : α
⊢ (a, b) ∈ mulAntidiagonal (_ : Set.IsPwo s) (_ : Set.IsPwo t) (Set.IsWf.min hs hns * Set.IsWf.min ht hnt) ↔
    (a, b) ∈ {(Set.IsWf.min hs hns, Set.IsWf.min ht hnt)}

Next tactic:
simp only [mem_mulAntidiagonal, mem_singleton, Prod.ext_iff]
@[to_additive]
theorem mulAntidiagonal_min_mul_min {α} [LinearOrderedCancelCommMonoid α] {s t : Set α}
    (hs : s.IsWf) (ht : t.IsWf) (hns : s.Nonempty) (hnt : t.Nonempty) :
    mulAntidiagonal hs.isPwo ht.isPwo (hs.min hns * ht.min hnt) = {(hs.min hns, ht.min hnt)} := by
  ext ⟨a, b⟩
  simp only [mem_mulAntidiagonal, mem_singleton, Prod.ext_iff]
  

Proof state:
case a.mk
α✝ : Type u_1
inst✝¹ : OrderedCancelCommMonoid α✝
s✝ t✝ : Set α✝
hs✝ : Set.IsPwo s✝
ht✝ : Set.IsPwo t✝
a✝ : α✝
u : Set α✝
hu : Set.IsPwo u
x : α✝ × α✝
α : Type u_2
inst✝ : LinearOrderedCancelCommMonoid α
s t : Set α
hs : Set.IsWf s
ht : Set.IsWf t
hns : Set.Nonempty s
hnt : Set.Nonempty t
a b : α
⊢ a ∈ s ∧ b ∈ t ∧ a * b = Set.IsWf.min hs hns * Set.IsWf.min ht hnt ↔ a = Set.IsWf.min hs hns ∧ b = Set.IsWf.min ht hnt

Next tactic:
constructor
@[to_additive]
theorem mulAntidiagonal_min_mul_min {α} [LinearOrderedCancelCommMonoid α] {s t : Set α}
    (hs : s.IsWf) (ht : t.IsWf) (hns : s.Nonempty) (hnt : t.Nonempty) :
    mulAntidiagonal hs.isPwo ht.isPwo (hs.min hns * ht.min hnt) = {(hs.min hns, ht.min hnt)} := by
  ext ⟨a, b⟩
  simp only [mem_mulAntidiagonal, mem_singleton, Prod.ext_iff]
  constructor
  · 

Proof state:
case a.mk.mp
α✝ : Type u_1
inst✝¹ : OrderedCancelCommMonoid α✝
s✝ t✝ : Set α✝
hs✝ : Set.IsPwo s✝
ht✝ : Set.IsPwo t✝
a✝ : α✝
u : Set α✝
hu : Set.IsPwo u
x : α✝ × α✝
α : Type u_2
inst✝ : LinearOrderedCancelCommMonoid α
s t : Set α
hs : Set.IsWf s
ht : Set.IsWf t
hns : Set.Nonempty s
hnt : Set.Nonempty t
a b : α
⊢ a ∈ s ∧ b ∈ t ∧ a * b = Set.IsWf.min hs hns * Set.IsWf.min ht hnt → a = Set.IsWf.min hs hns ∧ b = Set.IsWf.min ht hnt

Next tactic:
rintro ⟨has, hat, hst⟩
@[to_additive]
theorem mulAntidiagonal_min_mul_min {α} [LinearOrderedCancelCommMonoid α] {s t : Set α}
    (hs : s.IsWf) (ht : t.IsWf) (hns : s.Nonempty) (hnt : t.Nonempty) :
    mulAntidiagonal hs.isPwo ht.isPwo (hs.min hns * ht.min hnt) = {(hs.min hns, ht.min hnt)} := by
  ext ⟨a, b⟩
  simp only [mem_mulAntidiagonal, mem_singleton, Prod.ext_iff]
  constructor
  · rintro ⟨has, hat, hst⟩
    

Proof state:
case a.mk.mp.intro.intro
α✝ : Type u_1
inst✝¹ : OrderedCancelCommMonoid α✝
s✝ t✝ : Set α✝
hs✝ : Set.IsPwo s✝
ht✝ : Set.IsPwo t✝
a✝ : α✝
u : Set α✝
hu : Set.IsPwo u
x : α✝ × α✝
α : Type u_2
inst✝ : LinearOrderedCancelCommMonoid α
s t : Set α
hs : Set.IsWf s
ht : Set.IsWf t
hns : Set.Nonempty s
hnt : Set.Nonempty t
a b : α
has : a ∈ s
hat : b ∈ t
hst : a * b = Set.IsWf.min hs hns * Set.IsWf.min ht hnt
⊢ a = Set.IsWf.min hs hns ∧ b = Set.IsWf.min ht hnt

Next tactic:
obtain rfl :=
      (hs.min_le hns has).eq_of_not_lt fun hlt =>
        (mul_lt_mul_of_lt_of_le hlt <| ht.min_le hnt hat).ne' hst
@[to_additive]
theorem mulAntidiagonal_min_mul_min {α} [LinearOrderedCancelCommMonoid α] {s t : Set α}
    (hs : s.IsWf) (ht : t.IsWf) (hns : s.Nonempty) (hnt : t.Nonempty) :
    mulAntidiagonal hs.isPwo ht.isPwo (hs.min hns * ht.min hnt) = {(hs.min hns, ht.min hnt)} := by
  ext ⟨a, b⟩
  simp only [mem_mulAntidiagonal, mem_singleton, Prod.ext_iff]
  constructor
  · rintro ⟨has, hat, hst⟩
    obtain rfl :=
      (hs.min_le hns has).eq_of_not_lt fun hlt =>
        (mul_lt_mul_of_lt_of_le hlt <| ht.min_le hnt hat).ne' hst
    

Proof state:
case a.mk.mp.intro.intro
α✝ : Type u_1
inst✝¹ : OrderedCancelCommMonoid α✝
s✝ t✝ : Set α✝
hs✝ : Set.IsPwo s✝
ht✝ : Set.IsPwo t✝
a : α✝
u : Set α✝
hu : Set.IsPwo u
x : α✝ × α✝
α : Type u_2
inst✝ : LinearOrderedCancelCommMonoid α
s t : Set α
hs : Set.IsWf s
ht : Set.IsWf t
hns : Set.Nonempty s
hnt : Set.Nonempty t
b : α
hat : b ∈ t
has : Set.IsWf.min hs hns ∈ s
hst : Set.IsWf.min hs hns * b = Set.IsWf.min hs hns * Set.IsWf.min ht hnt
⊢ Set.IsWf.min hs hns = Set.IsWf.min hs hns ∧ b = Set.IsWf.min ht hnt

Next tactic:
exact ⟨rfl, mul_left_cancel hst⟩
@[to_additive]
theorem mulAntidiagonal_min_mul_min {α} [LinearOrderedCancelCommMonoid α] {s t : Set α}
    (hs : s.IsWf) (ht : t.IsWf) (hns : s.Nonempty) (hnt : t.Nonempty) :
    mulAntidiagonal hs.isPwo ht.isPwo (hs.min hns * ht.min hnt) = {(hs.min hns, ht.min hnt)} := by
  ext ⟨a, b⟩
  simp only [mem_mulAntidiagonal, mem_singleton, Prod.ext_iff]
  constructor
  · rintro ⟨has, hat, hst⟩
    obtain rfl :=
      (hs.min_le hns has).eq_of_not_lt fun hlt =>
        (mul_lt_mul_of_lt_of_le hlt <| ht.min_le hnt hat).ne' hst
    exact ⟨rfl, mul_left_cancel hst⟩
  · 

Proof state:
case a.mk.mpr
α✝ : Type u_1
inst✝¹ : OrderedCancelCommMonoid α✝
s✝ t✝ : Set α✝
hs✝ : Set.IsPwo s✝
ht✝ : Set.IsPwo t✝
a✝ : α✝
u : Set α✝
hu : Set.IsPwo u
x : α✝ × α✝
α : Type u_2
inst✝ : LinearOrderedCancelCommMonoid α
s t : Set α
hs : Set.IsWf s
ht : Set.IsWf t
hns : Set.Nonempty s
hnt : Set.Nonempty t
a b : α
⊢ a = Set.IsWf.min hs hns ∧ b = Set.IsWf.min ht hnt → a ∈ s ∧ b ∈ t ∧ a * b = Set.IsWf.min hs hns * Set.IsWf.min ht hnt

Next tactic:
rintro ⟨rfl, rfl⟩
@[to_additive]
theorem mulAntidiagonal_min_mul_min {α} [LinearOrderedCancelCommMonoid α] {s t : Set α}
    (hs : s.IsWf) (ht : t.IsWf) (hns : s.Nonempty) (hnt : t.Nonempty) :
    mulAntidiagonal hs.isPwo ht.isPwo (hs.min hns * ht.min hnt) = {(hs.min hns, ht.min hnt)} := by
  ext ⟨a, b⟩
  simp only [mem_mulAntidiagonal, mem_singleton, Prod.ext_iff]
  constructor
  · rintro ⟨has, hat, hst⟩
    obtain rfl :=
      (hs.min_le hns has).eq_of_not_lt fun hlt =>
        (mul_lt_mul_of_lt_of_le hlt <| ht.min_le hnt hat).ne' hst
    exact ⟨rfl, mul_left_cancel hst⟩
  · rintro ⟨rfl, rfl⟩
    

Proof state:
case a.mk.mpr.intro
α✝ : Type u_1
inst✝¹ : OrderedCancelCommMonoid α✝
s✝ t✝ : Set α✝
hs✝ : Set.IsPwo s✝
ht✝ : Set.IsPwo t✝
a : α✝
u : Set α✝
hu : Set.IsPwo u
x : α✝ × α✝
α : Type u_2
inst✝ : LinearOrderedCancelCommMonoid α
s t : Set α
hs : Set.IsWf s
ht : Set.IsWf t
hns : Set.Nonempty s
hnt : Set.Nonempty t
⊢ Set.IsWf.min hs hns ∈ s ∧
    Set.IsWf.min ht hnt ∈ t ∧ Set.IsWf.min hs hns * Set.IsWf.min ht hnt = Set.IsWf.min hs hns * Set.IsWf.min ht hnt

Next tactic:
exact ⟨hs.min_mem _, ht.min_mem _, rfl⟩
@[simp]
theorem id_app {X : Scheme} (U : (Opens X.carrier)ᵒᵖ) :
    (𝟙 X : _).val.c.app U =
      X.presheaf.map (eqToHom (by 

Proof state:
X : Scheme
U : (Opens ↑↑X.toPresheafedSpace)ᵒᵖ
⊢ U = U

Next tactic:
induction' U with U
@[simp]
theorem id_app {X : Scheme} (U : (Opens X.carrier)ᵒᵖ) :
    (𝟙 X : _).val.c.app U =
      X.presheaf.map (eqToHom (by induction' U with U; 

Proof state:
case h
X : Scheme
U : Opens ↑↑X.toPresheafedSpace
⊢ op U = op U

Next tactic:
cases U
@[simp]
theorem id_app {X : Scheme} (U : (Opens X.carrier)ᵒᵖ) :
    (𝟙 X : _).val.c.app U =
      X.presheaf.map (eqToHom (by induction' U with U; cases U; 

Proof state:
case h.mk
X : Scheme
carrier✝ : Set ↑↑X.toPresheafedSpace
is_open'✝ : IsOpen carrier✝
⊢ op { carrier := carrier✝, is_open' := is_open'✝ } = op { carrier := carrier✝, is_open' := is_open'✝ }

Next tactic:
rfl
theorem comp_val_base_apply {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) (x : X) :
    (f ≫ g).val.base x = g.val.base (f.val.base x) := by
  

Proof state:
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
x : ↑↑X.toPresheafedSpace
⊢ (f ≫ g).val.base x = g.val.base (f.val.base x)

Next tactic:
simp
theorem congr_app {X Y : Scheme} {f g : X ⟶ Y} (e : f = g) (U) :
    f.val.c.app U = g.val.c.app U ≫ X.presheaf.map (eqToHom (by 

Proof state:
X Y : Scheme
f g : X ⟶ Y
e : f = g
U : (Opens ↑↑Y.toPresheafedSpace)ᵒᵖ
⊢ (Opens.map g.val.base).op.obj U = (Opens.map f.val.base).op.obj U

Next tactic:
subst e
theorem congr_app {X Y : Scheme} {f g : X ⟶ Y} (e : f = g) (U) :
    f.val.c.app U = g.val.c.app U ≫ X.presheaf.map (eqToHom (by subst e; 

Proof state:
X Y : Scheme
f : X ⟶ Y
U : (Opens ↑↑Y.toPresheafedSpace)ᵒᵖ
⊢ (Opens.map f.val.base).op.obj U = (Opens.map f.val.base).op.obj U

Next tactic:
rfl
theorem congr_app {X Y : Scheme} {f g : X ⟶ Y} (e : f = g) (U) :
    f.val.c.app U = g.val.c.app U ≫ X.presheaf.map (eqToHom (by subst e; rfl)) := by
  

Proof state:
X Y : Scheme
f g : X ⟶ Y
e : f = g
U : (Opens ↑↑Y.toPresheafedSpace)ᵒᵖ
⊢ f.val.c.app U =
    g.val.c.app U ≫ X.presheaf.map (eqToHom (_ : (Opens.map g.val.base).op.obj U = (Opens.map f.val.base).op.obj U))

Next tactic:
subst e
theorem congr_app {X Y : Scheme} {f g : X ⟶ Y} (e : f = g) (U) :
    f.val.c.app U = g.val.c.app U ≫ X.presheaf.map (eqToHom (by subst e; rfl)) := by
  subst e; 

Proof state:
X Y : Scheme
f : X ⟶ Y
U : (Opens ↑↑Y.toPresheafedSpace)ᵒᵖ
⊢ f.val.c.app U =
    f.val.c.app U ≫ X.presheaf.map (eqToHom (_ : (Opens.map f.val.base).op.obj U = (Opens.map f.val.base).op.obj U))

Next tactic:
dsimp
theorem congr_app {X Y : Scheme} {f g : X ⟶ Y} (e : f = g) (U) :
    f.val.c.app U = g.val.c.app U ≫ X.presheaf.map (eqToHom (by subst e; rfl)) := by
  subst e; dsimp; 

Proof state:
X Y : Scheme
f : X ⟶ Y
U : (Opens ↑↑Y.toPresheafedSpace)ᵒᵖ
⊢ f.val.c.app U = f.val.c.app U ≫ X.presheaf.map (𝟙 (op ((Opens.map f.val.base).obj U.unop)))

Next tactic:
simp
theorem app_eq {X Y : Scheme} (f : X ⟶ Y) {U V : Opens Y.carrier} (e : U = V) :
    f.val.c.app (op U) =
      Y.presheaf.map (eqToHom e.symm).op ≫
        f.val.c.app (op V) ≫
          X.presheaf.map (eqToHom (congr_arg (Opens.map f.val.base).obj e)).op := by
  

Proof state:
X Y : Scheme
f : X ⟶ Y
U V : Opens ↑↑Y.toPresheafedSpace
e : U = V
⊢ f.val.c.app (op U) =
    Y.presheaf.map (eqToHom (_ : V = U)).op ≫
      f.val.c.app (op V) ≫ X.presheaf.map (eqToHom (_ : (Opens.map f.val.base).obj U = (Opens.map f.val.base).obj V)).op

Next tactic:
rw [← IsIso.inv_comp_eq, ← Functor.map_inv, f.val.c.naturality, Presheaf.pushforwardObj_map]
theorem app_eq {X Y : Scheme} (f : X ⟶ Y) {U V : Opens Y.carrier} (e : U = V) :
    f.val.c.app (op U) =
      Y.presheaf.map (eqToHom e.symm).op ≫
        f.val.c.app (op V) ≫
          X.presheaf.map (eqToHom (congr_arg (Opens.map f.val.base).obj e)).op := by
  rw [← IsIso.inv_comp_eq, ← Functor.map_inv, f.val.c.naturality, Presheaf.pushforwardObj_map]
  

Proof state:
X Y : Scheme
f : X ⟶ Y
U V : Opens ↑↑Y.toPresheafedSpace
e : U = V
⊢ f.val.c.app (op V) ≫ X.presheaf.map ((Opens.map f.val.base).op.map (inv (eqToHom (_ : V = U)).op)) =
    f.val.c.app (op V) ≫ X.presheaf.map (eqToHom (_ : (Opens.map f.val.base).obj U = (Opens.map f.val.base).obj V)).op

Next tactic:
cases e
theorem app_eq {X Y : Scheme} (f : X ⟶ Y) {U V : Opens Y.carrier} (e : U = V) :
    f.val.c.app (op U) =
      Y.presheaf.map (eqToHom e.symm).op ≫
        f.val.c.app (op V) ≫
          X.presheaf.map (eqToHom (congr_arg (Opens.map f.val.base).obj e)).op := by
  rw [← IsIso.inv_comp_eq, ← Functor.map_inv, f.val.c.naturality, Presheaf.pushforwardObj_map]
  cases e
  

Proof state:
case refl
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
⊢ f.val.c.app (op U) ≫ X.presheaf.map ((Opens.map f.val.base).op.map (inv (eqToHom (_ : U = U)).op)) =
    f.val.c.app (op U) ≫ X.presheaf.map (eqToHom (_ : (Opens.map f.val.base).obj U = (Opens.map f.val.base).obj U)).op

Next tactic:
rfl
lemma presheaf_map_eqToHom_op (X : Scheme) (U V : Opens X) (i : U = V) :
    X.presheaf.map (eqToHom i).op = eqToHom (i ▸ rfl) := by
  

Proof state:
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
i : U = V
⊢ X.presheaf.map (eqToHom i).op = eqToHom (_ : X.presheaf.obj (op V) = X.presheaf.obj (op U))

Next tactic:
rw [eqToHom_op, eqToHom_map]
@[simp]
theorem inv_val_c_app {X Y : Scheme} (f : X ⟶ Y) [IsIso f] (U : Opens X.carrier) :
    (inv f).val.c.app (op U) =
      X.presheaf.map
          (eqToHom <| by 

Proof state:
X Y : Scheme
f : X ⟶ Y
inst✝ : IsIso f
U : Opens ↑↑X.toPresheafedSpace
⊢ (Opens.map (f ≫ inv f).val.base).obj U = U

Next tactic:
rw [IsIso.hom_inv_id]
@[simp]
theorem inv_val_c_app {X Y : Scheme} (f : X ⟶ Y) [IsIso f] (U : Opens X.carrier) :
    (inv f).val.c.app (op U) =
      X.presheaf.map
          (eqToHom <| by rw [IsIso.hom_inv_id]; 

Proof state:
X Y : Scheme
f : X ⟶ Y
inst✝ : IsIso f
U : Opens ↑↑X.toPresheafedSpace
⊢ (Opens.map (𝟙 X).val.base).obj U = U

Next tactic:
ext1
@[simp]
theorem inv_val_c_app {X Y : Scheme} (f : X ⟶ Y) [IsIso f] (U : Opens X.carrier) :
    (inv f).val.c.app (op U) =
      X.presheaf.map
          (eqToHom <| by rw [IsIso.hom_inv_id]; ext1; 

Proof state:
case h
X Y : Scheme
f : X ⟶ Y
inst✝ : IsIso f
U : Opens ↑↑X.toPresheafedSpace
⊢ ↑((Opens.map (𝟙 X).val.base).obj U) = ↑U

Next tactic:
rfl
@[simp]
theorem inv_val_c_app {X Y : Scheme} (f : X ⟶ Y) [IsIso f] (U : Opens X.carrier) :
    (inv f).val.c.app (op U) =
      X.presheaf.map
          (eqToHom <| by rw [IsIso.hom_inv_id]; ext1; rfl :
              (Opens.map (f ≫ inv f).1.base).obj U ⟶ U).op ≫
        inv (f.val.c.app (op <| (Opens.map _).obj U)) := by
  

Proof state:
X Y : Scheme
f : X ⟶ Y
inst✝ : IsIso f
U : Opens ↑↑X.toPresheafedSpace
⊢ (inv f).val.c.app (op U) =
    X.presheaf.map (eqToHom (_ : (Opens.map (f ≫ inv f).val.base).obj U = U)).op ≫
      inv (f.val.c.app (op ((Opens.map (inv f).val.base).obj U)))

Next tactic:
rw [IsIso.eq_comp_inv]
@[simp]
theorem inv_val_c_app {X Y : Scheme} (f : X ⟶ Y) [IsIso f] (U : Opens X.carrier) :
    (inv f).val.c.app (op U) =
      X.presheaf.map
          (eqToHom <| by rw [IsIso.hom_inv_id]; ext1; rfl :
              (Opens.map (f ≫ inv f).1.base).obj U ⟶ U).op ≫
        inv (f.val.c.app (op <| (Opens.map _).obj U)) := by
  rw [IsIso.eq_comp_inv]
  

Proof state:
X Y : Scheme
f : X ⟶ Y
inst✝ : IsIso f
U : Opens ↑↑X.toPresheafedSpace
⊢ (inv f).val.c.app (op U) ≫ f.val.c.app (op ((Opens.map (inv f).val.base).obj U)) =
    X.presheaf.map (eqToHom (_ : (Opens.map (f ≫ inv f).val.base).obj U = U)).op

Next tactic:
erw [← Scheme.comp_val_c_app]
@[simp]
theorem inv_val_c_app {X Y : Scheme} (f : X ⟶ Y) [IsIso f] (U : Opens X.carrier) :
    (inv f).val.c.app (op U) =
      X.presheaf.map
          (eqToHom <| by rw [IsIso.hom_inv_id]; ext1; rfl :
              (Opens.map (f ≫ inv f).1.base).obj U ⟶ U).op ≫
        inv (f.val.c.app (op <| (Opens.map _).obj U)) := by
  rw [IsIso.eq_comp_inv]
  erw [← Scheme.comp_val_c_app]
  

Proof state:
X Y : Scheme
f : X ⟶ Y
inst✝ : IsIso f
U : Opens ↑↑X.toPresheafedSpace
⊢ (f ≫ inv f).val.c.app (op U) = X.presheaf.map (eqToHom (_ : (Opens.map (f ≫ inv f).val.base).obj U = U)).op

Next tactic:
rw [Scheme.congr_app (IsIso.hom_inv_id f), Scheme.id_app, ← Functor.map_comp, eqToHom_trans,
    eqToHom_op]
theorem inv_val_c_app_top {X Y : Scheme} (f : X ⟶ Y) [IsIso f] :
    (inv f).val.c.app (op ⊤) = inv (f.val.c.app (op ⊤)) := by 

Proof state:
X Y : Scheme
f : X ⟶ Y
inst✝ : IsIso f
⊢ (inv f).val.c.app (op ⊤) = inv (f.val.c.app (op ⊤))

Next tactic:
simp
/-- The spectrum, as a contravariant functor from commutative rings to schemes.
-/
-- porting note: removed @[simps]
-- TODO: We need to decide whether `Spec_obj` or `Spec.obj` the simp-normal form.
-- We probably want `Spec.obj`, but note
-- `locallyRingedSpaceObj` is currently the simp-normal form of `toLocallyRingedSpace.obj`.
def Spec : CommRingCatᵒᵖ ⥤ Scheme where
  obj R := specObj (unop R)
  map f := specMap f.unop
  map_id R := by 

Proof state:
R : CommRingCatᵒᵖ
⊢ { obj := fun R => specObj R.unop, map := fun {X Y} f => specMap f.unop }.map (𝟙 R) =
    𝟙 ({ obj := fun R => specObj R.unop, map := fun {X Y} f => specMap f.unop }.obj R)

Next tactic:
simp
/-- The spectrum, as a contravariant functor from commutative rings to schemes.
-/
-- porting note: removed @[simps]
-- TODO: We need to decide whether `Spec_obj` or `Spec.obj` the simp-normal form.
-- We probably want `Spec.obj`, but note
-- `locallyRingedSpaceObj` is currently the simp-normal form of `toLocallyRingedSpace.obj`.
def Spec : CommRingCatᵒᵖ ⥤ Scheme where
  obj R := specObj (unop R)
  map f := specMap f.unop
  map_id R := by simp
  map_comp f g := by 

Proof state:
X✝ Y✝ Z✝ : CommRingCatᵒᵖ
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
⊢ { obj := fun R => specObj R.unop, map := fun {X Y} f => specMap f.unop }.map (f ≫ g) =
    { obj := fun R => specObj R.unop, map := fun {X Y} f => specMap f.unop }.map f ≫
      { obj := fun R => specObj R.unop, map := fun {X Y} f => specMap f.unop }.map g

Next tactic:
simp [specMap_comp]
theorem mem_basicOpen_top' {U : Opens X} (f : X.presheaf.obj (op U)) (x : X.carrier) :
    x ∈ X.basicOpen f ↔ ∃ (m : x ∈ U), IsUnit (X.presheaf.germ (⟨x, m⟩ : U) f) := by
  

Proof state:
X : Scheme
V U✝ : Opens ↑↑X.toPresheafedSpace
f✝ g : ↑(X.presheaf.obj (op U✝))
U : Opens ↑↑X.toPresheafedSpace
f : ↑(X.presheaf.obj (op U))
x : ↑↑X.toPresheafedSpace
⊢ x ∈ X.basicOpen f ↔ ∃ (m : x ∈ U), IsUnit ((Presheaf.germ X.presheaf { val := x, property := m }) f)

Next tactic:
fconstructor