l3lab/ntp-mathlib huggingface dataset:
theorem le_suffixLevenshtein_cons_minimum (xs : List α) (y ys) :
    (suffixLevenshtein C xs ys).1.minimum ≤ (suffixLevenshtein C xs (y :: ys)).1.minimum := by
  apply List.le_minimum_of_forall_le
  simp only [suffixLevenshtein_eq_tails_map]
  simp only [List.mem_map, List.mem_tails, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂]
  intro a suff
  refine (?_ : _ ≤ _).trans (suffixLevenshtein_minimum_le_levenshtein_cons _ _ _)
  simp only [suffixLevenshtein_eq_tails_map]
  apply List.le_minimum_of_forall_le
  intro b m
  replace m : ∃ a_1, a_1 <:+ a ∧ levenshtein C a_1 ys = b
  · simpa using m
  obtain ⟨a', suff', rfl⟩ := m
  apply List.minimum_le_of_mem'
  simp only [List.mem_map, List.mem_tails]
  suffices ∃ a, a <:+ xs ∧ levenshtein C a ys = levenshtein C a' ys by 

Proof state:
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
y : β
ys : List β
a : List α
suff : a <:+ xs
a' : List α
suff' : a' <:+ a
this : ∃ a, a <:+ xs ∧ levenshtein C a ys = levenshtein C a' ys
⊢ ∃ a, a <:+ xs ∧ levenshtein C a ys = levenshtein C a' ys

Next tactic:
simpa
theorem le_suffixLevenshtein_cons_minimum (xs : List α) (y ys) :
    (suffixLevenshtein C xs ys).1.minimum ≤ (suffixLevenshtein C xs (y :: ys)).1.minimum := by
  apply List.le_minimum_of_forall_le
  simp only [suffixLevenshtein_eq_tails_map]
  simp only [List.mem_map, List.mem_tails, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂]
  intro a suff
  refine (?_ : _ ≤ _).trans (suffixLevenshtein_minimum_le_levenshtein_cons _ _ _)
  simp only [suffixLevenshtein_eq_tails_map]
  apply List.le_minimum_of_forall_le
  intro b m
  replace m : ∃ a_1, a_1 <:+ a ∧ levenshtein C a_1 ys = b
  · simpa using m
  obtain ⟨a', suff', rfl⟩ := m
  apply List.minimum_le_of_mem'
  simp only [List.mem_map, List.mem_tails]
  suffices ∃ a, a <:+ xs ∧ levenshtein C a ys = levenshtein C a' ys by simpa
  

Proof state:
case h.h.intro.intro.ha
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
y : β
ys : List β
a : List α
suff : a <:+ xs
a' : List α
suff' : a' <:+ a
⊢ ∃ a, a <:+ xs ∧ levenshtein C a ys = levenshtein C a' ys

Next tactic:
exact ⟨a', suff'.trans suff, rfl⟩
theorem le_suffixLevenshtein_append_minimum (xs : List α) (ys₁ ys₂) :
    (suffixLevenshtein C xs ys₂).1.minimum ≤ (suffixLevenshtein C xs (ys₁ ++ ys₂)).1.minimum := by
  

Proof state:
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
ys₁ ys₂ : List β
⊢ List.minimum ↑(suffixLevenshtein C xs ys₂) ≤ List.minimum ↑(suffixLevenshtein C xs (ys₁ ++ ys₂))

Next tactic:
induction ys₁ with
  | nil => exact le_refl _
  | cons y ys₁ ih => exact ih.trans (le_suffixLevenshtein_cons_minimum _ _ _)
theorem le_suffixLevenshtein_append_minimum (xs : List α) (ys₁ ys₂) :
    (suffixLevenshtein C xs ys₂).1.minimum ≤ (suffixLevenshtein C xs (ys₁ ++ ys₂)).1.minimum := by
  induction ys₁ with
  

Proof state:
case nil
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
ys₂ : List β
⊢ List.minimum ↑(suffixLevenshtein C xs ys₂) ≤ List.minimum ↑(suffixLevenshtein C xs ([] ++ ys₂))

Next tactic:
| nil => exact le_refl _
theorem le_suffixLevenshtein_append_minimum (xs : List α) (ys₁ ys₂) :
    (suffixLevenshtein C xs ys₂).1.minimum ≤ (suffixLevenshtein C xs (ys₁ ++ ys₂)).1.minimum := by
  induction ys₁ with
  | nil => 

Proof state:
case nil
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
ys₂ : List β
⊢ List.minimum ↑(suffixLevenshtein C xs ys₂) ≤ List.minimum ↑(suffixLevenshtein C xs ([] ++ ys₂))

Next tactic:
exact le_refl _
theorem le_suffixLevenshtein_append_minimum (xs : List α) (ys₁ ys₂) :
    (suffixLevenshtein C xs ys₂).1.minimum ≤ (suffixLevenshtein C xs (ys₁ ++ ys₂)).1.minimum := by
  induction ys₁ with
  | nil => exact le_refl _
  

Proof state:
case cons
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
ys₂ : List β
y : β
ys₁ : List β
ih : List.minimum ↑(suffixLevenshtein C xs ys₂) ≤ List.minimum ↑(suffixLevenshtein C xs (ys₁ ++ ys₂))
⊢ List.minimum ↑(suffixLevenshtein C xs ys₂) ≤ List.minimum ↑(suffixLevenshtein C xs (y :: ys₁ ++ ys₂))

Next tactic:
| cons y ys₁ ih => exact ih.trans (le_suffixLevenshtein_cons_minimum _ _ _)
theorem le_suffixLevenshtein_append_minimum (xs : List α) (ys₁ ys₂) :
    (suffixLevenshtein C xs ys₂).1.minimum ≤ (suffixLevenshtein C xs (ys₁ ++ ys₂)).1.minimum := by
  induction ys₁ with
  | nil => exact le_refl _
  | cons y ys₁ ih => 

Proof state:
case cons
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
ys₂ : List β
y : β
ys₁ : List β
ih : List.minimum ↑(suffixLevenshtein C xs ys₂) ≤ List.minimum ↑(suffixLevenshtein C xs (ys₁ ++ ys₂))
⊢ List.minimum ↑(suffixLevenshtein C xs ys₂) ≤ List.minimum ↑(suffixLevenshtein C xs (y :: ys₁ ++ ys₂))

Next tactic:
exact ih.trans (le_suffixLevenshtein_cons_minimum _ _ _)
theorem suffixLevenshtein_minimum_le_levenshtein_append (xs ys₁ ys₂) :
    (suffixLevenshtein C xs ys₂).1.minimum ≤ levenshtein C xs (ys₁ ++ ys₂) := by
  

Proof state:
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
ys₁ ys₂ : List β
⊢ List.minimum ↑(suffixLevenshtein C xs ys₂) ≤ ↑(levenshtein C xs (ys₁ ++ ys₂))

Next tactic:
cases ys₁ with
  | nil => exact List.minimum_le_of_mem' (List.get_mem _ _ _)
  | cons y ys₁ =>
      exact (le_suffixLevenshtein_append_minimum _ _ _).trans
        (suffixLevenshtein_minimum_le_levenshtein_cons _ _ _)
theorem suffixLevenshtein_minimum_le_levenshtein_append (xs ys₁ ys₂) :
    (suffixLevenshtein C xs ys₂).1.minimum ≤ levenshtein C xs (ys₁ ++ ys₂) := by
  cases ys₁ with
  

Proof state:
case nil
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
ys₂ : List β
⊢ List.minimum ↑(suffixLevenshtein C xs ys₂) ≤ ↑(levenshtein C xs ([] ++ ys₂))

Next tactic:
| nil => exact List.minimum_le_of_mem' (List.get_mem _ _ _)
theorem suffixLevenshtein_minimum_le_levenshtein_append (xs ys₁ ys₂) :
    (suffixLevenshtein C xs ys₂).1.minimum ≤ levenshtein C xs (ys₁ ++ ys₂) := by
  cases ys₁ with
  | nil => 

Proof state:
case nil
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
ys₂ : List β
⊢ List.minimum ↑(suffixLevenshtein C xs ys₂) ≤ ↑(levenshtein C xs ([] ++ ys₂))

Next tactic:
exact List.minimum_le_of_mem' (List.get_mem _ _ _)
theorem suffixLevenshtein_minimum_le_levenshtein_append (xs ys₁ ys₂) :
    (suffixLevenshtein C xs ys₂).1.minimum ≤ levenshtein C xs (ys₁ ++ ys₂) := by
  cases ys₁ with
  | nil => exact List.minimum_le_of_mem' (List.get_mem _ _ _)
  

Proof state:
case cons
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
ys₂ : List β
y : β
ys₁ : List β
⊢ List.minimum ↑(suffixLevenshtein C xs ys₂) ≤ ↑(levenshtein C xs (y :: ys₁ ++ ys₂))

Next tactic:
| cons y ys₁ =>
      exact (le_suffixLevenshtein_append_minimum _ _ _).trans
        (suffixLevenshtein_minimum_le_levenshtein_cons _ _ _)
theorem suffixLevenshtein_minimum_le_levenshtein_append (xs ys₁ ys₂) :
    (suffixLevenshtein C xs ys₂).1.minimum ≤ levenshtein C xs (ys₁ ++ ys₂) := by
  cases ys₁ with
  | nil => exact List.minimum_le_of_mem' (List.get_mem _ _ _)
  | cons y ys₁ =>
      

Proof state:
case cons
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
ys₂ : List β
y : β
ys₁ : List β
⊢ List.minimum ↑(suffixLevenshtein C xs ys₂) ≤ ↑(levenshtein C xs (y :: ys₁ ++ ys₂))

Next tactic:
exact (le_suffixLevenshtein_append_minimum _ _ _).trans
        (suffixLevenshtein_minimum_le_levenshtein_cons _ _ _)
theorem le_levenshtein_cons (xs : List α) (y ys) :
    ∃ xs', xs' <:+ xs ∧ levenshtein C xs' ys ≤ levenshtein C xs (y :: ys) := by
  

Proof state:
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
y : β
ys : List β
⊢ ∃ xs', xs' <:+ xs ∧ levenshtein C xs' ys ≤ levenshtein C xs (y :: ys)

Next tactic:
simpa [suffixLevenshtein_eq_tails_map, List.minimum_le_coe_iff] using
    suffixLevenshtein_minimum_le_levenshtein_cons (δ := δ) xs y ys
theorem le_levenshtein_append (xs : List α) (ys₁ ys₂) :
    ∃ xs', xs' <:+ xs ∧ levenshtein C xs' ys₂ ≤ levenshtein C xs (ys₁ ++ ys₂) := by
  

Proof state:
α : Type u_1
β : Type u_2
δ : Type u_3
C : Levenshtein.Cost α β δ
inst✝ : CanonicallyLinearOrderedAddCommMonoid δ
xs : List α
ys₁ ys₂ : List β
⊢ ∃ xs', xs' <:+ xs ∧ levenshtein C xs' ys₂ ≤ levenshtein C xs (ys₁ ++ ys₂)

Next tactic:
simpa [suffixLevenshtein_eq_tails_map, List.minimum_le_coe_iff] using
    suffixLevenshtein_minimum_le_levenshtein_append (δ := δ) xs ys₁ ys₂
@[simp 1100]
theorem mem_map_equiv {f : α ≃ β} {b : β} : b ∈ s.map f.toEmbedding ↔ f.symm b ∈ s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s : Finset α
f : α ≃ β
b : β
⊢ b ∈ map (Equiv.toEmbedding f) s ↔ f.symm b ∈ s

Next tactic:
rw [mem_map]
@[simp 1100]
theorem mem_map_equiv {f : α ≃ β} {b : β} : b ∈ s.map f.toEmbedding ↔ f.symm b ∈ s := by
  rw [mem_map]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s : Finset α
f : α ≃ β
b : β
⊢ (∃ a ∈ s, (Equiv.toEmbedding f) a = b) ↔ f.symm b ∈ s

Next tactic:
exact
    ⟨by
      rintro ⟨a, H, rfl⟩
      simpa, fun h => ⟨_, h, by simp⟩⟩
@[simp 1100]
theorem mem_map_equiv {f : α ≃ β} {b : β} : b ∈ s.map f.toEmbedding ↔ f.symm b ∈ s := by
  rw [mem_map]
  exact
    ⟨by
      

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s : Finset α
f : α ≃ β
b : β
⊢ (∃ a ∈ s, (Equiv.toEmbedding f) a = b) → f.symm b ∈ s

Next tactic:
rintro ⟨a, H, rfl⟩
@[simp 1100]
theorem mem_map_equiv {f : α ≃ β} {b : β} : b ∈ s.map f.toEmbedding ↔ f.symm b ∈ s := by
  rw [mem_map]
  exact
    ⟨by
      rintro ⟨a, H, rfl⟩
      

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s : Finset α
f : α ≃ β
a : α
H : a ∈ s
⊢ f.symm ((Equiv.toEmbedding f) a) ∈ s

Next tactic:
simpa
@[simp 1100]
theorem mem_map_equiv {f : α ≃ β} {b : β} : b ∈ s.map f.toEmbedding ↔ f.symm b ∈ s := by
  rw [mem_map]
  exact
    ⟨by
      rintro ⟨a, H, rfl⟩
      simpa, fun h => ⟨_, h, by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s : Finset α
f : α ≃ β
b : β
h : f.symm b ∈ s
⊢ (Equiv.toEmbedding f) (f.symm b) = b

Next tactic:
simp
theorem forall_mem_map {f : α ↪ β} {s : Finset α} {p : ∀ a, a ∈ s.map f → Prop} :
    (∀ y (H : y ∈ s.map f), p y H) ↔ ∀ x (H : x ∈ s), p (f x) (mem_map_of_mem _ H) :=
  ⟨fun h y hy => h (f y) (mem_map_of_mem _ hy),
   fun h x hx => by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s✝ : Finset α
f : α ↪ β
s : Finset α
p : (a : β) → a ∈ map f s → Prop
h : ∀ (x : α) (H : x ∈ s), p (f x) (_ : f x ∈ map f s)
x : β
hx : x ∈ map f s
⊢ p x hx

Next tactic:
obtain ⟨y, hy, rfl⟩ := mem_map.1 hx
theorem forall_mem_map {f : α ↪ β} {s : Finset α} {p : ∀ a, a ∈ s.map f → Prop} :
    (∀ y (H : y ∈ s.map f), p y H) ↔ ∀ x (H : x ∈ s), p (f x) (mem_map_of_mem _ H) :=
  ⟨fun h y hy => h (f y) (mem_map_of_mem _ hy),
   fun h x hx => by
    obtain ⟨y, hy, rfl⟩ := mem_map.1 hx
    

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s✝ : Finset α
f : α ↪ β
s : Finset α
p : (a : β) → a ∈ map f s → Prop
h : ∀ (x : α) (H : x ∈ s), p (f x) (_ : f x ∈ map f s)
y : α
hy : y ∈ s
hx : f y ∈ map f s
⊢ p (f y) hx

Next tactic:
exact h _ hy
@[simp, norm_cast]
theorem coe_map (f : α ↪ β) (s : Finset α) : (s.map f : Set β) = f '' s :=
  Set.ext (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s✝ : Finset α
f : α ↪ β
s : Finset α
⊢ ∀ (x : β), x ∈ ↑(map f s) ↔ x ∈ ⇑f '' ↑s

Next tactic:
simp only [mem_coe, mem_map, Set.mem_image, implies_true]
theorem map_toFinset [DecidableEq α] [DecidableEq β] {s : Multiset α} :
    s.toFinset.map f = (s.map f).toFinset :=
  ext fun _ => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Multiset α
x✝ : β
⊢ x✝ ∈ map f (toFinset s) ↔ x✝ ∈ toFinset (Multiset.map (⇑f) s)

Next tactic:
simp only [mem_map, Multiset.mem_map, exists_prop, Multiset.mem_toFinset]
@[simp]
theorem map_refl : s.map (Embedding.refl _) = s :=
  ext fun _ => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s : Finset α
x✝ : α
⊢ x✝ ∈ map (Embedding.refl α) s ↔ x✝ ∈ s

Next tactic:
simpa only [mem_map, exists_prop] using exists_eq_right
@[simp]
theorem map_cast_heq {α β} (h : α = β) (s : Finset α) :
    HEq (s.map (Equiv.cast h).toEmbedding) s := by
  

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
f : α✝ ↪ β✝
s✝ : Finset α✝
α β : Type u_4
h : α = β
s : Finset α
⊢ HEq (map (Equiv.toEmbedding (Equiv.cast h)) s) s

Next tactic:
subst h
@[simp]
theorem map_cast_heq {α β} (h : α = β) (s : Finset α) :
    HEq (s.map (Equiv.cast h).toEmbedding) s := by
  subst h
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
f : α✝ ↪ β
s✝ : Finset α✝
α : Type u_4
s : Finset α
⊢ HEq (map (Equiv.toEmbedding (Equiv.cast (_ : α = α))) s) s

Next tactic:
simp
theorem map_map (f : α ↪ β) (g : β ↪ γ) (s : Finset α) : (s.map f).map g = s.map (f.trans g) :=
  eq_of_veq <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s✝ : Finset α
f : α ↪ β
g : β ↪ γ
s : Finset α
⊢ (map g (map f s)).val = (map (Embedding.trans f g) s).val

Next tactic:
simp only [map_val, Multiset.map_map]
theorem map_map (f : α ↪ β) (g : β ↪ γ) (s : Finset α) : (s.map f).map g = s.map (f.trans g) :=
  eq_of_veq <| by simp only [map_val, Multiset.map_map]; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s✝ : Finset α
f : α ↪ β
g : β ↪ γ
s : Finset α
⊢ Multiset.map (⇑g ∘ ⇑f) s.val = Multiset.map (⇑(Embedding.trans f g)) s.val

Next tactic:
rfl
theorem map_comm {β'} {f : β ↪ γ} {g : α ↪ β} {f' : α ↪ β'} {g' : β' ↪ γ}
    (h_comm : ∀ a, f (g a) = g' (f' a)) : (s.map g).map f = (s.map f').map g' := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s : Finset α
β' : Type u_4
f : β ↪ γ
g : α ↪ β
f' : α ↪ β'
g' : β' ↪ γ
h_comm : ∀ (a : α), f (g a) = g' (f' a)
⊢ map f (map g s) = map g' (map f' s)

Next tactic:
simp_rw [map_map, Embedding.trans, Function.comp, h_comm]
@[simp]
theorem map_subset_map {s₁ s₂ : Finset α} : s₁.map f ⊆ s₂.map f ↔ s₁ ⊆ s₂ :=
  ⟨fun h x xs => (mem_map' _).1 <| h <| (mem_map' f).2 xs,
   fun h => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s s₁ s₂ : Finset α
h : s₁ ⊆ s₂
⊢ map f s₁ ⊆ map f s₂

Next tactic:
simp [subset_def, Multiset.map_subset_map h]
lemma map_filter' (p : α → Prop) [DecidablePred p] (f : α ↪ β) (s : Finset α)
    [DecidablePred (∃ a, p a ∧ f a = ·)] :
    (s.filter p).map f = (s.map f).filter fun b => ∃ a, p a ∧ f a = b := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s✝ : Finset α
p : α → Prop
inst✝¹ : DecidablePred p
f : α ↪ β
s : Finset α
inst✝ : DecidablePred fun x => ∃ a, p a ∧ f a = x
⊢ map f (filter p s) = filter (fun b => ∃ a, p a ∧ f a = b) (map f s)

Next tactic:
simp [(· ∘ ·), filter_map, f.injective.eq_iff]
theorem map_filter {f : α ≃ β} {p : α → Prop} [DecidablePred p] :
    (s.filter p).map f.toEmbedding = (s.map f.toEmbedding).filter (p ∘ f.symm) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s : Finset α
f : α ≃ β
p : α → Prop
inst✝ : DecidablePred p
⊢ map (Equiv.toEmbedding f) (filter p s) = filter (p ∘ ⇑f.symm) (map (Equiv.toEmbedding f) s)

Next tactic:
simp only [filter_map, Function.comp, Equiv.toEmbedding_apply, Equiv.symm_apply_apply]
@[simp]
theorem disjoint_map {s t : Finset α} (f : α ↪ β) :
    Disjoint (s.map f) (t.map f) ↔ Disjoint s t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s✝ s t : Finset α
f : α ↪ β
⊢ _root_.Disjoint (map f s) (map f t) ↔ _root_.Disjoint s t

Next tactic:
simp only [disjoint_iff_ne, mem_map, exists_prop, exists_imp, and_imp]
@[simp]
theorem disjoint_map {s t : Finset α} (f : α ↪ β) :
    Disjoint (s.map f) (t.map f) ↔ Disjoint s t := by
  simp only [disjoint_iff_ne, mem_map, exists_prop, exists_imp, and_imp]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s✝ s t : Finset α
f : α ↪ β
⊢ (∀ (a : β), ∀ x ∈ s, f x = a → ∀ (b : β), ∀ x ∈ t, f x = b → a ≠ b) ↔ ∀ a ∈ s, ∀ b ∈ t, a ≠ b

Next tactic:
refine' ⟨fun h a ha b hb hab => h _ _ ha rfl _ _ hb rfl <| congr_arg _ hab, _⟩
@[simp]
theorem disjoint_map {s t : Finset α} (f : α ↪ β) :
    Disjoint (s.map f) (t.map f) ↔ Disjoint s t := by
  simp only [disjoint_iff_ne, mem_map, exists_prop, exists_imp, and_imp]
  refine' ⟨fun h a ha b hb hab => h _ _ ha rfl _ _ hb rfl <| congr_arg _ hab, _⟩
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s✝ s t : Finset α
f : α ↪ β
⊢ (∀ a ∈ s, ∀ b ∈ t, a ≠ b) → ∀ (a : β), ∀ x ∈ s, f x = a → ∀ (b : β), ∀ x ∈ t, f x = b → a ≠ b

Next tactic:
rintro h _ a ha rfl _ b hb rfl
@[simp]
theorem disjoint_map {s t : Finset α} (f : α ↪ β) :
    Disjoint (s.map f) (t.map f) ↔ Disjoint s t := by
  simp only [disjoint_iff_ne, mem_map, exists_prop, exists_imp, and_imp]
  refine' ⟨fun h a ha b hb hab => h _ _ ha rfl _ _ hb rfl <| congr_arg _ hab, _⟩
  rintro h _ a ha rfl _ b hb rfl
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s✝ s t : Finset α
f : α ↪ β
h : ∀ a ∈ s, ∀ b ∈ t, a ≠ b
a : α
ha : a ∈ s
b : α
hb : b ∈ t
⊢ f a ≠ f b

Next tactic:
exact f.injective.ne (h _ ha _ hb)
theorem map_union [DecidableEq α] [DecidableEq β] {f : α ↪ β} (s₁ s₂ : Finset α) :
    (s₁ ∪ s₂).map f = s₁.map f ∪ s₂.map f :=
  coe_injective <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α ↪ β
s₁ s₂ : Finset α
⊢ ↑(map f (s₁ ∪ s₂)) = ↑(map f s₁ ∪ map f s₂)

Next tactic:
simp only [coe_map, coe_union, Set.image_union]
theorem map_inter [DecidableEq α] [DecidableEq β] {f : α ↪ β} (s₁ s₂ : Finset α) :
    (s₁ ∩ s₂).map f = s₁.map f ∩ s₂.map f :=
  coe_injective <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α ↪ β
s₁ s₂ : Finset α
⊢ ↑(map f (s₁ ∩ s₂)) = ↑(map f s₁ ∩ map f s₂)

Next tactic:
simp only [coe_map, coe_inter, Set.image_inter f.injective]
@[simp]
theorem map_singleton (f : α ↪ β) (a : α) : map f {a} = {f a} :=
  coe_injective <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s : Finset α
f : α ↪ β
a : α
⊢ ↑(map f {a}) = ↑{f a}

Next tactic:
simp only [coe_map, coe_singleton, Set.image_singleton]
@[simp]
theorem map_insert [DecidableEq α] [DecidableEq β] (f : α ↪ β) (a : α) (s : Finset α) :
    (insert a s).map f = insert (f a) (s.map f) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s✝ : Finset α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α ↪ β
a : α
s : Finset α
⊢ map f (insert a s) = insert (f a) (map f s)

Next tactic:
simp only [insert_eq, map_union, map_singleton]
@[simp]
theorem map_cons (f : α ↪ β) (a : α) (s : Finset α) (ha : a ∉ s) :
    (cons a s ha).map f = cons (f a) (s.map f) (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f✝ : α ↪ β
s✝ : Finset α
f : α ↪ β
a : α
s : Finset α
ha : a ∉ s
⊢ f a ∉ map f s

Next tactic:
simpa using ha
@[simp]
theorem map_nonempty : (s.map f).Nonempty ↔ s.Nonempty := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s : Finset α
⊢ Finset.Nonempty (map f s) ↔ Finset.Nonempty s

Next tactic:
rw [nonempty_iff_ne_empty, nonempty_iff_ne_empty, Ne.def, map_eq_empty]
theorem attach_map_val {s : Finset α} : s.attach.map (Embedding.subtype _) = s :=
  eq_of_veq <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s✝ s : Finset α
⊢ (map (Embedding.subtype fun x => x ∈ s) (attach s)).val = s.val

Next tactic:
rw [map_val, attach_val]
theorem attach_map_val {s : Finset α} : s.attach.map (Embedding.subtype _) = s :=
  eq_of_veq <| by rw [map_val, attach_val]; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s✝ s : Finset α
⊢ Multiset.map (⇑(Embedding.subtype fun x => x ∈ s)) (Multiset.attach s.val) = s.val

Next tactic:
exact Multiset.attach_map_val _
theorem disjoint_range_addLeftEmbedding (a b : ℕ) :
    Disjoint (range a) (map (addLeftEmbedding a) (range b)) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s : Finset α
a b : ℕ
⊢ _root_.Disjoint (range a) (map (addLeftEmbedding a) (range b))

Next tactic:
refine' disjoint_iff_inf_le.mpr _
theorem disjoint_range_addLeftEmbedding (a b : ℕ) :
    Disjoint (range a) (map (addLeftEmbedding a) (range b)) := by
  refine' disjoint_iff_inf_le.mpr _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s : Finset α
a b : ℕ
⊢ range a ⊓ map (addLeftEmbedding a) (range b) ≤ ⊥

Next tactic:
intro k hk
theorem disjoint_range_addLeftEmbedding (a b : ℕ) :
    Disjoint (range a) (map (addLeftEmbedding a) (range b)) := by
  refine' disjoint_iff_inf_le.mpr _
  intro k hk
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s : Finset α
a b k : ℕ
hk : k ∈ range a ⊓ map (addLeftEmbedding a) (range b)
⊢ k ∈ ⊥

Next tactic:
simp only [exists_prop, mem_range, inf_eq_inter, mem_map, addLeftEmbedding, mem_inter]
    at hk
theorem disjoint_range_addLeftEmbedding (a b : ℕ) :
    Disjoint (range a) (map (addLeftEmbedding a) (range b)) := by
  refine' disjoint_iff_inf_le.mpr _
  intro k hk
  simp only [exists_prop, mem_range, inf_eq_inter, mem_map, addLeftEmbedding, mem_inter]
    at hk
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s : Finset α
a b k : ℕ
hk : k < a ∧ ∃ a_1 < b, { toFun := fun h => a + h, inj' := (_ : Injective fun x => a + x) } a_1 = k
⊢ k ∈ ⊥

Next tactic:
obtain ⟨a, _, ha⟩ := hk.2
theorem disjoint_range_addLeftEmbedding (a b : ℕ) :
    Disjoint (range a) (map (addLeftEmbedding a) (range b)) := by
  refine' disjoint_iff_inf_le.mpr _
  intro k hk
  simp only [exists_prop, mem_range, inf_eq_inter, mem_map, addLeftEmbedding, mem_inter]
    at hk
  obtain ⟨a, _, ha⟩ := hk.2
  

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s : Finset α
a✝ b k : ℕ
hk : k < a✝ ∧ ∃ a < b, { toFun := fun h => a✝ + h, inj' := (_ : Injective fun x => a✝ + x) } a = k
a : ℕ
left✝ : a < b
ha : { toFun := fun h => a✝ + h, inj' := (_ : Injective fun x => a✝ + x) } a = k
⊢ k ∈ ⊥

Next tactic:
simpa [← ha] using hk.1
theorem disjoint_range_addRightEmbedding (a b : ℕ) :
    Disjoint (range a) (map (addRightEmbedding a) (range b)) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s : Finset α
a b : ℕ
⊢ _root_.Disjoint (range a) (map (addRightEmbedding a) (range b))

Next tactic:
refine' disjoint_iff_inf_le.mpr _
theorem disjoint_range_addRightEmbedding (a b : ℕ) :
    Disjoint (range a) (map (addRightEmbedding a) (range b)) := by
  refine' disjoint_iff_inf_le.mpr _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s : Finset α
a b : ℕ
⊢ range a ⊓ map (addRightEmbedding a) (range b) ≤ ⊥

Next tactic:
intro k hk
theorem disjoint_range_addRightEmbedding (a b : ℕ) :
    Disjoint (range a) (map (addRightEmbedding a) (range b)) := by
  refine' disjoint_iff_inf_le.mpr _
  intro k hk
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s : Finset α
a b k : ℕ
hk : k ∈ range a ⊓ map (addRightEmbedding a) (range b)
⊢ k ∈ ⊥

Next tactic:
simp only [exists_prop, mem_range, inf_eq_inter, mem_map, addRightEmbedding, mem_inter]
    at hk
theorem disjoint_range_addRightEmbedding (a b : ℕ) :
    Disjoint (range a) (map (addRightEmbedding a) (range b)) := by
  refine' disjoint_iff_inf_le.mpr _
  intro k hk
  simp only [exists_prop, mem_range, inf_eq_inter, mem_map, addRightEmbedding, mem_inter]
    at hk
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
f : α ↪ β
s : Finset α
a b k : ℕ
hk : k < a ∧ ∃ a_1 < b, { toFun := fun h => h + a, inj' := (_ : Injective fun x => x + a) } a_1 = k
⊢ k ∈ ⊥

Next tactic:
obtain ⟨a, _, ha⟩ := hk.2