l3lab/ntp-mathlib huggingface dataset:
theorem log_two_near_10 : |log 2 - 287209 / 414355| ≤ 1 / 10 ^ 10 := by
  suffices |log 2 - 287209 / 414355| ≤ 1 / 17179869184 + (1 / 10 ^ 10 - 1 / 2 ^ 34) by
    norm_num1 at *
    assumption
  have t : |(2⁻¹ : ℝ)| = 2⁻¹ := by rw [abs_of_pos]; norm_num
  have z := Real.abs_log_sub_add_sum_range_le (show |(2⁻¹ : ℝ)| < 1 by rw [t]; norm_num) 34
  rw [t] at z
  norm_num1 at z
  rw [one_div (2 : ℝ), log_inv, ← sub_eq_add_neg, _root_.abs_sub_comm] at z
  apply le_trans (_root_.abs_sub_le _ _ _) (add_le_add z _)
  simp_rw [sum_range_succ]
  norm_num
  

Proof state:
t : |2⁻¹| = 2⁻¹
z : |log 2 - Finset.sum (range 34) fun x => 2⁻¹ ^ (x + 1) / (↑x + 1)| ≤ 1 / 17179869184
⊢ |30417026706710207 / 51397301678363663775930777600| ≤ 7011591 / 167772160000000000

Next tactic:
rw [abs_of_pos]
theorem log_two_near_10 : |log 2 - 287209 / 414355| ≤ 1 / 10 ^ 10 := by
  suffices |log 2 - 287209 / 414355| ≤ 1 / 17179869184 + (1 / 10 ^ 10 - 1 / 2 ^ 34) by
    norm_num1 at *
    assumption
  have t : |(2⁻¹ : ℝ)| = 2⁻¹ := by rw [abs_of_pos]; norm_num
  have z := Real.abs_log_sub_add_sum_range_le (show |(2⁻¹ : ℝ)| < 1 by rw [t]; norm_num) 34
  rw [t] at z
  norm_num1 at z
  rw [one_div (2 : ℝ), log_inv, ← sub_eq_add_neg, _root_.abs_sub_comm] at z
  apply le_trans (_root_.abs_sub_le _ _ _) (add_le_add z _)
  simp_rw [sum_range_succ]
  norm_num
  rw [abs_of_pos] <;> 

Proof state:
t : |2⁻¹| = 2⁻¹
z : |log 2 - Finset.sum (range 34) fun x => 2⁻¹ ^ (x + 1) / (↑x + 1)| ≤ 1 / 17179869184
⊢ 30417026706710207 / 51397301678363663775930777600 ≤ 7011591 / 167772160000000000

Next tactic:
norm_num
theorem log_two_near_10 : |log 2 - 287209 / 414355| ≤ 1 / 10 ^ 10 := by
  suffices |log 2 - 287209 / 414355| ≤ 1 / 17179869184 + (1 / 10 ^ 10 - 1 / 2 ^ 34) by
    norm_num1 at *
    assumption
  have t : |(2⁻¹ : ℝ)| = 2⁻¹ := by rw [abs_of_pos]; norm_num
  have z := Real.abs_log_sub_add_sum_range_le (show |(2⁻¹ : ℝ)| < 1 by rw [t]; norm_num) 34
  rw [t] at z
  norm_num1 at z
  rw [one_div (2 : ℝ), log_inv, ← sub_eq_add_neg, _root_.abs_sub_comm] at z
  apply le_trans (_root_.abs_sub_le _ _ _) (add_le_add z _)
  simp_rw [sum_range_succ]
  norm_num
  rw [abs_of_pos] <;> 

Proof state:
t : |2⁻¹| = 2⁻¹
z : |log 2 - Finset.sum (range 34) fun x => 2⁻¹ ^ (x + 1) / (↑x + 1)| ≤ 1 / 17179869184
⊢ 0 < 30417026706710207 / 51397301678363663775930777600

Next tactic:
norm_num
theorem log_two_gt_d9 : 0.6931471803 < log 2 :=
  lt_of_lt_of_le (by 

Proof state:
⊢ 0.6931471803 < 287209 / 414355 - 1 / 10 ^ 10

Next tactic:
norm_num1
theorem log_two_lt_d9 : log 2 < 0.6931471808 :=
  lt_of_le_of_lt (sub_le_iff_le_add.1 (abs_sub_le_iff.1 log_two_near_10).1) (by 

Proof state:
⊢ 1 / 10 ^ 10 + 287209 / 414355 < 0.6931471808

Next tactic:
norm_num
/-- The `R`-`AlgEquiv` between the localization of `R` away from `r` and
    `R` with an inverse of `r` adjoined. -/
noncomputable def Localization.awayEquivAdjoin (r : R) : Away r ≃ₐ[R] AdjoinRoot (C r * X - 1) :=
  AlgEquiv.ofAlgHom
    { awayLift _ r
      -- Porting note: This argument used to be found automatically, i.e. `_`
      (isUnit_of_mul_eq_one ((algebraMap R (AdjoinRoot (C r * X - 1))) r) (root (C r * X - 1))
        (root_isInv r)) with
      commutes' :=
        IsLocalization.Away.AwayMap.lift_eq r (isUnit_of_mul_eq_one _ _ <| root_isInv r) }
    (liftHom _ (IsLocalization.Away.invSelf r) <| by
      

Proof state:
R : Type u_1
inst✝ : CommRing R
r : R
⊢ (aeval (IsLocalization.Away.invSelf r)) (C r * X - 1) = 0

Next tactic:
simp only [map_sub, map_mul, aeval_C, aeval_X, IsLocalization.Away.mul_invSelf, aeval_one,
        sub_self]
set_option linter.deprecated false in
theorem nthLe_range'_1 {n m} (i) (H : i < (range' n m).length) :
    nthLe (range' n m) i H = n + i := by 

Proof state:
α : Type u
n m i : ℕ
H : i < length (range' n m)
⊢ nthLe (range' n m) i H = n + i

Next tactic:
simp
theorem pairwise_lt_range (n : ℕ) : Pairwise (· < ·) (range n) := by
  

Proof state:
α : Type u
n : ℕ
⊢ Pairwise (fun x x_1 => x < x_1) (range n)

Next tactic:
simp (config := {decide := true}) only [range_eq_range', pairwise_lt_range']
theorem nodup_range (n : ℕ) : Nodup (range n) := by
  

Proof state:
α : Type u
n : ℕ
⊢ Nodup (range n)

Next tactic:
simp (config := {decide := true}) only [range_eq_range', nodup_range']
theorem chain'_range_succ (r : ℕ → ℕ → Prop) (n : ℕ) :
    Chain' r (range n.succ) ↔ ∀ m < n, r m m.succ := by
  

Proof state:
α : Type u
r : ℕ → ℕ → Prop
n : ℕ
⊢ Chain' r (range (succ n)) ↔ ∀ m < n, r m (succ m)

Next tactic:
rw [range_succ]
theorem chain'_range_succ (r : ℕ → ℕ → Prop) (n : ℕ) :
    Chain' r (range n.succ) ↔ ∀ m < n, r m m.succ := by
  rw [range_succ]
  

Proof state:
α : Type u
r : ℕ → ℕ → Prop
n : ℕ
⊢ Chain' r (range n ++ [n]) ↔ ∀ m < n, r m (succ m)

Next tactic:
induction' n with n hn
theorem chain'_range_succ (r : ℕ → ℕ → Prop) (n : ℕ) :
    Chain' r (range n.succ) ↔ ∀ m < n, r m m.succ := by
  rw [range_succ]
  induction' n with n hn
  · 

Proof state:
case zero
α : Type u
r : ℕ → ℕ → Prop
⊢ Chain' r (range zero ++ [zero]) ↔ ∀ m < zero, r m (succ m)

Next tactic:
simp
theorem chain'_range_succ (r : ℕ → ℕ → Prop) (n : ℕ) :
    Chain' r (range n.succ) ↔ ∀ m < n, r m m.succ := by
  rw [range_succ]
  induction' n with n hn
  · simp
  · 

Proof state:
case succ
α : Type u
r : ℕ → ℕ → Prop
n : ℕ
hn : Chain' r (range n ++ [n]) ↔ ∀ m < n, r m (succ m)
⊢ Chain' r (range (succ n) ++ [succ n]) ↔ ∀ m < succ n, r m (succ m)

Next tactic:
rw [range_succ]
theorem chain'_range_succ (r : ℕ → ℕ → Prop) (n : ℕ) :
    Chain' r (range n.succ) ↔ ∀ m < n, r m m.succ := by
  rw [range_succ]
  induction' n with n hn
  · simp
  · rw [range_succ]
    

Proof state:
case succ
α : Type u
r : ℕ → ℕ → Prop
n : ℕ
hn : Chain' r (range n ++ [n]) ↔ ∀ m < n, r m (succ m)
⊢ Chain' r (range n ++ [n] ++ [succ n]) ↔ ∀ m < succ n, r m (succ m)

Next tactic:
simp only [append_assoc, singleton_append, chain'_append_cons_cons, chain'_singleton,
      and_true_iff]
theorem chain'_range_succ (r : ℕ → ℕ → Prop) (n : ℕ) :
    Chain' r (range n.succ) ↔ ∀ m < n, r m m.succ := by
  rw [range_succ]
  induction' n with n hn
  · simp
  · rw [range_succ]
    simp only [append_assoc, singleton_append, chain'_append_cons_cons, chain'_singleton,
      and_true_iff]
    

Proof state:
case succ
α : Type u
r : ℕ → ℕ → Prop
n : ℕ
hn : Chain' r (range n ++ [n]) ↔ ∀ m < n, r m (succ m)
⊢ Chain' r (range n ++ [n]) ∧ r n (succ n) ↔ ∀ m < succ n, r m (succ m)

Next tactic:
rw [hn, forall_lt_succ]
theorem chain_range_succ (r : ℕ → ℕ → Prop) (n a : ℕ) :
    Chain r a (range n.succ) ↔ r a 0 ∧ ∀ m < n, r m m.succ := by
  

Proof state:
α : Type u
r : ℕ → ℕ → Prop
n a : ℕ
⊢ Chain r a (range (succ n)) ↔ r a 0 ∧ ∀ m < n, r m (succ m)

Next tactic:
rw [range_succ_eq_map, chain_cons, and_congr_right_iff, ← chain'_range_succ, range_succ_eq_map]
theorem chain_range_succ (r : ℕ → ℕ → Prop) (n a : ℕ) :
    Chain r a (range n.succ) ↔ r a 0 ∧ ∀ m < n, r m m.succ := by
  rw [range_succ_eq_map, chain_cons, and_congr_right_iff, ← chain'_range_succ, range_succ_eq_map]
  

Proof state:
α : Type u
r : ℕ → ℕ → Prop
n a : ℕ
⊢ r a 0 → (Chain r 0 (map succ (range n)) ↔ Chain' (fun m => r m) (0 :: map succ (range n)))

Next tactic:
exact fun _ => Iff.rfl
theorem pairwise_gt_iota (n : ℕ) : Pairwise (· > ·) (iota n) := by
  

Proof state:
α : Type u
n : ℕ
⊢ Pairwise (fun x x_1 => x > x_1) (iota n)

Next tactic:
simpa only [iota_eq_reverse_range', pairwise_reverse] using pairwise_lt_range' 1 n
@[simp]
theorem mem_finRange {n : ℕ} (a : Fin n) : a ∈ finRange n :=
  mem_pmap.2
    ⟨a.1, mem_range.2 a.2, by
      

Proof state:
α : Type u
n : ℕ
a : Fin n
⊢ { val := ↑a, isLt := (_ : ↑a < n) } = a

Next tactic:
cases a
@[simp]
theorem mem_finRange {n : ℕ} (a : Fin n) : a ∈ finRange n :=
  mem_pmap.2
    ⟨a.1, mem_range.2 a.2, by
      cases a
      

Proof state:
case mk
α : Type u
n val✝ : ℕ
isLt✝ : val✝ < n
⊢ { val := ↑{ val := val✝, isLt := isLt✝ }, isLt := (_ : ↑{ val := val✝, isLt := isLt✝ } < n) } =
    { val := val✝, isLt := isLt✝ }

Next tactic:
rfl
@[simp]
theorem length_finRange (n : ℕ) : (finRange n).length = n := by
  

Proof state:
α : Type u
n : ℕ
⊢ length (finRange n) = n

Next tactic:
rw [finRange, length_pmap, length_range]
@[simp]
theorem finRange_eq_nil {n : ℕ} : finRange n = [] ↔ n = 0 := by
  

Proof state:
α : Type u
n : ℕ
⊢ finRange n = [] ↔ n = 0

Next tactic:
rw [← length_eq_zero, length_finRange]
theorem pairwise_lt_finRange (n : ℕ) : Pairwise (· < ·) (finRange n) :=
  (List.pairwise_lt_range n).pmap (by 

Proof state:
α : Type u
n : ℕ
⊢ ∀ x ∈ range n, x < n

Next tactic:
simp
theorem pairwise_lt_finRange (n : ℕ) : Pairwise (· < ·) (finRange n) :=
  (List.pairwise_lt_range n).pmap (by simp) (by 

Proof state:
α : Type u
n : ℕ
⊢ ∀ ⦃x : ℕ⦄ (hx : x < n) ⦃y : ℕ⦄ (hy : y < n), x < y → { val := x, isLt := hx } < { val := y, isLt := hy }

Next tactic:
simp
theorem pairwise_le_finRange (n : ℕ) : Pairwise (· ≤ ·) (finRange n) :=
  (List.pairwise_le_range n).pmap (by 

Proof state:
α : Type u
n : ℕ
⊢ ∀ x ∈ range n, x < n

Next tactic:
simp
theorem pairwise_le_finRange (n : ℕ) : Pairwise (· ≤ ·) (finRange n) :=
  (List.pairwise_le_range n).pmap (by simp) (by 

Proof state:
α : Type u
n : ℕ
⊢ ∀ ⦃x : ℕ⦄ (hx : x < n) ⦃y : ℕ⦄ (hy : y < n), x ≤ y → { val := x, isLt := hx } ≤ { val := y, isLt := hy }

Next tactic:
simp
@[to_additive]
theorem prod_range_succ {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
    ((range n.succ).map f).prod = ((range n).map f).prod * f n := by
  

Proof state:
α✝ α : Type u
inst✝ : Monoid α
f : ℕ → α
n : ℕ
⊢ prod (map f (range (succ n))) = prod (map f (range n)) * f n

Next tactic:
rw [range_succ, map_append, map_singleton, prod_append, prod_cons, prod_nil, mul_one]
/-- A variant of `prod_range_succ` which pulls off the first
  term in the product rather than the last.-/
@[to_additive
  "A variant of `sum_range_succ` which pulls off the first term in the sum rather than the last."]
theorem prod_range_succ' {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
    ((range n.succ).map f).prod = f 0 * ((range n).map fun i => f (succ i)).prod :=
  Nat.recOn n (show 1 * f 0 = f 0 * 1 by 

Proof state:
α✝ α : Type u
inst✝ : Monoid α
f : ℕ → α
n : ℕ
⊢ 1 * f 0 = f 0 * 1

Next tactic:
rw [one_mul, mul_one]
/-- A variant of `prod_range_succ` which pulls off the first
  term in the product rather than the last.-/
@[to_additive
  "A variant of `sum_range_succ` which pulls off the first term in the sum rather than the last."]
theorem prod_range_succ' {α : Type u} [Monoid α] (f : ℕ → α) (n : ℕ) :
    ((range n.succ).map f).prod = f 0 * ((range n).map fun i => f (succ i)).prod :=
  Nat.recOn n (show 1 * f 0 = f 0 * 1 by rw [one_mul, mul_one]) fun _ hd => by
    

Proof state:
α✝ α : Type u
inst✝ : Monoid α
f : ℕ → α
n x✝ : ℕ
hd : prod (map f (range (succ x✝))) = f 0 * prod (map (fun i => f (succ i)) (range x✝))
⊢ prod (map f (range (succ (succ x✝)))) = f 0 * prod (map (fun i => f (succ i)) (range (succ x✝)))

Next tactic:
rw [List.prod_range_succ, hd, mul_assoc, ← List.prod_range_succ]
@[simp]
theorem unzip_enum_eq_prod (l : List α) : l.enum.unzip = (range l.length, l) := by
  

Proof state:
α : Type u
l : List α
⊢ unzip (enum l) = (range (length l), l)

Next tactic:
simp only [enum_eq_zip_range, unzip_zip, length_range]
@[simp]
theorem unzip_enumFrom_eq_prod (l : List α) {n : ℕ} :
    (l.enumFrom n).unzip = (range' n l.length, l) := by
  

Proof state:
α : Type u
l : List α
n : ℕ
⊢ unzip (enumFrom n l) = (range' n (length l), l)

Next tactic:
simp only [enumFrom_eq_zip_range', unzip_zip, length_range']
@[simp]
theorem get_finRange {n : ℕ} {i : ℕ} (h) :
    (finRange n).get ⟨i, h⟩ = ⟨i, length_finRange n ▸ h⟩ := by
  

Proof state:
α : Type u
n i : ℕ
h : i < length (finRange n)
⊢ get (finRange n) { val := i, isLt := h } = { val := i, isLt := (_ : i < n) }

Next tactic:
simp only [finRange, get_range, get_pmap]
@[simp]
theorem finRange_map_get (l : List α) : (finRange l.length).map l.get = l :=
  List.ext_get (by 

Proof state:
α : Type u
l : List α
⊢ length (map (get l) (finRange (length l))) = length l

Next tactic:
simp
@[simp]
theorem finRange_map_get (l : List α) : (finRange l.length).map l.get = l :=
  List.ext_get (by simp) (by 

Proof state:
α : Type u
l : List α
⊢ ∀ (n : ℕ) (h₁ : n < length (map (get l) (finRange (length l)))) (h₂ : n < length l),
    get (map (get l) (finRange (length l))) { val := n, isLt := h₁ } = get l { val := n, isLt := h₂ }

Next tactic:
simp
@[simp] theorem indexOf_finRange (i : Fin k) : (finRange k).indexOf i = i := by
  

Proof state:
α : Type u
k : ℕ
i : Fin k
⊢ indexOf i (finRange k) = ↑i

Next tactic:
have : (finRange k).indexOf i < (finRange k).length := indexOf_lt_length.mpr (by simp)
@[simp] theorem indexOf_finRange (i : Fin k) : (finRange k).indexOf i = i := by
  have : (finRange k).indexOf i < (finRange k).length := indexOf_lt_length.mpr (by 

Proof state:
α : Type u
k : ℕ
i : Fin k
⊢ i ∈ finRange k

Next tactic:
simp
@[simp] theorem indexOf_finRange (i : Fin k) : (finRange k).indexOf i = i := by
  have : (finRange k).indexOf i < (finRange k).length := indexOf_lt_length.mpr (by simp)
  

Proof state:
α : Type u
k : ℕ
i : Fin k
this : indexOf i (finRange k) < length (finRange k)
⊢ indexOf i (finRange k) = ↑i

Next tactic:
have h₁ : (finRange k).get ⟨(finRange k).indexOf i, this⟩ = i := indexOf_get this
@[simp] theorem indexOf_finRange (i : Fin k) : (finRange k).indexOf i = i := by
  have : (finRange k).indexOf i < (finRange k).length := indexOf_lt_length.mpr (by simp)
  have h₁ : (finRange k).get ⟨(finRange k).indexOf i, this⟩ = i := indexOf_get this
  

Proof state:
α : Type u
k : ℕ
i : Fin k
this : indexOf i (finRange k) < length (finRange k)
h₁ : get (finRange k) { val := indexOf i (finRange k), isLt := this } = i
⊢ indexOf i (finRange k) = ↑i

Next tactic:
have h₂ : (finRange k).get ⟨i, by simp⟩ = i := get_finRange _
@[simp] theorem indexOf_finRange (i : Fin k) : (finRange k).indexOf i = i := by
  have : (finRange k).indexOf i < (finRange k).length := indexOf_lt_length.mpr (by simp)
  have h₁ : (finRange k).get ⟨(finRange k).indexOf i, this⟩ = i := indexOf_get this
  have h₂ : (finRange k).get ⟨i, by 

Proof state:
α : Type u
k : ℕ
i : Fin k
this : indexOf i (finRange k) < length (finRange k)
h₁ : get (finRange k) { val := indexOf i (finRange k), isLt := this } = i
⊢ ↑i < length (finRange k)

Next tactic:
simp
@[simp] theorem indexOf_finRange (i : Fin k) : (finRange k).indexOf i = i := by
  have : (finRange k).indexOf i < (finRange k).length := indexOf_lt_length.mpr (by simp)
  have h₁ : (finRange k).get ⟨(finRange k).indexOf i, this⟩ = i := indexOf_get this
  have h₂ : (finRange k).get ⟨i, by simp⟩ = i := get_finRange _
  

Proof state:
α : Type u
k : ℕ
i : Fin k
this : indexOf i (finRange k) < length (finRange k)
h₁ : get (finRange k) { val := indexOf i (finRange k), isLt := this } = i
h₂ : get (finRange k) { val := ↑i, isLt := (_ : ↑i < length (finRange k)) } = i
⊢ indexOf i (finRange k) = ↑i

Next tactic:
simpa using (Nodup.get_inj_iff (nodup_finRange k)).mp (Eq.trans h₁ h₂.symm)
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  

Proof state:
α : Type u
l : List ℕ
⊢ Pairwise Disjoint (ranges l)

Next tactic:
induction l with
  | nil => exact Pairwise.nil
  | cons a l hl =>
    simp only [ranges, pairwise_cons]
    constructor
    · intro s hs
      obtain ⟨s', _, rfl⟩ := mem_map.mp hs
      intro u hu
      rw [mem_map]
      rintro ⟨v, _, rfl⟩
      rw [mem_range] at hu
      exact lt_iff_not_le.mp hu le_self_add
    · rw [pairwise_map]
      apply Pairwise.imp _ hl
      intro u v
      apply disjoint_map
      exact fun u v => Nat.add_left_cancel
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  

Proof state:
case nil
α : Type u
⊢ Pairwise Disjoint (ranges [])

Next tactic:
| nil => exact Pairwise.nil
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => 

Proof state:
case nil
α : Type u
⊢ Pairwise Disjoint (ranges [])

Next tactic:
exact Pairwise.nil
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => exact Pairwise.nil
  

Proof state:
case cons
α : Type u
a : ℕ
l : List ℕ
hl : Pairwise Disjoint (ranges l)
⊢ Pairwise Disjoint (ranges (a :: l))

Next tactic:
| cons a l hl =>
    simp only [ranges, pairwise_cons]
    constructor
    · intro s hs
      obtain ⟨s', _, rfl⟩ := mem_map.mp hs
      intro u hu
      rw [mem_map]
      rintro ⟨v, _, rfl⟩
      rw [mem_range] at hu
      exact lt_iff_not_le.mp hu le_self_add
    · rw [pairwise_map]
      apply Pairwise.imp _ hl
      intro u v
      apply disjoint_map
      exact fun u v => Nat.add_left_cancel
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => exact Pairwise.nil
  | cons a l hl =>
    

Proof state:
case cons
α : Type u
a : ℕ
l : List ℕ
hl : Pairwise Disjoint (ranges l)
⊢ Pairwise Disjoint (ranges (a :: l))

Next tactic:
simp only [ranges, pairwise_cons]
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => exact Pairwise.nil
  | cons a l hl =>
    simp only [ranges, pairwise_cons]
    

Proof state:
case cons
α : Type u
a : ℕ
l : List ℕ
hl : Pairwise Disjoint (ranges l)
⊢ (∀ a' ∈ map (map fun x => a + x) (ranges l), Disjoint (range a) a') ∧
    Pairwise Disjoint (map (map fun x => a + x) (ranges l))

Next tactic:
constructor
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => exact Pairwise.nil
  | cons a l hl =>
    simp only [ranges, pairwise_cons]
    constructor
    · 

Proof state:
case cons.left
α : Type u
a : ℕ
l : List ℕ
hl : Pairwise Disjoint (ranges l)
⊢ ∀ a' ∈ map (map fun x => a + x) (ranges l), Disjoint (range a) a'

Next tactic:
intro s hs
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => exact Pairwise.nil
  | cons a l hl =>
    simp only [ranges, pairwise_cons]
    constructor
    · intro s hs
      

Proof state:
case cons.left
α : Type u
a : ℕ
l : List ℕ
hl : Pairwise Disjoint (ranges l)
s : List ℕ
hs : s ∈ map (map fun x => a + x) (ranges l)
⊢ Disjoint (range a) s

Next tactic:
obtain ⟨s', _, rfl⟩ := mem_map.mp hs
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => exact Pairwise.nil
  | cons a l hl =>
    simp only [ranges, pairwise_cons]
    constructor
    · intro s hs
      obtain ⟨s', _, rfl⟩ := mem_map.mp hs
      

Proof state:
case cons.left.intro.intro
α : Type u
a : ℕ
l : List ℕ
hl : Pairwise Disjoint (ranges l)
s' : List ℕ
left✝ : s' ∈ ranges l
hs : map (fun x => a + x) s' ∈ map (map fun x => a + x) (ranges l)
⊢ Disjoint (range a) (map (fun x => a + x) s')

Next tactic:
intro u hu
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => exact Pairwise.nil
  | cons a l hl =>
    simp only [ranges, pairwise_cons]
    constructor
    · intro s hs
      obtain ⟨s', _, rfl⟩ := mem_map.mp hs
      intro u hu
      

Proof state:
case cons.left.intro.intro
α : Type u
a : ℕ
l : List ℕ
hl : Pairwise Disjoint (ranges l)
s' : List ℕ
left✝ : s' ∈ ranges l
hs : map (fun x => a + x) s' ∈ map (map fun x => a + x) (ranges l)
u : ℕ
hu : u ∈ range a
⊢ u ∈ map (fun x => a + x) s' → False

Next tactic:
rw [mem_map]
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => exact Pairwise.nil
  | cons a l hl =>
    simp only [ranges, pairwise_cons]
    constructor
    · intro s hs
      obtain ⟨s', _, rfl⟩ := mem_map.mp hs
      intro u hu
      rw [mem_map]
      

Proof state:
case cons.left.intro.intro
α : Type u
a : ℕ
l : List ℕ
hl : Pairwise Disjoint (ranges l)
s' : List ℕ
left✝ : s' ∈ ranges l
hs : map (fun x => a + x) s' ∈ map (map fun x => a + x) (ranges l)
u : ℕ
hu : u ∈ range a
⊢ (∃ a_1 ∈ s', a + a_1 = u) → False

Next tactic:
rintro ⟨v, _, rfl⟩
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => exact Pairwise.nil
  | cons a l hl =>
    simp only [ranges, pairwise_cons]
    constructor
    · intro s hs
      obtain ⟨s', _, rfl⟩ := mem_map.mp hs
      intro u hu
      rw [mem_map]
      rintro ⟨v, _, rfl⟩
      

Proof state:
case cons.left.intro.intro.intro.intro
α : Type u
a : ℕ
l : List ℕ
hl : Pairwise Disjoint (ranges l)
s' : List ℕ
left✝¹ : s' ∈ ranges l
hs : map (fun x => a + x) s' ∈ map (map fun x => a + x) (ranges l)
v : ℕ
left✝ : v ∈ s'
hu : a + v ∈ range a
⊢ False

Next tactic:
rw [mem_range] at hu
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => exact Pairwise.nil
  | cons a l hl =>
    simp only [ranges, pairwise_cons]
    constructor
    · intro s hs
      obtain ⟨s', _, rfl⟩ := mem_map.mp hs
      intro u hu
      rw [mem_map]
      rintro ⟨v, _, rfl⟩
      rw [mem_range] at hu
      

Proof state:
case cons.left.intro.intro.intro.intro
α : Type u
a : ℕ
l : List ℕ
hl : Pairwise Disjoint (ranges l)
s' : List ℕ
left✝¹ : s' ∈ ranges l
hs : map (fun x => a + x) s' ∈ map (map fun x => a + x) (ranges l)
v : ℕ
left✝ : v ∈ s'
hu : a + v < a
⊢ False

Next tactic:
exact lt_iff_not_le.mp hu le_self_add
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => exact Pairwise.nil
  | cons a l hl =>
    simp only [ranges, pairwise_cons]
    constructor
    · intro s hs
      obtain ⟨s', _, rfl⟩ := mem_map.mp hs
      intro u hu
      rw [mem_map]
      rintro ⟨v, _, rfl⟩
      rw [mem_range] at hu
      exact lt_iff_not_le.mp hu le_self_add
    · 

Proof state:
case cons.right
α : Type u
a : ℕ
l : List ℕ
hl : Pairwise Disjoint (ranges l)
⊢ Pairwise Disjoint (map (map fun x => a + x) (ranges l))

Next tactic:
rw [pairwise_map]
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => exact Pairwise.nil
  | cons a l hl =>
    simp only [ranges, pairwise_cons]
    constructor
    · intro s hs
      obtain ⟨s', _, rfl⟩ := mem_map.mp hs
      intro u hu
      rw [mem_map]
      rintro ⟨v, _, rfl⟩
      rw [mem_range] at hu
      exact lt_iff_not_le.mp hu le_self_add
    · rw [pairwise_map]
      

Proof state:
case cons.right
α : Type u
a : ℕ
l : List ℕ
hl : Pairwise Disjoint (ranges l)
⊢ Pairwise (fun a_1 b => Disjoint (map (fun x => a + x) a_1) (map (fun x => a + x) b)) (ranges l)

Next tactic:
apply Pairwise.imp _ hl
/-- The members of `l.ranges` are pairwise disjoint -/
theorem ranges_disjoint (l : List ℕ) :
    Pairwise Disjoint (ranges l) := by
  induction l with
  | nil => exact Pairwise.nil
  | cons a l hl =>
    simp only [ranges, pairwise_cons]
    constructor
    · intro s hs
      obtain ⟨s', _, rfl⟩ := mem_map.mp hs
      intro u hu
      rw [mem_map]
      rintro ⟨v, _, rfl⟩
      rw [mem_range] at hu
      exact lt_iff_not_le.mp hu le_self_add
    · rw [pairwise_map]
      apply Pairwise.imp _ hl
      

Proof state:
α : Type u
a : ℕ
l : List ℕ
hl : Pairwise Disjoint (ranges l)
⊢ ∀ {a_1 b : List ℕ}, Disjoint a_1 b → Disjoint (map (fun x => a + x) a_1) (map (fun x => a + x) b)

Next tactic:
intro u v