11module
22
3- def is_simple_power : Unit :=
4- ()
3+ public section
4+
5+ /-!
6+ ## Implementation
7+ -/
8+
9+ private def isSimplePowerHelper (x n : Nat) (hx : 0 < x) (hn : 1 < n) : Bool :=
10+ if _ : x = 1 then
11+ true
12+ else if hdvd : n ∣ x then
13+ isSimplePowerHelper (x / n) n (Nat.pos_of_dvd_of_pos (Nat.div_dvd_of_dvd hdvd) hx) hn
14+ else
15+ false
16+ termination_by x
17+ decreasing_by
18+ rw [Nat.div_lt_iff_lt_mul (by grind), Nat.lt_mul_iff_one_lt_right hx]
19+ grind
20+
21+ def isSimplePower (x n : Nat) : Bool :=
22+ if _ : n = 0 then
23+ x ≤ 1
24+ else if _ : n = 1 then
25+ x = 1
26+ else if _ : x = 0 then
27+ false
28+ else
29+ isSimplePowerHelper x n (by grind) (by grind)
30+
31+ /-!
32+ ## Tests
33+ -/
34+
35+ example : isSimplePower 16 2 = true := by native_decide
36+ example : isSimplePower 143214 16 = false := by native_decide
37+ example : isSimplePower 4 2 = true := by native_decide
38+ example : isSimplePower 9 3 = true := by native_decide
39+ example : isSimplePower 16 4 = true := by native_decide
40+ example : isSimplePower 24 2 = false := by native_decide
41+ example : isSimplePower 128 4 = false := by native_decide
42+ example : isSimplePower 12 6 = false := by native_decide
43+ example : isSimplePower 1 1 = true := by native_decide
44+ example : isSimplePower 1 12 = true := by native_decide
45+
46+ /-!
47+ ## Verification
48+ -/
49+
50+ private theorem isSimplePowerHelper_iff :
51+ isSimplePowerHelper x n hx hn ↔ ∃ i, n ^ i = x := by
52+ fun_induction isSimplePowerHelper x n hx hn
53+ · simp
54+ · rename_i ih
55+ rw [ih]
56+ constructor
57+ · rintro ⟨i, hi⟩
58+ refine ⟨i + 1 , ?_⟩
59+ simp only [Nat.pow_add, Nat.pow_one]
60+ rw [hi, Nat.div_mul_cancel ‹_›]
61+ · rintro ⟨i, hi⟩
62+ match i with
63+ | 0 => grind
64+ | i + 1 =>
65+ refine ⟨i, ?_⟩
66+ rw [Nat.eq_div_iff_mul_eq_left (by grind) ‹_›]
67+ grind
68+ · simp only [Bool.false_eq_true, false_iff, not_exists]
69+ intro i
70+ match i with
71+ | 0 => grind
72+ | i' + 1 =>
73+ have := Nat.dvd_mul_left n (n ^ i')
74+ grind
75+
76+ theorem isSimplePower_iff :
77+ isSimplePower x n ↔ ∃ i, n ^ i = x := by
78+ fun_cases isSimplePower
79+ · rename_i hn
80+ cases hn
81+ constructor
82+ · intro h
83+ match x with
84+ | 0 => exact ⟨1 , by grind⟩
85+ | 1 => exact ⟨0 , by grind⟩
86+ | _ + 2 => grind
87+ · rintro ⟨i, hi⟩
88+ match i with
89+ | 0 | _ + 1 => grind
90+ · simp_all [eq_comm]
91+ · simp_all
92+ · apply isSimplePowerHelper_iff
593
694/-!
795## Prompt
@@ -25,12 +113,12 @@ def is_simple_power(x, n):
25113## Canonical solution
26114
27115```python3
28- if (n == 1):
29- return (x == 1)
116+ if (n == 1):
117+ return (x == 1)
30118 power = 1
31- while (power < x):
32- power = power * n
33- return (power == x)
119+ while (power < x):
120+ power = power * n
121+ return (power == x)
34122```
35123
36124## Tests
@@ -53,4 +141,4 @@ def check(candidate):
53141 assert candidate(1, 12)==True, "This prints if this assert fails 2 (also good for debugging!)"
54142
55143```
56- -/
144+ -/
0 commit comments