-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathLiouville.v
More file actions
477 lines (426 loc) · 15.3 KB
/
Liouville.v
File metadata and controls
477 lines (426 loc) · 15.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
(*
Copyright © 2009 Valentin Blot
Permission is hereby granted, free of charge, to any person obtaining a copy of
this proof and associated documentation files (the "Proof"), to deal in
the Proof without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Proof, and to permit persons to whom the Proof is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Proof.
THE PROOF IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE PROOF OR THE USE OR OTHER DEALINGS IN THE PROOF.
*)
Require Import CRing_Homomorphisms.
Require Import CPoly_NthCoeff.
Require Import MoreFunctions.
Require Import Rolle.
Require Import Zlcm Q_can RX_deg QX_ZX QX_root_loc QX_extract_roots.
Section CPoly_bounded.
Variable I : interval.
Hypothesis I_fin : finite I.
Fixpoint AbsPoly (P : cpoly_cring IR) : cpoly_cring IR :=
match P with
| cpoly_zero _ => cpoly_zero IR
| cpoly_linear _ c P => cpoly_linear IR (AbsIR c) (AbsPoly P)
end.
Lemma AbsPoly_zero : AbsPoly [0] = [0].
Proof. reflexivity. Qed.
Lemma AbsPoly_linear : forall c P, AbsPoly (c[+X*]P) = AbsIR c[+X*]AbsPoly P.
Proof. reflexivity. Qed.
Lemma Abs_poly_nth_coeff : forall P i, nth_coeff i (AbsPoly P) [=] AbsIR (nth_coeff i P).
Proof.
intro P.
pattern P; apply Ccpoly_induc; clear P.
intro; rewrite -> AbsPoly_zero, nth_coeff_zero.
symmetry; apply AbsIRz_isz.
intros P c Hrec n.
rewrite AbsPoly_linear.
destruct n.
rewrite -> coeff_O_lin; reflexivity.
rewrite -> coeff_Sm_lin.
rewrite -> Hrec.
apply AbsIR_wd.
symmetry; apply coeff_Sm_lin.
Qed.
Definition CPoly_bound (P : cpoly_cring IR) : IR :=
(AbsPoly P) ! (Max (AbsIR (left_end I I_fin)) (AbsIR (right_end I I_fin))).
Lemma AbsIR_leEq : forall a b, a [<=] b -> [--]a [<=] b -> AbsIR a [<=] b.
Proof.
intros a b Hp Hm.
unfold AbsIR, ABSIR; simpl.
apply Max_leEq; assumption.
Qed.
Lemma abs_max : forall a b x, a [<=] x -> x [<=] b -> AbsIR x [<=] Max (AbsIR a) (AbsIR b).
Proof.
intros a b x Ha Hb.
apply AbsIR_leEq.
apply (leEq_transitive _ _ (AbsIR b)); [|apply rht_leEq_Max].
apply (leEq_transitive _ _ b); [assumption|apply leEq_AbsIR].
apply (leEq_transitive _ _ (AbsIR a)); [|apply lft_leEq_Max].
apply (leEq_transitive _ _ ([--]a)).
apply inv_resp_leEq; assumption.
rewrite -> AbsIR_inv; apply leEq_AbsIR.
Qed.
Lemma Abs_min_max : forall x, I x ->
AbsIR x [<=] Max (AbsIR (left_end I I_fin)) (AbsIR (right_end I I_fin)).
Proof.
intros x HI; unfold left_end, right_end.
destruct I; try inversion I_fin; destruct HI; apply abs_max;
(apply less_leEq; assumption)|| assumption.
Qed.
Lemma CPoly_bound_spec : forall x P, I x -> AbsIR (P ! x) [<=] CPoly_bound P.
Proof.
intros x P HI.
destruct (Cpoly_ex_degree _ P) as [n Hdeg].
destruct (Cpoly_ex_degree _ (AbsPoly P)) as [m HdegA].
unfold CPoly_bound.
generalize (degree_le_mon _ _ _ _ (Nat.le_max_l n m) Hdeg).
generalize (degree_le_mon _ _ _ _ (Nat.le_max_r n m) HdegA).
revert HI.
generalize (Nat.max n m). clear.
intros n HI HdegP HdegA.
rewrite -> (poly_as_sum _ _ _ HdegP).
rewrite -> (poly_as_sum _ _ _ HdegA).
apply (leEq_transitive _ _ (Sum 0 n (fun i => AbsIR (nth_coeff i P[*]x[^]i)))).
apply triangle_SumIR.
apply Nat.le_0_l.
apply Sum_resp_leEq.
apply Nat.le_0_l.
intros i H1 H2.
rewrite -> AbsIR_resp_mult.
rewrite -> Abs_poly_nth_coeff.
apply mult_resp_leEq_lft; [|apply AbsIR_nonneg].
rewrite -> AbsIR_nexp_op.
apply nexp_resp_leEq; [apply AbsIR_nonneg|].
apply Abs_min_max; assumption.
Qed.
End CPoly_bounded.
Section poly_law_of_mean.
Variable I : interval.
Hypothesis I_fin : finite I.
Hypothesis I_proper : proper I.
Variable P : cpoly_cring IR.
Let C := CPoly_bound I I_fin (_D_ P).
Let Hderiv := Derivative_poly I I_proper P.
Lemma poly_law_of_mean : forall a b, I a -> I b ->
AbsIR (P ! b [-] P ! a) [<=] C [*] (AbsIR (b [-] a)).
Proof.
intros a b Ha Hb.
set (Law_of_the_Mean_Abs_ineq I I_proper (FPoly IR P) (FPoly IR (_D_ P)) Hderiv a b Ha Hb
(CPoly_bound I I_fin (_D_ P))).
simpl in c.
apply c; [|auto|auto].
clear c; intros x Hcomp Htrue; clear Htrue.
apply CPoly_bound_spec.
destruct Hcomp.
destruct I; simpl in *; try auto; try split; try (destruct Ha; destruct Hb);
(apply (less_leEq_trans _ _ (MIN a b)); [apply less_Min|]; assumption)||
(apply (leEq_less_trans _ _ (MAX a b)); [|apply Max_less]; assumption)||
(apply (leEq_transitive _ _ (MIN a b)); [apply leEq_Min|]; assumption)||
(apply (leEq_transitive _ _ (MAX a b)); [|apply Max_leEq]; assumption).
Qed.
End poly_law_of_mean.
Section liouville_lemmas.
Variable a : IR.
Definition Ia : interval := clcr (a[-]Two) (a[+]Two).
Lemma Ia_fin : finite Ia.
Proof. simpl; auto. Qed.
Lemma Ia_proper : proper Ia.
Proof.
simpl.
apply shift_minus_less.
apply (less_wdl _ (a[+](([0][+][0][+][0])[+]([0][+][0][+][0])))); [|rational].
apply (less_wdr _ _ (a[+](Two[+]Two))); [|rational].
apply plus_resp_less_lft.
apply plus_resp_less_both.
apply plus_resp_less_both; [|apply pos_one].
apply plus_resp_less_lft; apply pos_one.
apply plus_resp_less_both; [|apply pos_one].
apply plus_resp_less_lft; apply pos_one.
Qed.
Lemma a_in_Ia : Ia a.
Proof.
split.
apply less_leEq.
apply (less_wdr _ _ (a[-]([0][+][0][+][0]))); [|rational].
apply minus_resp_less_rht.
apply plus_resp_less_both; [|apply pos_one].
apply plus_resp_less_lft; apply pos_one.
apply less_leEq.
apply (less_wdl _ (a[+]([0][+][0][+][0]))); [|rational].
apply plus_resp_less_lft.
apply plus_resp_less_both; [|apply pos_one].
apply plus_resp_less_lft; apply pos_one.
Qed.
Lemma Liouville_lemma1 : forall x : IR, AbsIR (x[-]a) [<=] Two -> Ia x.
Proof.
intros x Hle.
split.
apply (leEq_wdr _ _ (x[+]Two[-]Two)); [|rational].
apply minus_resp_leEq.
apply (leEq_wdl _ (x[+](a[-]x))); [|rational].
apply plus_resp_leEq_lft.
rewrite -> AbsIR_minus in Hle.
apply (leEq_transitive _ _ (AbsIR (a[-]x))); [|assumption].
apply leEq_AbsIR.
apply (leEq_wdl _ (x[-]Two[+]Two)); [|rational].
apply plus_resp_leEq.
apply (leEq_wdr _ _ (x[-](x[-]a))); [|rational].
apply minus_resp_leEq_rht.
apply (leEq_transitive _ _ (AbsIR (x[-]a))); [|assumption].
apply leEq_AbsIR.
Qed.
Variable P : cpoly_cring IR.
Let C := CPoly_bound Ia Ia_fin (_D_ P).
Lemma Liouville_lemma2 : forall x : IR, AbsIR (x[-]a) [<=] Two ->
AbsIR (P ! x [-] P ! a) [<=] C [*] AbsIR (x [-] a).
Proof.
intros x Hle.
apply (poly_law_of_mean Ia Ia_fin Ia_proper P a x a_in_Ia (Liouville_lemma1 x Hle)).
Qed.
Lemma Liouville_lemma3 : forall x : IR, [1] [<] x or x [<] Two.
Proof.
intro x.
apply less_cotransitive_unfolded.
apply (less_wdl _ ([0][+][0][+][1])); [|rational].
apply plus_resp_less_rht.
apply plus_resp_less_lft.
apply pos_one.
Qed.
End liouville_lemmas.
Section liouville_lemmas2.
Let ZX_deg := RX_deg Z_as_CRing Z_dec.
Variable P : cpoly_cring Z_as_CRing.
Lemma Liouville_lemma4 : forall p : Z_as_CRing,
p [#] [0] -> [1] [<=] AbsIR (inj_Q_rh p).
Proof.
intros p Hap.
change ([1][<=]AbsIR(inj_Q IR p)).
rewrite -> AbsIR_Qabs.
unfold Qabs.Qabs.
unfold inject_Z.
rewrite <- inj_Q_One.
apply inj_Q_leEq.
unfold Z.abs.
destruct p.
destruct Hap; reflexivity.
simpl; unfold Qle; simpl; intuition; auto with *.
simpl; unfold Qle; simpl; intuition; auto with *.
Qed.
Lemma Liouville_lemma5 : forall (p : Z_as_CRing) (q : positive), (zx2qx P) ! (p#q)%Q [#] [0] ->
[1] [<=] (inj_Q_rh q)[^](ZX_deg P) [*] AbsIR (inj_Q_rh ((zx2qx P) ! (p#q)%Q)).
Proof.
intros p q Hap.
set (n := ZX_deg P).
assert (Zpos q=Z.abs q); [reflexivity|].
rewrite H; clear H.
rewrite <- nexp_ring_hom.
assert (((Z.abs q):Q_as_CRing)[^]n [=] Z.abs ((q:Z_as_CRing)[^]n)).
generalize n; clear; induction n; [reflexivity|].
rewrite <- nexp_Sn.
rewrite <- nexp_Sn.
rewrite Zabs_Zmult.
rewrite -> IHn.
reflexivity.
rewrite -> H; clear H.
rewrite <- (AbsIR_Qabs ((q:Z_as_CRing)[^]n)).
rewrite <- AbsIR_resp_mult.
change (inj_Q IR ((q:Z_as_CRing)[^]n)) with (inj_Q_rh ((q:Z_as_CRing)[^]n)).
rewrite <- rh_pres_mult.
assert (inject_Z ((q:Z_as_CRing)[^]n) [=] (inject_Z (q:Z_as_CRing))[^]n).
generalize n; clear; induction n; [reflexivity|].
rewrite <- nexp_Sn.
rewrite <- nexp_Sn.
rewrite <- IHn.
reflexivity.
rewrite -> H; clear H.
set (H:=Q_Z_poly_apply P p q).
cbv zeta in H.
fold ZX_deg in H.
fold n in H.
rewrite -> H.
apply Liouville_lemma4.
intro.
destruct (ap_imp_neq _ _ _ Hap); clear Hap.
assert ((inject_Z (Zpos q))[^]n [#] [0]).
generalize n; clear; induction n; [discriminate|].
intro; destruct IHn.
rewrite <- nexp_Sn in H.
destruct (Qmult_integral _ _ H); [discriminate|assumption].
rewrite -> H0 in H.
apply (mult_eq_zero _ _ _ X); assumption.
Qed.
End liouville_lemmas2.
Section liouville_lemmas3.
Let ZX_deg := RX_deg Z_as_CRing Z_dec.
Let QX_deg := RX_deg Q_as_CRing Q_dec.
Variable P : cpoly_cring Q_as_CRing.
Lemma Liouville_lemma6 : forall (p : Z_as_CRing) (q : positive), P ! (p#q)%Q [#] [0] ->
[1] [<=] (inj_Q_rh q)[^](QX_deg P) [*] AbsIR (inj_Q_rh ((Zlcm_den_poly P:Q_as_CRing)[*]P ! (p#q)%Q)).
Proof.
intros p q Hap.
assert ((zx2qx (qx2zx P)) ! (p#q)%Q[#][0]).
case (Q_dec ((zx2qx (qx2zx P)) ! (p#q)%Q) [0]); [|tauto].
intro Heq; destruct (ap_imp_neq _ _ _ Hap); revert Heq.
rewrite -> qx2zx_spec.
rewrite -> mult_apply, c_apply.
intro Heq.
apply (mult_eq_zero _ (Zlcm_den_poly P:Q_as_CField)).
replace (cm_unit Q_as_CField) with (inject_Z (cm_unit Z_as_CRing)) by reflexivity.
intro Heq2; rewrite Q.Qeq_Zeq in Heq2.
apply (eq_imp_not_ap _ (Zlcm_den_poly P) [0]).
assumption.
apply Zlcm_den_poly_nz.
assumption.
rewrite -> qx2zx_deg; fold ZX_deg.
apply (leEq_wdr _ _ _ _ (Liouville_lemma5 _ _ _ X)); fold ZX_deg.
apply mult_wdr.
apply AbsIR_wd.
apply csf_wd.
rewrite -> qx2zx_spec.
rewrite -> mult_apply, c_apply; reflexivity.
Qed.
Lemma Liouville_lemma7 : forall (p : Z_as_CRing) (q : positive), P ! (p#q)%Q [#] [0] ->
[1] [<=] (inj_Q_rh q)[^](QX_deg P) [*] AbsIR (inj_Q_rh (Zlcm_den_poly P:Q_as_CRing)) [*] AbsIR (inj_Q_rh (P ! (p#q)%Q)).
Proof.
intros p q Hap.
apply (leEq_wdr _ _ _ _ (Liouville_lemma6 _ _ Hap)).
rewrite <- CRings.mult_assoc.
apply mult_wdr.
rewrite -> rh_pres_mult.
apply AbsIR_resp_mult.
Qed.
Variable a : IR.
Let C := AbsIR (inj_Q_rh (Zlcm_den_poly P:Q_as_CRing)) [*] CPoly_bound (Ia a) (Ia_fin a) (_D_ (inj_QX_rh P)).
Hypothesis Ha : (inj_QX_rh P) ! a [=] [0].
Lemma Liouville_lemma8 : forall (n : nat) (q : positive), [1] [<=] (inj_Q_rh q)[^]n.
Proof.
intros n q; induction n.
apply leEq_reflexive.
rewrite <- nexp_Sn.
apply (leEq_wdl _ ([1][*][1])); [|rational].
apply mult_resp_leEq_both; [apply less_leEq; apply pos_one|apply less_leEq; apply pos_one| |apply IHn].
rewrite <- (rh_pres_unit _ _ inj_Q_rh).
apply inj_Q_leEq.
simpl; unfold Qle; simpl; rewrite Pmult_1_r.
unfold Z.le; simpl.
case q; intros; discriminate.
Qed.
Lemma Liouville_lemma9 : forall (p : Z_as_CRing) (q : positive),
P ! (p#q)%Q [#] [0] -> AbsIR ((inj_Q_rh (p#q)%Q) [-] a) [<=] Two ->
[1] [<=] (inj_Q_rh q)[^](QX_deg P) [*] C [*] AbsIR ((inj_Q_rh (p#q)%Q) [-] a).
Proof.
intros p q Hap Hle.
apply (leEq_transitive _ _ _ _ (Liouville_lemma7 _ _ Hap)).
rewrite <- CRings.mult_assoc, <- CRings.mult_assoc.
apply mult_resp_leEq_lft.
unfold C.
rewrite <- CRings.mult_assoc.
apply mult_resp_leEq_lft; [|apply AbsIR_nonneg].
apply (leEq_wdl _ _ _ _ (Liouville_lemma2 _ _ _ Hle)).
apply AbsIR_wd.
rewrite -> Ha.
rewrite -> cg_inv_zero.
unfold inj_QX_rh.
rewrite -> cpoly_map_apply; reflexivity.
set (Liouville_lemma8 (QX_deg P) q).
apply (leEq_transitive _ _ [1]); [apply less_leEq; apply pos_one|].
apply Liouville_lemma8.
Qed.
Let C' := Max [1] C.
Lemma Liouville_lemma10 : forall (p : Z_as_CRing) (q : positive),
P ! (p#q)%Q [#] [0] ->
[1] [<=] (inj_Q_rh q)[^](QX_deg P) [*] C' [*] AbsIR ((inj_Q_rh (p#q)%Q) [-] a).
Proof.
intros p q Hap.
destruct (Liouville_lemma3 (AbsIR (inj_Q_rh (p # q)%Q[-]a))).
apply (leEq_transitive _ _ _ _ (less_leEq _ _ _ c)).
apply (leEq_wdl _ ([1] [*] AbsIR (inj_Q_rh (p#q)%Q [-] a))); [|rational].
apply mult_resp_leEq_rht; [|apply AbsIR_nonneg].
apply (leEq_wdl _ ([1] [*] [1])); [|rational].
apply mult_resp_leEq_both; [apply less_leEq; apply pos_one|apply less_leEq; apply pos_one| |apply lft_leEq_Max].
apply Liouville_lemma8.
apply (leEq_transitive _ _ _ _ (Liouville_lemma9 _ _ Hap (less_leEq _ _ _ c))).
apply mult_resp_leEq_rht; [|apply AbsIR_nonneg].
apply mult_resp_leEq_lft; [|].
unfold C'; apply rht_leEq_Max.
apply (leEq_transitive _ _ [1]); [apply less_leEq; apply pos_one|].
apply Liouville_lemma8.
Qed.
End liouville_lemmas3.
Section liouville_theorem.
Variable a : IR.
Hypothesis a_irrat : forall x : Q, a [~=] inj_Q _ x.
Variable P : cpoly_cring Q_as_CRing.
Hypothesis P_nz : P [#] [0].
Hypothesis a_alg : (inj_QX_rh P) ! a [=] [0].
Let C : IR := Max [1] (AbsIR (inj_Q_rh (Zlcm_den_poly (QX_extract_roots P):Q_as_CRing)) [*] CPoly_bound (Ia a) (Ia_fin a) (_D_ (inj_QX_rh (QX_extract_roots P)))).
Lemma constant_pos : [0] [<] C.
Proof.
unfold C.
apply (less_leEq_trans _ _ [1]).
apply pos_one.
apply lft_leEq_Max.
Qed.
Lemma constant_nz : C [#] [0].
Proof. apply pos_ap_zero; apply constant_pos. Qed.
Definition Liouville_constant : IR := [1] [/] C [//] constant_nz.
Definition Liouville_degree := RX_deg _ Q_dec (QX_extract_roots P).
Theorem Liouville_theorem : forall (x : Q),
(Liouville_constant[*]inj_Q IR (1#Qden x)%Q[^]Liouville_degree)
[<=] AbsIR (inj_Q _ x [-] a).
Proof.
intro x.
destruct x as [p q]; unfold Qden.
apply (mult_cancel_leEq _ _ _ (inj_Q_rh q[^]Liouville_degree)).
apply (less_leEq_trans _ _ [1]); [apply pos_one|].
apply Liouville_lemma8.
assert (H : inj_Q IR (1#q)%Q = inj_Q_rh (1#q)%Q).
reflexivity.
rewrite H; clear H.
rewrite <- nexp_ring_hom.
rewrite <- CRings.mult_assoc.
rewrite <- nexp_ring_hom.
rewrite <- rh_pres_mult.
assert (H : (1 # q)%Q[^]Liouville_degree[*](inject_Z q)[^]Liouville_degree [=] [1]).
rewrite <- mult_nexp.
rewrite <- (one_nexp _ Liouville_degree).
apply nexp_wd; reflexivity.
rewrite -> H; clear H.
rewrite -> rh_pres_unit.
rewrite -> mult_one.
unfold Liouville_constant.
apply shift_div_leEq'.
apply constant_pos.
assert (H : (inj_QX_rh (QX_extract_roots P)) ! a[=][0]).
apply QX_extract_roots_spec_nrat; assumption.
assert (H1 : (QX_extract_roots P) ! ((p # q)%Q)[#][0]).
apply QX_extract_roots_spec_rat; assumption.
apply (leEq_wdr _ _ _ _ (Liouville_lemma10 _ _ H _ _ H1)).
fold C.
rewrite -> (mult_commutes _ _ C).
rewrite <- CRings.mult_assoc.
apply mult_wdr.
rewrite -> mult_commutes.
apply mult_wdr.
unfold Liouville_degree.
symmetry; apply nexp_ring_hom.
Qed.
Theorem Liouville_theorem2 :
{n : nat | {C : IR | [0] [<] C | forall (x : Q),
(C[*]inj_Q IR (1#Qden x)%Q[^]n) [<=] AbsIR (inj_Q _ x [-] a)}}.
Proof.
exists Liouville_degree.
exists Liouville_constant.
unfold Liouville_constant.
apply recip_resp_pos.
apply constant_pos.
intro x.
apply Liouville_theorem.
Qed.
End liouville_theorem.