2 ||M|| This file is part of HELM, an Hypertextual, Electronic
3 ||A|| Library of Mathematics, developed at the Computer Science
4 ||T|| Department of the University of Bologna, Italy.
7 ||A|| This file is distributed under the terms of the
8 \ / GNU General Public License Version 2
10 V_______________________________________________________________ *)
12 include "arithmetics/chebyshev/bertrand.ma".
13 include "basics/lists/list.ma".
15 let rec list_divides l n ≝
18 | cons (m:nat) (tl:list nat) ⇒ orb (dividesb m n) (list_divides tl n) ].
20 lemma list_divides_true: ∀l,n. list_divides l n = true → ∃p. mem ? p l ∧ p ∣ n.
22 [#n normalize in ⊢ (%→?); #H destruct (H)
23 |#a #tl #Hind #b cases (true_or_false (dividesb a b)) #Hcase
24 [#_ %{a} % [% // | @dividesb_true_to_divides //]
25 |whd in ⊢ (??%?→?); >Hcase whd in ⊢ (??%?→?); #Htl
26 cases (Hind b Htl) #d * #memd #divd %{d} % [%2 // | //]
31 lemma list_divides_false: ∀l,n. list_divides l n = false →
32 ∀p. mem ? p l → p \ndivides n.
34 [#n #_ #p normalize in ⊢ (%→?); @False_ind
35 |#a #tl #Hind #b cases (true_or_false (dividesb a b)) #Hcase
36 [whd in ⊢ (??%?→?); >Hcase whd in ⊢ (??%?→?);
38 |whd in ⊢ (??%?→?); >Hcase whd in ⊢ (??%?→?); #Htl #d *
39 [#eqda >eqda @dividesb_false_to_not_divides //
46 let rec lprim m i acc ≝
49 | S m1 ⇒ match (list_divides acc i) with
50 [ true ⇒ lprim m1 (S i) acc
51 | false ⇒ lprim m1 (S i) (acc@[i]) ]].
53 definition list_of_primes ≝ λn. lprim n 2 [].
55 lemma lop_Strue: ∀m,i,acc. list_divides acc i =true →
56 lprim (S m) i acc = lprim m (S i) acc.
57 #m #i #acc #Hdiv normalize >Hdiv //
60 lemma lop_Sfalse: ∀m,i,acc. list_divides acc i = false →
61 lprim (S m) i acc = lprim m (S i) (acc@[i]).
62 #m #i #acc #Hdiv normalize >Hdiv %
65 lemma list_of_primes_def : ∀n. list_of_primes n = lprim n 2 [].
68 example lprim_ex: lprim 8 2 [ ] = [2; 3; 5; 7]. // qed.
70 lemma start_lprim: ∀n,m,a,acc.
71 option_hd ? (lprim n m (a::acc)) = Some ? a.
74 |#n1 #Hind #m #a #acc cases (true_or_false (list_divides (a::acc) m)) #Hc
75 [>lop_Strue [@Hind | //] |>lop_Sfalse [@Hind |//]
79 lemma start_lop: ∀n. 1 ≤ n →
80 option_hd ? (list_of_primes n) = Some ? 2.
81 #n #posn cases posn //
82 #m #lem >list_of_primes_def normalize in ⊢ (??(??%)?);
86 lemma eq_lop: ∀n. 1 ≤ n →
87 list_of_primes n = 2::(tail ? (list_of_primes n)).
88 #n #posn lapply (start_lop ? posn) cases (list_of_primes n)
89 [whd in ⊢ (??%?→?); #H destruct (H)
90 |normalize #a #l #H destruct (H) //
97 definition all_primes ≝ λl.∀p. mem nat p l → prime p.
99 definition all_below ≝ λl,n.∀p. mem nat p l → p < n.
101 definition primes_all ≝ λl,n. ∀p. prime p → p < n → mem nat p l.
103 definition primes_below ≝ λl,n.
104 all_primes l ∧ all_below l n ∧ primes_all l n.
106 lemma ld_to_prime: ∀i,acc. 1 < i →
107 primes_below acc i → list_divides acc i = false → prime i.
108 #i #acc #posi * * #Hall #Hbelow #Hcomplete #Hfalse % //
110 cut (m ≤ i)[@divides_to_le [@lt_to_le //|//]] #lemi
111 cases (le_to_or_lt_eq … lemi) [2://] #ltmi
113 cut (divides (smallest_factor m) i)
114 [@(transitive_divides … mdivi) @divides_smallest_factor_n @lt_to_le //]
115 #Hcut @(absurd … Hcut) @(list_divides_false … Hfalse) @Hcomplete
116 [@prime_smallest_factor_n // | @(le_to_lt_to_lt … ltmi) //]
119 lemma lprim_invariant: ∀n,i,acc. 1 < i →
120 primes_below acc i → primes_below (lprim n i acc) (n+i).
123 |#m #Hind #i #acc #lt1i * * #Hall #Hbelow #Hcomplete cases (true_or_false (list_divides acc i)) #Hc
124 [>(lop_Strue … Hc) whd in ⊢ (??%); >plus_n_Sm @(Hind … (le_S … lt1i)) %
125 [% [// |#p #memp @le_S @Hbelow //]
126 |#p #primep #lepi cases (le_to_or_lt_eq … (le_S_S_to_le … lepi))
128 |#eqpi @False_ind cases (list_divides_true … Hc) #q * #memq #divqi
129 cases primep #lt1p >eqpi #Hi @(absurd (q=i))
130 [@Hi [@divqi |@prime_to_lt_SO @Hall //]
131 |@lt_to_not_eq @Hbelow //
135 |>(lop_Sfalse … Hc) whd in ⊢ (??%); >plus_n_Sm @(Hind … (le_S … lt1i)) %
136 [% [#p #memp cases (mem_append ???? memp) -memp #memp
137 [@Hall //|>(mem_single ??? memp) @(ld_to_prime … Hc) // % [% // |//]]
138 |#p #memp cases (mem_append ???? memp) -memp #memp
139 [@le_S @Hbelow // |<(mem_single ??? memp) @le_n]]
140 |#p #memp #ltp cases (le_to_or_lt_eq … (le_S_S_to_le … ltp))
141 [#ltpi @mem_append_l1 @Hcomplete //|#eqpi @mem_append_l2 <eqpi % //]
147 lemma primes_below2: primes_below [] 2.
148 %[%[#p @False_ind|#p @False_ind]
149 |#p #primep #ltp2 @False_ind @(absurd … ltp2) @le_to_not_lt
154 lemma primes_below_lop: ∀n. primes_below (list_of_primes n) (n+2).
155 #n @lprim_invariant //
159 theorem primes_below_to_bertrand:
160 ∀pm,l.prime pm → primes_below l (S pm) →
161 (∀p. mem ? p l → 2 < p → ∃pp. mem ? pp l ∧ pp < p ∧ p ≤ 2*pp)
162 → ∀n.0 < n → n < pm → bertrand n.
163 #pm #l #primepm * * #Hall #Hbelow #Hcomplete #H #n #posn #ltn
164 cases (min_prim n) #p1 * * #ltnp1 #primep1 #Hmin
166 cases(le_to_or_lt_eq ? ? (prime_to_lt_SO ? primep1)) #Hp1
168 [#x * * #memxl #ltxp1 #Hp1 @(transitive_le … Hp1) @monotonic_le_times_r
170 |@Hcomplete [//] @le_S_S @not_lt_to_le % #ltpm @(absurd ? ltn)
171 @le_to_not_lt @Hmin //
173 |<Hp1 >(times_n_1 2) in ⊢ (?%?); @monotonic_le_times_r //
184 leb (S hd) hd1 ∧ leb hd1 (2*hd) ∧ checker tl
188 lemma checker_ab: ∀a,b,l.checker (a::b::l) =
189 (leb (S a) b ∧ leb b (2*a) ∧ checker (b::l)).
192 lemma checker_abl: ∀a,b,l.checker (a::b::l) = true →
193 a < b ∧ b ≤ 2*a ∧ checker (b::l) = true.
194 #a #b #l >checker_ab #H
195 % [% [@leb_true_to_le @(andb_true_l … (andb_true_l … H))
196 |@leb_true_to_le @(andb_true_r … (andb_true_l … H))
202 theorem checker_spec: ∀tl,a,l. checker l = true → l = a::tl →
203 ∀p. mem ? p tl → ∃pp. mem nat pp l ∧ pp < p ∧ p ≤ 2*pp.
205 [#a #l #_ #_ #p whd in ⊢ (%→?); @False_ind
206 |#b #tl #Hind #a #l #Hc #Hl #p #Hmem >Hl in Hc;
207 #Hc cases(checker_abl … Hc) *
208 #ltab #leb #Hc2 cases Hmem #Hc
209 [>Hc -Hc %{a} % [ % [ % % |//]|//]
210 |cases(Hind b (b::tl) Hc2 (refl …) ? Hc) #pp * * #Hmemnp #ltpp #lepp
211 %{pp} % [ % [ %2 //|//]|//]
216 lemma bertrand_down : ∀n.O < n → n ≤ 2^8 → bertrand n.
218 cut (∃it.it=2^8) [%{(2^8)} %] * #it #itdef
219 lapply(primes_below_lop … it) * * #Hall #Hbelow #Hcomplete
220 @(primes_below_to_bertrand (S it) (list_of_primes it) … posn)
221 [@primeb_true_to_prime >itdef %
222 |>(plus_n_O it) in ⊢ (??%); >plus_n_Sm >plus_n_Sm @primes_below_lop
223 |#p #memp #lt2p @(checker_spec (tail ? (list_of_primes it)) 2 (list_of_primes it))
225 |>itdef @eq_lop @lt_O_S
226 |>eq_lop in memp; [2:>itdef @lt_O_S] *
227 [#eqp2 @False_ind @(absurd ? lt2p) @le_to_not_lt >eqp2 @le_n
236 ∀n. O < n → bertrand n.
237 #n #posn elim (decidable_le n 256)
239 |#len @bertrand_up @lt_to_le @not_le_to_lt @len]