Skip to content

Commit 82ecf95

Browse files
committed
feat(Tactic/Simproc/Divisors): add simprocs to compute the divisors of a natural number. (#27101)
This PR continues the work from #23026. Original PR: #23026
1 parent 75d6f9e commit 82ecf95

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5995,6 +5995,7 @@ import Mathlib.Tactic.Set
59955995
import Mathlib.Tactic.SetLike
59965996
import Mathlib.Tactic.SimpIntro
59975997
import Mathlib.Tactic.SimpRw
5998+
import Mathlib.Tactic.Simproc.Divisors
59985999
import Mathlib.Tactic.Simproc.ExistsAndEq
59996000
import Mathlib.Tactic.Simproc.Factors
60006001
import Mathlib.Tactic.Simps.Basic

Mathlib/Tactic.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ import Mathlib.Tactic.Set
248248
import Mathlib.Tactic.SetLike
249249
import Mathlib.Tactic.SimpIntro
250250
import Mathlib.Tactic.SimpRw
251+
import Mathlib.Tactic.Simproc.Divisors
251252
import Mathlib.Tactic.Simproc.ExistsAndEq
252253
import Mathlib.Tactic.Simproc.Factors
253254
import Mathlib.Tactic.Simps.Basic
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/-
2+
Copyright (c) 2025 Paul Lezeau. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Paul Lezeau, Bhavik Mehta
5+
-/
6+
import Mathlib.NumberTheory.Divisors
7+
import Mathlib.Util.Qq
8+
9+
/-! # Divisor Simprocs
10+
11+
This file implements (d)simprocs to compute various objects related to divisors:
12+
- `Nat.divisorsEq`: computes `Nat.divisors n` for explicit values of `n`
13+
- `Nat.properDivisorsEq`: computes `Nat.properDivisors n` for explicit values of `n`
14+
15+
-/
16+
17+
open Lean Meta Simp Qq
18+
19+
/-- The `Nat.divisorsEq` computes the finset `Nat.divisors n` when `n` is a natural number
20+
literal. For instance, this simplifies `Nat.divisors 6` to `{1, 2, 3, 6}`. -/
21+
dsimproc_decl Nat.divisors_ofNat (Nat.divisors _) := fun e => do
22+
unless e.isAppOfArity `Nat.divisors 1 do return .continue
23+
let some n ← fromExpr? e.appArg! | return .continue
24+
return .done <| mkSetLiteralQ q(Finset ℕ) <| ((unsafe n.divisors.val.unquot).map mkNatLit)
25+
26+
/-- Compute the finset `Nat.properDivisorsEq n` when `n` is a numeral.
27+
For instance, this simplifies `Nat.properDivisorsEq 12` to `{1, 2, 3, 4, 6}`. -/
28+
dsimproc_decl Nat.properDivisors_ofNat (Nat.properDivisors _) := fun e => do
29+
unless e.isAppOfArity `Nat.properDivisors 1 do return .continue
30+
let some n ← fromExpr? e.appArg! | return .continue
31+
return unsafe .done <| mkSetLiteralQ q(Finset ℕ) <|
32+
((unsafe n.properDivisors.val.unquot).map mkNatLit)

MathlibTest/Simproc/Divisors.lean

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import Mathlib.Tactic.Simproc.Divisors
2+
import Mathlib.NumberTheory.Primorial
3+
4+
open Nat
5+
6+
example :
7+
Nat.divisors 1710 = {1, 2, 3, 5, 6, 9, 10, 15, 18, 19, 30, 38, 45, 57,
8+
90, 95, 114, 171, 190, 285, 342, 570, 855, 1710} := by
9+
simp only [Nat.divisors_ofNat]
10+
11+
example : Nat.divisors 57 = {1, 3, 19, 57} := by
12+
simp only [Nat.divisors_ofNat]
13+
14+
example : (Nat.divisors <| 6 !).card = 30 := by
15+
simp [Nat.divisors_ofNat, Nat.factorial_succ]
16+
17+
example : (Nat.divisors <| primorial 12).card = 32 := by
18+
--TODO(Paul-Lez): seems like we need a norm_num extension for computing `primorial`!
19+
have : primorial 12 = 2310 := rfl
20+
simp [Nat.divisors_ofNat, this]
21+
22+
example : (Nat.divisors <| 2^13).card = 14 := by
23+
simp [Nat.divisors_ofNat]
24+
25+
example : 2 ≤ Finset.card (Nat.divisors 3) := by
26+
simp [Nat.divisors_ofNat]
27+
28+
/-- error: simp made no progress -/
29+
#guard_msgs in
30+
example (n : ℕ) (hn : n ≠ 0) : 1 ≤ Finset.card (Nat.divisors n) := by
31+
simp only [Nat.divisors_ofNat]
32+
33+
example :
34+
Nat.properDivisors 1710 = {1, 2, 3, 5, 6, 9, 10, 15, 18, 19, 30, 38, 45, 57,
35+
90, 95, 114, 171, 190, 285, 342, 570, 855} := by
36+
simp only [Nat.properDivisors_ofNat]
37+
38+
example : Nat.properDivisors 57 = {1, 3, 19} := by
39+
simp only [Nat.properDivisors_ofNat]
40+
41+
example : 2 ≤ Finset.card (Nat.divisors 3) := by
42+
simp [Nat.divisors_ofNat]

0 commit comments

Comments
 (0)