Advertisement
Guest User

Current state

a guest
Sep 25th, 2022
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 31.00 KB | None | 0 0
  1. From Coq Require Import Arith.
  2. From Coq Require Import Wf_nat.
  3. From Coq Require Import ZArith.
  4. From Coq Require Import Peano_dec.
  5. From Coq Require Import ZArith_dec.
  6.  
  7. From Coqprime Require Import NatAux ZCAux ZCmisc ZSum Pmod Ppow.
  8.  
  9. (** * Compatibility lemmas (provisional) *)
  10.  
  11. (** more general than [NatAux] lemma *)
  12.  
  13. Definition CoPrime (a b : nat) := (* done *)
  14. Zis_gcd (Z.of_nat a) (Z.of_nat b) 1%Z.
  15.  
  16. Lemma coPrimeSym (* done *) : forall a b : nat, CoPrime a b -> CoPrime b a.
  17. Proof. intros. now apply Zis_gcd_sym. Qed.
  18.  
  19. Definition LinComb (c x y: Z) := exists a b: Z, c = x * a + y * b.
  20.  
  21. Lemma gcd_lincomb_nat:
  22. forall (x y d : nat),
  23. (x > 0)%nat ->
  24. Zis_gcd (Z_of_nat x) (Z_of_nat y) (Z_of_nat d) ->
  25. LinComb (Z_of_nat d) (Z_of_nat x) (Z_of_nat y).
  26. Proof.
  27. Admitted.
  28.  
  29. Lemma coPrimeMult : (* done *)
  30. forall a b c : nat, CoPrime a b -> divide a (b * c) -> divide a c.
  31. Proof.
  32. intros ? ? ? H H0; unfold CoPrime in H.
  33. induction a as [| a _].
  34. - (* a = 0 *)
  35. induction H0 as (x, H0).
  36. cbn in H0. rewrite Nat.eq_mul_0 in H0. (* b = O \/ c = O *)
  37. destruct H0 as [H1 | H1].
  38. + rewrite H1 in H. simpl in H.
  39. inversion H. clear H H0 H1 H2.
  40. assert (2 | 0). { exists 0. auto. }
  41. destruct (H3 _ H H). nia.
  42. + rewrite H1. exists 0%nat. auto.
  43. - assert (H1: (S a > 0)%nat) by apply gt_Sn_O.
  44. destruct (gcd_lincomb_nat _ _ 1 H1 H) as [x [x0 H2]].
  45. destruct H0 as [x1 H0].
  46. assert (1 * Z.of_nat c = Z_of_nat (S a) * (x * Z.of_nat c + Z.of_nat x1 * x0)).
  47. { rewrite (Z.mul_comm (Z.of_nat (S a))).
  48. rewrite Z.mul_add_distr_r.
  49. rewrite (Z.mul_comm (x * Z.of_nat c)).
  50. rewrite (Z.mul_comm (Z.of_nat x1 * x0)).
  51. repeat rewrite Z.mul_assoc.
  52. rewrite <- Znat.inj_mult.
  53. rewrite <- H0.
  54. rewrite Znat.inj_mult.
  55. rewrite (Z.mul_comm (Z.of_nat b)).
  56. rewrite <- (Z.mul_assoc (Z.of_nat c)).
  57. rewrite (Z.mul_comm (Z.of_nat c)).
  58. rewrite <- Z.mul_add_distr_r.
  59. now rewrite <- H2. }
  60. rewrite Zmult_1_l in H3.
  61. assert (Z.divide (Z.of_nat (S a)) (Z.of_nat c)).
  62. { exists (x * Z.of_nat c + Z.of_nat x1 * x0).
  63. now rewrite Z.mul_comm at 1. }
  64. clear H2 H3 x x0.
  65. rewrite <- (Znat.Zabs2Nat.id (S a)).
  66. rewrite <- (Znat.Zabs2Nat.id c).
  67. repeat rewrite Zabs2Nat.id. destruct H4. exists (Z.to_nat x). lia.
  68. Qed.
  69.  
  70. Lemma coPrimeMult2 : (* done *)
  71. forall a b c : nat,
  72. CoPrime a b -> divide a c -> divide b c -> divide (a * b) c.
  73. Proof.
  74. intros a b c H H0 [x H1].
  75. assert (divide a x).
  76. { eapply coPrimeMult with (1:= H); now rewrite <- H1. }
  77. destruct H2 as [x0 H2]; exists x0; subst; ring.
  78. Qed.
  79.  
  80. Lemma ltgt1 (* done *): forall a b : nat, (a < b -> b > 0)%nat. (* done *)
  81. Proof. lia. Qed.
  82.  
  83. Lemma minus1 (* done *) : forall a b c : Z, (a - c)%Z = (b - c)%Z -> a = b.
  84. Proof. lia. Qed.
  85.  
  86. Lemma chRem2 : (* done *)
  87. forall b1 r1 b2 r2 q : Z,
  88. (0 <= r1)%Z ->
  89. (0 <= r2)%Z ->
  90. (r1 < q)%Z -> (r2 < q)%Z -> (b1 * q + r1)%Z = (b2 * q + r2)%Z ->
  91. r1 = r2.
  92. Proof.
  93. intros * H H0 H1 H2 H3.
  94. assert (H4: ((b1 - b2) * q)%Z = (r2 - r1)%Z) by
  95. (rewrite Z.mul_sub_distr_r; lia).
  96. induction (Zle_or_lt 0 (b1 - b2)) as [H5 | H5].
  97. induction (Zle_lt_or_eq _ _ H5) as [H6 | H6].
  98. assert (H7: (1 <= b1 - b2)%Z).
  99. { replace 1%Z with (Z.succ 0).
  100. apply Zlt_le_succ.
  101. assumption.
  102. auto.
  103. }
  104. assert (H8:(q <= r2 - r1)%Z).
  105. { replace q with (1 * q)%Z.
  106. rewrite <- H4.
  107. apply Zmult_le_compat_r.
  108. assumption.
  109. eapply Z.le_trans.
  110. apply H.
  111. apply Zlt_le_weak.
  112. assumption.
  113. apply Zmult_1_l.
  114. }
  115. set (A1 := Zplus_lt_le_compat r2 q (- r1) 0 H2) in *.
  116. assert (H9:(r2 - r1 < q)%Z).
  117. { replace q with (q + 0)%Z.
  118. unfold Zminus in |- *.
  119. apply A1.
  120. eapply (fun a b : Z => Zplus_le_reg_l a b r1).
  121. rewrite Zplus_opp_r.
  122. rewrite <- Zplus_0_r_reverse.
  123. assumption.
  124. rewrite <- Zplus_0_r_reverse.
  125. reflexivity.
  126. }
  127. elim (Zle_not_lt q (r2 - r1)).
  128. assumption.
  129. assumption.
  130. rewrite <- H6 in H4.
  131. rewrite Z.mul_comm in H4.
  132. rewrite <- Zmult_0_r_reverse in H4.
  133. rewrite <- (Zplus_opp_r r2) in H4.
  134. unfold Zminus in H4.
  135. apply Z.opp_inj.
  136. symmetry in |- *.
  137. eapply Zplus_reg_l.
  138. apply H4.
  139. assert (H6:(1 <= b2 - b1)%Z).
  140. { replace 1%Z with (Z.succ 0).
  141. apply Zlt_le_succ.
  142. apply (Zplus_lt_reg_l 0 (b2 - b1) b1).
  143. rewrite Zplus_minus.
  144. rewrite <- Zplus_0_r_reverse.
  145. apply (Zplus_lt_reg_l b1 b2 (- b2)).
  146. rewrite Zplus_opp_l.
  147. rewrite Zplus_comm.
  148. unfold Zminus in H5.
  149. assumption.
  150. auto.
  151. }
  152. assert (H7: ((b2 - b1) * q)%Z = (r1 - r2)%Z) by
  153. ( rewrite Z.mul_sub_distr_r ; lia ).
  154. assert (H8:(q <= r1 - r2)%Z).
  155. { replace q with (1 * q)%Z.
  156. rewrite <- H7.
  157. apply Zmult_le_compat_r.
  158. assumption.
  159. eapply Z.le_trans.
  160. apply H.
  161. apply Zlt_le_weak.
  162. assumption.
  163. apply Zmult_1_l.
  164. }
  165. set (A1 := Zplus_lt_le_compat r1 q (- r2) 0 H1) in *.
  166. assert (H9:(r1 - r2 < q)%Z).
  167. { replace q with (q + 0)%Z.
  168. unfold Zminus in |- *.
  169. apply A1.
  170. eapply (fun a b : Z => Zplus_le_reg_l a b r2).
  171. rewrite Zplus_opp_r.
  172. rewrite <- Zplus_0_r_reverse.
  173. assumption.
  174. rewrite <- Zplus_0_r_reverse.
  175. reflexivity.
  176. }
  177. elim (Zle_not_lt q (r1 - r2)).
  178. assumption.
  179. assumption.
  180. Qed.
  181.  
  182.  
  183.  
  184. Open Scope nat_scope.
  185.  
  186. Lemma uniqueRem : (* done *)
  187. forall r1 r2 b : nat,
  188. b > 0 ->
  189. forall a : nat,
  190. (exists q : nat, a = q * b + r1 /\ b > r1) ->
  191. (exists q : nat, a = q * b + r2 /\ b > r2) -> r1 = r2.
  192. Proof.
  193. intros ? ? ? H a [x [H0 H2]] [x0 [H1 H3]].
  194. assert (x = x0). { nia. } nia.
  195. Qed.
  196.  
  197. Lemma modulo :
  198. forall b : nat, b > 0 ->
  199. forall a : nat, {p : nat * nat | a = fst p * b + snd p /\ b > snd p}.
  200. Proof.
  201. intros b H a; apply (gt_wf_rec a).
  202. intros n H0 .
  203. destruct (le_lt_dec b n) as [Hle | Hlt].
  204. - assert (n > n - b).
  205. { unfold gt in |- *; apply lt_minus; assumption. }
  206. destruct (H0 _ H1) as [[a1 b0] p].
  207. simpl in p; exists (S a1, b0); simpl in |- *.
  208. destruct p as (H2, H3).
  209. split.
  210. + rewrite <- Nat.add_assoc, <- H2.
  211. now apply le_plus_minus.
  212. + assumption.
  213. - exists (0, n); simpl in |- *; now split.
  214. Qed.
  215.  
  216.  
  217. Lemma chRem1 : (* done *)
  218. forall b : nat, b > 0 -> forall a : Z,
  219. {p : Z * nat | snd p < b /\
  220. Z.of_nat (snd p) = (fst p * Z.of_nat b + a)%Z}.
  221. Proof.
  222. intros b H a.
  223. assert
  224. (H0: forall a' : Z,
  225. (a' >= 0)%Z ->
  226. {p : Z * nat | snd p < b /\
  227. Z.of_nat (snd p) =
  228. (fst p * Z.of_nat b + a')%Z}).
  229. { intros a' H0; set (A := Z.to_nat a') in *.
  230. induction (modulo b H A) as [x p].
  231. destruct x as (a0, b0).
  232. exists ((- Z.of_nat a0)%Z, b0).
  233. destruct p as (H1, H2).
  234. split.
  235. - apply H2.
  236. - rewrite <- (Z2Nat.id a').
  237. + simpl fst ; simpl snd.
  238. rewrite Zopp_mult_distr_l_reverse.
  239. rewrite Z.add_comm.
  240. fold (Z.of_nat (Z.to_nat a') - Z.of_nat a0 * Z.of_nat b)%Z
  241. in |- *.
  242. apply Zplus_minus_eq.
  243. rewrite <- Znat.inj_mult.
  244. rewrite <- Znat.inj_plus.
  245. apply Znat.inj_eq.
  246. apply H1.
  247. + auto.
  248. now rewrite <- Z.ge_le_iff.
  249. }
  250. destruct (Z_ge_lt_dec a 0).
  251. + apply H0; assumption.
  252. + assert (a + Z.of_nat b * - a >= 0)%Z.
  253. induction b as [| b Hrecb].
  254. * elim (lt_irrefl _ H).
  255. * rewrite Znat.inj_S.
  256. rewrite Z.mul_comm.
  257. rewrite <- Zmult_succ_r_reverse.
  258. fold (- a * Z.of_nat b - a)%Z in |- *.
  259. rewrite Zplus_minus.
  260. replace 0%Z with (0 * Z.of_nat b)%Z.
  261. apply Zmult_ge_compat_r.
  262. rewrite (Zminus_diag_reverse a).
  263. rewrite <- (Zplus_0_l (- a)).
  264. unfold Zminus in |- *.
  265. apply Z.le_ge.
  266. apply Zplus_le_compat_r.
  267. apply Zlt_le_weak.
  268. assumption.
  269. replace 0%Z with (Z.of_nat 0).
  270. apply Znat.inj_ge.
  271. unfold ge in |- *.
  272. apply le_O_n.
  273. auto.
  274. auto.
  275. * induction (H0 _ H1) as [x [H2 H3]].
  276. induction x as (a0, b1).
  277. exists ((a0 - a)%Z, b1).
  278. split.
  279. -- simpl in |- *; apply H2.
  280. -- cbv beta iota zeta delta [fst snd] in |- *.
  281. cbv beta iota zeta delta [fst snd] in H3.
  282. rewrite H3.
  283. rewrite (Zplus_comm a).
  284. rewrite Zplus_assoc.
  285. apply Zplus_eq_compat.
  286. rewrite Zmult_minus_distr_r.
  287. unfold Zminus in |- *.
  288. apply Zplus_eq_compat.
  289. reflexivity.
  290. rewrite Z.mul_comm.
  291. apply Zopp_mult_distr_l_reverse.
  292. reflexivity.
  293. Qed.
  294.  
  295. Lemma euclid_gcd1 :
  296. forall (d : nat) (x y q r : Z), Zis_gcd x y (Z.of_nat d) -> x = (q * y + r)%Z -> Zis_gcd r y (Z.of_nat d).
  297. Proof.
  298. intros. rewrite H0 in H. clear H0 x.
  299. replace (q * y + r)%Z with (r - (- q) * y)%Z in H by lia.
  300. apply Zis_gcd_sym in H. apply Zis_gcd_for_euclid in H. auto.
  301. Qed.
  302.  
  303. Lemma euclid_gcd :
  304. forall (d1 d2 : nat) (x y q r : Z),
  305. x = (q * y + r)%Z -> Zis_gcd x y (Z.of_nat d1) -> Zis_gcd r y (Z.of_nat d2) -> d1 = d2.
  306. Proof.
  307. intros. pose proof (euclid_gcd1 d1 x y q r H0 H).
  308. pose proof (Zis_gcd_unique r y _ _ H2 H1). lia.
  309. Qed.
  310.  
  311. Lemma gcd_lincomb_nat_dec :
  312. forall x y d : nat,
  313. x > 0 ->
  314. Zis_gcd (Z.of_nat x) (Z.of_nat y) (Z.of_nat d) ->
  315. {a : Z * Z |
  316. Z.of_nat d = (Z.of_nat x * fst a + Z.of_nat y * snd a)%Z}.
  317. Proof.
  318. intro x; apply (lt_wf_rec x); intros X IH. intros y d H H0.
  319. elim (modulo X H y).
  320. intro z; elim z.
  321. intros q r; clear z; simpl in |- *.
  322. case r.
  323. (* case r = 0 *)
  324. - intros; induction p as (H1, H2).
  325. rewrite <- plus_n_O in H1.
  326. exists (1%Z, 0%Z).
  327. simpl fst; simpl snd.
  328. rewrite <- Zmult_0_r_reverse; rewrite <- Zplus_0_r_reverse.
  329. rewrite Z.mul_comm. rewrite Zmult_1_l.
  330. apply Znat.inj_eq.
  331. apply (euclid_gcd d X (Z.of_nat y) (Z.of_nat X) (Z.of_nat q) 0).
  332. rewrite <- Zplus_0_r_reverse; rewrite <- Znat.inj_mult;
  333. apply Znat.inj_eq; assumption.
  334. apply Zis_gcd_sym; assumption.
  335. constructor.
  336. + exists 0%Z. auto.
  337. + exists 1%Z. lia.
  338. + auto.
  339. - (* case r > 0 *)
  340. intros r1 [H1 H2].
  341. elim (IH (S r1) H2 X d).
  342. + intro z; elim z.
  343. intros delta gamma; clear z.
  344. simpl fst; simpl snd.
  345. intros p.
  346. exists ((gamma - Z.of_nat q * delta)%Z, delta).
  347. simpl fst; simpl snd.
  348. rewrite p, H1.
  349. unfold Zminus in |- *; rewrite Zmult_plus_distr_r.
  350. rewrite Znat.inj_plus; rewrite Zmult_plus_distr_l.
  351. rewrite Znat.inj_mult; rewrite <- Zopp_mult_distr_l_reverse.
  352. rewrite (Z.mul_assoc (Z.of_nat X)).
  353. rewrite (Z.mul_comm (Z.of_nat X) (- Z.of_nat q)).
  354. rewrite Zopp_mult_distr_l_reverse.
  355. rewrite Zopp_mult_distr_l_reverse.
  356. rewrite <- (Z.add_assoc (Z.of_nat X * gamma)).
  357. rewrite <- Znat.inj_mult.
  358. rewrite (Z.add_assoc (- (Z.of_nat (q * X) * delta))).
  359. rewrite Zplus_opp_l. simpl in |- *. apply Z.add_comm.
  360. + auto with arith.
  361. + apply (euclid_gcd1 d (Z.of_nat y) (Z.of_nat X) (Z.of_nat q) (Z.of_nat (S r1))).
  362. * apply Zis_gcd_sym; assumption.
  363. * rewrite <- Znat.inj_mult; rewrite <- Znat.inj_plus;
  364. apply Znat.inj_eq; assumption.
  365. Qed.
  366.  
  367. Lemma chineseRemainderTheoremHelp :
  368. forall x1 x2 : nat,
  369. CoPrime x1 x2 ->
  370. forall (a b : nat) (pa : a < x1) (pb : b < x2),
  371. a <= b ->
  372. {y : nat |
  373. y < x1 * x2 /\
  374. a = snd (proj1_sig (modulo x1 (ltgt1 _ _ pa) y)) /\
  375. b = snd (proj1_sig (modulo x2 (ltgt1 _ _ pb) y))}.
  376. Proof.
  377. intros ? ? H a b pa pb H0. unfold CoPrime in H.
  378. replace 1%Z with (Z.of_nat 1) in H by auto.
  379. destruct (gcd_lincomb_nat_dec _ _ _ (ltgt1 _ _ pa) H)
  380. as [(a0,b0) p].
  381. set (A := Z.of_nat a) in *.
  382. set (B := Z.of_nat b) in *.
  383. set (X1 := Z.of_nat x1) in *.
  384. set (X2 := Z.of_nat x2) in *.
  385. set (y := (a0 * (B - A))%Z) in *.
  386. set (z := (b0 * (A - B))%Z) in *.
  387. set (d := (A + X1 * y)%Z) in *.
  388. assert (d = (B + X2 * z)%Z).
  389. unfold d in |- *; simpl in p.
  390. apply minus1 with (X2 * z)%Z.
  391. rewrite (Z.add_comm B).
  392. rewrite Zminus_plus.
  393. unfold z in |- *.
  394. replace (A - B)%Z with (- (B - A))%Z.
  395. unfold Zminus in |- *.
  396. rewrite (Z.mul_comm b0).
  397. rewrite Zopp_mult_distr_l_reverse.
  398. rewrite (Z.mul_comm X2).
  399. rewrite Zopp_mult_distr_l_reverse.
  400. rewrite Z.opp_involutive.
  401. unfold y in |- *.
  402. rewrite <- (Z.mul_assoc (B + - A)).
  403. rewrite (Z.mul_comm (B + - A)).
  404. rewrite (Z.mul_assoc X1).
  405. rewrite (Z.mul_comm b0).
  406. rewrite <- Z.add_assoc.
  407. rewrite <- Zmult_plus_distr_l.
  408. rewrite <- p.
  409. rewrite Z.mul_1_l.
  410. fold (B - A)%Z in |- *.
  411. apply Zplus_minus.
  412. unfold Zminus in |- *.
  413. rewrite Zopp_plus_distr.
  414. rewrite Z.add_comm.
  415. rewrite Z.opp_involutive.
  416. reflexivity.
  417. assert (H2: x1 * x2 > 0).
  418. replace 0 with (0 * x2).
  419. unfold gt in |- *.
  420. rewrite Nat.mul_comm.
  421. rewrite (Nat.mul_comm x1).
  422. induction x2 as [| x2 Hrecx2].
  423. elim (lt_n_O _ pb).
  424. apply mult_S_lt_compat_l.
  425. fold (x1 > 0) in |- *.
  426. eapply ltgt1.
  427. apply pa.
  428. auto.
  429. destruct (chRem1 _ H2 d) as [(a1, b1) [H3 H4]].
  430. exists b1; split.
  431. apply H3.
  432. cbv beta iota zeta delta [snd fst] in H4, p.
  433. split.
  434. induction (modulo x1 (ltgt1 a x1 pa) b1).
  435. induction x as (a2, b2).
  436. simpl in |- *.
  437. induction p0 as (H5, H6).
  438. cbv beta iota zeta delta [snd fst] in H5.
  439. rewrite H5 in H4.
  440. unfold d in H4.
  441. unfold A, X1 in H4.
  442. assert (Z.of_nat a = Z.of_nat b2).
  443. { eapply chRem2; try lia.
  444. + apply Znat.inj_lt.
  445. apply pa.
  446. + apply Znat.inj_lt.
  447. apply H6.
  448. + rewrite Znat.inj_plus in H4.
  449. repeat rewrite Znat.inj_mult in H4.
  450. symmetry in |- *.
  451. rewrite (Z.add_comm (Z.of_nat a)) in H4.
  452. rewrite Z.add_assoc in H4.
  453. rewrite Z.mul_assoc in H4.
  454. rewrite (Z.mul_comm a1) in H4.
  455. rewrite <- (Z.mul_assoc (Z.of_nat x1)) in H4.
  456. rewrite <- Zmult_plus_distr_r in H4.
  457. rewrite (Z.mul_comm (Z.of_nat x1)) in H4.
  458. apply H4. }
  459. lia.
  460. induction (modulo x2 (ltgt1 b x2 pb) b1).
  461. simpl in |- *.
  462. induction x as (a2, b2).
  463. cbv beta iota zeta delta [snd fst] in p0.
  464. induction p0 as (H5, H6).
  465. rewrite H5 in H4.
  466. rewrite H1 in H4.
  467. unfold B, X2 in H4.
  468. simpl. assert (Z.of_nat b = Z.of_nat b2).
  469. { eapply chRem2; try lia.
  470. + apply Znat.inj_lt.
  471. apply pb.
  472. + apply Znat.inj_lt.
  473. apply H6.
  474. + rewrite Znat.inj_plus in H4.
  475. repeat rewrite Znat.inj_mult in H4.
  476. symmetry in |- *.
  477. rewrite (Z.add_comm (Z.of_nat b)) in H4.
  478. rewrite Z.mul_assoc in H4.
  479. rewrite Z.add_assoc in H4.
  480. rewrite (Z.mul_comm a1) in H4.
  481. rewrite (Z.mul_comm (Z.of_nat x2)) in H4.
  482. rewrite <- Zmult_plus_distr_l in H4.
  483. apply H4. }
  484. lia.
  485. Qed.
  486.  
  487. Lemma chineseRemainderTheorem :
  488. forall x1 x2 : nat,
  489. CoPrime x1 x2 ->
  490. forall (a b : nat) (pa : a < x1) (pb : b < x2),
  491. {y : nat |
  492. y < x1 * x2 /\
  493. a = snd (proj1_sig (modulo x1 (ltgt1 _ _ pa) y)) /\
  494. b = snd (proj1_sig (modulo x2 (ltgt1 _ _ pb) y))}.
  495. Proof.
  496. intros ? ? H a b pa pb.
  497. destruct (le_lt_dec a b).
  498. - apply chineseRemainderTheoremHelp; assumption.
  499. - assert (H0: b <= a) by (now apply lt_le_weak).
  500. assert (H1: CoPrime x2 x1) by (now apply coPrimeSym).
  501. induction (chineseRemainderTheoremHelp _ _ H1 b a pb pa H0)
  502. as [x [H2 [H3 H4]]].
  503. exists x.
  504. split.
  505. + now rewrite Nat.mul_comm.
  506. + split; assumption.
  507. Qed.
  508.  
  509. Fixpoint prod (n:nat) (x: nat -> nat) :=
  510. match n with
  511. O => 1%nat
  512. | S p => x p * prod p x
  513. end.
  514.  
  515. Definition factorial (n : nat) : nat := prod n S.
  516.  
  517. Lemma coPrime1 : forall a : nat, CoPrime 1 a.
  518. Proof.
  519. split.
  520. - simpl. exists 1%Z. auto.
  521. - exists (Z.of_nat a); lia.
  522. - intros e [H H0] [H1 H2].
  523. simpl in H0. symmetry in H0.
  524. assert (H >= 0 \/ H <= 0)%Z by lia. destruct H3.
  525. + pose proof (Zmult_one _ _ H3 H0). subst. exists 1%Z. lia.
  526. + assert (- H >= 0)%Z by lia.
  527. replace (H * e)%Z with ((- H) * (- e))%Z in H0 by lia.
  528. pose proof (Zmult_one _ _ H4 H0). rewrite H5 in H0.
  529. exists (-1)%Z. lia.
  530. Qed.
  531.  
  532. Lemma coPrimeMult3 (a b c: nat):
  533. a > 0 -> b > 0 -> c > 0 ->
  534. CoPrime a c -> CoPrime b c -> CoPrime (a * b) c.
  535. Proof.
  536. intros H H0 H1 H2 H3;
  537. assert (H4: LinComb
  538. (Z.of_nat 1) (Z.of_nat a) (Z.of_nat c)).
  539. { apply gcd_lincomb_nat.
  540. assumption.
  541. apply H2.
  542. }
  543. assert (H5: LinComb
  544. (Z.of_nat 1) (Z.of_nat b) (Z.of_nat c)).
  545. { apply gcd_lincomb_nat.
  546. assumption.
  547. apply H3.
  548. }
  549. destruct H4 as [x [x0 H4]].
  550. destruct H5 as [x1 [x2 H5]].
  551. split.
  552. - exists (Z.of_nat (a * b)). lia.
  553. - exists (Z.of_nat c). lia.
  554. - intros e [H6 H7].
  555. set (A := Z.of_nat a) in *.
  556. set (B := Z.of_nat b) in *.
  557. set (C := Z.of_nat c) in *.
  558. assert (H8:
  559. (1%Z =
  560. (A * B * (x * x1) +
  561. C * (x0 * B * x1 + x2 * A * x + x0 * x2 * C))%Z)).
  562. {
  563. change 1%Z with (Z.of_nat 1 * Z.of_nat 1)%Z.
  564. rewrite H4 at 1.
  565. rewrite H5.
  566. ring; reflexivity.
  567. }
  568. intros. destruct H9. rewrite H8.
  569. apply Z.divide_add_r.
  570. + exists (H6 * x * x1)%Z. assert (A * B = Z.of_nat (a * b))%Z by lia.
  571. rewrite H10. rewrite H7. lia.
  572. + apply Z.divide_mul_l. exists x3. auto.
  573. Qed.
  574.  
  575.  
  576.  
  577. Lemma prodBig1 :
  578. forall (n : nat) (x : nat -> nat),
  579. (forall z : nat, z < n -> x z > 0) -> prod n x > 0.
  580. Proof.
  581. induction n as [| n Hrecn].
  582. - intros x H; simpl in |- *; apply gt_Sn_n.
  583. - intros x H; simpl in |- *; apply Nat.mul_pos_pos.
  584. + apply H; apply lt_n_Sn.
  585. + apply Hrecn; intros; now apply H, lt_S.
  586. Qed.
  587.  
  588. Lemma sameProd :
  589. forall (n : nat) (x1 x2 : nat -> nat),
  590. (forall z : nat, z < n -> x1 z = x2 z) -> prod n x1 = prod n x2.
  591. Proof.
  592. induction n as [| n Hrecn].
  593. - intros; reflexivity.
  594. - intros x1 x2 H; simpl in |- *; replace (x1 n) with (x2 n).
  595. + f_equal; auto.
  596. + rewrite (H n); auto.
  597. Qed.
  598.  
  599. Lemma coPrimeProd :
  600. forall (n : nat) (x : nat -> nat),
  601. (forall z1 z2 : nat,
  602. z1 < S n -> z2 < S n -> z1 <> z2 -> CoPrime (x z1) (x z2)) ->
  603. (forall z : nat, z < S n -> x z > 0) -> CoPrime (prod n x) (x n).
  604. Proof.
  605. induction n as [| n Hrecn].
  606. - intros; simpl in |- *; apply coPrime1.
  607. - intros x H H0.
  608. assert
  609. (H1: forall z1 z2 : nat,
  610. z1 < S n -> z2 < S n -> z1 <> z2 -> CoPrime (x z1) (x z2)).
  611. { intros;apply H.
  612. 1,2: now apply Nat.lt_lt_succ_r.
  613. - assumption.
  614. }
  615. simpl in |- *; apply coPrimeMult3.
  616. + apply H0.
  617. apply Nat.lt_lt_succ_r.
  618. apply lt_n_Sn.
  619. + apply prodBig1.
  620. intros; apply H0.
  621. do 2 apply Nat.lt_lt_succ_r.
  622. assumption.
  623. + apply H0.
  624. apply lt_n_Sn.
  625. + apply H.
  626. apply Nat.lt_lt_succ_r.
  627. apply lt_n_Sn.
  628. apply lt_n_Sn.
  629. auto.
  630. + set
  631. (A1 :=
  632. fun a : nat =>
  633. match eq_nat_dec a n with
  634. | left _ => x (S n)
  635. | right _ => x a
  636. end) in *.
  637. assert (H2: CoPrime (prod n A1) (A1 n)).
  638. { apply Hrecn.
  639. intros.
  640. unfold A1 in |- *.
  641. induction (eq_nat_dec z1 n).
  642. + induction (eq_nat_dec z2 n).
  643. * elim H4.
  644. rewrite a0.
  645. assumption.
  646. * apply H.
  647. apply lt_n_Sn.
  648. apply Nat.lt_lt_succ_r.
  649. assumption.
  650. unfold not in |- *; intros.
  651. rewrite H5 in H3.
  652. elim (lt_irrefl _ H3).
  653. + induction (eq_nat_dec z2 n).
  654. * apply H.
  655. apply Nat.lt_lt_succ_r.
  656. assumption.
  657. apply lt_n_Sn.
  658. unfold not in |- *; intros.
  659. rewrite H5 in H2.
  660. elim (lt_irrefl _ H2).
  661. * apply H.
  662. apply Nat.lt_lt_succ_r.
  663. assumption.
  664. apply Nat.lt_lt_succ_r.
  665. assumption.
  666. assumption.
  667. + intros.
  668. unfold A1 in |- *.
  669. induction (eq_nat_dec z n).
  670. * apply H0.
  671. apply lt_n_Sn.
  672. * apply H0.
  673. apply Nat.lt_lt_succ_r.
  674. assumption.
  675. }
  676. auto.
  677. replace (x (S n)) with (A1 n).
  678. replace (prod n x) with (prod n A1).
  679. assumption.
  680. apply sameProd.
  681. intros.
  682. unfold A1 in |- *.
  683. induction (eq_nat_dec z n).
  684. * rewrite a in H3.
  685. elim (lt_irrefl _ H3).
  686. * reflexivity.
  687. * unfold A1 in |- *.
  688. induction (eq_nat_dec n n).
  689. -- reflexivity.
  690. -- elim b; reflexivity.
  691. Qed.
  692.  
  693. Lemma divProd :
  694. forall (n : nat) (x : nat -> nat) (i : nat),
  695. i < n -> divide (x i) (prod n x).
  696. Proof.
  697. induction n as [| n Hrecn].
  698. - intros x i H; destruct (lt_n_O _ H).
  699. - intros x i H; destruct (le_lt_or_eq i n).
  700. + now apply lt_n_Sm_le.
  701. + simpl in |- *.
  702. rewrite Nat.mul_comm.
  703. destruct (Hrecn x i H0).
  704. rewrite H1. exists (x0 * x n). lia.
  705. + subst. simpl. exists (prod n x). auto.
  706. Qed.
  707.  
  708. Lemma chRem :
  709. forall (n : nat) (x : nat -> nat),
  710. (forall z1 z2 : nat, z1 < n -> z2 < n -> z1 <> z2 -> CoPrime (x z1) (x z2)) ->
  711. forall (y : nat -> nat) (py : forall z : nat, z < n -> y z < x z),
  712. {a : nat |
  713. a < prod n x /\
  714. (forall (z : nat) (pz : z < n),
  715. y z = snd (proj1_sig (modulo (x z) (ltgt1 _ _ (py z pz)) a)))}.
  716. Proof.
  717. intro.
  718. induction n as [| n Hrecn].
  719. - intros; exists 0.
  720. split.
  721. + simpl in |- *.
  722. apply lt_O_Sn.
  723. + intros.
  724. elim (lt_n_O _ pz).
  725. - intros.
  726. assert
  727. (H0: forall z1 z2 : nat,
  728. z1 < n -> z2 < n -> z1 <> z2 -> CoPrime (x z1) (x z2)).
  729. { intros; apply H.
  730. apply Nat.lt_lt_succ_r.
  731. assumption.
  732. apply Nat.lt_lt_succ_r.
  733. assumption.
  734. assumption.
  735. }
  736. assert (H1: forall z : nat, z < n -> y z < x z).
  737. { intros.
  738. apply py.
  739. apply Nat.lt_lt_succ_r.
  740. assumption.
  741. }
  742. induction (Hrecn x H0 y H1).
  743. clear Hrecn; induction p as (H2, H3).
  744. assert (H4: CoPrime (prod n x) (x n)).
  745. { apply coPrimeProd.
  746. - apply H.
  747. - intros.
  748. eapply ltgt1.
  749. apply py.
  750. assumption.
  751. } assert (H5: y n < x n).
  752. { apply py.
  753. apply lt_n_Sn.
  754. }
  755. induction (chineseRemainderTheorem
  756. (prod n x) (x n) H4 x0 (y n) H2 H5).
  757. exists x1; induction p as (H6, (H7, H8)).
  758. split.
  759. simpl in |- *.
  760. rewrite Nat.mul_comm.
  761. assumption.
  762. intros.
  763. induction (le_lt_or_eq z n).
  764. + assert
  765. (H10: y z =
  766. snd (proj1_sig (modulo (x z) (ltgt1 (y z) (x z)
  767. (H1 z H9)) x0)))
  768. by apply H3.
  769. induction (modulo (x z) (ltgt1 (y z) (x z) (H1 z H9)) x0).
  770. simpl in H10.
  771. induction (modulo (x z) (ltgt1 (y z) (x z) (py z pz)) x1).
  772. simpl in |- *; rewrite H10.
  773. induction (modulo (prod n x) (ltgt1 x0 (prod n x) H2) x1).
  774. simpl in H7.
  775. rewrite H7 in p.
  776. induction p1 as (H11, H12).
  777. induction p as (H13, H14).
  778. induction p0 as (H15, H16).
  779. rewrite H13 in H11.
  780. apply uniqueRem with (x z) x1.
  781. apply (ltgt1 (y z) (x z) (py z pz)).
  782. assert (divide (x z) (prod n x)).
  783. { apply divProd.
  784. assumption.
  785. }
  786. induction H17 as (x5, H17).
  787. rewrite H17 in H11.
  788. rewrite (Nat.mul_comm (x z)) in H11.
  789. rewrite mult_assoc in H11.
  790. rewrite plus_assoc in H11.
  791. rewrite <- mult_plus_distr_r in H11.
  792. exists (fst x4 * x5 + fst x2).
  793. split.
  794. apply H11.
  795. assumption.
  796. exists (fst x3); auto.
  797. + induction (modulo (x z) (ltgt1 (y z) (x z) (py z pz)) x1).
  798. induction (modulo (x n) (ltgt1 (y n) (x n) H5) x1).
  799. simpl in H8.
  800. simpl in |- *.
  801. rewrite H9.
  802. rewrite H8.
  803. eapply uniqueRem.
  804. apply (ltgt1 (y n) (x n) H5).
  805. exists (fst x3).
  806. apply p0.
  807. exists (fst x2).
  808. rewrite H9 in p.
  809. assumption.
  810. + now apply lt_n_Sm_le.
  811. Qed.
  812.  
  813. Lemma minusS : forall a b : nat, b - a = S b - S a.
  814. Proof. lia. Qed.
  815.  
  816. Definition Prime (n : nat) : Prop :=
  817. n > 1 /\ (forall q : nat, divide q n -> q = 1 \/ q = n).
  818.  
  819. Lemma primeDiv :
  820. forall a : nat, 1 < a ->
  821. exists p : nat, Prime p /\
  822. divide p a.
  823. Proof.
  824. Admitted.
  825.  
  826. Lemma coPrimePrime :
  827. forall a b : nat,
  828. (forall p : nat, Prime p ->
  829. ~ divide p a \/ ~ divide p b) ->
  830. CoPrime a b.
  831. Proof.
  832. Admitted.
  833.  
  834. Lemma divdec : forall n d : nat, divide d n \/ ~ divide d n.
  835. Proof.
  836. Admitted.
  837.  
  838. Lemma div_plus_r :
  839. forall a b d : nat, divide d a -> divide d (a + b) -> divide d b.
  840. Proof.
  841. Admitted.
  842.  
  843. Lemma div_mult_compat_l :
  844. forall a b c : nat, divide a b -> divide a (b * c).
  845. Proof.
  846. Admitted.
  847.  
  848. Lemma primedivmult :
  849. forall p n m : nat,
  850. Prime p -> divide p (n * m) -> divide p n \/ divide p m.
  851. Proof.
  852. Admitted.
  853.  
  854. Lemma div_trans :
  855. forall p q r : nat, divide p q -> divide q r -> divide p r.
  856. Proof.
  857. Admitted.
  858.  
  859. Lemma coPrimeSeqHelp :
  860. forall c i j n : nat,
  861. divide (factorial n) c ->
  862. i < j -> i <= n -> j <= n -> CoPrime (S (c * S i)) (S (c * S j)).
  863. Proof.
  864. intros ? ? ? ? H H0 H1 H2.
  865. apply coPrimePrime.
  866. intros p H3.
  867. destruct (divdec (S (c * S i)) p) as [H4 | H4].
  868. assert (H5: ~ divide p c).
  869. { intro H5.
  870. assert (H6: divide p 1).
  871. { eapply div_plus_r.
  872. apply div_mult_compat_l.
  873. apply H5.
  874. rewrite plus_comm.
  875. simpl in |- *.
  876. apply H4.
  877. }
  878. induction H3 as (H3, H7).
  879. elim (lt_not_le _ _ H3).
  880. destruct H6. destruct x; lia.
  881. }
  882. destruct (divdec (S (c * S j)) p).
  883. assert (H7: divide p (c * (j - i))).
  884. { rewrite minusS.
  885. rewrite Nat.mul_comm.
  886. rewrite mult_minus_distr_r.
  887. rewrite (Nat.mul_comm (S j)).
  888. rewrite (Nat.mul_comm (S i)).
  889. rewrite minusS.
  890. destruct H4, H6. rewrite H4, H6. exists (x0 - x). nia.
  891. }
  892. destruct (primedivmult _ _ _ H3 H7).
  893. - elim H5.
  894. assumption.
  895. - assert (H9: j - i <= n).
  896. { eapply le_trans.
  897. apply Minus.le_minus.
  898. assumption.
  899. }
  900. elim H5.
  901. apply div_trans with (factorial n).
  902. apply div_trans with (j - i).
  903. assumption.
  904. unfold factorial in |- *.
  905. assert (H10: 1 <= j - i).
  906. { assert (H10: j = i + (j - i)).
  907. apply le_plus_minus.
  908. apply lt_le_weak.
  909. assumption.
  910. rewrite H10 in H0.
  911. lia.
  912. }
  913. replace (j - i) with (S (pred (j - i))).
  914. apply divProd.
  915. rewrite pred_of_minus.
  916. apply lt_S_n.
  917. apply le_lt_n_Sm.
  918. replace (S (j - i - 1)) with (1 + (j - i - 1)).
  919. rewrite <- le_plus_minus.
  920. assumption.
  921. assumption.
  922. auto.
  923. induction (j - i).
  924. elim (le_Sn_n _ H10).
  925. rewrite <- pred_Sn.
  926. reflexivity.
  927. assumption.
  928. - auto.
  929. - auto.
  930. Qed.
  931.  
  932. Definition coPrimeBeta (z c : nat) : nat := S (c * S z).
  933.  
  934. Lemma coPrimeSeq :
  935. forall c i j n : nat,
  936. divide (factorial n) c ->
  937. i <> j -> i <= n -> j <= n ->
  938. CoPrime (coPrimeBeta i c) (coPrimeBeta j c).
  939. Proof.
  940. unfold coPrimeBeta in |- *.
  941. intros ? ? ? ? H H0 H1 H2.
  942. induction (nat_total_order _ _ H0) as [H3 | H3].
  943. - eapply coPrimeSeqHelp.
  944. apply H.
  945. assumption.
  946. assumption.
  947. assumption.
  948. - apply coPrimeSym.
  949. eapply coPrimeSeqHelp.
  950. + apply H.
  951. + assumption.
  952. + assumption.
  953. + assumption.
  954. Qed.
  955.  
  956. Lemma gtBeta : forall z c : nat, coPrimeBeta z c > 0.
  957. Proof.
  958. unfold coPrimeBeta in |- *; intros; apply gt_Sn_O.
  959. Qed.
  960.  
  961. Fixpoint maxBeta (n: nat) (x: nat -> nat) :=
  962. match n with
  963. | 0 => 0
  964. | S n => Nat.max (x n) (maxBeta n x)
  965. end.
  966.  
  967. Lemma maxBetaLe :
  968. forall (n : nat) (x : nat -> nat) (i : nat),
  969. i < n -> x i <= maxBeta n x.
  970. Proof.
  971. simple induction n.
  972. - intros x i H; elim (lt_n_O _ H).
  973. - intros; simpl in |- *; induction (le_lt_or_eq i n0).
  974. + eapply le_trans; [now apply H | apply Nat.le_max_r].
  975. + rewrite H1; apply Nat.le_max_l.
  976. + now apply lt_n_Sm_le.
  977. Qed.
  978.  
  979. Theorem divProd2 :
  980. forall (n : nat) (x : nat -> nat) (i : nat),
  981. i <= n -> divide (prod i x) (prod n x).
  982. Proof.
  983. simple induction n.
  984. - intros x i ?; assert (H0: (0 = i)) by (now apply le_n_O_eq).
  985. rewrite H0.
  986. exists 1. lia.
  987. - intros n0 H x i H0.
  988. induction (le_lt_or_eq i (S n0)).
  989. + simpl in |- *.
  990. rewrite Nat.mul_comm. assert (i <= n0) by lia.
  991. destruct (H x i H2).
  992. rewrite H3.
  993. exists (x0 * x n0). lia.
  994. + rewrite H1; exists 1; lia.
  995. + assumption.
  996. Qed.
  997.  
  998. Theorem betaTheorem1 :
  999. forall (n : nat) (y : nat -> nat),
  1000. {a : nat * nat |
  1001. forall z : nat,
  1002. z < n ->
  1003. y z =
  1004. snd (proj1_sig (modulo (coPrimeBeta z (snd a))
  1005. (gtBeta z (snd a)) (fst a)))}.
  1006. Proof.
  1007. intros n y.
  1008. set (c := factorial (max n (maxBeta n y))) in *.
  1009. set (x := fun z : nat => coPrimeBeta z c) in *.
  1010. assert
  1011. (H: forall z1 z2 : nat,
  1012. z1 < n -> z2 < n -> z1 <> z2 -> CoPrime (x z1) (x z2)).
  1013. { intros; unfold x in |- *; eapply coPrimeSeq.
  1014. - eapply div_trans.
  1015. + unfold factorial in |- *; apply divProd2.
  1016. apply Nat.le_max_l.
  1017. + unfold c, factorial in |- *.
  1018. exists 1. rewrite mult_1_r. reflexivity.
  1019. - assumption.
  1020. - now apply lt_le_weak.
  1021. - apply lt_le_weak; assumption.
  1022. }
  1023. assert (H0: forall z : nat, z < n -> y z < x z).
  1024. { intros; unfold x, coPrimeBeta in |- *.
  1025. apply le_lt_n_Sm.
  1026. induction (mult_O_le c (S z)).
  1027. - discriminate H1.
  1028. - apply le_trans with c.
  1029. + unfold c in |- *.
  1030. apply le_trans with (max n (maxBeta n y)).
  1031. apply le_trans with (maxBeta n y).
  1032. apply maxBetaLe.
  1033. assumption.
  1034. apply Nat.le_max_r.
  1035. generalize (max n (maxBeta n y)).
  1036. intros.
  1037. induction n0 as [| n0 Hrecn0].
  1038. simpl in |- *.
  1039. apply le_n_Sn.
  1040. induction n0 as [| n0 Hrecn1].
  1041. simpl in |- *.
  1042. apply le_n.
  1043. assert (H2: factorial n0 > 0).
  1044. { unfold factorial in |- *.
  1045. apply prodBig1.
  1046. intros.
  1047. apply gt_Sn_O.
  1048. }
  1049. simpl in |- *.
  1050. apply le_trans with
  1051. (1 + (1 + n0 * (factorial n0 + n0 * factorial n0))).
  1052. * simpl in |- *.
  1053. repeat apply le_n_S.
  1054. induction (mult_O_le n0 (factorial n0 + n0 * factorial n0)).
  1055. -- unfold gt in H2.
  1056. assert (H4: factorial n0 = factorial n0 + 0)
  1057. by (rewrite Nat.add_comm; auto).
  1058. rewrite H4 in H2.
  1059. set (A1 := factorial n0 + 0) in *.
  1060. rewrite <- H3 in H2.
  1061. unfold A1 in H2.
  1062. clear H4 A1.
  1063. assert (H4: n0 * factorial n0 < 0).
  1064. { eapply plus_lt_reg_l.
  1065. apply H2.
  1066. }
  1067. elim (lt_n_O _ H4).
  1068. -- rewrite Nat.mul_comm.
  1069. assumption.
  1070. * apply plus_le_compat.
  1071. apply le_plus_trans.
  1072. apply lt_n_Sm_le.
  1073. apply lt_n_S.
  1074. assumption.
  1075. apply plus_le_compat.
  1076. apply le_plus_trans.
  1077. apply lt_n_Sm_le.
  1078. apply lt_n_S.
  1079. assumption.
  1080. apply le_n.
  1081. + rewrite Nat.mul_comm.
  1082. assumption.
  1083. }
  1084. induction (chRem _ _ H _ H0) as [x0 [H2 H3]].
  1085. exists (x0, c).
  1086. intros.
  1087. rewrite (H3 z H1).
  1088. induction (modulo (x z) (ltgt1 (y z) (x z) (H0 z H1)) x0).
  1089. simpl fst; simpl snd.
  1090. destruct (modulo (coPrimeBeta z c) (gtBeta z c) x0) as [x2 p0].
  1091. simpl in |- *.
  1092. eapply uniqueRem.
  1093. apply gtBeta.
  1094. unfold x in p.
  1095. exists (fst x1).
  1096. apply p.
  1097. exists (fst x2).
  1098. apply p0.
  1099. Qed.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement