l3lab/ntp-mathlib huggingface dataset:
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> 

Proof state:
case Adj.h.h.a.mp.inl.intro
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
v w : V
hvw : SimpleGraph.Adj G v w
⊢ Adj (induce ⊤ {v, w}) v w

Next tactic:
simp [hvw, hvw.symm]
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> 

Proof state:
case Adj.h.h.a.mp.inr.intro
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
v w : V
hvw : SimpleGraph.Adj G v w
⊢ Adj (induce ⊤ {v, w}) w v

Next tactic:
simp [hvw, hvw.symm]
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> simp [hvw, hvw.symm]
    · 

Proof state:
case Adj.h.h.a.mpr
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
v w : V
hvw : SimpleGraph.Adj G v w
x✝¹ x✝ : V
⊢ Adj (induce ⊤ {v, w}) x✝¹ x✝ → Adj (subgraphOfAdj G hvw) x✝¹ x✝

Next tactic:
intro h
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> simp [hvw, hvw.symm]
    · intro h
      

Proof state:
case Adj.h.h.a.mpr
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
v w : V
hvw : SimpleGraph.Adj G v w
x✝¹ x✝ : V
h : Adj (induce ⊤ {v, w}) x✝¹ x✝
⊢ Adj (subgraphOfAdj G hvw) x✝¹ x✝

Next tactic:
simp only [induce_adj, Set.mem_insert_iff, Set.mem_singleton_iff, top_adj] at h
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> simp [hvw, hvw.symm]
    · intro h
      simp only [induce_adj, Set.mem_insert_iff, Set.mem_singleton_iff, top_adj] at h
      

Proof state:
case Adj.h.h.a.mpr
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
v w : V
hvw : SimpleGraph.Adj G v w
x✝¹ x✝ : V
h : (x✝¹ = v ∨ x✝¹ = w) ∧ (x✝ = v ∨ x✝ = w) ∧ SimpleGraph.Adj G x✝¹ x✝
⊢ Adj (subgraphOfAdj G hvw) x✝¹ x✝

Next tactic:
obtain ⟨rfl | rfl, rfl | rfl, ha⟩ := h
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> simp [hvw, hvw.symm]
    · intro h
      simp only [induce_adj, Set.mem_insert_iff, Set.mem_singleton_iff, top_adj] at h
      obtain ⟨rfl | rfl, rfl | rfl, ha⟩ := h <;> 

Proof state:
case Adj.h.h.a.mpr.intro.inl.intro.inl
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
w x✝ : V
hvw : SimpleGraph.Adj G x✝ w
ha : SimpleGraph.Adj G x✝ x✝
⊢ Adj (subgraphOfAdj G hvw) x✝ x✝

Next tactic:
first |exact (ha.ne rfl).elim|simp
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> simp [hvw, hvw.symm]
    · intro h
      simp only [induce_adj, Set.mem_insert_iff, Set.mem_singleton_iff, top_adj] at h
      obtain ⟨rfl | rfl, rfl | rfl, ha⟩ := h <;> first |

Proof state:
case Adj.h.h.a.mpr.intro.inl.intro.inl
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
w x✝ : V
hvw : SimpleGraph.Adj G x✝ w
ha : SimpleGraph.Adj G x✝ x✝
⊢ Adj (subgraphOfAdj G hvw) x✝ x✝

Next tactic:
exact (ha.ne rfl).elim
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> simp [hvw, hvw.symm]
    · intro h
      simp only [induce_adj, Set.mem_insert_iff, Set.mem_singleton_iff, top_adj] at h
      obtain ⟨rfl | rfl, rfl | rfl, ha⟩ := h <;> 

Proof state:
case Adj.h.h.a.mpr.intro.inl.intro.inr
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
x✝¹ x✝ : V
ha hvw : SimpleGraph.Adj G x✝¹ x✝
⊢ Adj (subgraphOfAdj G hvw) x✝¹ x✝

Next tactic:
first |exact (ha.ne rfl).elim|simp
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> simp [hvw, hvw.symm]
    · intro h
      simp only [induce_adj, Set.mem_insert_iff, Set.mem_singleton_iff, top_adj] at h
      obtain ⟨rfl | rfl, rfl | rfl, ha⟩ := h <;> first |

Proof state:
case Adj.h.h.a.mpr.intro.inl.intro.inr
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
x✝¹ x✝ : V
ha hvw : SimpleGraph.Adj G x✝¹ x✝
⊢ Adj (subgraphOfAdj G hvw) x✝¹ x✝

Next tactic:
exact (ha.ne rfl).elim
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> simp [hvw, hvw.symm]
    · intro h
      simp only [induce_adj, Set.mem_insert_iff, Set.mem_singleton_iff, top_adj] at h
      obtain ⟨rfl | rfl, rfl | rfl, ha⟩ := h <;> first |exact (ha.ne rfl).elim|

Proof state:
case Adj.h.h.a.mpr.intro.inl.intro.inr
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
x✝¹ x✝ : V
ha hvw : SimpleGraph.Adj G x✝¹ x✝
⊢ Adj (subgraphOfAdj G hvw) x✝¹ x✝

Next tactic:
simp
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> simp [hvw, hvw.symm]
    · intro h
      simp only [induce_adj, Set.mem_insert_iff, Set.mem_singleton_iff, top_adj] at h
      obtain ⟨rfl | rfl, rfl | rfl, ha⟩ := h <;> 

Proof state:
case Adj.h.h.a.mpr.intro.inr.intro.inl
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
x✝¹ x✝ : V
ha : SimpleGraph.Adj G x✝¹ x✝
hvw : SimpleGraph.Adj G x✝ x✝¹
⊢ Adj (subgraphOfAdj G hvw) x✝¹ x✝

Next tactic:
first |exact (ha.ne rfl).elim|simp
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> simp [hvw, hvw.symm]
    · intro h
      simp only [induce_adj, Set.mem_insert_iff, Set.mem_singleton_iff, top_adj] at h
      obtain ⟨rfl | rfl, rfl | rfl, ha⟩ := h <;> first |

Proof state:
case Adj.h.h.a.mpr.intro.inr.intro.inl
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
x✝¹ x✝ : V
ha : SimpleGraph.Adj G x✝¹ x✝
hvw : SimpleGraph.Adj G x✝ x✝¹
⊢ Adj (subgraphOfAdj G hvw) x✝¹ x✝

Next tactic:
exact (ha.ne rfl).elim
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> simp [hvw, hvw.symm]
    · intro h
      simp only [induce_adj, Set.mem_insert_iff, Set.mem_singleton_iff, top_adj] at h
      obtain ⟨rfl | rfl, rfl | rfl, ha⟩ := h <;> first |exact (ha.ne rfl).elim|

Proof state:
case Adj.h.h.a.mpr.intro.inr.intro.inl
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
x✝¹ x✝ : V
ha : SimpleGraph.Adj G x✝¹ x✝
hvw : SimpleGraph.Adj G x✝ x✝¹
⊢ Adj (subgraphOfAdj G hvw) x✝¹ x✝

Next tactic:
simp
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> simp [hvw, hvw.symm]
    · intro h
      simp only [induce_adj, Set.mem_insert_iff, Set.mem_singleton_iff, top_adj] at h
      obtain ⟨rfl | rfl, rfl | rfl, ha⟩ := h <;> 

Proof state:
case Adj.h.h.a.mpr.intro.inr.intro.inr
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
v x✝ : V
hvw : SimpleGraph.Adj G v x✝
ha : SimpleGraph.Adj G x✝ x✝
⊢ Adj (subgraphOfAdj G hvw) x✝ x✝

Next tactic:
first |exact (ha.ne rfl).elim|simp
theorem subgraphOfAdj_eq_induce {v w : V} (hvw : G.Adj v w) :
    G.subgraphOfAdj hvw = (⊤ : G.Subgraph).induce {v, w} := by
  ext
  · simp
  · constructor
    · intro h
      simp only [subgraphOfAdj_adj, Quotient.eq, Sym2.rel_iff] at h
      obtain ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩ := h <;> simp [hvw, hvw.symm]
    · intro h
      simp only [induce_adj, Set.mem_insert_iff, Set.mem_singleton_iff, top_adj] at h
      obtain ⟨rfl | rfl, rfl | rfl, ha⟩ := h <;> first |

Proof state:
case Adj.h.h.a.mpr.intro.inr.intro.inr
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' G'' : Subgraph G
s s' : Set V
v x✝ : V
hvw : SimpleGraph.Adj G v x✝
ha : SimpleGraph.Adj G x✝ x✝
⊢ Adj (subgraphOfAdj G hvw) x✝ x✝

Next tactic:
exact (ha.ne rfl).elim
theorem deleteVerts_adj {u v : V} :
    (G'.deleteVerts s).Adj u v ↔ u ∈ G'.verts ∧ ¬u ∈ s ∧ v ∈ G'.verts ∧ ¬v ∈ s ∧ G'.Adj u v := by
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s : Set V
u v : V
⊢ Adj (deleteVerts G' s) u v ↔ u ∈ G'.verts ∧ u ∉ s ∧ v ∈ G'.verts ∧ v ∉ s ∧ Adj G' u v

Next tactic:
simp [and_assoc]
@[simp]
theorem deleteVerts_deleteVerts (s s' : Set V) :
    (G'.deleteVerts s).deleteVerts s' = G'.deleteVerts (s ∪ s') := by
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s✝ s s' : Set V
⊢ deleteVerts (deleteVerts G' s) s' = deleteVerts G' (s ∪ s')

Next tactic:
ext
@[simp]
theorem deleteVerts_deleteVerts (s s' : Set V) :
    (G'.deleteVerts s).deleteVerts s' = G'.deleteVerts (s ∪ s') := by
  ext <;> 

Proof state:
case verts.h
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s✝ s s' : Set V
x✝ : V
⊢ x✝ ∈ (deleteVerts (deleteVerts G' s) s').verts ↔ x✝ ∈ (deleteVerts G' (s ∪ s')).verts

Next tactic:
simp (config := { contextual := true }) [not_or, and_assoc]
@[simp]
theorem deleteVerts_deleteVerts (s s' : Set V) :
    (G'.deleteVerts s).deleteVerts s' = G'.deleteVerts (s ∪ s') := by
  ext <;> 

Proof state:
case Adj.h.h.a
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s✝ s s' : Set V
x✝¹ x✝ : V
⊢ Adj (deleteVerts (deleteVerts G' s) s') x✝¹ x✝ ↔ Adj (deleteVerts G' (s ∪ s')) x✝¹ x✝

Next tactic:
simp (config := { contextual := true }) [not_or, and_assoc]
@[simp]
theorem deleteVerts_empty : G'.deleteVerts ∅ = G' := by
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s : Set V
⊢ deleteVerts G' ∅ = G'

Next tactic:
simp [deleteVerts]
theorem deleteVerts_le : G'.deleteVerts s ≤ G' := by
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s : Set V
⊢ deleteVerts G' s ≤ G'

Next tactic:
constructor
theorem deleteVerts_le : G'.deleteVerts s ≤ G' := by
  constructor <;> 

Proof state:
case left
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s : Set V
⊢ (deleteVerts G' s).verts ⊆ G'.verts

Next tactic:
simp [Set.diff_subset]
theorem deleteVerts_le : G'.deleteVerts s ≤ G' := by
  constructor <;> 

Proof state:
case right
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s : Set V
⊢ ∀ ⦃v w : V⦄, Adj (deleteVerts G' s) v w → Adj G' v w

Next tactic:
simp [Set.diff_subset]
@[simp]
theorem deleteVerts_inter_verts_left_eq : G'.deleteVerts (G'.verts ∩ s) = G'.deleteVerts s := by
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s : Set V
⊢ deleteVerts G' (G'.verts ∩ s) = deleteVerts G' s

Next tactic:
ext
@[simp]
theorem deleteVerts_inter_verts_left_eq : G'.deleteVerts (G'.verts ∩ s) = G'.deleteVerts s := by
  ext <;> 

Proof state:
case verts.h
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s : Set V
x✝ : V
⊢ x✝ ∈ (deleteVerts G' (G'.verts ∩ s)).verts ↔ x✝ ∈ (deleteVerts G' s).verts

Next tactic:
simp (config := { contextual := true }) [imp_false]
@[simp]
theorem deleteVerts_inter_verts_left_eq : G'.deleteVerts (G'.verts ∩ s) = G'.deleteVerts s := by
  ext <;> 

Proof state:
case Adj.h.h.a
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s : Set V
x✝¹ x✝ : V
⊢ Adj (deleteVerts G' (G'.verts ∩ s)) x✝¹ x✝ ↔ Adj (deleteVerts G' s) x✝¹ x✝

Next tactic:
simp (config := { contextual := true }) [imp_false]
@[simp]
theorem deleteVerts_inter_verts_set_right_eq : G'.deleteVerts (s ∩ G'.verts) = G'.deleteVerts s :=
  by 

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s : Set V
⊢ deleteVerts G' (s ∩ G'.verts) = deleteVerts G' s

Next tactic:
ext
@[simp]
theorem deleteVerts_inter_verts_set_right_eq : G'.deleteVerts (s ∩ G'.verts) = G'.deleteVerts s :=
  by ext <;> 

Proof state:
case verts.h
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s : Set V
x✝ : V
⊢ x✝ ∈ (deleteVerts G' (s ∩ G'.verts)).verts ↔ x✝ ∈ (deleteVerts G' s).verts

Next tactic:
simp (config := { contextual := true }) [imp_false]
@[simp]
theorem deleteVerts_inter_verts_set_right_eq : G'.deleteVerts (s ∩ G'.verts) = G'.deleteVerts s :=
  by ext <;> 

Proof state:
case Adj.h.h.a
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G' : Subgraph G
s : Set V
x✝¹ x✝ : V
⊢ Adj (deleteVerts G' (s ∩ G'.verts)) x✝¹ x✝ ↔ Adj (deleteVerts G' s) x✝¹ x✝

Next tactic:
simp (config := { contextual := true }) [imp_false]
@[symm]
theorem IsCoprime.symm (H : IsCoprime x y) : IsCoprime y x :=
  let ⟨a, b, H⟩ := H
  ⟨b, a, by 

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
H✝ : IsCoprime x y
a b : R
H : a * x + b * y = 1
⊢ b * y + a * x = 1

Next tactic:
rw [add_comm, H]
theorem isCoprime_self : IsCoprime x x ↔ IsUnit x :=
  ⟨fun ⟨a, b, h⟩ => isUnit_of_mul_eq_one x (a + b) <| by 

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
x✝ : IsCoprime x x
a b : R
h : a * x + b * x = 1
⊢ x * (a + b) = 1

Next tactic:
rwa [mul_comm, add_mul]
theorem isCoprime_self : IsCoprime x x ↔ IsUnit x :=
  ⟨fun ⟨a, b, h⟩ => isUnit_of_mul_eq_one x (a + b) <| by rwa [mul_comm, add_mul], fun h =>
    let ⟨b, hb⟩ := isUnit_iff_exists_inv'.1 h
    ⟨b, 0, by 

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
h : IsUnit x
b : R
hb : b * x = 1
⊢ b * x + 0 * x = 1

Next tactic:
rwa [zero_mul, add_zero]
theorem isCoprime_zero_left : IsCoprime 0 x ↔ IsUnit x :=
  ⟨fun ⟨a, b, H⟩ => isUnit_of_mul_eq_one x b <| by 

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
x✝ : IsCoprime 0 x
a b : R
H : a * 0 + b * x = 1
⊢ x * b = 1

Next tactic:
rwa [mul_zero, zero_add, mul_comm] at H
theorem isCoprime_zero_left : IsCoprime 0 x ↔ IsUnit x :=
  ⟨fun ⟨a, b, H⟩ => isUnit_of_mul_eq_one x b <| by rwa [mul_zero, zero_add, mul_comm] at H, fun H =>
    let ⟨b, hb⟩ := isUnit_iff_exists_inv'.1 H
    ⟨1, b, by 

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
H : IsUnit x
b : R
hb : b * x = 1
⊢ 1 * 0 + b * x = 1

Next tactic:
rwa [one_mul, zero_add]
lemma IsCoprime.intCast {R : Type*} [CommRing R] {a b : ℤ} (h : IsCoprime a b) :
    IsCoprime (a : R) (b : R) := by
  

Proof state:
R✝ : Type u
inst✝¹ : CommSemiring R✝
x y z : R✝
R : Type u_1
inst✝ : CommRing R
a b : ℤ
h : IsCoprime a b
⊢ IsCoprime ↑a ↑b

Next tactic:
rcases h with ⟨u, v, H⟩
lemma IsCoprime.intCast {R : Type*} [CommRing R] {a b : ℤ} (h : IsCoprime a b) :
    IsCoprime (a : R) (b : R) := by
  rcases h with ⟨u, v, H⟩
  

Proof state:
case intro.intro
R✝ : Type u
inst✝¹ : CommSemiring R✝
x y z : R✝
R : Type u_1
inst✝ : CommRing R
a b u v : ℤ
H : u * a + v * b = 1
⊢ IsCoprime ↑a ↑b

Next tactic:
use u, v
lemma IsCoprime.intCast {R : Type*} [CommRing R] {a b : ℤ} (h : IsCoprime a b) :
    IsCoprime (a : R) (b : R) := by
  rcases h with ⟨u, v, H⟩
  use u, v
  

Proof state:
case h
R✝ : Type u
inst✝¹ : CommSemiring R✝
x y z : R✝
R : Type u_1
inst✝ : CommRing R
a b u v : ℤ
H : u * a + v * b = 1
⊢ ↑u * ↑a + ↑v * ↑b = 1

Next tactic:
rw_mod_cast [H]
lemma IsCoprime.intCast {R : Type*} [CommRing R] {a b : ℤ} (h : IsCoprime a b) :
    IsCoprime (a : R) (b : R) := by
  rcases h with ⟨u, v, H⟩
  use u, v
  rw_mod_cast [H]
  

Proof state:
case h
R✝ : Type u
inst✝¹ : CommSemiring R✝
x y z : R✝
R : Type u_1
inst✝ : CommRing R
a b u v : ℤ
H : u * a + v * b = 1
⊢ ↑1 = 1

Next tactic:
exact Int.cast_one
/-- If a 2-vector `p` satisfies `IsCoprime (p 0) (p 1)`, then `p ≠ 0`. -/
theorem IsCoprime.ne_zero [Nontrivial R] {p : Fin 2 → R} (h : IsCoprime (p 0) (p 1)) : p ≠ 0 := by
  

Proof state:
R : Type u
inst✝¹ : CommSemiring R
x y z : R
inst✝ : Nontrivial R
p : Fin 2 → R
h : IsCoprime (p 0) (p 1)
⊢ p ≠ 0

Next tactic:
rintro rfl
/-- If a 2-vector `p` satisfies `IsCoprime (p 0) (p 1)`, then `p ≠ 0`. -/
theorem IsCoprime.ne_zero [Nontrivial R] {p : Fin 2 → R} (h : IsCoprime (p 0) (p 1)) : p ≠ 0 := by
  rintro rfl
  

Proof state:
R : Type u
inst✝¹ : CommSemiring R
x y z : R
inst✝ : Nontrivial R
h : IsCoprime (OfNat.ofNat 0 0) (OfNat.ofNat 0 1)
⊢ False

Next tactic:
exact not_isCoprime_zero_zero h
theorem IsCoprime.ne_zero_or_ne_zero [Nontrivial R] (h : IsCoprime x y) : x ≠ 0 ∨ y ≠ 0 := by
  

Proof state:
R : Type u
inst✝¹ : CommSemiring R
x y z : R
inst✝ : Nontrivial R
h : IsCoprime x y
⊢ x ≠ 0 ∨ y ≠ 0

Next tactic:
apply not_or_of_imp
theorem IsCoprime.ne_zero_or_ne_zero [Nontrivial R] (h : IsCoprime x y) : x ≠ 0 ∨ y ≠ 0 := by
  apply not_or_of_imp
  

Proof state:
case a
R : Type u
inst✝¹ : CommSemiring R
x y z : R
inst✝ : Nontrivial R
h : IsCoprime x y
⊢ x = 0 → y ≠ 0

Next tactic:
rintro rfl rfl
theorem IsCoprime.ne_zero_or_ne_zero [Nontrivial R] (h : IsCoprime x y) : x ≠ 0 ∨ y ≠ 0 := by
  apply not_or_of_imp
  rintro rfl rfl
  

Proof state:
case a
R : Type u
inst✝¹ : CommSemiring R
z : R
inst✝ : Nontrivial R
h : IsCoprime 0 0
⊢ False

Next tactic:
exact not_isCoprime_zero_zero h
theorem isCoprime_one_left : IsCoprime 1 x :=
  ⟨1, 0, by 

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
⊢ 1 * 1 + 0 * x = 1

Next tactic:
rw [one_mul, zero_mul, add_zero]
theorem isCoprime_one_right : IsCoprime x 1 :=
  ⟨0, 1, by 

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
⊢ 0 * x + 1 * 1 = 1

Next tactic:
rw [one_mul, zero_mul, zero_add]
theorem IsCoprime.dvd_of_dvd_mul_right (H1 : IsCoprime x z) (H2 : x ∣ y * z) : x ∣ y := by
  

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
H1 : IsCoprime x z
H2 : x ∣ y * z
⊢ x ∣ y

Next tactic:
let ⟨a, b, H⟩ := H1
theorem IsCoprime.dvd_of_dvd_mul_right (H1 : IsCoprime x z) (H2 : x ∣ y * z) : x ∣ y := by
  let ⟨a, b, H⟩ := H1
  

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
H1 : IsCoprime x z
H2 : x ∣ y * z
a b : R
H : a * x + b * z = 1
⊢ x ∣ y

Next tactic:
rw [← mul_one y, ← H, mul_add, ← mul_assoc, mul_left_comm]
theorem IsCoprime.dvd_of_dvd_mul_right (H1 : IsCoprime x z) (H2 : x ∣ y * z) : x ∣ y := by
  let ⟨a, b, H⟩ := H1
  rw [← mul_one y, ← H, mul_add, ← mul_assoc, mul_left_comm]
  

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
H1 : IsCoprime x z
H2 : x ∣ y * z
a b : R
H : a * x + b * z = 1
⊢ x ∣ y * a * x + b * (y * z)

Next tactic:
exact dvd_add (dvd_mul_left _ _) (H2.mul_left _)
theorem IsCoprime.dvd_of_dvd_mul_left (H1 : IsCoprime x y) (H2 : x ∣ y * z) : x ∣ z := by
  

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
H1 : IsCoprime x y
H2 : x ∣ y * z
⊢ x ∣ z

Next tactic:
let ⟨a, b, H⟩ := H1
theorem IsCoprime.dvd_of_dvd_mul_left (H1 : IsCoprime x y) (H2 : x ∣ y * z) : x ∣ z := by
  let ⟨a, b, H⟩ := H1
  

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
H1 : IsCoprime x y
H2 : x ∣ y * z
a b : R
H : a * x + b * y = 1
⊢ x ∣ z

Next tactic:
rw [← one_mul z, ← H, add_mul, mul_right_comm, mul_assoc b]
theorem IsCoprime.dvd_of_dvd_mul_left (H1 : IsCoprime x y) (H2 : x ∣ y * z) : x ∣ z := by
  let ⟨a, b, H⟩ := H1
  rw [← one_mul z, ← H, add_mul, mul_right_comm, mul_assoc b]
  

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
H1 : IsCoprime x y
H2 : x ∣ y * z
a b : R
H : a * x + b * y = 1
⊢ x ∣ a * z * x + b * (y * z)

Next tactic:
exact dvd_add (dvd_mul_left _ _) (H2.mul_left _)
theorem IsCoprime.mul_left (H1 : IsCoprime x z) (H2 : IsCoprime y z) : IsCoprime (x * y) z :=
  let ⟨a, b, h1⟩ := H1
  let ⟨c, d, h2⟩ := H2
  ⟨a * c, a * x * d + b * c * y + b * d * z,
    calc
      a * c * (x * y) + (a * x * d + b * c * y + b * d * z) * z =
          (a * x + b * z) * (c * y + d * z) :=
        by 

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
H1 : IsCoprime x z
H2 : IsCoprime y z
a b : R
h1 : a * x + b * z = 1
c d : R
h2 : c * y + d * z = 1
⊢ a * c * (x * y) + (a * x * d + b * c * y + b * d * z) * z = (a * x + b * z) * (c * y + d * z)

Next tactic:
ring
theorem IsCoprime.mul_left (H1 : IsCoprime x z) (H2 : IsCoprime y z) : IsCoprime (x * y) z :=
  let ⟨a, b, h1⟩ := H1
  let ⟨c, d, h2⟩ := H2
  ⟨a * c, a * x * d + b * c * y + b * d * z,
    calc
      a * c * (x * y) + (a * x * d + b * c * y + b * d * z) * z =
          (a * x + b * z) * (c * y + d * z) :=
        by ring
      _ = 1 := by 

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
H1 : IsCoprime x z
H2 : IsCoprime y z
a b : R
h1 : a * x + b * z = 1
c d : R
h2 : c * y + d * z = 1
⊢ (a * x + b * z) * (c * y + d * z) = 1

Next tactic:
rw [h1, h2, mul_one]
theorem IsCoprime.mul_right (H1 : IsCoprime x y) (H2 : IsCoprime x z) : IsCoprime x (y * z) := by
  

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
H1 : IsCoprime x y
H2 : IsCoprime x z
⊢ IsCoprime x (y * z)

Next tactic:
rw [isCoprime_comm] at H1 H2 ⊢
theorem IsCoprime.mul_right (H1 : IsCoprime x y) (H2 : IsCoprime x z) : IsCoprime x (y * z) := by
  rw [isCoprime_comm] at H1 H2 ⊢
  

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
H1 : IsCoprime y x
H2 : IsCoprime z x
⊢ IsCoprime (y * z) x

Next tactic:
exact H1.mul_left H2
theorem IsCoprime.mul_dvd (H : IsCoprime x y) (H1 : x ∣ z) (H2 : y ∣ z) : x * y ∣ z := by
  

Proof state:
R : Type u
inst✝ : CommSemiring R
x y z : R
H : IsCoprime x y
H1 : x ∣ z
H2 : y ∣ z
⊢ x * y ∣ z

Next tactic:
obtain ⟨a, b, h⟩ := H
theorem IsCoprime.mul_dvd (H : IsCoprime x y) (H1 : x ∣ z) (H2 : y ∣ z) : x * y ∣ z := by
  obtain ⟨a, b, h⟩ := H
  

Proof state:
case intro.intro
R : Type u
inst✝ : CommSemiring R
x y z : R
H1 : x ∣ z
H2 : y ∣ z
a b : R
h : a * x + b * y = 1
⊢ x * y ∣ z

Next tactic:
rw [← mul_one z, ← h, mul_add]
theorem IsCoprime.mul_dvd (H : IsCoprime x y) (H1 : x ∣ z) (H2 : y ∣ z) : x * y ∣ z := by
  obtain ⟨a, b, h⟩ := H
  rw [← mul_one z, ← h, mul_add]
  

Proof state:
case intro.intro
R : Type u
inst✝ : CommSemiring R
x y z : R
H1 : x ∣ z
H2 : y ∣ z
a b : R
h : a * x + b * y = 1
⊢ x * y ∣ z * (a * x) + z * (b * y)

Next tactic:
apply dvd_add
theorem IsCoprime.mul_dvd (H : IsCoprime x y) (H1 : x ∣ z) (H2 : y ∣ z) : x * y ∣ z := by
  obtain ⟨a, b, h⟩ := H
  rw [← mul_one z, ← h, mul_add]
  apply dvd_add
  · 

Proof state:
case intro.intro.h₁
R : Type u
inst✝ : CommSemiring R
x y z : R
H1 : x ∣ z
H2 : y ∣ z
a b : R
h : a * x + b * y = 1
⊢ x * y ∣ z * (a * x)

Next tactic:
rw [mul_comm z, mul_assoc]