Skip to content
The Lumenary

Formal mathematics laboratory

Lumenary.Fractions

Fractions and decimals

Formal library

  • FracstructureDefinitionNo axioms
    FracLean 4Formally verified
    /-- A fraction `num / den` of whole numbers. The denominator must not be `0`: it says how
    many equal parts the whole is cut into. -/
    structure Frac where
      /-- The numerator: how many parts we take. -/
      num : Nat
      /-- The denominator: how many equal parts make one whole. -/
      den : Nat
      /-- A whole cannot be cut into `0` parts. -/
      den_pos : 0 < den
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • fracdefDefinitionNo axioms
    fracLean 4Formally verified
    /-- `frac a b` is the fraction `a / b`. When `b` is a numeral, Lean checks `0 < b` by itself. -/
    def frac (a b : Nat) (h : 0 < b := by decide) : Frac := ⟨a, b, h⟩
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • Frac.EquivdefDefinitionNo axioms
    EquivLean 4Formally verified
    /-- `a / b` and `c / d` are **equivalent** (they are the same number) when `a × d = c × b`:
    written over the common denominator `b × d`, they have the same numerator. -/
    def Frac.Equiv (x y : Frac) : Prop := x.num * y.den = y.num * x.den
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • instHasEquivinstanceDefinitionNo axioms
    instHasEquivLean 4Formally verified
    /-- Lets us write `x ≈ y` for "`x` and `y` are equivalent fractions". -/
    instance instHasEquiv : HasEquiv Frac := ⟨Frac.Equiv⟩
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • instDecidableEquivinstanceDefinitionNo axioms
    instDecidableEquivLean 4Formally verified
    /-- Equivalence of two particular fractions can be decided by multiplying, so `decide` can
    check statements such as `frac 2 4 ≈ frac 1 2`. -/
    instance instDecidableEquiv (x y : Frac) : Decidable (x ≈ y) :=
      inferInstanceAs (Decidable (x.num * y.den = y.num * x.den))
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • scale_equivtheoremProved here from basic factspropext
    scale_equivLean 4Proved here from basic factsFormally verified
    /-- Multiplying the numerator and the denominator by the same `n > 0` gives an equivalent
    fraction: `(n × a) / (n × b) = a / b`. Cutting every part into `n` smaller parts makes `n`
    times as many parts, each `n` times smaller. -/
    theorem scale_equiv (a b n : Nat) (hb : 0 < b) (hn : 0 < n) :
        frac (n * a) (n * b) (Nat.mul_pos hn hb) ≈ frac a b hb := by
      -- Unfolded, the claim is `(n × a) × b = a × (n × b)`: reorder the product.
      change n * a * b = a * (n * b)
      rw [Nat.mul_comm n a, Nat.mul_assoc]
    Axioms used: propextformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • equiv_refltheoremProved here from basic factsNo axioms
    equiv_reflLean 4Proved here from basic factsFormally verified
    /-- Every fraction is equivalent to itself. -/
    theorem equiv_refl (x : Frac) : x ≈ x := rfl
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • equiv_symmtheoremProved here from basic factsNo axioms
    equiv_symmLean 4Proved here from basic factsFormally verified
    /-- If `x` is equivalent to `y`, then `y` is equivalent to `x`. -/
    theorem equiv_symm {x y : Frac} (h : x ≈ y) : y ≈ x := h.symm
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • equiv_transtheoremProved here from basic factspropext, Quot.sound
    equiv_transLean 4Proved here from basic factsFormally verified
    /-- If `a/b ≈ c/d` and `c/d ≈ e/f`, then `a/b ≈ e/f`. We multiply out, use both facts, and
    cancel the factor `d`, which is allowed because `d > 0` (`Nat.eq_of_mul_eq_mul_right`).
    `ac_rfl` reorders a product; multiplication is commutative and associative. -/
    theorem equiv_trans {x y z : Frac} (h1 : x ≈ y) (h2 : y ≈ z) : x ≈ z := by
      obtain ⟨a, b, _⟩ := x
      obtain ⟨c, d, hd⟩ := y
      obtain ⟨e, f, _⟩ := z
      change a * d = c * b at h1
      change c * f = e * d at h2
      change a * f = e * b
      apply Nat.eq_of_mul_eq_mul_right hd
      calc a * f * d = (a * d) * f := by ac_rfl
        _ = (c * b) * f := by rw [h1]
        _ = (c * f) * b := by ac_rfl
        _ = (e * d) * b := by rw [h2]
        _ = e * b * d := by ac_rfl
    Axioms used: propext, Quot.soundformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • two_quarterstheoremProved here from basic factsNo axioms
    two_quartersLean 4Proved here from basic factsFormally verified
    /-- `2/4`, `3/6` and `50/100` are all equivalent to `1/2`. -/
    theorem two_quarters : frac 2 4 ≈ frac 1 2 ∧ frac 3 6 ≈ frac 1 2 ∧ frac 50 100 ≈ frac 1 2 := by
      decide
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • Frac.LtdefDefinitionNo axioms
    LtLean 4Formally verified
    /-- `a / b < c / d` when `a × d < c × b`: over the common denominator `b × d`, the first
    numerator is smaller. -/
    def Frac.Lt (x y : Frac) : Prop := x.num * y.den < y.num * x.den
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • instLTinstanceDefinitionNo axioms
    instLTLean 4Formally verified
    /-- Lets us write `x < y` for fractions. -/
    instance instLT : LT Frac := ⟨Frac.Lt⟩
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • instDecidableLtinstanceDefinitionNo axioms
    instDecidableLtLean 4Formally verified
    /-- Comparing two particular fractions is a calculation, so `decide` can do it. -/
    instance instDecidableLt (x y : Frac) : Decidable (x < y) :=
      inferInstanceAs (Decidable (x.num * y.den < y.num * x.den))
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • same_den_lttheoremProved here from basic factspropext, Classical.choice, Quot.sound
    same_den_ltLean 4Proved here from basic factsFormally verified
    /-- With the same denominator, the fraction with the bigger numerator is bigger:
    `a / b < c / b` exactly when `a < c` (same-sized pieces, so compare how many). -/
    theorem same_den_lt (a c b : Nat) (hb : 0 < b) : frac a b hb < frac c b hb ↔ a < c := by
      change a * b < c * b ↔ a < c
      exact Nat.mul_lt_mul_right hb
    Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • bigger_den_smaller_piecetheoremProved here from basic factsNo axioms
    bigger_den_smaller_pieceLean 4Proved here from basic factsFormally verified
    /-- A bigger denominator means a *smaller* piece: if `b < d` then `1/d < 1/b`.
    Cutting the whole into more parts makes each part smaller. -/
    theorem bigger_den_smaller_piece (b d : Nat) (hb : 0 < b) (hd : 0 < d) (h : b < d) :
        frac 1 d hd < frac 1 b hb := by
      change 1 * b < 1 * d
      rw [Nat.one_mul, Nat.one_mul]
      exact h
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • three_quarters_gt_two_thirdstheoremProved here from basic factsNo axioms
    three_quarters_gt_two_thirdsLean 4Proved here from basic factsFormally verified
    /-- `2/3 < 3/4`, because over the common denominator `12` they are `8/12` and `9/12`. -/
    theorem three_quarters_gt_two_thirds : frac 2 3 < frac 3 4 := by decide
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • Frac.adddefDefinitionNo axioms
    addLean 4Formally verified
    /-- `a/b + c/d = (a × d + c × b) / (b × d)`: rewrite both fractions over the common
    denominator `b × d`, then add the numerators. -/
    def Frac.add (x y : Frac) : Frac :=
      ⟨x.num * y.den + y.num * x.den, x.den * y.den, Nat.mul_pos x.den_pos y.den_pos⟩
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • half_plus_thirdtheoremProved here from basic factsNo axioms
    half_plus_thirdLean 4Proved here from basic factsFormally verified
    /-- `1/2 + 1/3 = 5/6`. The rule gives `(1 × 3 + 1 × 2) / (2 × 3) = 5/6`. -/
    theorem half_plus_third : (frac 1 2).add (frac 1 3) ≈ frac 5 6 := by decide
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • half_plus_third_not_two_fifthstheoremProved here from basic factsNo axioms
    half_plus_third_not_two_fifthsLean 4Proved here from basic factsFormally verified
    /-- Adding tops and bottoms is wrong: `1/2 + 1/3` is **not** `2/5`. In fact `2/5` is smaller
    than `1/2`, and a sum of two positive fractions must be bigger than each of them. -/
    theorem half_plus_third_not_two_fifths :
        ¬ ((frac 1 2).add (frac 1 3) ≈ frac 2 5) ∧ frac 2 5 < frac 1 2 := by decide
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • add_respects_equivtheoremProved here from basic factspropext, Quot.sound
    add_respects_equivLean 4Proved here from basic factsFormally verified
    /-- The answer to an addition does not depend on which equivalent fractions we use:
    if `x ≈ x'` and `y ≈ y'` then `x + y ≈ x' + y'`. So adding `2/4 + 1/3` gives the same number
    as `1/2 + 1/3`. The proof multiplies out and uses the two cross-multiplication facts. -/
    theorem add_respects_equiv {x x' y y' : Frac} (hx : x ≈ x') (hy : y ≈ y') :
        x.add y ≈ x'.add y' := by
      obtain ⟨a, b, _⟩ := x
      obtain ⟨a', b', _⟩ := x'
      obtain ⟨c, d, _⟩ := y
      obtain ⟨c', d', _⟩ := y'
      change a * b' = a' * b at hx
      change c * d' = c' * d at hy
      change (a * d + c * b) * (b' * d') = (a' * d' + c' * b') * (b * d)
      calc (a * d + c * b) * (b' * d') = (a * b') * (d * d') + (c * d') * (b * b') := by
              rw [Nat.add_mul]; ac_rfl
        _ = (a' * b) * (d * d') + (c' * d) * (b * b') := by rw [hx, hy]
        _ = (a' * d' + c' * b') * (b * d) := by rw [Nat.add_mul]; ac_rfl
    Axioms used: propext, Quot.soundformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • Frac.natMuldefDefinitionNo axioms
    natMulLean 4Formally verified
    /-- A whole number times a fraction: `n × (a / b) = (n × a) / b`, that is, `n` groups of
    `a` pieces of size `1/b`. -/
    def Frac.natMul (n : Nat) (x : Frac) : Frac := ⟨n * x.num, x.den, x.den_pos⟩
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • four_times_two_thirdstheoremProved here from basic factsNo axioms
    four_times_two_thirdsLean 4Proved here from basic factsFormally verified
    /-- `4 × 2/3 = 8/3`, which is `2 2/3`: eight thirds, or two wholes and two thirds. -/
    theorem four_times_two_thirds : (frac 2 3).natMul 4 ≈ frac 8 3 := by decide
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • decimals_comparetheoremProved here from basic factsNo axioms
    decimals_compareLean 4Proved here from basic factsFormally verified
    /-- `0.25 < 0.3`: as fractions, `25/100 < 3/10`, because `3/10 = 30/100`. -/
    theorem decimals_compare : frac 25 100 < frac 3 10 ∧ frac 3 10 ≈ frac 30 100 := by decide
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • eighth_as_decimaltheoremProved here from basic factsNo axioms
    eighth_as_decimalLean 4Proved here from basic factsFormally verified
    /-- `1/8 = 125/1000 = 0.125` and `3/8 = 375/1000 = 0.375`: since `8 × 125 = 1000`,
    eighths can be written as thousandths. -/
    theorem eighth_as_decimal : frac 1 8 ≈ frac 125 1000 ∧ frac 3 8 ≈ frac 375 1000 := by decide
    Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • ten_pow_mod_threetheoremProved here from basic factspropext
    ten_pow_mod_threeLean 4Proved here from basic factsFormally verified
    /-- Every power of ten leaves remainder `1` when divided by `3`: `10 = 9 + 1`,
    `100 = 99 + 1`, `1000 = 999 + 1`, … Proved by induction, using that the remainder of a
    product depends only on the remainders of the factors (`Nat.mul_mod`). -/
    theorem ten_pow_mod_three (k : Nat) : 10 ^ k % 3 = 1 := by
      induction k with
      | zero => rfl
      | succ n ih => rw [Nat.pow_succ, Nat.mul_mod, ih]
    Axioms used: propextformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • third_not_terminatingtheoremProved here from basic factspropext
    third_not_terminatingLean 4Proved here from basic factsFormally verified
    /-- `1/3` has no finite decimal: there are no `m` and `k` with `1/3 = m / 10^k`.
    By cross-multiplication that would mean `10^k = 3 × m`, a multiple of `3`, but every power
    of ten leaves remainder `1` when divided by `3`. -/
    theorem third_not_terminating (m k : Nat) :
        ¬ (frac 1 3 ≈ frac m (10 ^ k) (Nat.pow_pos (by decide))) := by
      intro h
      change 1 * 10 ^ k = m * 3 at h
      have hrem : 10 ^ k % 3 = m * 3 % 3 := by rw [← h, Nat.one_mul]
      rw [ten_pow_mod_three, Nat.mul_mod_left] at hrem
      -- `hrem : 1 = 0`, which is false.
      exact absurd hrem (by decide)
    Axioms used: propextformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • rat_cross_multheoremApplies a library theorempropext, Classical.choice, Quot.sound
    rat_cross_mulLean 4Applies a library theoremFormally verified
    /-- In Lean's own type of fractions `Rat`, `a/b = c/d` exactly when `a × d = c × b`
    (for nonzero `b`, `d`). This applies core Lean's theorem `Rat.divInt_eq_divInt_iff`. -/
    theorem rat_cross_mul {a b c d : Int} (hb : b ≠ 0) (hd : d ≠ 0) :
        (a : Rat) / b = c / d ↔ a * d = c * b := by
      rw [← Rat.divInt_eq_div, ← Rat.divInt_eq_div]
      exact Rat.divInt_eq_divInt_iff hb hd
    Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Fractions.leanTry it in the Lean web editor
  • rat_examplestheoremProved here from basic factspropext, Classical.choice, Quot.sound
    rat_examplesLean 4Proved here from basic factsFormally verified
    /-- The lesson's examples in Lean's `Rat`: `1/2 + 1/3 = 5/6`, `1/2 + 1/3 ≠ 2/5`,
    `0.25 < 0.3` and `0.125 = 1/8`. The kernel evaluates both sides exactly. -/
    theorem rat_examples :
        (1 : Rat) / 2 + 1 / 3 = 5 / 6 ∧ (1 : Rat) / 2 + 1 / 3 ≠ 2 / 5 ∧
          (0.25 : Rat) < 0.3 ∧ (0.125 : Rat) = 1 / 8 := by
      decide +kernel
    Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/Fractions.leanTry it in the Lean web editor

Formal exercises

Each exercise contains a sorry for you to replace. Open it in the Lean web editor, or clone the repository and run lake build.

bigger_den_smaller_piecesorry × 1Try it in the Lean web editor
/-- Show that a bigger denominator gives a smaller unit fraction: if `b < d` then `1/d < 1/b`.
Hint: `change 1 * b < 1 * d` unfolds the comparison; then `Nat.one_mul` simplifies. -/
theorem bigger_den_smaller_piece (b d : Nat) (hb : 0 < b) (hd : 0 < d) (h : b < d) :
    frac 1 d hd < frac 1 b hb := by
  sorry
Show the compiled solution
bigger_den_smaller_pieceLean 4Proved here from basic factsFormally verified
/-- A bigger denominator means a *smaller* piece: if `b < d` then `1/d < 1/b`.
Cutting the whole into more parts makes each part smaller. -/
theorem bigger_den_smaller_piece (b d : Nat) (hb : 0 < b) (hd : 0 < d) (h : b < d) :
    frac 1 d hd < frac 1 b hb := by
  change 1 * b < 1 * d
  rw [Nat.one_mul, Nat.one_mul]
  exact h
Axioms used: No axiomsformal/Lumenary/Fractions.leanTry it in the Lean web editor
ten_pow_mod_threesorry × 1Try it in the Lean web editor
/-- Show that every power of ten leaves remainder `1` when divided by `3`.
Hint: induction on `k`; in the step use `Nat.pow_succ` and `Nat.mul_mod`. -/
theorem ten_pow_mod_three (k : Nat) : 10 ^ k % 3 = 1 := by
  sorry
Show the compiled solution
ten_pow_mod_threeLean 4Proved here from basic factsFormally verified
/-- Every power of ten leaves remainder `1` when divided by `3`: `10 = 9 + 1`,
`100 = 99 + 1`, `1000 = 999 + 1`, … Proved by induction, using that the remainder of a
product depends only on the remainders of the factors (`Nat.mul_mod`). -/
theorem ten_pow_mod_three (k : Nat) : 10 ^ k % 3 = 1 := by
  induction k with
  | zero => rfl
  | succ n ih => rw [Nat.pow_succ, Nat.mul_mod, ih]
Axioms used: propextformal/Lumenary/Fractions.leanTry it in the Lean web editor