l3lab/ntp-mathlib huggingface dataset:
theorem isNat_natMod : {a b : ℕ} → {a' b' c : ℕ} →
    IsNat a a' → IsNat b b' → Nat.mod a' b' = c → IsNat (a % b) c
  | _, _, _, _, _, ⟨rfl⟩, ⟨rfl⟩, rfl => ⟨by 

Proof state:
n✝¹ n✝ : ℕ
⊢ ↑n✝¹ % ↑n✝ = ↑(Nat.mod n✝¹ n✝)

Next tactic:
aesop
theorem isNat_natDiv : {a b : ℕ} → {a' b' c : ℕ} →
    IsNat a a' → IsNat b b' → Nat.div a' b' = c → IsNat (a / b) c
  | _, _, _, _, _, ⟨rfl⟩, ⟨rfl⟩, rfl => ⟨by 

Proof state:
n✝¹ n✝ : ℕ
⊢ ↑n✝¹ / ↑n✝ = ↑(Nat.div n✝¹ n✝)

Next tactic:
aesop
theorem encard_diff_le_aux (exch : ExchangeProperty Base) (hB₁ : Base B₁) (hB₂ : Base B₂) :
    (B₁ \ B₂).encard ≤ (B₂ \ B₁).encard := by
  

Proof state:
α : Type u_1
M : Matroid α
Base : Set α → Prop
exch✝ : ExchangeProperty Base
B₁ B₂ : Set α
exch : ExchangeProperty Base
hB₁ : Base B₁
hB₂ : Base B₂
⊢ encard (B₁ \ B₂) ≤ encard (B₂ \ B₁)

Next tactic:
obtain (he | hinf | ⟨e, he, hcard⟩) :=
    (B₂ \ B₁).eq_empty_or_encard_eq_top_or_encard_diff_singleton_lt
theorem encard_diff_le_aux (exch : ExchangeProperty Base) (hB₁ : Base B₁) (hB₂ : Base B₂) :
    (B₁ \ B₂).encard ≤ (B₂ \ B₁).encard := by
  obtain (he | hinf | ⟨e, he, hcard⟩) :=
    (B₂ \ B₁).eq_empty_or_encard_eq_top_or_encard_diff_singleton_lt
  · 

Proof state:
case inl
α : Type u_1
M : Matroid α
Base : Set α → Prop
exch✝ : ExchangeProperty Base
B₁ B₂ : Set α
exch : ExchangeProperty Base
hB₁ : Base B₁
hB₂ : Base B₂
he : B₂ \ B₁ = ∅
⊢ encard (B₁ \ B₂) ≤ encard (B₂ \ B₁)

Next tactic:
rw [exch.antichain hB₂ hB₁ (diff_eq_empty.mp he)]
theorem encard_diff_le_aux (exch : ExchangeProperty Base) (hB₁ : Base B₁) (hB₂ : Base B₂) :
    (B₁ \ B₂).encard ≤ (B₂ \ B₁).encard := by
  obtain (he | hinf | ⟨e, he, hcard⟩) :=
    (B₂ \ B₁).eq_empty_or_encard_eq_top_or_encard_diff_singleton_lt
  · rw [exch.antichain hB₂ hB₁ (diff_eq_empty.mp he)]
  · 

Proof state:
case inr.inl
α : Type u_1
M : Matroid α
Base : Set α → Prop
exch✝ : ExchangeProperty Base
B₁ B₂ : Set α
exch : ExchangeProperty Base
hB₁ : Base B₁
hB₂ : Base B₂
hinf : encard (B₂ \ B₁) = ⊤
⊢ encard (B₁ \ B₂) ≤ encard (B₂ \ B₁)

Next tactic:
exact le_top.trans_eq hinf.symm
theorem encard_diff_le_aux (exch : ExchangeProperty Base) (hB₁ : Base B₁) (hB₂ : Base B₂) :
    (B₁ \ B₂).encard ≤ (B₂ \ B₁).encard := by
  obtain (he | hinf | ⟨e, he, hcard⟩) :=
    (B₂ \ B₁).eq_empty_or_encard_eq_top_or_encard_diff_singleton_lt
  · rw [exch.antichain hB₂ hB₁ (diff_eq_empty.mp he)]
  · exact le_top.trans_eq hinf.symm

  

Proof state:
case inr.inr.intro.intro
α : Type u_1
M : Matroid α
Base : Set α → Prop
exch✝ : ExchangeProperty Base
B₁ B₂ : Set α
exch : ExchangeProperty Base
hB₁ : Base B₁
hB₂ : Base B₂
e : α
he : e ∈ B₂ \ B₁
hcard : encard ((B₂ \ B₁) \ {e}) < encard (B₂ \ B₁)
⊢ encard (B₁ \ B₂) ≤ encard (B₂ \ B₁)

Next tactic:
obtain ⟨f, hf, hB'⟩ := exch B₂ B₁ hB₂ hB₁ e he
theorem encard_diff_le_aux (exch : ExchangeProperty Base) (hB₁ : Base B₁) (hB₂ : Base B₂) :
    (B₁ \ B₂).encard ≤ (B₂ \ B₁).encard := by
  obtain (he | hinf | ⟨e, he, hcard⟩) :=
    (B₂ \ B₁).eq_empty_or_encard_eq_top_or_encard_diff_singleton_lt
  · rw [exch.antichain hB₂ hB₁ (diff_eq_empty.mp he)]
  · exact le_top.trans_eq hinf.symm

  obtain ⟨f, hf, hB'⟩ := exch B₂ B₁ hB₂ hB₁ e he

  

Proof state:
case inr.inr.intro.intro.intro.intro
α : Type u_1
M : Matroid α
Base : Set α → Prop
exch✝ : ExchangeProperty Base
B₁ B₂ : Set α
exch : ExchangeProperty Base
hB₁ : Base B₁
hB₂ : Base B₂
e : α
he : e ∈ B₂ \ B₁
hcard : encard ((B₂ \ B₁) \ {e}) < encard (B₂ \ B₁)
f : α
hf : f ∈ B₁ \ B₂
hB' : Base (insert f (B₂ \ {e}))
⊢ encard (B₁ \ B₂) ≤ encard (B₂ \ B₁)

Next tactic:
have : encard (insert f (B₂ \ {e}) \ B₁) < encard (B₂ \ B₁) := by
    rw [insert_diff_of_mem _ hf.1, diff_diff_comm]; exact hcard
theorem encard_diff_le_aux (exch : ExchangeProperty Base) (hB₁ : Base B₁) (hB₂ : Base B₂) :
    (B₁ \ B₂).encard ≤ (B₂ \ B₁).encard := by
  obtain (he | hinf | ⟨e, he, hcard⟩) :=
    (B₂ \ B₁).eq_empty_or_encard_eq_top_or_encard_diff_singleton_lt
  · rw [exch.antichain hB₂ hB₁ (diff_eq_empty.mp he)]
  · exact le_top.trans_eq hinf.symm

  obtain ⟨f, hf, hB'⟩ := exch B₂ B₁ hB₂ hB₁ e he

  have : encard (insert f (B₂ \ {e}) \ B₁) < encard (B₂ \ B₁) := by
    

Proof state:
α : Type u_1
M : Matroid α
Base : Set α → Prop
exch✝ : ExchangeProperty Base
B₁ B₂ : Set α
exch : ExchangeProperty Base
hB₁ : Base B₁
hB₂ : Base B₂
e : α
he : e ∈ B₂ \ B₁
hcard : encard ((B₂ \ B₁) \ {e}) < encard (B₂ \ B₁)
f : α
hf : f ∈ B₁ \ B₂
hB' : Base (insert f (B₂ \ {e}))
⊢ encard (insert f (B₂ \ {e}) \ B₁) < encard (B₂ \ B₁)

Next tactic:
rw [insert_diff_of_mem _ hf.1, diff_diff_comm]
theorem encard_diff_le_aux (exch : ExchangeProperty Base) (hB₁ : Base B₁) (hB₂ : Base B₂) :
    (B₁ \ B₂).encard ≤ (B₂ \ B₁).encard := by
  obtain (he | hinf | ⟨e, he, hcard⟩) :=
    (B₂ \ B₁).eq_empty_or_encard_eq_top_or_encard_diff_singleton_lt
  · rw [exch.antichain hB₂ hB₁ (diff_eq_empty.mp he)]
  · exact le_top.trans_eq hinf.symm

  obtain ⟨f, hf, hB'⟩ := exch B₂ B₁ hB₂ hB₁ e he

  have : encard (insert f (B₂ \ {e}) \ B₁) < encard (B₂ \ B₁) := by
    rw [insert_diff_of_mem _ hf.1, diff_diff_comm]; 

Proof state:
α : Type u_1
M : Matroid α
Base : Set α → Prop
exch✝ : ExchangeProperty Base
B₁ B₂ : Set α
exch : ExchangeProperty Base
hB₁ : Base B₁
hB₂ : Base B₂
e : α
he : e ∈ B₂ \ B₁
hcard : encard ((B₂ \ B₁) \ {e}) < encard (B₂ \ B₁)
f : α
hf : f ∈ B₁ \ B₂
hB' : Base (insert f (B₂ \ {e}))
⊢ encard ((B₂ \ B₁) \ {e}) < encard (B₂ \ B₁)

Next tactic:
exact hcard
theorem encard_diff_le_aux (exch : ExchangeProperty Base) (hB₁ : Base B₁) (hB₂ : Base B₂) :
    (B₁ \ B₂).encard ≤ (B₂ \ B₁).encard := by
  obtain (he | hinf | ⟨e, he, hcard⟩) :=
    (B₂ \ B₁).eq_empty_or_encard_eq_top_or_encard_diff_singleton_lt
  · rw [exch.antichain hB₂ hB₁ (diff_eq_empty.mp he)]
  · exact le_top.trans_eq hinf.symm

  obtain ⟨f, hf, hB'⟩ := exch B₂ B₁ hB₂ hB₁ e he

  have : encard (insert f (B₂ \ {e}) \ B₁) < encard (B₂ \ B₁) := by
    rw [insert_diff_of_mem _ hf.1, diff_diff_comm]; exact hcard

  

Proof state:
case inr.inr.intro.intro.intro.intro
α : Type u_1
M : Matroid α
Base : Set α → Prop
exch✝ : ExchangeProperty Base
B₁ B₂ : Set α
exch : ExchangeProperty Base
hB₁ : Base B₁
hB₂ : Base B₂
e : α
he : e ∈ B₂ \ B₁
hcard : encard ((B₂ \ B₁) \ {e}) < encard (B₂ \ B₁)
f : α
hf : f ∈ B₁ \ B₂
hB' : Base (insert f (B₂ \ {e}))
this : encard (insert f (B₂ \ {e}) \ B₁) < encard (B₂ \ B₁)
⊢ encard (B₁ \ B₂) ≤ encard (B₂ \ B₁)

Next tactic:
have hencard := encard_diff_le_aux exch hB₁ hB'
theorem encard_diff_le_aux (exch : ExchangeProperty Base) (hB₁ : Base B₁) (hB₂ : Base B₂) :
    (B₁ \ B₂).encard ≤ (B₂ \ B₁).encard := by
  obtain (he | hinf | ⟨e, he, hcard⟩) :=
    (B₂ \ B₁).eq_empty_or_encard_eq_top_or_encard_diff_singleton_lt
  · rw [exch.antichain hB₂ hB₁ (diff_eq_empty.mp he)]
  · exact le_top.trans_eq hinf.symm

  obtain ⟨f, hf, hB'⟩ := exch B₂ B₁ hB₂ hB₁ e he

  have : encard (insert f (B₂ \ {e}) \ B₁) < encard (B₂ \ B₁) := by
    rw [insert_diff_of_mem _ hf.1, diff_diff_comm]; exact hcard

  have hencard := encard_diff_le_aux exch hB₁ hB'
  

Proof state:
case inr.inr.intro.intro.intro.intro
α : Type u_1
M : Matroid α
Base : Set α → Prop
exch✝ : ExchangeProperty Base
B₁ B₂ : Set α
exch : ExchangeProperty Base
hB₁ : Base B₁
hB₂ : Base B₂
e : α
he : e ∈ B₂ \ B₁
hcard : encard ((B₂ \ B₁) \ {e}) < encard (B₂ \ B₁)
f : α
hf : f ∈ B₁ \ B₂
hB' : Base (insert f (B₂ \ {e}))
this : encard (insert f (B₂ \ {e}) \ B₁) < encard (B₂ \ B₁)
hencard : encard (B₁ \ insert f (B₂ \ {e})) ≤ encard (insert f (B₂ \ {e}) \ B₁)
⊢ encard (B₁ \ B₂) ≤ encard (B₂ \ B₁)

Next tactic:
rw [insert_diff_of_mem _ hf.1, diff_diff_comm, ← union_singleton, ← diff_diff, diff_diff_right,
    inter_singleton_eq_empty.mpr he.2, union_empty] at hencard
theorem encard_diff_le_aux (exch : ExchangeProperty Base) (hB₁ : Base B₁) (hB₂ : Base B₂) :
    (B₁ \ B₂).encard ≤ (B₂ \ B₁).encard := by
  obtain (he | hinf | ⟨e, he, hcard⟩) :=
    (B₂ \ B₁).eq_empty_or_encard_eq_top_or_encard_diff_singleton_lt
  · rw [exch.antichain hB₂ hB₁ (diff_eq_empty.mp he)]
  · exact le_top.trans_eq hinf.symm

  obtain ⟨f, hf, hB'⟩ := exch B₂ B₁ hB₂ hB₁ e he

  have : encard (insert f (B₂ \ {e}) \ B₁) < encard (B₂ \ B₁) := by
    rw [insert_diff_of_mem _ hf.1, diff_diff_comm]; exact hcard

  have hencard := encard_diff_le_aux exch hB₁ hB'
  rw [insert_diff_of_mem _ hf.1, diff_diff_comm, ← union_singleton, ← diff_diff, diff_diff_right,
    inter_singleton_eq_empty.mpr he.2, union_empty] at hencard

  

Proof state:
case inr.inr.intro.intro.intro.intro
α : Type u_1
M : Matroid α
Base : Set α → Prop
exch✝ : ExchangeProperty Base
B₁ B₂ : Set α
exch : ExchangeProperty Base
hB₁ : Base B₁
hB₂ : Base B₂
e : α
he : e ∈ B₂ \ B₁
hcard : encard ((B₂ \ B₁) \ {e}) < encard (B₂ \ B₁)
f : α
hf : f ∈ B₁ \ B₂
hB' : Base (insert f (B₂ \ {e}))
this : encard (insert f (B₂ \ {e}) \ B₁) < encard (B₂ \ B₁)
hencard : encard ((B₁ \ B₂) \ {f}) ≤ encard ((B₂ \ B₁) \ {e})
⊢ encard (B₁ \ B₂) ≤ encard (B₂ \ B₁)

Next tactic:
rw [← encard_diff_singleton_add_one he, ← encard_diff_singleton_add_one hf]
theorem encard_diff_le_aux (exch : ExchangeProperty Base) (hB₁ : Base B₁) (hB₂ : Base B₂) :
    (B₁ \ B₂).encard ≤ (B₂ \ B₁).encard := by
  obtain (he | hinf | ⟨e, he, hcard⟩) :=
    (B₂ \ B₁).eq_empty_or_encard_eq_top_or_encard_diff_singleton_lt
  · rw [exch.antichain hB₂ hB₁ (diff_eq_empty.mp he)]
  · exact le_top.trans_eq hinf.symm

  obtain ⟨f, hf, hB'⟩ := exch B₂ B₁ hB₂ hB₁ e he

  have : encard (insert f (B₂ \ {e}) \ B₁) < encard (B₂ \ B₁) := by
    rw [insert_diff_of_mem _ hf.1, diff_diff_comm]; exact hcard

  have hencard := encard_diff_le_aux exch hB₁ hB'
  rw [insert_diff_of_mem _ hf.1, diff_diff_comm, ← union_singleton, ← diff_diff, diff_diff_right,
    inter_singleton_eq_empty.mpr he.2, union_empty] at hencard

  rw [← encard_diff_singleton_add_one he, ← encard_diff_singleton_add_one hf]
  

Proof state:
case inr.inr.intro.intro.intro.intro
α : Type u_1
M : Matroid α
Base : Set α → Prop
exch✝ : ExchangeProperty Base
B₁ B₂ : Set α
exch : ExchangeProperty Base
hB₁ : Base B₁
hB₂ : Base B₂
e : α
he : e ∈ B₂ \ B₁
hcard : encard ((B₂ \ B₁) \ {e}) < encard (B₂ \ B₁)
f : α
hf : f ∈ B₁ \ B₂
hB' : Base (insert f (B₂ \ {e}))
this : encard (insert f (B₂ \ {e}) \ B₁) < encard (B₂ \ B₁)
hencard : encard ((B₁ \ B₂) \ {f}) ≤ encard ((B₂ \ B₁) \ {e})
⊢ encard ((B₁ \ B₂) \ {f}) + 1 ≤ encard ((B₂ \ B₁) \ {e}) + 1

Next tactic:
exact add_le_add_right hencard 1
/-- Any two sets `B₁`, `B₂` in a family with the exchange property have the same
`ℕ∞`-cardinality. -/
theorem encard_base_eq (hB₁ : Base B₁) (hB₂ : Base B₂) : B₁.encard = B₂.encard := by


Proof state:
α : Type u_1
M : Matroid α
Base : Set α → Prop
exch : ExchangeProperty Base
B₁ B₂ : Set α
hB₁ : Base B₁
hB₂ : Base B₂
⊢ encard B₁ = encard B₂

Next tactic:
rw [← encard_diff_add_encard_inter B₁ B₂, exch.encard_diff_eq hB₁ hB₂, inter_comm,
     encard_diff_add_encard_inter]
theorem Base.exchange_mem (hB₁ : M.Base B₁) (hB₂ : M.Base B₂) (hxB₁ : e ∈ B₁) (hxB₂ : e ∉ B₂) :
    ∃ y, (y ∈ B₂ ∧ y ∉ B₁) ∧ M.Base (insert y (B₁ \ {e})) :=
  by 

Proof state:
α : Type u_1
M : Matroid α
B₁ B₂ : Set α
e : α
hB₁ : M.Base B₁
hB₂ : M.Base B₂
hxB₁ : e ∈ B₁
hxB₂ : e ∉ B₂
⊢ ∃ y, (y ∈ B₂ ∧ y ∉ B₁) ∧ M.Base (insert y (B₁ \ {e}))

Next tactic:
simpa using hB₁.exchange hB₂ ⟨hxB₁, hxB₂⟩
theorem Base.ncard_diff_comm (hB₁ : M.Base B₁) (hB₂ : M.Base B₂) :
    (B₁ \ B₂).ncard = (B₂ \ B₁).ncard := by
  

Proof state:
α : Type u_1
M : Matroid α
B₁ B₂ : Set α
hB₁ : M.Base B₁
hB₂ : M.Base B₂
⊢ ncard (B₁ \ B₂) = ncard (B₂ \ B₁)

Next tactic:
rw [ncard_def, hB₁.encard_diff_comm hB₂, ← ncard_def]
theorem Base.card_eq_card_of_base (hB₁ : M.Base B₁) (hB₂ : M.Base B₂) :
    B₁.encard = B₂.encard := by
  

Proof state:
α : Type u_1
M : Matroid α
B₁ B₂ : Set α
hB₁ : M.Base B₁
hB₂ : M.Base B₂
⊢ encard B₁ = encard B₂

Next tactic:
rw [M.base_exchange.encard_base_eq hB₁ hB₂]
theorem Base.ncard_eq_ncard_of_base (hB₁ : M.Base B₁) (hB₂ : M.Base B₂) : B₁.ncard = B₂.ncard := by
  

Proof state:
α : Type u_1
M : Matroid α
B₁ B₂ : Set α
hB₁ : M.Base B₁
hB₂ : M.Base B₂
⊢ ncard B₁ = ncard B₂

Next tactic:
rw [ncard_def B₁, hB₁.card_eq_card_of_base hB₂, ← ncard_def]
theorem Base.nonempty [RkPos M] (hB : M.Base B) : B.Nonempty := by
  

Proof state:
α : Type u_1
M : Matroid α
B : Set α
inst✝ : RkPos M
hB : M.Base B
⊢ Set.Nonempty B

Next tactic:
rw [nonempty_iff_ne_empty]
theorem Base.nonempty [RkPos M] (hB : M.Base B) : B.Nonempty := by
  rw [nonempty_iff_ne_empty]; 

Proof state:
α : Type u_1
M : Matroid α
B : Set α
inst✝ : RkPos M
hB : M.Base B
⊢ B ≠ ∅

Next tactic:
rintro rfl
theorem Base.nonempty [RkPos M] (hB : M.Base B) : B.Nonempty := by
  rw [nonempty_iff_ne_empty]; rintro rfl; 

Proof state:
α : Type u_1
M : Matroid α
inst✝ : RkPos M
hB : M.Base ∅
⊢ False

Next tactic:
exact M.empty_not_base hB
theorem Base.rkPos_of_nonempty (hB : M.Base B) (h : B.Nonempty) : M.RkPos := by
  

Proof state:
α : Type u_1
M : Matroid α
B : Set α
hB : M.Base B
h : Set.Nonempty B
⊢ RkPos M

Next tactic:
rw [rkPos_iff_empty_not_base]
theorem Base.rkPos_of_nonempty (hB : M.Base B) (h : B.Nonempty) : M.RkPos := by
  rw [rkPos_iff_empty_not_base]
  

Proof state:
α : Type u_1
M : Matroid α
B : Set α
hB : M.Base B
h : Set.Nonempty B
⊢ ¬M.Base ∅

Next tactic:
intro he
theorem Base.rkPos_of_nonempty (hB : M.Base B) (h : B.Nonempty) : M.RkPos := by
  rw [rkPos_iff_empty_not_base]
  intro he
  

Proof state:
α : Type u_1
M : Matroid α
B : Set α
hB : M.Base B
h : Set.Nonempty B
he : M.Base ∅
⊢ False

Next tactic:
obtain rfl := he.eq_of_subset_base hB (empty_subset B)
theorem Base.rkPos_of_nonempty (hB : M.Base B) (h : B.Nonempty) : M.RkPos := by
  rw [rkPos_iff_empty_not_base]
  intro he
  obtain rfl := he.eq_of_subset_base hB (empty_subset B)
  

Proof state:
α : Type u_1
M : Matroid α
he hB : M.Base ∅
h : Set.Nonempty ∅
⊢ False

Next tactic:
simp at h
theorem not_finiteRk (M : Matroid α) [InfiniteRk M] : ¬ FiniteRk M := by
  

Proof state:
α : Type u_1
M✝ M : Matroid α
inst✝ : InfiniteRk M
⊢ ¬FiniteRk M

Next tactic:
intro h
theorem not_finiteRk (M : Matroid α) [InfiniteRk M] : ¬ FiniteRk M := by
  intro h; 

Proof state:
α : Type u_1
M✝ M : Matroid α
inst✝ : InfiniteRk M
h : FiniteRk M
⊢ False

Next tactic:
obtain ⟨B,hB⟩ := M.exists_base
theorem not_finiteRk (M : Matroid α) [InfiniteRk M] : ¬ FiniteRk M := by
  intro h; obtain ⟨B,hB⟩ := M.exists_base; 

Proof state:
case intro
α : Type u_1
M✝ M : Matroid α
inst✝ : InfiniteRk M
h : FiniteRk M
B : Set α
hB : M.Base B
⊢ False

Next tactic:
exact hB.infinite hB.finite
theorem not_infiniteRk (M : Matroid α) [FiniteRk M] : ¬ InfiniteRk M := by
  

Proof state:
α : Type u_1
M✝ M : Matroid α
inst✝ : FiniteRk M
⊢ ¬InfiniteRk M

Next tactic:
intro h
theorem not_infiniteRk (M : Matroid α) [FiniteRk M] : ¬ InfiniteRk M := by
  intro h; 

Proof state:
α : Type u_1
M✝ M : Matroid α
inst✝ : FiniteRk M
h : InfiniteRk M
⊢ False

Next tactic:
obtain ⟨B,hB⟩ := M.exists_base
theorem not_infiniteRk (M : Matroid α) [FiniteRk M] : ¬ InfiniteRk M := by
  intro h; obtain ⟨B,hB⟩ := M.exists_base; 

Proof state:
case intro
α : Type u_1
M✝ M : Matroid α
inst✝ : FiniteRk M
h : InfiniteRk M
B : Set α
hB : M.Base B
⊢ False

Next tactic:
exact hB.infinite hB.finite
theorem eq_of_base_iff_base_forall {M₁ M₂ : Matroid α} (hE : M₁.E = M₂.E)
    (h : ∀ B, B ⊆ M₁.E → (M₁.Base B ↔ M₂.Base B)) : M₁ = M₂ := by
  

Proof state:
α : Type u_1
M M₁ M₂ : Matroid α
hE : M₁.E = M₂.E
h : ∀ B ⊆ M₁.E, M₁.Base B ↔ M₂.Base B
⊢ M₁ = M₂

Next tactic:
apply Matroid.ext _ _ hE
theorem eq_of_base_iff_base_forall {M₁ M₂ : Matroid α} (hE : M₁.E = M₂.E)
    (h : ∀ B, B ⊆ M₁.E → (M₁.Base B ↔ M₂.Base B)) : M₁ = M₂ := by
  apply Matroid.ext _ _ hE
  

Proof state:
α : Type u_1
M M₁ M₂ : Matroid α
hE : M₁.E = M₂.E
h : ∀ B ⊆ M₁.E, M₁.Base B ↔ M₂.Base B
⊢ M₁.Base = M₂.Base

Next tactic:
ext B
theorem eq_of_base_iff_base_forall {M₁ M₂ : Matroid α} (hE : M₁.E = M₂.E)
    (h : ∀ B, B ⊆ M₁.E → (M₁.Base B ↔ M₂.Base B)) : M₁ = M₂ := by
  apply Matroid.ext _ _ hE
  ext B
  

Proof state:
case h.a
α : Type u_1
M M₁ M₂ : Matroid α
hE : M₁.E = M₂.E
h : ∀ B ⊆ M₁.E, M₁.Base B ↔ M₂.Base B
B : Set α
⊢ M₁.Base B ↔ M₂.Base B

Next tactic:
exact ⟨fun h' ↦ (h _ h'.subset_ground).mp h',
    fun h' ↦ (h _ (h'.subset_ground.trans_eq hE.symm)).mpr h'⟩
theorem base_compl_iff_mem_maximals_disjoint_base (hB : B ⊆ M.E := by aesop_mat) :
    M.Base (M.E \ B) ↔ B ∈ maximals (· ⊆ ·) {I | I ⊆ M.E ∧ ∃ B, M.Base B ∧ Disjoint I B} := by
  

Proof state:
α : Type u_1
M : Matroid α
B : Set α
hB : autoParam (B ⊆ M.E) _auto✝
⊢ M.Base (M.E \ B) ↔ B ∈ maximals (fun x x_1 => x ⊆ x_1) {I | I ⊆ M.E ∧ ∃ B, M.Base B ∧ Disjoint I B}

Next tactic:
simp_rw [mem_maximals_setOf_iff, and_iff_right hB, and_imp, forall_exists_index]
theorem base_compl_iff_mem_maximals_disjoint_base (hB : B ⊆ M.E := by aesop_mat) :
    M.Base (M.E \ B) ↔ B ∈ maximals (· ⊆ ·) {I | I ⊆ M.E ∧ ∃ B, M.Base B ∧ Disjoint I B} := by
  simp_rw [mem_maximals_setOf_iff, and_iff_right hB, and_imp, forall_exists_index]
  

Proof state:
α : Type u_1
M : Matroid α
B : Set α
hB : autoParam (B ⊆ M.E) _auto✝
⊢ M.Base (M.E \ B) ↔
    (∃ B_1, M.Base B_1 ∧ Disjoint B B_1) ∧
      ∀ ⦃y : Set α⦄, y ⊆ M.E → ∀ (x : Set α), M.Base x ∧ Disjoint y x → B ⊆ y → B = y

Next tactic:
refine' ⟨fun h ↦ ⟨⟨_, h, disjoint_sdiff_right⟩,
    fun I hI B' ⟨hB', hIB'⟩ hBI ↦ hBI.antisymm _⟩, fun ⟨⟨ B', hB', hBB'⟩,h⟩ ↦ _⟩
theorem base_compl_iff_mem_maximals_disjoint_base (hB : B ⊆ M.E := by aesop_mat) :
    M.Base (M.E \ B) ↔ B ∈ maximals (· ⊆ ·) {I | I ⊆ M.E ∧ ∃ B, M.Base B ∧ Disjoint I B} := by
  simp_rw [mem_maximals_setOf_iff, and_iff_right hB, and_imp, forall_exists_index]
  refine' ⟨fun h ↦ ⟨⟨_, h, disjoint_sdiff_right⟩,
    fun I hI B' ⟨hB', hIB'⟩ hBI ↦ hBI.antisymm _⟩, fun ⟨⟨ B', hB', hBB'⟩,h⟩ ↦ _⟩
  · 

Proof state:
case refine'_1
α : Type u_1
M : Matroid α
B : Set α
hB : autoParam (B ⊆ M.E) _auto✝
h : M.Base (M.E \ B)
I : Set α
hI : I ⊆ M.E
B' : Set α
x✝ : M.Base B' ∧ Disjoint I B'
hBI : B ⊆ I
hB' : M.Base B'
hIB' : Disjoint I B'
⊢ I ⊆ B

Next tactic:
rw [hB'.eq_of_subset_base h, ← subset_compl_iff_disjoint_right, diff_eq, compl_inter,
      compl_compl] at hIB'
theorem base_compl_iff_mem_maximals_disjoint_base (hB : B ⊆ M.E := by aesop_mat) :
    M.Base (M.E \ B) ↔ B ∈ maximals (· ⊆ ·) {I | I ⊆ M.E ∧ ∃ B, M.Base B ∧ Disjoint I B} := by
  simp_rw [mem_maximals_setOf_iff, and_iff_right hB, and_imp, forall_exists_index]
  refine' ⟨fun h ↦ ⟨⟨_, h, disjoint_sdiff_right⟩,
    fun I hI B' ⟨hB', hIB'⟩ hBI ↦ hBI.antisymm _⟩, fun ⟨⟨ B', hB', hBB'⟩,h⟩ ↦ _⟩
  · rw [hB'.eq_of_subset_base h, ← subset_compl_iff_disjoint_right, diff_eq, compl_inter,
      compl_compl] at hIB'
    · 

Proof state:
case refine'_1
α : Type u_1
M : Matroid α
B : Set α
hB : autoParam (B ⊆ M.E) _auto✝
h : M.Base (M.E \ B)
I : Set α
hI : I ⊆ M.E
B' : Set α
x✝ : M.Base B' ∧ Disjoint I B'
hBI : B ⊆ I
hB' : M.Base B'
hIB' : I ⊆ M.Eᶜ ∪ B
⊢ I ⊆ B

Next tactic:
exact fun e he ↦  (hIB' he).elim (fun h' ↦ (h' (hI he)).elim) id
theorem base_compl_iff_mem_maximals_disjoint_base (hB : B ⊆ M.E := by aesop_mat) :
    M.Base (M.E \ B) ↔ B ∈ maximals (· ⊆ ·) {I | I ⊆ M.E ∧ ∃ B, M.Base B ∧ Disjoint I B} := by
  simp_rw [mem_maximals_setOf_iff, and_iff_right hB, and_imp, forall_exists_index]
  refine' ⟨fun h ↦ ⟨⟨_, h, disjoint_sdiff_right⟩,
    fun I hI B' ⟨hB', hIB'⟩ hBI ↦ hBI.antisymm _⟩, fun ⟨⟨ B', hB', hBB'⟩,h⟩ ↦ _⟩
  · rw [hB'.eq_of_subset_base h, ← subset_compl_iff_disjoint_right, diff_eq, compl_inter,
      compl_compl] at hIB'
    · exact fun e he ↦  (hIB' he).elim (fun h' ↦ (h' (hI he)).elim) id
    

Proof state:
case refine'_1
α : Type u_1
M : Matroid α
B : Set α
hB : autoParam (B ⊆ M.E) _auto✝
h : M.Base (M.E \ B)
I : Set α
hI : I ⊆ M.E
B' : Set α
x✝ : M.Base B' ∧ Disjoint I B'
hBI : B ⊆ I
hB' : M.Base B'
hIB' : Disjoint I B'
⊢ B' ⊆ M.E \ B

Next tactic:
rw [subset_diff, and_iff_right hB'.subset_ground, disjoint_comm]
theorem base_compl_iff_mem_maximals_disjoint_base (hB : B ⊆ M.E := by aesop_mat) :
    M.Base (M.E \ B) ↔ B ∈ maximals (· ⊆ ·) {I | I ⊆ M.E ∧ ∃ B, M.Base B ∧ Disjoint I B} := by
  simp_rw [mem_maximals_setOf_iff, and_iff_right hB, and_imp, forall_exists_index]
  refine' ⟨fun h ↦ ⟨⟨_, h, disjoint_sdiff_right⟩,
    fun I hI B' ⟨hB', hIB'⟩ hBI ↦ hBI.antisymm _⟩, fun ⟨⟨ B', hB', hBB'⟩,h⟩ ↦ _⟩
  · rw [hB'.eq_of_subset_base h, ← subset_compl_iff_disjoint_right, diff_eq, compl_inter,
      compl_compl] at hIB'
    · exact fun e he ↦  (hIB' he).elim (fun h' ↦ (h' (hI he)).elim) id
    rw [subset_diff, and_iff_right hB'.subset_ground, disjoint_comm]
    

Proof state:
case refine'_1
α : Type u_1
M : Matroid α
B : Set α
hB : autoParam (B ⊆ M.E) _auto✝
h : M.Base (M.E \ B)
I : Set α
hI : I ⊆ M.E
B' : Set α
x✝ : M.Base B' ∧ Disjoint I B'
hBI : B ⊆ I
hB' : M.Base B'
hIB' : Disjoint I B'
⊢ Disjoint B B'

Next tactic:
exact disjoint_of_subset_left hBI hIB'
theorem base_compl_iff_mem_maximals_disjoint_base (hB : B ⊆ M.E := by aesop_mat) :
    M.Base (M.E \ B) ↔ B ∈ maximals (· ⊆ ·) {I | I ⊆ M.E ∧ ∃ B, M.Base B ∧ Disjoint I B} := by
  simp_rw [mem_maximals_setOf_iff, and_iff_right hB, and_imp, forall_exists_index]
  refine' ⟨fun h ↦ ⟨⟨_, h, disjoint_sdiff_right⟩,
    fun I hI B' ⟨hB', hIB'⟩ hBI ↦ hBI.antisymm _⟩, fun ⟨⟨ B', hB', hBB'⟩,h⟩ ↦ _⟩
  · rw [hB'.eq_of_subset_base h, ← subset_compl_iff_disjoint_right, diff_eq, compl_inter,
      compl_compl] at hIB'
    · exact fun e he ↦  (hIB' he).elim (fun h' ↦ (h' (hI he)).elim) id
    rw [subset_diff, and_iff_right hB'.subset_ground, disjoint_comm]
    exact disjoint_of_subset_left hBI hIB'
  

Proof state:
case refine'_2
α : Type u_1
M : Matroid α
B : Set α
hB : autoParam (B ⊆ M.E) _auto✝
x✝ :
  (∃ B_1, M.Base B_1 ∧ Disjoint B B_1) ∧ ∀ ⦃y : Set α⦄, y ⊆ M.E → ∀ (x : Set α), M.Base x ∧ Disjoint y x → B ⊆ y → B = y
B' : Set α
hB' : M.Base B'
hBB' : Disjoint B B'
h : ∀ ⦃y : Set α⦄, y ⊆ M.E → ∀ (x : Set α), M.Base x ∧ Disjoint y x → B ⊆ y → B = y
⊢ M.Base (M.E \ B)

Next tactic:
rw [h (diff_subset M.E B') B' ⟨hB', disjoint_sdiff_left⟩]
theorem base_compl_iff_mem_maximals_disjoint_base (hB : B ⊆ M.E := by aesop_mat) :
    M.Base (M.E \ B) ↔ B ∈ maximals (· ⊆ ·) {I | I ⊆ M.E ∧ ∃ B, M.Base B ∧ Disjoint I B} := by
  simp_rw [mem_maximals_setOf_iff, and_iff_right hB, and_imp, forall_exists_index]
  refine' ⟨fun h ↦ ⟨⟨_, h, disjoint_sdiff_right⟩,
    fun I hI B' ⟨hB', hIB'⟩ hBI ↦ hBI.antisymm _⟩, fun ⟨⟨ B', hB', hBB'⟩,h⟩ ↦ _⟩
  · rw [hB'.eq_of_subset_base h, ← subset_compl_iff_disjoint_right, diff_eq, compl_inter,
      compl_compl] at hIB'
    · exact fun e he ↦  (hIB' he).elim (fun h' ↦ (h' (hI he)).elim) id
    rw [subset_diff, and_iff_right hB'.subset_ground, disjoint_comm]
    exact disjoint_of_subset_left hBI hIB'
  rw [h (diff_subset M.E B') B' ⟨hB', disjoint_sdiff_left⟩]
  · 

Proof state:
case refine'_2
α : Type u_1
M : Matroid α
B : Set α
hB : autoParam (B ⊆ M.E) _auto✝
x✝ :
  (∃ B_1, M.Base B_1 ∧ Disjoint B B_1) ∧ ∀ ⦃y : Set α⦄, y ⊆ M.E → ∀ (x : Set α), M.Base x ∧ Disjoint y x → B ⊆ y → B = y
B' : Set α
hB' : M.Base B'
hBB' : Disjoint B B'
h : ∀ ⦃y : Set α⦄, y ⊆ M.E → ∀ (x : Set α), M.Base x ∧ Disjoint y x → B ⊆ y → B = y
⊢ M.Base (M.E \ (M.E \ B'))

Next tactic:
simpa [hB'.subset_ground]
theorem base_compl_iff_mem_maximals_disjoint_base (hB : B ⊆ M.E := by aesop_mat) :
    M.Base (M.E \ B) ↔ B ∈ maximals (· ⊆ ·) {I | I ⊆ M.E ∧ ∃ B, M.Base B ∧ Disjoint I B} := by
  simp_rw [mem_maximals_setOf_iff, and_iff_right hB, and_imp, forall_exists_index]
  refine' ⟨fun h ↦ ⟨⟨_, h, disjoint_sdiff_right⟩,
    fun I hI B' ⟨hB', hIB'⟩ hBI ↦ hBI.antisymm _⟩, fun ⟨⟨ B', hB', hBB'⟩,h⟩ ↦ _⟩
  · rw [hB'.eq_of_subset_base h, ← subset_compl_iff_disjoint_right, diff_eq, compl_inter,
      compl_compl] at hIB'
    · exact fun e he ↦  (hIB' he).elim (fun h' ↦ (h' (hI he)).elim) id
    rw [subset_diff, and_iff_right hB'.subset_ground, disjoint_comm]
    exact disjoint_of_subset_left hBI hIB'
  rw [h (diff_subset M.E B') B' ⟨hB', disjoint_sdiff_left⟩]
  · simpa [hB'.subset_ground]
  

Proof state:
case refine'_2
α : Type u_1
M : Matroid α
B : Set α
hB : autoParam (B ⊆ M.E) _auto✝
x✝ :
  (∃ B_1, M.Base B_1 ∧ Disjoint B B_1) ∧ ∀ ⦃y : Set α⦄, y ⊆ M.E → ∀ (x : Set α), M.Base x ∧ Disjoint y x → B ⊆ y → B = y
B' : Set α
hB' : M.Base B'
hBB' : Disjoint B B'
h : ∀ ⦃y : Set α⦄, y ⊆ M.E → ∀ (x : Set α), M.Base x ∧ Disjoint y x → B ⊆ y → B = y
⊢ B ⊆ M.E \ B'

Next tactic:
simp [subset_diff, hB, hBB']