injective_comptheoremProved here from basic factsNo axioms
injective_compLean 4Proved here from basic factsFormally verified
/-- **A composite of injections is injective**, proved as on paper: if `g (f x) = g (f y)`,then `f x = f y` because `g` is injective, and then `x = y` because `f` is injective. -/theorem injective_comp {α β γ : Type*} {f : α → β} {g : β → γ} (hg : Injective g) (hf : Injective f) : Injective (g ∘ f) := by intro x y h -- `h : (g ∘ f) x = (g ∘ f) y`, which is `g (f x) = g (f y)` by definition. apply hf apply hg exact h
injective_comp_librarytheoremApplies a library theoremNo axioms
injective_comp_libraryLean 4Applies a library theoremFormally verified
/-- The same theorem, found in Mathlib: `Function.Injective.comp`. Its name follows Mathlib'snaming convention — the conclusion's shape, `Injective (g ∘ f)`, read as `Injective.comp` — andit can be found by `exact?` or by searching the documentation. -/theorem injective_comp_library {α β γ : Type*} {f : α → β} {g : β → γ} (hg : Injective g) (hf : Injective f) : Injective (g ∘ f) := hg.comp hf
surjective_comptheoremProved here from basic factsNo axioms
surjective_compLean 4Proved here from basic factsFormally verified
/-- **A composite of surjections is surjective.** Given `z`, choose `y` with `g y = z`, then`x` with `f x = y`; then `g (f x) = z`. Each "choose" is the elimination of an `∃`. -/theorem surjective_comp {α β γ : Type*} {f : α → β} {g : β → γ} (hg : Surjective g) (hf : Surjective f) : Surjective (g ∘ f) := by intro z obtain ⟨y, rfl⟩ := hg z obtain ⟨x, rfl⟩ := hf y exact ⟨x, rfl⟩
injective_of_comptheoremProved here from basic factsNo axioms
injective_of_compLean 4Proved here from basic factsFormally verified
/-- If `g ∘ f` is injective then `f` is injective (but `g` need not be). -/theorem injective_of_comp {α β γ : Type*} {f : α → β} {g : β → γ} (h : Injective (g ∘ f)) : Injective f := by intro x y hxy apply h show g (f x) = g (f y) rw [hxy]
image_uniontheoremProved here from basic factspropext, Quot.sound
image_unionLean 4Proved here from basic factsFormally verified
/-- `f(s ∪ t) = f(s) ∪ f(t)`, by extensionality: show that an arbitrary `y` lies in the leftside exactly when it lies in the right side. (Mathlib: `Set.image_union`.) -/theorem image_union {α β : Type*} (f : α → β) (s t : Set α) : f '' (s ∪ t) = f '' s ∪ f '' t := by ext y constructor · rintro ⟨x, hx | hx, rfl⟩ · exact Or.inl ⟨x, hx, rfl⟩ · exact Or.inr ⟨x, hx, rfl⟩ · rintro (⟨x, hx, rfl⟩ | ⟨x, hx, rfl⟩) · exact ⟨x, Or.inl hx, rfl⟩ · exact ⟨x, Or.inr hx, rfl⟩
image_inter_subsettheoremProved here from basic factsNo axioms
image_inter_subsetLean 4Proved here from basic factsFormally verified
/-- `f(s ∩ t) ⊆ f(s) ∩ f(t)` always holds. -/theorem image_inter_subset {α β : Type*} (f : α → β) (s t : Set α) : f '' (s ∩ t) ⊆ f '' s ∩ f '' t := by rintro y ⟨x, ⟨hs, ht⟩, rfl⟩ exact ⟨⟨x, hs, rfl⟩, ⟨x, ht, rfl⟩⟩
image_inter_of_injectivetheoremApplies a library theorempropext, Classical.choice, Quot.sound
image_inter_of_injectiveLean 4Applies a library theoremFormally verified
/-- For an *injective* `f`, equality does hold: Mathlib's `Set.image_inter`. The hypothesis`Injective f` is exactly what the counterexample above lacks. -/theorem image_inter_of_injective {α β : Type*} {f : α → β} (hf : Injective f) (s t : Set α) : f '' (s ∩ t) = f '' s ∩ f '' t := Set.image_inter hf
preimage_intertheoremProved here from basic factsNo axioms
preimage_interLean 4Proved here from basic factsFormally verified
/-- Preimages behave perfectly: `f⁻¹(s ∩ t) = f⁻¹(s) ∩ f⁻¹(t)`. In Lean both sides unfold to thesame predicate `fun x => f x ∈ s ∧ f x ∈ t`, so the proof is `rfl`: true *by definition*. -/theorem preimage_inter {α β : Type*} (f : α → β) (s t : Set β) : f ⁻¹' (s ∩ t) = f ⁻¹' s ∩ f ⁻¹' t := rfl
exists_forall_imptheoremProved here from basic factsNo axioms
exists_forall_impLean 4Proved here from basic factsFormally verified
/-- `∃ x, ∀ y, P x y` implies `∀ y, ∃ x, P x y`: a single `x` that works for every `y` certainlygives, for each `y`, some `x`. -/theorem exists_forall_imp {α β : Type*} (P : α → β → Prop) : (∃ x, ∀ y, P x y) → ∀ y, ∃ x, P x y := by rintro ⟨x, hx⟩ y exact ⟨x, hx y⟩
forall_exists_not_imptheoremProved here from basic factsNo axioms
forall_exists_not_impLean 4Proved here from basic factsFormally verified
/-- The converse fails: every natural number has a larger one (`∀ n, ∃ m, n < m`), but nonatural number is larger than all of them (`∃ m, ∀ n, n < m` is false — take `n = m`). -/theorem forall_exists_not_imp : ¬ ((∀ n : ℕ, ∃ m, n < m) → ∃ m : ℕ, ∀ n, n < m) := by intro h obtain ⟨m, hm⟩ := h (fun n => ⟨n + 1, Nat.lt_succ_self n⟩) exact lt_irrefl m (hm m)
/-- The ε–N definition of convergence of a real sequence, written exactly as in an analysiscourse: for every `ε > 0` there is `N` such that `|aₙ − L| < ε` for all `n ≥ N`. -/def ConvergesTo (a : ℕ → ℝ) (L : ℝ) : Prop := ∀ ε > 0, ∃ N : ℕ, ∀ n ≥ N, |a n - L| < ε
convergesTo_iff_tendstotheoremApplies a library theorempropext, Classical.choice, Quot.sound
convergesTo_iff_tendstoLean 4Applies a library theoremFormally verified
/-- **Does our definition mean what Mathlib means?** Mathlib defines convergence with filters:`Tendsto a atTop (𝓝 L)`. Mathlib's `Metric.tendsto_atTop` unfolds it to the ε–N form with`dist (a n) L`, and `Real.dist_eq` says `dist x y = |x − y|`. So the two definitions agree, andevery Mathlib theorem about `Tendsto` applies to `ConvergesTo`. -/theorem convergesTo_iff_tendsto (a : ℕ → ℝ) (L : ℝ) : ConvergesTo a L ↔ Tendsto a atTop (𝓝 L) := by rw [Metric.tendsto_atTop] simp only [ConvergesTo, Real.dist_eq]
/-- A home-made **type class** for monoids: a type `M` with a multiplication and a unit, and thethree laws as fields. A *structure* bundles data and proofs; declaring it as a `class` lets Leanfind an instance automatically. (Mathlib's real `Monoid` is built the same way, from smallerclasses such as `Mul`, `One` and `Semigroup`.) -/class MyMonoid (M : Type*) where mul : M → M → M one : M mul_assoc : ∀ a b c, mul (mul a b) c = mul a (mul b c) one_mul : ∀ a, mul one a = a mul_one : ∀ a, mul a one = a
/-- An **instance**: the natural numbers under addition form a monoid with unit `0`. The lawsare discharged by core lemmas about `Nat`. -/instance natAddMyMonoid : MyMonoid ℕ where mul := (· + ·) one := 0 mul_assoc := Nat.add_assoc one_mul := Nat.zero_add mul_one := Nat.add_zero
MyMonoid.one_uniquetheoremProved here from basic factsNo axioms
one_uniqueLean 4Proved here from basic factsFormally verified
/-- **The unit of a monoid is unique**, proved once for *every* instance of `MyMonoid`: if `e`is a two-sided unit then `e = one`, because `e = e · one = one`. -/theorem MyMonoid.one_unique {M : Type*} [MyMonoid M] (e : M) (he : ∀ a : M, MyMonoid.mul e a = a ∧ MyMonoid.mul a e = a) : e = MyMonoid.one := calc e = MyMonoid.mul e MyMonoid.one := (MyMonoid.mul_one e).symm _ = MyMonoid.one := (he MyMonoid.one).1
zero_unique_nattheoremProved here from basic factsNo axioms
zero_unique_natLean 4Proved here from basic factsFormally verified
/-- Using the generic theorem at the instance for `ℕ`: a number `e` with `e + a = a` and`a + e = a` for all `a` must be `0`. Lean finds `natAddMyMonoid` by instance search. -/theorem zero_unique_nat (e : ℕ) (he : ∀ a : ℕ, e + a = a ∧ a + e = a) : e = 0 := MyMonoid.one_unique e he
inv_uniquetheoremProved here from basic factsNo axioms
inv_uniqueLean 4Proved here from basic factsFormally verified
/-- In any Mathlib `Monoid`, a left inverse and a right inverse of the same element agree:`b = b (a c) = (b a) c = c`. -/theorem inv_unique {M : Type*} [Monoid M] {a b c : M} (hb : b * a = 1) (hc : a * c = 1) : b = c := calc b = b * (a * c) := by rw [hc, mul_one] _ = b * a * c := (mul_assoc b a c).symm _ = c := by rw [hb, one_mul]
comm_of_sq_eq_onetheoremProved here from basic factspropext
comm_of_sq_eq_oneLean 4Proved here from basic factsFormally verified
/-- **A group in which every element squares to `1` is commutative.** From `x x = 1` we get`x⁻¹ = x` for every `x`, so `a b = (a b)⁻¹ = b⁻¹ a⁻¹ = b a`. This works in *every* `Group`,because the proof uses only the group laws (Mathlib lemmas `inv_eq_of_mul_eq_one_right` and`mul_inv_rev`). -/theorem comm_of_sq_eq_one {G : Type*} [Group G] (h : ∀ x : G, x * x = 1) (a b : G) : a * b = b * a := by have hinv : ∀ x : G, x⁻¹ = x := fun x => inv_eq_of_mul_eq_one_right (h x) calc a * b = (a * b)⁻¹ := (hinv (a * b)).symm _ = b⁻¹ * a⁻¹ := mul_inv_rev a b _ = b * a := by rw [hinv a, hinv b]
add_sq_comm_ringtheoremProved here from basic factspropext
add_sq_comm_ringLean 4Proved here from basic factsFormally verified
/-- In every commutative ring, `(a + b)² = a² + 2ab + b²`. The `ring` tactic decides suchidentities by normalising both sides; the theorem then holds in `ℤ`, `ℚ`, `ℝ`, `ℤ/nℤ`,polynomial rings, … at once. -/theorem add_sq_comm_ring {R : Type*} [CommRing R] (a b : R) : (a + b) ^ 2 = a ^ 2 + 2 * a * b + b ^ 2 := by ring
div_zero_conventiontheoremApplies a library theorempropext, Classical.choice, Quot.sound
div_zero_conventionLean 4Applies a library theoremFormally verified
/-- In Lean and Mathlib, `x / 0 = 0` (`div_zero`). This is a convention making division a totalfunction; it does not change any theorem about division by non-zero numbers. -/theorem div_zero_convention (x : ℝ) : x / 0 = 0 := div_zero x
div_mul_cancel_of_netheoremApplies a library theorempropext, Classical.choice, Quot.sound
div_mul_cancel_of_neLean 4Applies a library theoremFormally verified
/-- The familiar cancellation law carries its hypothesis explicitly: if `b ≠ 0` then`a / b · b = a` (`div_mul_cancel₀`). -/theorem div_mul_cancel_of_ne (a : ℝ) {b : ℝ} (hb : b ≠ 0) : a / b * b = a := div_mul_cancel₀ a hb
div_mul_cancel_needs_hyptheoremProved here from basic factspropext, Classical.choice, Quot.sound
div_mul_cancel_needs_hypLean 4Proved here from basic factsFormally verified
/-- Without the hypothesis the law is false: `1 / 0 · 0 = 0 ≠ 1`. So the convention `x / 0 = 0`cannot be used to "prove" anything false about real division. -/theorem div_mul_cancel_needs_hyp : ¬ ∀ a b : ℝ, a / b * b = a := by intro h have := h 1 0 norm_num at this
nat_sub_truncatestheoremProved here from basic factsNo axioms
nat_sub_truncatesLean 4Proved here from basic factsFormally verified
/-- Subtraction on `ℕ` is **truncated**: `2 − 3 = 0`, because there is no natural number`−1`. -/theorem nat_sub_truncates : (2 : ℕ) - 3 = 0 := by decide
nat_sub_add_canceltheoremApplies a library theorempropext
nat_sub_add_cancelLean 4Applies a library theoremFormally verified
/-- So `(a − b) + b = a` needs the hypothesis `b ≤ a` (`Nat.sub_add_cancel`); for `a = 2`,`b = 3` the left side is `3`. -/theorem nat_sub_add_cancel {a b : ℕ} (h : b ≤ a) : a - b + b = a := Nat.sub_add_cancel h
/-- Prove that a composite of surjections is surjective.Hint: `intro z`, then use `obtain ⟨y, hy⟩ := hg z` and `obtain ⟨x, hx⟩ := hf y`, and provide`x` as the witness. -/theorem surjective_comp {α β γ : Type*} {f : α → β} {g : β → γ} (hg : Surjective g) (hf : Surjective f) : Surjective (g ∘ f) := by sorry
Show the compiled solution
surjective_compLean 4Proved here from basic factsFormally verified
/-- **A composite of surjections is surjective.** Given `z`, choose `y` with `g y = z`, then`x` with `f x = y`; then `g (f x) = z`. Each "choose" is the elimination of an `∃`. -/theorem surjective_comp {α β γ : Type*} {f : α → β} {g : β → γ} (hg : Surjective g) (hf : Surjective f) : Surjective (g ∘ f) := by intro z obtain ⟨y, rfl⟩ := hg z obtain ⟨x, rfl⟩ := hf y exact ⟨x, rfl⟩
/-- Prove that `∃ x, ∀ y, P x y` implies `∀ y, ∃ x, P x y`.Hint: `rintro ⟨x, hx⟩ y`, then `exact ⟨x, hx y⟩`. -/theorem exists_forall_imp {α β : Type*} (P : α → β → Prop) : (∃ x, ∀ y, P x y) → ∀ y, ∃ x, P x y := by sorry
Show the compiled solution
exists_forall_impLean 4Proved here from basic factsFormally verified
/-- `∃ x, ∀ y, P x y` implies `∀ y, ∃ x, P x y`: a single `x` that works for every `y` certainlygives, for each `y`, some `x`. -/theorem exists_forall_imp {α β : Type*} (P : α → β → Prop) : (∃ x, ∀ y, P x y) → ∀ y, ∃ x, P x y := by rintro ⟨x, hx⟩ y exact ⟨x, hx y⟩
/-- Prove that in a monoid a left inverse and a right inverse of the same element agree.Hint: a `calc` chain `b = b * (a * c) = b * a * c = c`, using `mul_one`, `mul_assoc` and`one_mul`. -/theorem inv_unique {M : Type*} [Monoid M] {a b c : M} (hb : b * a = 1) (hc : a * c = 1) : b = c := by sorry
Show the compiled solution
inv_uniqueLean 4Proved here from basic factsFormally verified
/-- In any Mathlib `Monoid`, a left inverse and a right inverse of the same element agree:`b = b (a c) = (b a) c = c`. -/theorem inv_unique {M : Type*} [Monoid M] {a b c : M} (hb : b * a = 1) (hc : a * c = 1) : b = c := calc b = b * (a * c) := by rw [hc, mul_one] _ = b * a * c := (mul_assoc b a c).symm _ = c := by rw [hb, one_mul]