src/HOL/Decision_Procs/MIR.thy
 author wenzelm Thu Mar 03 15:19:20 2011 +0100 (2011-03-03) changeset 41882 ae8d62656392 parent 41849 1a65b780bd56 child 41891 d37babdf5cae permissions -rw-r--r--
removed spurious 'unused_thms' (cf. 1a65b780bd56);
1 (*  Title:      HOL/Decision_Procs/MIR.thy
2     Author:     Amine Chaieb
3 *)
5 theory MIR
6 imports Complex_Main Dense_Linear_Order DP_Library
7   "~~/src/HOL/Library/Efficient_Nat"
8 uses ("mir_tac.ML")
9 begin
11 section {* Quantifier elimination for @{text "\<real> (0, 1, +, floor, <)"} *}
13 declare real_of_int_floor_cancel [simp del]
15 lemma myle: fixes a b :: "'a::{ordered_ab_group_add}"
16   shows "(a \<le> b) = (0 \<le> b - a)"
19 lemma myless: fixes a b :: "'a::{ordered_ab_group_add}"
20   shows "(a < b) = (0 < b - a)"
21 by (metis le_iff_diff_le_0 less_le_not_le myle)
23   (* Maybe should be added to the library \<dots> *)
24 lemma floor_int_eq: "(real n\<le> x \<and> x < real (n+1)) = (floor x = n)"
25 proof( auto)
26   assume lb: "real n \<le> x"
27     and ub: "x < real n + 1"
28   have "real (floor x) \<le> x" by simp
29   hence "real (floor x) < real (n + 1) " using ub by arith
30   hence "floor x < n+1" by simp
31   moreover from lb have "n \<le> floor x" using floor_mono[where x="real n" and y="x"]
32     by simp ultimately show "floor x = n" by simp
33 qed
35 (* Periodicity of dvd *)
36 lemma dvd_period:
37   assumes advdd: "(a::int) dvd d"
38   shows "(a dvd (x + t)) = (a dvd ((x+ c*d) + t))"
40 proof-
41   {fix x k
42     from inf_period(3)[OF advdd, rule_format, where x=x and k="-k"]
43     have " ((a::int) dvd (x + t)) = (a dvd (x+k*d + t))" by simp}
44   hence "\<forall>x.\<forall>k. ((a::int) dvd (x + t)) = (a dvd (x+k*d + t))"  by simp
45   then show ?thesis by simp
46 qed
48 (* The Divisibility relation between reals *)
49 definition
50   rdvd:: "real \<Rightarrow> real \<Rightarrow> bool" (infixl "rdvd" 50)
51 where
52   rdvd_def: "x rdvd y \<longleftrightarrow> (\<exists>k\<Colon>int. y = x * real k)"
54 lemma int_rdvd_real:
55   shows "real (i::int) rdvd x = (i dvd (floor x) \<and> real (floor x) = x)" (is "?l = ?r")
56 proof
57   assume "?l"
58   hence th: "\<exists> k. x=real (i*k)" by (simp add: rdvd_def)
59   hence th': "real (floor x) = x" by (auto simp del: real_of_int_mult)
60   with th have "\<exists> k. real (floor x) = real (i*k)" by simp
61   hence "\<exists> k. floor x = i*k" by (simp only: real_of_int_inject)
62   thus ?r  using th' by (simp add: dvd_def)
63 next
64   assume "?r" hence "(i\<Colon>int) dvd \<lfloor>x\<Colon>real\<rfloor>" ..
65   hence "\<exists> k. real (floor x) = real (i*k)"
66     by (simp only: real_of_int_inject) (simp add: dvd_def)
67   thus ?l using `?r` by (simp add: rdvd_def)
68 qed
70 lemma int_rdvd_iff: "(real (i::int) rdvd real t) = (i dvd t)"
71 by (auto simp add: rdvd_def dvd_def) (rule_tac x="k" in exI, simp only :real_of_int_mult[symmetric])
74 lemma rdvd_abs1:
75   "(abs (real d) rdvd t) = (real (d ::int) rdvd t)"
76 proof
77   assume d: "real d rdvd t"
78   from d int_rdvd_real have d2: "d dvd (floor t)" and ti: "real (floor t) = t" by auto
80   from iffD2[OF abs_dvd_iff] d2 have "(abs d) dvd (floor t)" by blast
81   with ti int_rdvd_real[symmetric] have "real (abs d) rdvd t" by blast
82   thus "abs (real d) rdvd t" by simp
83 next
84   assume "abs (real d) rdvd t" hence "real (abs d) rdvd t" by simp
85   with int_rdvd_real[where i="abs d" and x="t"] have d2: "abs d dvd floor t" and ti: "real (floor t) =t" by auto
86   from iffD1[OF abs_dvd_iff] d2 have "d dvd floor t" by blast
87   with ti int_rdvd_real[symmetric] show "real d rdvd t" by blast
88 qed
90 lemma rdvd_minus: "(real (d::int) rdvd t) = (real d rdvd -t)"
91   apply (auto simp add: rdvd_def)
92   apply (rule_tac x="-k" in exI, simp)
93   apply (rule_tac x="-k" in exI, simp)
94 done
96 lemma rdvd_left_0_eq: "(0 rdvd t) = (t=0)"
97 by (auto simp add: rdvd_def)
99 lemma rdvd_mult:
100   assumes knz: "k\<noteq>0"
101   shows "(real (n::int) * real (k::int) rdvd x * real k) = (real n rdvd x)"
102 using knz by (simp add:rdvd_def)
104   (*********************************************************************************)
105   (****                            SHADOW SYNTAX AND SEMANTICS                  ****)
106   (*********************************************************************************)
108 datatype num = C int | Bound nat | CN nat int num | Neg num | Add num num| Sub num num
109   | Mul int num | Floor num| CF int num num
111   (* A size for num to make inductive proofs simpler*)
112 primrec num_size :: "num \<Rightarrow> nat" where
113  "num_size (C c) = 1"
114 | "num_size (Bound n) = 1"
115 | "num_size (Neg a) = 1 + num_size a"
116 | "num_size (Add a b) = 1 + num_size a + num_size b"
117 | "num_size (Sub a b) = 3 + num_size a + num_size b"
118 | "num_size (CN n c a) = 4 + num_size a "
119 | "num_size (CF c a b) = 4 + num_size a + num_size b"
120 | "num_size (Mul c a) = 1 + num_size a"
121 | "num_size (Floor a) = 1 + num_size a"
123   (* Semantics of numeral terms (num) *)
124 primrec Inum :: "real list \<Rightarrow> num \<Rightarrow> real" where
125   "Inum bs (C c) = (real c)"
126 | "Inum bs (Bound n) = bs!n"
127 | "Inum bs (CN n c a) = (real c) * (bs!n) + (Inum bs a)"
128 | "Inum bs (Neg a) = -(Inum bs a)"
129 | "Inum bs (Add a b) = Inum bs a + Inum bs b"
130 | "Inum bs (Sub a b) = Inum bs a - Inum bs b"
131 | "Inum bs (Mul c a) = (real c) * Inum bs a"
132 | "Inum bs (Floor a) = real (floor (Inum bs a))"
133 | "Inum bs (CF c a b) = real c * real (floor (Inum bs a)) + Inum bs b"
134 definition "isint t bs \<equiv> real (floor (Inum bs t)) = Inum bs t"
136 lemma isint_iff: "isint n bs = (real (floor (Inum bs n)) = Inum bs n)"
139 lemma isint_Floor: "isint (Floor n) bs"
142 lemma isint_Mul: "isint e bs \<Longrightarrow> isint (Mul c e) bs"
143 proof-
144   let ?e = "Inum bs e"
145   let ?fe = "floor ?e"
146   assume be: "isint e bs" hence efe:"real ?fe = ?e" by (simp add: isint_iff)
147   have "real ((floor (Inum bs (Mul c e)))) = real (floor (real (c * ?fe)))" using efe by simp
148   also have "\<dots> = real (c* ?fe)" by (simp only: floor_real_of_int)
149   also have "\<dots> = real c * ?e" using efe by simp
150   finally show ?thesis using isint_iff by simp
151 qed
153 lemma isint_neg: "isint e bs \<Longrightarrow> isint (Neg e) bs"
154 proof-
155   let ?I = "\<lambda> t. Inum bs t"
156   assume ie: "isint e bs"
157   hence th: "real (floor (?I e)) = ?I e" by (simp add: isint_def)
158   have "real (floor (?I (Neg e))) = real (floor (- (real (floor (?I e)))))" by (simp add: th)
159   also have "\<dots> = - real (floor (?I e))" by(simp add: floor_minus_real_of_int)
160   finally show "isint (Neg e) bs" by (simp add: isint_def th)
161 qed
163 lemma isint_sub:
164   assumes ie: "isint e bs" shows "isint (Sub (C c) e) bs"
165 proof-
166   let ?I = "\<lambda> t. Inum bs t"
167   from ie have th: "real (floor (?I e)) = ?I e" by (simp add: isint_def)
168   have "real (floor (?I (Sub (C c) e))) = real (floor ((real (c -floor (?I e)))))" by (simp add: th)
169   also have "\<dots> = real (c- floor (?I e))" by(simp add: floor_minus_real_of_int)
170   finally show "isint (Sub (C c) e) bs" by (simp add: isint_def th)
171 qed
174   ai:"isint a bs" and bi: "isint b bs" shows "isint (Add a b) bs"
175 proof-
176   let ?a = "Inum bs a"
177   let ?b = "Inum bs b"
178   from ai bi isint_iff have "real (floor (?a + ?b)) = real (floor (real (floor ?a) + real (floor ?b)))" by simp
179   also have "\<dots> = real (floor ?a) + real (floor ?b)" by simp
180   also have "\<dots> = ?a + ?b" using ai bi isint_iff by simp
181   finally show "isint (Add a b) bs" by (simp add: isint_iff)
182 qed
184 lemma isint_c: "isint (C j) bs"
188     (* FORMULAE *)
189 datatype fm  =
190   T| F| Lt num| Le num| Gt num| Ge num| Eq num| NEq num| Dvd int num| NDvd int num|
191   NOT fm| And fm fm|  Or fm fm| Imp fm fm| Iff fm fm| E fm| A fm
194   (* A size for fm *)
195 fun fmsize :: "fm \<Rightarrow> nat" where
196  "fmsize (NOT p) = 1 + fmsize p"
197 | "fmsize (And p q) = 1 + fmsize p + fmsize q"
198 | "fmsize (Or p q) = 1 + fmsize p + fmsize q"
199 | "fmsize (Imp p q) = 3 + fmsize p + fmsize q"
200 | "fmsize (Iff p q) = 3 + 2*(fmsize p + fmsize q)"
201 | "fmsize (E p) = 1 + fmsize p"
202 | "fmsize (A p) = 4+ fmsize p"
203 | "fmsize (Dvd i t) = 2"
204 | "fmsize (NDvd i t) = 2"
205 | "fmsize p = 1"
206   (* several lemmas about fmsize *)
207 lemma fmsize_pos: "fmsize p > 0"
208 by (induct p rule: fmsize.induct) simp_all
210   (* Semantics of formulae (fm) *)
211 primrec Ifm ::"real list \<Rightarrow> fm \<Rightarrow> bool" where
212   "Ifm bs T = True"
213 | "Ifm bs F = False"
214 | "Ifm bs (Lt a) = (Inum bs a < 0)"
215 | "Ifm bs (Gt a) = (Inum bs a > 0)"
216 | "Ifm bs (Le a) = (Inum bs a \<le> 0)"
217 | "Ifm bs (Ge a) = (Inum bs a \<ge> 0)"
218 | "Ifm bs (Eq a) = (Inum bs a = 0)"
219 | "Ifm bs (NEq a) = (Inum bs a \<noteq> 0)"
220 | "Ifm bs (Dvd i b) = (real i rdvd Inum bs b)"
221 | "Ifm bs (NDvd i b) = (\<not>(real i rdvd Inum bs b))"
222 | "Ifm bs (NOT p) = (\<not> (Ifm bs p))"
223 | "Ifm bs (And p q) = (Ifm bs p \<and> Ifm bs q)"
224 | "Ifm bs (Or p q) = (Ifm bs p \<or> Ifm bs q)"
225 | "Ifm bs (Imp p q) = ((Ifm bs p) \<longrightarrow> (Ifm bs q))"
226 | "Ifm bs (Iff p q) = (Ifm bs p = Ifm bs q)"
227 | "Ifm bs (E p) = (\<exists> x. Ifm (x#bs) p)"
228 | "Ifm bs (A p) = (\<forall> x. Ifm (x#bs) p)"
230 consts prep :: "fm \<Rightarrow> fm"
231 recdef prep "measure fmsize"
232   "prep (E T) = T"
233   "prep (E F) = F"
234   "prep (E (Or p q)) = Or (prep (E p)) (prep (E q))"
235   "prep (E (Imp p q)) = Or (prep (E (NOT p))) (prep (E q))"
236   "prep (E (Iff p q)) = Or (prep (E (And p q))) (prep (E (And (NOT p) (NOT q))))"
237   "prep (E (NOT (And p q))) = Or (prep (E (NOT p))) (prep (E(NOT q)))"
238   "prep (E (NOT (Imp p q))) = prep (E (And p (NOT q)))"
239   "prep (E (NOT (Iff p q))) = Or (prep (E (And p (NOT q)))) (prep (E(And (NOT p) q)))"
240   "prep (E p) = E (prep p)"
241   "prep (A (And p q)) = And (prep (A p)) (prep (A q))"
242   "prep (A p) = prep (NOT (E (NOT p)))"
243   "prep (NOT (NOT p)) = prep p"
244   "prep (NOT (And p q)) = Or (prep (NOT p)) (prep (NOT q))"
245   "prep (NOT (A p)) = prep (E (NOT p))"
246   "prep (NOT (Or p q)) = And (prep (NOT p)) (prep (NOT q))"
247   "prep (NOT (Imp p q)) = And (prep p) (prep (NOT q))"
248   "prep (NOT (Iff p q)) = Or (prep (And p (NOT q))) (prep (And (NOT p) q))"
249   "prep (NOT p) = NOT (prep p)"
250   "prep (Or p q) = Or (prep p) (prep q)"
251   "prep (And p q) = And (prep p) (prep q)"
252   "prep (Imp p q) = prep (Or (NOT p) q)"
253   "prep (Iff p q) = Or (prep (And p q)) (prep (And (NOT p) (NOT q)))"
254   "prep p = p"
256 lemma prep: "\<And> bs. Ifm bs (prep p) = Ifm bs p"
257 by (induct p rule: prep.induct, auto)
260   (* Quantifier freeness *)
261 fun qfree:: "fm \<Rightarrow> bool" where
262   "qfree (E p) = False"
263   | "qfree (A p) = False"
264   | "qfree (NOT p) = qfree p"
265   | "qfree (And p q) = (qfree p \<and> qfree q)"
266   | "qfree (Or  p q) = (qfree p \<and> qfree q)"
267   | "qfree (Imp p q) = (qfree p \<and> qfree q)"
268   | "qfree (Iff p q) = (qfree p \<and> qfree q)"
269   | "qfree p = True"
271   (* Boundedness and substitution *)
272 primrec numbound0 :: "num \<Rightarrow> bool" (* a num is INDEPENDENT of Bound 0 *) where
273   "numbound0 (C c) = True"
274   | "numbound0 (Bound n) = (n>0)"
275   | "numbound0 (CN n i a) = (n > 0 \<and> numbound0 a)"
276   | "numbound0 (Neg a) = numbound0 a"
277   | "numbound0 (Add a b) = (numbound0 a \<and> numbound0 b)"
278   | "numbound0 (Sub a b) = (numbound0 a \<and> numbound0 b)"
279   | "numbound0 (Mul i a) = numbound0 a"
280   | "numbound0 (Floor a) = numbound0 a"
281   | "numbound0 (CF c a b) = (numbound0 a \<and> numbound0 b)"
283 lemma numbound0_I:
284   assumes nb: "numbound0 a"
285   shows "Inum (b#bs) a = Inum (b'#bs) a"
286   using nb by (induct a) auto
288 lemma numbound0_gen:
289   assumes nb: "numbound0 t" and ti: "isint t (x#bs)"
290   shows "\<forall> y. isint t (y#bs)"
291 using nb ti
292 proof(clarify)
293   fix y
294   from numbound0_I[OF nb, where bs="bs" and b="y" and b'="x"] ti[simplified isint_def]
295   show "isint t (y#bs)"
297 qed
299 primrec bound0:: "fm \<Rightarrow> bool" (* A Formula is independent of Bound 0 *) where
300   "bound0 T = True"
301   | "bound0 F = True"
302   | "bound0 (Lt a) = numbound0 a"
303   | "bound0 (Le a) = numbound0 a"
304   | "bound0 (Gt a) = numbound0 a"
305   | "bound0 (Ge a) = numbound0 a"
306   | "bound0 (Eq a) = numbound0 a"
307   | "bound0 (NEq a) = numbound0 a"
308   | "bound0 (Dvd i a) = numbound0 a"
309   | "bound0 (NDvd i a) = numbound0 a"
310   | "bound0 (NOT p) = bound0 p"
311   | "bound0 (And p q) = (bound0 p \<and> bound0 q)"
312   | "bound0 (Or p q) = (bound0 p \<and> bound0 q)"
313   | "bound0 (Imp p q) = ((bound0 p) \<and> (bound0 q))"
314   | "bound0 (Iff p q) = (bound0 p \<and> bound0 q)"
315   | "bound0 (E p) = False"
316   | "bound0 (A p) = False"
318 lemma bound0_I:
319   assumes bp: "bound0 p"
320   shows "Ifm (b#bs) p = Ifm (b'#bs) p"
321  using bp numbound0_I [where b="b" and bs="bs" and b'="b'"]
322   by (induct p) auto
324 primrec numsubst0:: "num \<Rightarrow> num \<Rightarrow> num" (* substitute a num into a num for Bound 0 *) where
325   "numsubst0 t (C c) = (C c)"
326   | "numsubst0 t (Bound n) = (if n=0 then t else Bound n)"
327   | "numsubst0 t (CN n i a) = (if n=0 then Add (Mul i t) (numsubst0 t a) else CN n i (numsubst0 t a))"
328   | "numsubst0 t (CF i a b) = CF i (numsubst0 t a) (numsubst0 t b)"
329   | "numsubst0 t (Neg a) = Neg (numsubst0 t a)"
330   | "numsubst0 t (Add a b) = Add (numsubst0 t a) (numsubst0 t b)"
331   | "numsubst0 t (Sub a b) = Sub (numsubst0 t a) (numsubst0 t b)"
332   | "numsubst0 t (Mul i a) = Mul i (numsubst0 t a)"
333   | "numsubst0 t (Floor a) = Floor (numsubst0 t a)"
335 lemma numsubst0_I:
336   shows "Inum (b#bs) (numsubst0 a t) = Inum ((Inum (b#bs) a)#bs) t"
337   by (induct t) simp_all
339 primrec subst0:: "num \<Rightarrow> fm \<Rightarrow> fm" (* substitue a num into a formula for Bound 0 *) where
340   "subst0 t T = T"
341   | "subst0 t F = F"
342   | "subst0 t (Lt a) = Lt (numsubst0 t a)"
343   | "subst0 t (Le a) = Le (numsubst0 t a)"
344   | "subst0 t (Gt a) = Gt (numsubst0 t a)"
345   | "subst0 t (Ge a) = Ge (numsubst0 t a)"
346   | "subst0 t (Eq a) = Eq (numsubst0 t a)"
347   | "subst0 t (NEq a) = NEq (numsubst0 t a)"
348   | "subst0 t (Dvd i a) = Dvd i (numsubst0 t a)"
349   | "subst0 t (NDvd i a) = NDvd i (numsubst0 t a)"
350   | "subst0 t (NOT p) = NOT (subst0 t p)"
351   | "subst0 t (And p q) = And (subst0 t p) (subst0 t q)"
352   | "subst0 t (Or p q) = Or (subst0 t p) (subst0 t q)"
353   | "subst0 t (Imp p q) = Imp (subst0 t p) (subst0 t q)"
354   | "subst0 t (Iff p q) = Iff (subst0 t p) (subst0 t q)"
356 lemma subst0_I: assumes qfp: "qfree p"
357   shows "Ifm (b#bs) (subst0 a p) = Ifm ((Inum (b#bs) a)#bs) p"
358   using qfp numsubst0_I[where b="b" and bs="bs" and a="a"]
359   by (induct p) simp_all
361 fun decrnum:: "num \<Rightarrow> num" where
362   "decrnum (Bound n) = Bound (n - 1)"
363 | "decrnum (Neg a) = Neg (decrnum a)"
364 | "decrnum (Add a b) = Add (decrnum a) (decrnum b)"
365 | "decrnum (Sub a b) = Sub (decrnum a) (decrnum b)"
366 | "decrnum (Mul c a) = Mul c (decrnum a)"
367 | "decrnum (Floor a) = Floor (decrnum a)"
368 | "decrnum (CN n c a) = CN (n - 1) c (decrnum a)"
369 | "decrnum (CF c a b) = CF c (decrnum a) (decrnum b)"
370 | "decrnum a = a"
372 fun decr :: "fm \<Rightarrow> fm" where
373   "decr (Lt a) = Lt (decrnum a)"
374 | "decr (Le a) = Le (decrnum a)"
375 | "decr (Gt a) = Gt (decrnum a)"
376 | "decr (Ge a) = Ge (decrnum a)"
377 | "decr (Eq a) = Eq (decrnum a)"
378 | "decr (NEq a) = NEq (decrnum a)"
379 | "decr (Dvd i a) = Dvd i (decrnum a)"
380 | "decr (NDvd i a) = NDvd i (decrnum a)"
381 | "decr (NOT p) = NOT (decr p)"
382 | "decr (And p q) = And (decr p) (decr q)"
383 | "decr (Or p q) = Or (decr p) (decr q)"
384 | "decr (Imp p q) = Imp (decr p) (decr q)"
385 | "decr (Iff p q) = Iff (decr p) (decr q)"
386 | "decr p = p"
388 lemma decrnum: assumes nb: "numbound0 t"
389   shows "Inum (x#bs) t = Inum bs (decrnum t)"
390   using nb by (induct t rule: decrnum.induct, simp_all)
392 lemma decr: assumes nb: "bound0 p"
393   shows "Ifm (x#bs) p = Ifm bs (decr p)"
394   using nb
395   by (induct p rule: decr.induct, simp_all add: decrnum)
397 lemma decr_qf: "bound0 p \<Longrightarrow> qfree (decr p)"
398 by (induct p, simp_all)
400 fun isatom :: "fm \<Rightarrow> bool" (* test for atomicity *) where
401   "isatom T = True"
402 | "isatom F = True"
403 | "isatom (Lt a) = True"
404 | "isatom (Le a) = True"
405 | "isatom (Gt a) = True"
406 | "isatom (Ge a) = True"
407 | "isatom (Eq a) = True"
408 | "isatom (NEq a) = True"
409 | "isatom (Dvd i b) = True"
410 | "isatom (NDvd i b) = True"
411 | "isatom p = False"
413 lemma numsubst0_numbound0: assumes nb: "numbound0 t"
414   shows "numbound0 (numsubst0 t a)"
415 using nb by (induct a, auto)
417 lemma subst0_bound0: assumes qf: "qfree p" and nb: "numbound0 t"
418   shows "bound0 (subst0 t p)"
419 using qf numsubst0_numbound0[OF nb] by (induct p, auto)
421 lemma bound0_qf: "bound0 p \<Longrightarrow> qfree p"
422 by (induct p, simp_all)
425 definition djf:: "('a \<Rightarrow> fm) \<Rightarrow> 'a \<Rightarrow> fm \<Rightarrow> fm" where
426   "djf f p q = (if q=T then T else if q=F then f p else
427   (let fp = f p in case fp of T \<Rightarrow> T | F \<Rightarrow> q | _ \<Rightarrow> Or fp q))"
429 definition evaldjf:: "('a \<Rightarrow> fm) \<Rightarrow> 'a list \<Rightarrow> fm" where
430   "evaldjf f ps = foldr (djf f) ps F"
432 lemma djf_Or: "Ifm bs (djf f p q) = Ifm bs (Or (f p) q)"
434 (cases "f p", simp_all add: Let_def djf_def)
436 lemma evaldjf_ex: "Ifm bs (evaldjf f ps) = (\<exists> p \<in> set ps. Ifm bs (f p))"
437   by(induct ps, simp_all add: evaldjf_def djf_Or)
439 lemma evaldjf_bound0:
440   assumes nb: "\<forall> x\<in> set xs. bound0 (f x)"
441   shows "bound0 (evaldjf f xs)"
442   using nb by (induct xs, auto simp add: evaldjf_def djf_def Let_def) (case_tac "f a", auto)
444 lemma evaldjf_qf:
445   assumes nb: "\<forall> x\<in> set xs. qfree (f x)"
446   shows "qfree (evaldjf f xs)"
447   using nb by (induct xs, auto simp add: evaldjf_def djf_def Let_def) (case_tac "f a", auto)
449 fun disjuncts :: "fm \<Rightarrow> fm list" where
450   "disjuncts (Or p q) = (disjuncts p) @ (disjuncts q)"
451 | "disjuncts F = []"
452 | "disjuncts p = [p]"
454 fun conjuncts :: "fm \<Rightarrow> fm list" where
455   "conjuncts (And p q) = (conjuncts p) @ (conjuncts q)"
456 | "conjuncts T = []"
457 | "conjuncts p = [p]"
459 lemma conjuncts: "(\<forall> q\<in> set (conjuncts p). Ifm bs q) = Ifm bs p"
460 by(induct p rule: conjuncts.induct, auto)
462 lemma disjuncts_qf: "qfree p \<Longrightarrow> \<forall> q\<in> set (disjuncts p). qfree q"
463 proof-
464   assume qf: "qfree p"
465   hence "list_all qfree (disjuncts p)"
466     by (induct p rule: disjuncts.induct, auto)
467   thus ?thesis by (simp only: list_all_iff)
468 qed
469 lemma conjuncts_qf: "qfree p \<Longrightarrow> \<forall> q\<in> set (conjuncts p). qfree q"
470 proof-
471   assume qf: "qfree p"
472   hence "list_all qfree (conjuncts p)"
473     by (induct p rule: conjuncts.induct, auto)
474   thus ?thesis by (simp only: list_all_iff)
475 qed
477 definition DJ :: "(fm \<Rightarrow> fm) \<Rightarrow> fm \<Rightarrow> fm" where
478   "DJ f p \<equiv> evaldjf f (disjuncts p)"
480 lemma DJ: assumes fdj: "\<forall> p q. f (Or p q) = Or (f p) (f q)"
481   and fF: "f F = F"
482   shows "Ifm bs (DJ f p) = Ifm bs (f p)"
483 proof-
484   have "Ifm bs (DJ f p) = (\<exists> q \<in> set (disjuncts p). Ifm bs (f q))"
485     by (simp add: DJ_def evaldjf_ex)
486   also have "\<dots> = Ifm bs (f p)" using fdj fF by (induct p rule: disjuncts.induct, auto)
487   finally show ?thesis .
488 qed
490 lemma DJ_qf: assumes
491   fqf: "\<forall> p. qfree p \<longrightarrow> qfree (f p)"
492   shows "\<forall>p. qfree p \<longrightarrow> qfree (DJ f p) "
493 proof(clarify)
494   fix  p assume qf: "qfree p"
495   have th: "DJ f p = evaldjf f (disjuncts p)" by (simp add: DJ_def)
496   from disjuncts_qf[OF qf] have "\<forall> q\<in> set (disjuncts p). qfree q" .
497   with fqf have th':"\<forall> q\<in> set (disjuncts p). qfree (f q)" by blast
499   from evaldjf_qf[OF th'] th show "qfree (DJ f p)" by simp
500 qed
502 lemma DJ_qe: assumes qe: "\<forall> bs p. qfree p \<longrightarrow> qfree (qe p) \<and> (Ifm bs (qe p) = Ifm bs (E p))"
503   shows "\<forall> bs p. qfree p \<longrightarrow> qfree (DJ qe p) \<and> (Ifm bs ((DJ qe p)) = Ifm bs (E p))"
504 proof(clarify)
505   fix p::fm and bs
506   assume qf: "qfree p"
507   from qe have qth: "\<forall> p. qfree p \<longrightarrow> qfree (qe p)" by blast
508   from DJ_qf[OF qth] qf have qfth:"qfree (DJ qe p)" by auto
509   have "Ifm bs (DJ qe p) = (\<exists> q\<in> set (disjuncts p). Ifm bs (qe q))"
510     by (simp add: DJ_def evaldjf_ex)
511   also have "\<dots> = (\<exists> q \<in> set(disjuncts p). Ifm bs (E q))" using qe disjuncts_qf[OF qf] by auto
512   also have "\<dots> = Ifm bs (E p)" by (induct p rule: disjuncts.induct, auto)
513   finally show "qfree (DJ qe p) \<and> Ifm bs (DJ qe p) = Ifm bs (E p)" using qfth by blast
514 qed
515   (* Simplification *)
517   (* Algebraic simplifications for nums *)
518 fun bnds:: "num \<Rightarrow> nat list" where
519   "bnds (Bound n) = [n]"
520 | "bnds (CN n c a) = n#(bnds a)"
521 | "bnds (Neg a) = bnds a"
522 | "bnds (Add a b) = (bnds a)@(bnds b)"
523 | "bnds (Sub a b) = (bnds a)@(bnds b)"
524 | "bnds (Mul i a) = bnds a"
525 | "bnds (Floor a) = bnds a"
526 | "bnds (CF c a b) = (bnds a)@(bnds b)"
527 | "bnds a = []"
528 fun lex_ns:: "nat list \<Rightarrow> nat list \<Rightarrow> bool" where
529   "lex_ns [] ms = True"
530 | "lex_ns ns [] = False"
531 | "lex_ns (n#ns) (m#ms) = (n<m \<or> ((n = m) \<and> lex_ns ns ms)) "
532 definition lex_bnd :: "num \<Rightarrow> num \<Rightarrow> bool" where
533   "lex_bnd t s \<equiv> lex_ns (bnds t) (bnds s)"
535 fun maxcoeff:: "num \<Rightarrow> int" where
536   "maxcoeff (C i) = abs i"
537 | "maxcoeff (CN n c t) = max (abs c) (maxcoeff t)"
538 | "maxcoeff (CF c t s) = max (abs c) (maxcoeff s)"
539 | "maxcoeff t = 1"
541 lemma maxcoeff_pos: "maxcoeff t \<ge> 0"
542   apply (induct t rule: maxcoeff.induct, auto)
543   done
545 fun numgcdh:: "num \<Rightarrow> int \<Rightarrow> int" where
546   "numgcdh (C i) = (\<lambda>g. gcd i g)"
547 | "numgcdh (CN n c t) = (\<lambda>g. gcd c (numgcdh t g))"
548 | "numgcdh (CF c s t) = (\<lambda>g. gcd c (numgcdh t g))"
549 | "numgcdh t = (\<lambda>g. 1)"
551 definition
552   numgcd :: "num \<Rightarrow> int"
553 where
554   numgcd_def: "numgcd t = numgcdh t (maxcoeff t)"
556 fun reducecoeffh:: "num \<Rightarrow> int \<Rightarrow> num" where
557   "reducecoeffh (C i) = (\<lambda> g. C (i div g))"
558 | "reducecoeffh (CN n c t) = (\<lambda> g. CN n (c div g) (reducecoeffh t g))"
559 | "reducecoeffh (CF c s t) = (\<lambda> g. CF (c div g)  s (reducecoeffh t g))"
560 | "reducecoeffh t = (\<lambda>g. t)"
562 definition
563   reducecoeff :: "num \<Rightarrow> num"
564 where
565   reducecoeff_def: "reducecoeff t =
566   (let g = numgcd t in
567   if g = 0 then C 0 else if g=1 then t else reducecoeffh t g)"
569 fun dvdnumcoeff:: "num \<Rightarrow> int \<Rightarrow> bool" where
570   "dvdnumcoeff (C i) = (\<lambda> g. g dvd i)"
571 | "dvdnumcoeff (CN n c t) = (\<lambda> g. g dvd c \<and> (dvdnumcoeff t g))"
572 | "dvdnumcoeff (CF c s t) = (\<lambda> g. g dvd c \<and> (dvdnumcoeff t g))"
573 | "dvdnumcoeff t = (\<lambda>g. False)"
575 lemma dvdnumcoeff_trans:
576   assumes gdg: "g dvd g'" and dgt':"dvdnumcoeff t g'"
577   shows "dvdnumcoeff t g"
578   using dgt' gdg
579   by (induct t rule: dvdnumcoeff.induct, simp_all add: gdg dvd_trans[OF gdg])
583 lemma numgcd0:
584   assumes g0: "numgcd t = 0"
585   shows "Inum bs t = 0"
586 proof-
587   have "\<And>x. numgcdh t x= 0 \<Longrightarrow> Inum bs t = 0"
588     by (induct t rule: numgcdh.induct, auto)
589   thus ?thesis using g0[simplified numgcd_def] by blast
590 qed
592 lemma numgcdh_pos: assumes gp: "g \<ge> 0" shows "numgcdh t g \<ge> 0"
593   using gp
594   by (induct t rule: numgcdh.induct, auto)
596 lemma numgcd_pos: "numgcd t \<ge>0"
597   by (simp add: numgcd_def numgcdh_pos maxcoeff_pos)
599 lemma reducecoeffh:
600   assumes gt: "dvdnumcoeff t g" and gp: "g > 0"
601   shows "real g *(Inum bs (reducecoeffh t g)) = Inum bs t"
602   using gt
603 proof(induct t rule: reducecoeffh.induct)
604   case (1 i) hence gd: "g dvd i" by simp
605   from gp have gnz: "g \<noteq> 0" by simp
606   from assms 1 show ?case by (simp add: real_of_int_div[OF gnz gd])
607 next
608   case (2 n c t)  hence gd: "g dvd c" by simp
609   from gp have gnz: "g \<noteq> 0" by simp
610   from assms 2 show ?case by (simp add: real_of_int_div[OF gnz gd] algebra_simps)
611 next
612   case (3 c s t)  hence gd: "g dvd c" by simp
613   from gp have gnz: "g \<noteq> 0" by simp
614   from assms 3 show ?case by (simp add: real_of_int_div[OF gnz gd] algebra_simps)
615 qed (auto simp add: numgcd_def gp)
617 fun ismaxcoeff:: "num \<Rightarrow> int \<Rightarrow> bool" where
618   "ismaxcoeff (C i) = (\<lambda> x. abs i \<le> x)"
619 | "ismaxcoeff (CN n c t) = (\<lambda>x. abs c \<le> x \<and> (ismaxcoeff t x))"
620 | "ismaxcoeff (CF c s t) = (\<lambda>x. abs c \<le> x \<and> (ismaxcoeff t x))"
621 | "ismaxcoeff t = (\<lambda>x. True)"
623 lemma ismaxcoeff_mono: "ismaxcoeff t c \<Longrightarrow> c \<le> c' \<Longrightarrow> ismaxcoeff t c'"
624 by (induct t rule: ismaxcoeff.induct, auto)
626 lemma maxcoeff_ismaxcoeff: "ismaxcoeff t (maxcoeff t)"
627 proof (induct t rule: maxcoeff.induct)
628   case (2 n c t)
629   hence H:"ismaxcoeff t (maxcoeff t)" .
630   have thh: "maxcoeff t \<le> max (abs c) (maxcoeff t)" by simp
631   from ismaxcoeff_mono[OF H thh] show ?case by (simp add: le_maxI1)
632 next
633   case (3 c t s)
634   hence H1:"ismaxcoeff s (maxcoeff s)" by auto
635   have thh1: "maxcoeff s \<le> max \<bar>c\<bar> (maxcoeff s)" by (simp add: max_def)
636   from ismaxcoeff_mono[OF H1 thh1] show ?case by (simp add: le_maxI1)
637 qed simp_all
639 lemma zgcd_gt1: "gcd i j > (1::int) \<Longrightarrow> ((abs i > 1 \<and> abs j > 1) \<or> (abs i = 0 \<and> abs j > 1) \<or> (abs i > 1 \<and> abs j = 0))"
640   apply (unfold gcd_int_def)
641   apply (cases "i = 0", simp_all)
642   apply (cases "j = 0", simp_all)
643   apply (cases "abs i = 1", simp_all)
644   apply (cases "abs j = 1", simp_all)
645   apply auto
646   done
647 lemma numgcdh0:"numgcdh t m = 0 \<Longrightarrow>  m =0"
648   by (induct t rule: numgcdh.induct) auto
650 lemma dvdnumcoeff_aux:
651   assumes "ismaxcoeff t m" and mp:"m \<ge> 0" and "numgcdh t m > 1"
652   shows "dvdnumcoeff t (numgcdh t m)"
653 using assms
654 proof(induct t rule: numgcdh.induct)
655   case (2 n c t)
656   let ?g = "numgcdh t m"
657   from 2 have th:"gcd c ?g > 1" by simp
658   from zgcd_gt1[OF th] numgcdh_pos[OF mp, where t="t"]
659   have "(abs c > 1 \<and> ?g > 1) \<or> (abs c = 0 \<and> ?g > 1) \<or> (abs c > 1 \<and> ?g = 0)" by simp
660   moreover {assume "abs c > 1" and gp: "?g > 1" with 2
661     have th: "dvdnumcoeff t ?g" by simp
662     have th': "gcd c ?g dvd ?g" by simp
663     from dvdnumcoeff_trans[OF th' th] have ?case by simp }
664   moreover {assume "abs c = 0 \<and> ?g > 1"
665     with 2 have th: "dvdnumcoeff t ?g" by simp
666     have th': "gcd c ?g dvd ?g" by simp
667     from dvdnumcoeff_trans[OF th' th] have ?case by simp
668     hence ?case by simp }
669   moreover {assume "abs c > 1" and g0:"?g = 0"
670     from numgcdh0[OF g0] have "m=0". with 2 g0 have ?case by simp }
671   ultimately show ?case by blast
672 next
673   case (3 c s t)
674   let ?g = "numgcdh t m"
675   from 3 have th:"gcd c ?g > 1" by simp
676   from zgcd_gt1[OF th] numgcdh_pos[OF mp, where t="t"]
677   have "(abs c > 1 \<and> ?g > 1) \<or> (abs c = 0 \<and> ?g > 1) \<or> (abs c > 1 \<and> ?g = 0)" by simp
678   moreover {assume "abs c > 1" and gp: "?g > 1" with 3
679     have th: "dvdnumcoeff t ?g" by simp
680     have th': "gcd c ?g dvd ?g" by simp
681     from dvdnumcoeff_trans[OF th' th] have ?case by simp }
682   moreover {assume "abs c = 0 \<and> ?g > 1"
683     with 3 have th: "dvdnumcoeff t ?g" by simp
684     have th': "gcd c ?g dvd ?g" by simp
685     from dvdnumcoeff_trans[OF th' th] have ?case by simp
686     hence ?case by simp }
687   moreover {assume "abs c > 1" and g0:"?g = 0"
688     from numgcdh0[OF g0] have "m=0". with 3 g0 have ?case by simp }
689   ultimately show ?case by blast
690 qed auto
692 lemma dvdnumcoeff_aux2:
693   assumes "numgcd t > 1" shows "dvdnumcoeff t (numgcd t) \<and> numgcd t > 0"
694   using assms
696   let ?mc = "maxcoeff t"
697   let ?g = "numgcdh t ?mc"
698   have th1: "ismaxcoeff t ?mc" by (rule maxcoeff_ismaxcoeff)
699   have th2: "?mc \<ge> 0" by (rule maxcoeff_pos)
700   assume H: "numgcdh t ?mc > 1"
701   from dvdnumcoeff_aux[OF th1 th2 H] show "dvdnumcoeff t ?g" .
702 qed
704 lemma reducecoeff: "real (numgcd t) * (Inum bs (reducecoeff t)) = Inum bs t"
705 proof-
706   let ?g = "numgcd t"
707   have "?g \<ge> 0"  by (simp add: numgcd_pos)
708   hence "?g = 0 \<or> ?g = 1 \<or> ?g > 1" by auto
709   moreover {assume "?g = 0" hence ?thesis by (simp add: numgcd0)}
710   moreover {assume "?g = 1" hence ?thesis by (simp add: reducecoeff_def)}
711   moreover { assume g1:"?g > 1"
712     from dvdnumcoeff_aux2[OF g1] have th1:"dvdnumcoeff t ?g" and g0: "?g > 0" by blast+
713     from reducecoeffh[OF th1 g0, where bs="bs"] g1 have ?thesis
714       by (simp add: reducecoeff_def Let_def)}
715   ultimately show ?thesis by blast
716 qed
718 lemma reducecoeffh_numbound0: "numbound0 t \<Longrightarrow> numbound0 (reducecoeffh t g)"
719 by (induct t rule: reducecoeffh.induct, auto)
721 lemma reducecoeff_numbound0: "numbound0 t \<Longrightarrow> numbound0 (reducecoeff t)"
722 using reducecoeffh_numbound0 by (simp add: reducecoeff_def Let_def)
724 consts
725   numadd:: "num \<times> num \<Rightarrow> num"
727 recdef numadd "measure (\<lambda> (t,s). size t + size s)"
728   "numadd (CN n1 c1 r1,CN n2 c2 r2) =
729   (if n1=n2 then
730   (let c = c1 + c2
731   in (if c=0 then numadd(r1,r2) else CN n1 c (numadd (r1,r2))))
732   else if n1 \<le> n2 then CN n1 c1 (numadd (r1,CN n2 c2 r2))
733   else (CN n2 c2 (numadd (CN n1 c1 r1,r2))))"
734   "numadd (CN n1 c1 r1,t) = CN n1 c1 (numadd (r1, t))"
735   "numadd (t,CN n2 c2 r2) = CN n2 c2 (numadd (t,r2))"
736   "numadd (CF c1 t1 r1,CF c2 t2 r2) =
737    (if t1 = t2 then
738     (let c=c1+c2; s= numadd(r1,r2) in (if c=0 then s else CF c t1 s))
739    else if lex_bnd t1 t2 then CF c1 t1 (numadd(r1,CF c2 t2 r2))
740    else CF c2 t2 (numadd(CF c1 t1 r1,r2)))"
741   "numadd (CF c1 t1 r1,C c) = CF c1 t1 (numadd (r1, C c))"
742   "numadd (C c,CF c1 t1 r1) = CF c1 t1 (numadd (r1, C c))"
743   "numadd (C b1, C b2) = C (b1+b2)"
748  apply (case_tac "c1+c2 = 0",case_tac "n1 \<le> n2", simp_all)
749   apply (case_tac "n1 = n2", simp_all add: algebra_simps)
750   apply (simp only: left_distrib[symmetric])
751  apply simp
752 apply (case_tac "lex_bnd t1 t2", simp_all)
753  apply (case_tac "c1+c2 = 0")
756 lemma numadd_nb[simp]: "\<lbrakk> numbound0 t ; numbound0 s\<rbrakk> \<Longrightarrow> numbound0 (numadd (t,s))"
759 fun nummul:: "num \<Rightarrow> int \<Rightarrow> num" where
760   "nummul (C j) = (\<lambda> i. C (i*j))"
761 | "nummul (CN n c t) = (\<lambda> i. CN n (c*i) (nummul t i))"
762 | "nummul (CF c t s) = (\<lambda> i. CF (c*i) t (nummul s i))"
763 | "nummul (Mul c t) = (\<lambda> i. nummul t (i*c))"
764 | "nummul t = (\<lambda> i. Mul i t)"
766 lemma nummul[simp]: "\<And> i. Inum bs (nummul t i) = Inum bs (Mul i t)"
767 by (induct t rule: nummul.induct, auto simp add: algebra_simps)
769 lemma nummul_nb[simp]: "\<And> i. numbound0 t \<Longrightarrow> numbound0 (nummul t i)"
770 by (induct t rule: nummul.induct, auto)
772 definition numneg :: "num \<Rightarrow> num" where
773   "numneg t \<equiv> nummul t (- 1)"
775 definition numsub :: "num \<Rightarrow> num \<Rightarrow> num" where
776   "numsub s t \<equiv> (if s = t then C 0 else numadd (s,numneg t))"
778 lemma numneg[simp]: "Inum bs (numneg t) = Inum bs (Neg t)"
779 using numneg_def nummul by simp
781 lemma numneg_nb[simp]: "numbound0 t \<Longrightarrow> numbound0 (numneg t)"
782 using numneg_def by simp
784 lemma numsub[simp]: "Inum bs (numsub a b) = Inum bs (Sub a b)"
785 using numsub_def by simp
787 lemma numsub_nb[simp]: "\<lbrakk> numbound0 t ; numbound0 s\<rbrakk> \<Longrightarrow> numbound0 (numsub t s)"
788 using numsub_def by simp
790 lemma isint_CF: assumes si: "isint s bs" shows "isint (CF c t s) bs"
791 proof-
792   have cti: "isint (Mul c (Floor t)) bs" by (simp add: isint_Mul isint_Floor)
794   have "?thesis = isint (Add (Mul c (Floor t)) s) bs" by (simp add: isint_def)
796   finally show ?thesis .
797 qed
799 fun split_int:: "num \<Rightarrow> num \<times> num" where
800   "split_int (C c) = (C 0, C c)"
801 | "split_int (CN n c b) =
802      (let (bv,bi) = split_int b
803        in (CN n c bv, bi))"
804 | "split_int (CF c a b) =
805      (let (bv,bi) = split_int b
806        in (bv, CF c a bi))"
807 | "split_int a = (a,C 0)"
809 lemma split_int: "\<And>tv ti. split_int t = (tv,ti) \<Longrightarrow> (Inum bs (Add tv ti) = Inum bs t) \<and> isint ti bs"
810 proof (induct t rule: split_int.induct)
811   case (2 c n b tv ti)
812   let ?bv = "fst (split_int b)"
813   let ?bi = "snd (split_int b)"
814   have "split_int b = (?bv,?bi)" by simp
815   with 2(1) have b:"Inum bs (Add ?bv ?bi) = Inum bs b" and bii: "isint ?bi bs" by blast+
816   from 2(2) have tibi: "ti = ?bi" by (simp add: Let_def split_def)
817   from 2(2) b[symmetric] bii show ?case by (auto simp add: Let_def split_def)
818 next
819   case (3 c a b tv ti)
820   let ?bv = "fst (split_int b)"
821   let ?bi = "snd (split_int b)"
822   have "split_int b = (?bv,?bi)" by simp
823   with 3(1) have b:"Inum bs (Add ?bv ?bi) = Inum bs b" and bii: "isint ?bi bs" by blast+
824   from 3(2) have tibi: "ti = CF c a ?bi"
825     by (simp add: Let_def split_def)
826   from 3(2) b[symmetric] bii show ?case
828 qed (auto simp add: Let_def isint_iff isint_Floor isint_add isint_Mul split_def algebra_simps)
830 lemma split_int_nb: "numbound0 t \<Longrightarrow> numbound0 (fst (split_int t)) \<and> numbound0 (snd (split_int t)) "
831   by (induct t rule: split_int.induct) (auto simp add: Let_def split_def)
833 definition numfloor:: "num \<Rightarrow> num"
834 where
835   "numfloor t = (let (tv,ti) = split_int t in
836   (case tv of C i \<Rightarrow> numadd (tv,ti)
837   | _ \<Rightarrow> numadd(CF 1 tv (C 0),ti)))"
839 lemma numfloor[simp]: "Inum bs (numfloor t) = Inum bs (Floor t)" (is "?n t = ?N (Floor t)")
840 proof-
841   let ?tv = "fst (split_int t)"
842   let ?ti = "snd (split_int t)"
843   have tvti:"split_int t = (?tv,?ti)" by simp
844   {assume H: "\<forall> v. ?tv \<noteq> C v"
845     hence th1: "?n t = ?N (Add (Floor ?tv) ?ti)"
847     from split_int[OF tvti] have "?N (Floor t) = ?N (Floor(Add ?tv ?ti))" and tii:"isint ?ti bs" by simp+
848     hence "?N (Floor t) = real (floor (?N (Add ?tv ?ti)))" by simp
849     also have "\<dots> = real (floor (?N ?tv) + (floor (?N ?ti)))"
850       by (simp,subst tii[simplified isint_iff, symmetric]) simp
851     also have "\<dots> = ?N (Add (Floor ?tv) ?ti)" by (simp add: tii[simplified isint_iff])
852     finally have ?thesis using th1 by simp}
853   moreover {fix v assume H:"?tv = C v"
854     from split_int[OF tvti] have "?N (Floor t) = ?N (Floor(Add ?tv ?ti))" and tii:"isint ?ti bs" by simp+
855     hence "?N (Floor t) = real (floor (?N (Add ?tv ?ti)))" by simp
856     also have "\<dots> = real (floor (?N ?tv) + (floor (?N ?ti)))"
857       by (simp,subst tii[simplified isint_iff, symmetric]) simp
858     also have "\<dots> = ?N (Add (Floor ?tv) ?ti)" by (simp add: tii[simplified isint_iff])
859     finally have ?thesis by (simp add: H numfloor_def Let_def split_def numadd) }
860   ultimately show ?thesis by auto
861 qed
863 lemma numfloor_nb[simp]: "numbound0 t \<Longrightarrow> numbound0 (numfloor t)"
864   using split_int_nb[where t="t"]
865   by (cases "fst(split_int t)" , auto simp add: numfloor_def Let_def split_def  numadd_nb)
867 function simpnum:: "num \<Rightarrow> num" where
868   "simpnum (C j) = C j"
869 | "simpnum (Bound n) = CN n 1 (C 0)"
870 | "simpnum (Neg t) = numneg (simpnum t)"
872 | "simpnum (Sub t s) = numsub (simpnum t) (simpnum s)"
873 | "simpnum (Mul i t) = (if i = 0 then (C 0) else nummul (simpnum t) i)"
874 | "simpnum (Floor t) = numfloor (simpnum t)"
875 | "simpnum (CN n c t) = (if c=0 then simpnum t else CN n c (simpnum t))"
876 | "simpnum (CF c t s) = simpnum(Add (Mul c (Floor t)) s)"
877 by pat_completeness auto
878 termination by (relation "measure num_size") auto
880 lemma simpnum_ci[simp]: "Inum bs (simpnum t) = Inum bs t"
881 by (induct t rule: simpnum.induct, auto)
883 lemma simpnum_numbound0[simp]:
884   "numbound0 t \<Longrightarrow> numbound0 (simpnum t)"
885 by (induct t rule: simpnum.induct, auto)
887 fun nozerocoeff:: "num \<Rightarrow> bool" where
888   "nozerocoeff (C c) = True"
889 | "nozerocoeff (CN n c t) = (c\<noteq>0 \<and> nozerocoeff t)"
890 | "nozerocoeff (CF c s t) = (c \<noteq> 0 \<and> nozerocoeff t)"
891 | "nozerocoeff (Mul c t) = (c\<noteq>0 \<and> nozerocoeff t)"
892 | "nozerocoeff t = True"
894 lemma numadd_nz : "nozerocoeff a \<Longrightarrow> nozerocoeff b \<Longrightarrow> nozerocoeff (numadd (a,b))"
897 lemma nummul_nz : "\<And> i. i\<noteq>0 \<Longrightarrow> nozerocoeff a \<Longrightarrow> nozerocoeff (nummul a i)"
900 lemma numneg_nz : "nozerocoeff a \<Longrightarrow> nozerocoeff (numneg a)"
901 by (simp add: numneg_def nummul_nz)
903 lemma numsub_nz: "nozerocoeff a \<Longrightarrow> nozerocoeff b \<Longrightarrow> nozerocoeff (numsub a b)"
906 lemma split_int_nz: "nozerocoeff t \<Longrightarrow> nozerocoeff (fst (split_int t)) \<and> nozerocoeff (snd (split_int t))"
907 by (induct t rule: split_int.induct,auto simp add: Let_def split_def)
909 lemma numfloor_nz: "nozerocoeff t \<Longrightarrow> nozerocoeff (numfloor t)"
910 by (simp add: numfloor_def Let_def split_def)
913 lemma simpnum_nz: "nozerocoeff (simpnum t)"
914 by(induct t rule: simpnum.induct, auto simp add: numadd_nz numneg_nz numsub_nz nummul_nz numfloor_nz)
916 lemma maxcoeff_nz: "nozerocoeff t \<Longrightarrow> maxcoeff t = 0 \<Longrightarrow> t = C 0"
917 proof (induct t rule: maxcoeff.induct)
918   case (2 n c t)
919   hence cnz: "c \<noteq>0" and mx: "max (abs c) (maxcoeff t) = 0" by simp+
920   have "max (abs c) (maxcoeff t) \<ge> abs c" by (simp add: le_maxI1)
921   with cnz have "max (abs c) (maxcoeff t) > 0" by arith
922   with 2 show ?case by simp
923 next
924   case (3 c s t)
925   hence cnz: "c \<noteq>0" and mx: "max (abs c) (maxcoeff t) = 0" by simp+
926   have "max (abs c) (maxcoeff t) \<ge> abs c" by (simp add: le_maxI1)
927   with cnz have "max (abs c) (maxcoeff t) > 0" by arith
928   with 3 show ?case by simp
929 qed auto
931 lemma numgcd_nz: assumes nz: "nozerocoeff t" and g0: "numgcd t = 0" shows "t = C 0"
932 proof-
933   from g0 have th:"numgcdh t (maxcoeff t) = 0" by (simp add: numgcd_def)
934   from numgcdh0[OF th]  have th:"maxcoeff t = 0" .
935   from maxcoeff_nz[OF nz th] show ?thesis .
936 qed
938 definition simp_num_pair :: "(num \<times> int) \<Rightarrow> num \<times> int" where
939   "simp_num_pair \<equiv> (\<lambda> (t,n). (if n = 0 then (C 0, 0) else
940    (let t' = simpnum t ; g = numgcd t' in
941       if g > 1 then (let g' = gcd n g in
942         if g' = 1 then (t',n)
943         else (reducecoeffh t' g', n div g'))
944       else (t',n))))"
946 lemma simp_num_pair_ci:
947   shows "((\<lambda> (t,n). Inum bs t / real n) (simp_num_pair (t,n))) = ((\<lambda> (t,n). Inum bs t / real n) (t,n))"
948   (is "?lhs = ?rhs")
949 proof-
950   let ?t' = "simpnum t"
951   let ?g = "numgcd ?t'"
952   let ?g' = "gcd n ?g"
953   {assume nz: "n = 0" hence ?thesis by (simp add: Let_def simp_num_pair_def)}
954   moreover
955   { assume nnz: "n \<noteq> 0"
956     {assume "\<not> ?g > 1" hence ?thesis by (simp add: Let_def simp_num_pair_def)}
957     moreover
958     {assume g1:"?g>1" hence g0: "?g > 0" by simp
959       from g1 nnz have gp0: "?g' \<noteq> 0" by simp
960       hence g'p: "?g' > 0" using gcd_ge_0_int[where x="n" and y="numgcd ?t'"] by arith
961       hence "?g'= 1 \<or> ?g' > 1" by arith
962       moreover {assume "?g'=1" hence ?thesis by (simp add: Let_def simp_num_pair_def)}
963       moreover {assume g'1:"?g'>1"
964         from dvdnumcoeff_aux2[OF g1] have th1:"dvdnumcoeff ?t' ?g" ..
965         let ?tt = "reducecoeffh ?t' ?g'"
966         let ?t = "Inum bs ?tt"
967         have gpdg: "?g' dvd ?g" by simp
968         have gpdd: "?g' dvd n" by simp
969         have gpdgp: "?g' dvd ?g'" by simp
970         from reducecoeffh[OF dvdnumcoeff_trans[OF gpdg th1] g'p]
971         have th2:"real ?g' * ?t = Inum bs ?t'" by simp
972         from nnz g1 g'1 have "?lhs = ?t / real (n div ?g')" by (simp add: simp_num_pair_def Let_def)
973         also have "\<dots> = (real ?g' * ?t) / (real ?g' * (real (n div ?g')))" by simp
974         also have "\<dots> = (Inum bs ?t' / real n)"
975           using real_of_int_div[OF gp0 gpdd] th2 gp0 by simp
976         finally have "?lhs = Inum bs t / real n" by simp
977         then have ?thesis using nnz g1 g'1 by (simp add: simp_num_pair_def) }
978       ultimately have ?thesis by blast }
979     ultimately have ?thesis by blast }
980   ultimately show ?thesis by blast
981 qed
983 lemma simp_num_pair_l:
984   assumes tnb: "numbound0 t" and np: "n >0" and tn: "simp_num_pair (t,n) = (t',n')"
985   shows "numbound0 t' \<and> n' >0"
986 proof-
987   let ?t' = "simpnum t"
988   let ?g = "numgcd ?t'"
989   let ?g' = "gcd n ?g"
990   { assume nz: "n = 0" hence ?thesis using assms by (simp add: Let_def simp_num_pair_def) }
991   moreover
992   { assume nnz: "n \<noteq> 0"
993     {assume "\<not> ?g > 1" hence ?thesis using assms by (auto simp add: Let_def simp_num_pair_def) }
994     moreover
995     {assume g1:"?g>1" hence g0: "?g > 0" by simp
996       from g1 nnz have gp0: "?g' \<noteq> 0" by simp
997       hence g'p: "?g' > 0" using gcd_ge_0_int[where x="n" and y="numgcd ?t'"] by arith
998       hence "?g'= 1 \<or> ?g' > 1" by arith
999       moreover {assume "?g'=1" hence ?thesis using assms g1 g0
1000           by (auto simp add: Let_def simp_num_pair_def) }
1001       moreover {assume g'1:"?g'>1"
1002         have gpdg: "?g' dvd ?g" by simp
1003         have gpdd: "?g' dvd n" by simp
1004         have gpdgp: "?g' dvd ?g'" by simp
1005         from zdvd_imp_le[OF gpdd np] have g'n: "?g' \<le> n" .
1006         from zdiv_mono1[OF g'n g'p, simplified zdiv_self[OF gp0]]
1007         have "n div ?g' >0" by simp
1008         hence ?thesis using assms g1 g'1
1009           by(auto simp add: simp_num_pair_def Let_def reducecoeffh_numbound0)}
1010       ultimately have ?thesis by blast }
1011     ultimately have ?thesis by blast }
1012   ultimately show ?thesis by blast
1013 qed
1015 fun not:: "fm \<Rightarrow> fm" where
1016   "not (NOT p) = p"
1017 | "not T = F"
1018 | "not F = T"
1019 | "not (Lt t) = Ge t"
1020 | "not (Le t) = Gt t"
1021 | "not (Gt t) = Le t"
1022 | "not (Ge t) = Lt t"
1023 | "not (Eq t) = NEq t"
1024 | "not (NEq t) = Eq t"
1025 | "not (Dvd i t) = NDvd i t"
1026 | "not (NDvd i t) = Dvd i t"
1027 | "not (And p q) = Or (not p) (not q)"
1028 | "not (Or p q) = And (not p) (not q)"
1029 | "not p = NOT p"
1030 lemma not[simp]: "Ifm bs (not p) = Ifm bs (NOT p)"
1031   by (induct p) auto
1032 lemma not_qf[simp]: "qfree p \<Longrightarrow> qfree (not p)"
1033   by (induct p) auto
1034 lemma not_nb[simp]: "bound0 p \<Longrightarrow> bound0 (not p)"
1035   by (induct p) auto
1037 definition conj :: "fm \<Rightarrow> fm \<Rightarrow> fm" where
1038   "conj p q \<equiv> (if (p = F \<or> q=F) then F else if p=T then q else if q=T then p else
1039    if p = q then p else And p q)"
1040 lemma conj[simp]: "Ifm bs (conj p q) = Ifm bs (And p q)"
1041   by (cases "p=F \<or> q=F", simp_all add: conj_def) (cases p, simp_all)
1043 lemma conj_qf[simp]: "\<lbrakk>qfree p ; qfree q\<rbrakk> \<Longrightarrow> qfree (conj p q)"
1044   using conj_def by auto
1045 lemma conj_nb[simp]: "\<lbrakk>bound0 p ; bound0 q\<rbrakk> \<Longrightarrow> bound0 (conj p q)"
1046   using conj_def by auto
1048 definition disj :: "fm \<Rightarrow> fm \<Rightarrow> fm" where
1049   "disj p q \<equiv> (if (p = T \<or> q=T) then T else if p=F then q else if q=F then p
1050        else if p=q then p else Or p q)"
1052 lemma disj[simp]: "Ifm bs (disj p q) = Ifm bs (Or p q)"
1053   by (cases "p=T \<or> q=T",simp_all add: disj_def) (cases p,simp_all)
1054 lemma disj_qf[simp]: "\<lbrakk>qfree p ; qfree q\<rbrakk> \<Longrightarrow> qfree (disj p q)"
1055   using disj_def by auto
1056 lemma disj_nb[simp]: "\<lbrakk>bound0 p ; bound0 q\<rbrakk> \<Longrightarrow> bound0 (disj p q)"
1057   using disj_def by auto
1059 definition imp :: "fm \<Rightarrow> fm \<Rightarrow> fm" where
1060   "imp p q \<equiv> (if (p = F \<or> q=T \<or> p=q) then T else if p=T then q else if q=F then not p
1061     else Imp p q)"
1062 lemma imp[simp]: "Ifm bs (imp p q) = Ifm bs (Imp p q)"
1063   by (cases "p=F \<or> q=T",simp_all add: imp_def)
1064 lemma imp_qf[simp]: "\<lbrakk>qfree p ; qfree q\<rbrakk> \<Longrightarrow> qfree (imp p q)"
1065   using imp_def by (cases "p=F \<or> q=T",simp_all add: imp_def)
1067 definition iff :: "fm \<Rightarrow> fm \<Rightarrow> fm" where
1068   "iff p q \<equiv> (if (p = q) then T else if (p = not q \<or> not p = q) then F else
1069        if p=F then not q else if q=F then not p else if p=T then q else if q=T then p else
1070   Iff p q)"
1071 lemma iff[simp]: "Ifm bs (iff p q) = Ifm bs (Iff p q)"
1072   by (unfold iff_def,cases "p=q", simp,cases "p=not q", simp add:not)
1073 (cases "not p= q", auto simp add:not)
1074 lemma iff_qf[simp]: "\<lbrakk>qfree p ; qfree q\<rbrakk> \<Longrightarrow> qfree (iff p q)"
1075   by (unfold iff_def,cases "p=q", auto)
1077 fun check_int:: "num \<Rightarrow> bool" where
1078   "check_int (C i) = True"
1079 | "check_int (Floor t) = True"
1080 | "check_int (Mul i t) = check_int t"
1081 | "check_int (Add t s) = (check_int t \<and> check_int s)"
1082 | "check_int (Neg t) = check_int t"
1083 | "check_int (CF c t s) = check_int s"
1084 | "check_int t = False"
1085 lemma check_int: "check_int t \<Longrightarrow> isint t bs"
1086 by (induct t, auto simp add: isint_add isint_Floor isint_Mul isint_neg isint_c isint_CF)
1088 lemma rdvd_left1_int: "real \<lfloor>t\<rfloor> = t \<Longrightarrow> 1 rdvd t"
1089   by (simp add: rdvd_def,rule_tac x="\<lfloor>t\<rfloor>" in exI) simp
1091 lemma rdvd_reduce:
1092   assumes gd:"g dvd d" and gc:"g dvd c" and gp: "g > 0"
1093   shows "real (d::int) rdvd real (c::int)*t = (real (d div g) rdvd real (c div g)*t)"
1094 proof
1095   assume d: "real d rdvd real c * t"
1096   from d rdvd_def obtain k where k_def: "real c * t = real d* real (k::int)" by auto
1097   from gd dvd_def obtain kd where kd_def: "d = g * kd" by auto
1098   from gc dvd_def obtain kc where kc_def: "c = g * kc" by auto
1099   from k_def kd_def kc_def have "real g * real kc * t = real g * real kd * real k" by simp
1100   hence "real kc * t = real kd * real k" using gp by simp
1101   hence th:"real kd rdvd real kc * t" using rdvd_def by blast
1102   from kd_def gp have th':"kd = d div g" by simp
1103   from kc_def gp have "kc = c div g" by simp
1104   with th th' show "real (d div g) rdvd real (c div g) * t" by simp
1105 next
1106   assume d: "real (d div g) rdvd real (c div g) * t"
1107   from gp have gnz: "g \<noteq> 0" by simp
1108   thus "real d rdvd real c * t" using d rdvd_mult[OF gnz, where n="d div g" and x="real (c div g) * t"] real_of_int_div[OF gnz gd] real_of_int_div[OF gnz gc] by simp
1109 qed
1111 definition simpdvd :: "int \<Rightarrow> num \<Rightarrow> (int \<times> num)" where
1112   "simpdvd d t \<equiv>
1113    (let g = numgcd t in
1114       if g > 1 then (let g' = gcd d g in
1115         if g' = 1 then (d, t)
1116         else (d div g',reducecoeffh t g'))
1117       else (d, t))"
1118 lemma simpdvd:
1119   assumes tnz: "nozerocoeff t" and dnz: "d \<noteq> 0"
1120   shows "Ifm bs (Dvd (fst (simpdvd d t)) (snd (simpdvd d t))) = Ifm bs (Dvd d t)"
1121 proof-
1122   let ?g = "numgcd t"
1123   let ?g' = "gcd d ?g"
1124   {assume "\<not> ?g > 1" hence ?thesis by (simp add: Let_def simpdvd_def)}
1125   moreover
1126   {assume g1:"?g>1" hence g0: "?g > 0" by simp
1127     from g1 dnz have gp0: "?g' \<noteq> 0" by simp
1128     hence g'p: "?g' > 0" using gcd_ge_0_int[where x="d" and y="numgcd t"] by arith
1129     hence "?g'= 1 \<or> ?g' > 1" by arith
1130     moreover {assume "?g'=1" hence ?thesis by (simp add: Let_def simpdvd_def)}
1131     moreover {assume g'1:"?g'>1"
1132       from dvdnumcoeff_aux2[OF g1] have th1:"dvdnumcoeff t ?g" ..
1133       let ?tt = "reducecoeffh t ?g'"
1134       let ?t = "Inum bs ?tt"
1135       have gpdg: "?g' dvd ?g" by simp
1136       have gpdd: "?g' dvd d" by simp
1137       have gpdgp: "?g' dvd ?g'" by simp
1138       from reducecoeffh[OF dvdnumcoeff_trans[OF gpdg th1] g'p]
1139       have th2:"real ?g' * ?t = Inum bs t" by simp
1140       from assms g1 g0 g'1
1141       have "Ifm bs (Dvd (fst (simpdvd d t)) (snd(simpdvd d t))) = Ifm bs (Dvd (d div ?g') ?tt)"
1142         by (simp add: simpdvd_def Let_def)
1143       also have "\<dots> = (real d rdvd (Inum bs t))"
1144         using rdvd_reduce[OF gpdd gpdgp g'p, where t="?t", simplified zdiv_self[OF gp0]]
1145           th2[symmetric] by simp
1146       finally have ?thesis by simp  }
1147     ultimately have ?thesis by blast
1148   }
1149   ultimately show ?thesis by blast
1150 qed
1152 function (sequential) simpfm :: "fm \<Rightarrow> fm" where
1153   "simpfm (And p q) = conj (simpfm p) (simpfm q)"
1154 | "simpfm (Or p q) = disj (simpfm p) (simpfm q)"
1155 | "simpfm (Imp p q) = imp (simpfm p) (simpfm q)"
1156 | "simpfm (Iff p q) = iff (simpfm p) (simpfm q)"
1157 | "simpfm (NOT p) = not (simpfm p)"
1158 | "simpfm (Lt a) = (let a' = simpnum a in case a' of C v \<Rightarrow> if (v < 0) then T else F
1159   | _ \<Rightarrow> Lt (reducecoeff a'))"
1160 | "simpfm (Le a) = (let a' = simpnum a in case a' of C v \<Rightarrow> if (v \<le> 0)  then T else F | _ \<Rightarrow> Le (reducecoeff a'))"
1161 | "simpfm (Gt a) = (let a' = simpnum a in case a' of C v \<Rightarrow> if (v > 0)  then T else F | _ \<Rightarrow> Gt (reducecoeff a'))"
1162 | "simpfm (Ge a) = (let a' = simpnum a in case a' of C v \<Rightarrow> if (v \<ge> 0)  then T else F | _ \<Rightarrow> Ge (reducecoeff a'))"
1163 | "simpfm (Eq a) = (let a' = simpnum a in case a' of C v \<Rightarrow> if (v = 0)  then T else F | _ \<Rightarrow> Eq (reducecoeff a'))"
1164 | "simpfm (NEq a) = (let a' = simpnum a in case a' of C v \<Rightarrow> if (v \<noteq> 0)  then T else F | _ \<Rightarrow> NEq (reducecoeff a'))"
1165 | "simpfm (Dvd i a) = (if i=0 then simpfm (Eq a)
1166              else if (abs i = 1) \<and> check_int a then T
1167              else let a' = simpnum a in case a' of C v \<Rightarrow> if (i dvd v)  then T else F | _ \<Rightarrow> (let (d,t) = simpdvd i a' in Dvd d t))"
1168 | "simpfm (NDvd i a) = (if i=0 then simpfm (NEq a)
1169              else if (abs i = 1) \<and> check_int a then F
1170              else let a' = simpnum a in case a' of C v \<Rightarrow> if (\<not>(i dvd v)) then T else F | _ \<Rightarrow> (let (d,t) = simpdvd i a' in NDvd d t))"
1171 | "simpfm p = p"
1172 by pat_completeness auto
1173 termination by (relation "measure fmsize") auto
1175 lemma simpfm[simp]: "Ifm bs (simpfm p) = Ifm bs p"
1176 proof(induct p rule: simpfm.induct)
1177   case (6 a) let ?sa = "simpnum a" have sa: "Inum bs ?sa = Inum bs a" by simp
1178   {fix v assume "?sa = C v" hence ?case using sa by simp }
1179   moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
1180     let ?g = "numgcd ?sa"
1181     let ?rsa = "reducecoeff ?sa"
1182     let ?r = "Inum bs ?rsa"
1183     have sa_nz: "nozerocoeff ?sa" by (rule simpnum_nz)
1184     {assume gz: "?g=0" from numgcd_nz[OF sa_nz gz] H have "False" by auto}
1185     with numgcd_pos[where t="?sa"] have "?g > 0" by (cases "?g=0", auto)
1186     hence gp: "real ?g > 0" by simp
1187     have "Inum bs ?sa = real ?g* ?r" by (simp add: reducecoeff)
1188     with sa have "Inum bs a < 0 = (real ?g * ?r < real ?g * 0)" by simp
1189     also have "\<dots> = (?r < 0)" using gp
1190       by (simp only: mult_less_cancel_left) simp
1191     finally have ?case using H by (cases "?sa" , simp_all add: Let_def)}
1192   ultimately show ?case by blast
1193 next
1194   case (7 a)  let ?sa = "simpnum a" have sa: "Inum bs ?sa = Inum bs a" by simp
1195   {fix v assume "?sa = C v" hence ?case using sa by simp }
1196   moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
1197     let ?g = "numgcd ?sa"
1198     let ?rsa = "reducecoeff ?sa"
1199     let ?r = "Inum bs ?rsa"
1200     have sa_nz: "nozerocoeff ?sa" by (rule simpnum_nz)
1201     {assume gz: "?g=0" from numgcd_nz[OF sa_nz gz] H have "False" by auto}
1202     with numgcd_pos[where t="?sa"] have "?g > 0" by (cases "?g=0", auto)
1203     hence gp: "real ?g > 0" by simp
1204     have "Inum bs ?sa = real ?g* ?r" by (simp add: reducecoeff)
1205     with sa have "Inum bs a \<le> 0 = (real ?g * ?r \<le> real ?g * 0)" by simp
1206     also have "\<dots> = (?r \<le> 0)" using gp
1207       by (simp only: mult_le_cancel_left) simp
1208     finally have ?case using H by (cases "?sa" , simp_all add: Let_def)}
1209   ultimately show ?case by blast
1210 next
1211   case (8 a)  let ?sa = "simpnum a" have sa: "Inum bs ?sa = Inum bs a" by simp
1212   {fix v assume "?sa = C v" hence ?case using sa by simp }
1213   moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
1214     let ?g = "numgcd ?sa"
1215     let ?rsa = "reducecoeff ?sa"
1216     let ?r = "Inum bs ?rsa"
1217     have sa_nz: "nozerocoeff ?sa" by (rule simpnum_nz)
1218     {assume gz: "?g=0" from numgcd_nz[OF sa_nz gz] H have "False" by auto}
1219     with numgcd_pos[where t="?sa"] have "?g > 0" by (cases "?g=0", auto)
1220     hence gp: "real ?g > 0" by simp
1221     have "Inum bs ?sa = real ?g* ?r" by (simp add: reducecoeff)
1222     with sa have "Inum bs a > 0 = (real ?g * ?r > real ?g * 0)" by simp
1223     also have "\<dots> = (?r > 0)" using gp
1224       by (simp only: mult_less_cancel_left) simp
1225     finally have ?case using H by (cases "?sa" , simp_all add: Let_def)}
1226   ultimately show ?case by blast
1227 next
1228   case (9 a)  let ?sa = "simpnum a" have sa: "Inum bs ?sa = Inum bs a" by simp
1229   {fix v assume "?sa = C v" hence ?case using sa by simp }
1230   moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
1231     let ?g = "numgcd ?sa"
1232     let ?rsa = "reducecoeff ?sa"
1233     let ?r = "Inum bs ?rsa"
1234     have sa_nz: "nozerocoeff ?sa" by (rule simpnum_nz)
1235     {assume gz: "?g=0" from numgcd_nz[OF sa_nz gz] H have "False" by auto}
1236     with numgcd_pos[where t="?sa"] have "?g > 0" by (cases "?g=0", auto)
1237     hence gp: "real ?g > 0" by simp
1238     have "Inum bs ?sa = real ?g* ?r" by (simp add: reducecoeff)
1239     with sa have "Inum bs a \<ge> 0 = (real ?g * ?r \<ge> real ?g * 0)" by simp
1240     also have "\<dots> = (?r \<ge> 0)" using gp
1241       by (simp only: mult_le_cancel_left) simp
1242     finally have ?case using H by (cases "?sa" , simp_all add: Let_def)}
1243   ultimately show ?case by blast
1244 next
1245   case (10 a)  let ?sa = "simpnum a" have sa: "Inum bs ?sa = Inum bs a" by simp
1246   {fix v assume "?sa = C v" hence ?case using sa by simp }
1247   moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
1248     let ?g = "numgcd ?sa"
1249     let ?rsa = "reducecoeff ?sa"
1250     let ?r = "Inum bs ?rsa"
1251     have sa_nz: "nozerocoeff ?sa" by (rule simpnum_nz)
1252     {assume gz: "?g=0" from numgcd_nz[OF sa_nz gz] H have "False" by auto}
1253     with numgcd_pos[where t="?sa"] have "?g > 0" by (cases "?g=0", auto)
1254     hence gp: "real ?g > 0" by simp
1255     have "Inum bs ?sa = real ?g* ?r" by (simp add: reducecoeff)
1256     with sa have "Inum bs a = 0 = (real ?g * ?r = 0)" by simp
1257     also have "\<dots> = (?r = 0)" using gp
1259     finally have ?case using H by (cases "?sa" , simp_all add: Let_def)}
1260   ultimately show ?case by blast
1261 next
1262   case (11 a)  let ?sa = "simpnum a" have sa: "Inum bs ?sa = Inum bs a" by simp
1263   {fix v assume "?sa = C v" hence ?case using sa by simp }
1264   moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
1265     let ?g = "numgcd ?sa"
1266     let ?rsa = "reducecoeff ?sa"
1267     let ?r = "Inum bs ?rsa"
1268     have sa_nz: "nozerocoeff ?sa" by (rule simpnum_nz)
1269     {assume gz: "?g=0" from numgcd_nz[OF sa_nz gz] H have "False" by auto}
1270     with numgcd_pos[where t="?sa"] have "?g > 0" by (cases "?g=0", auto)
1271     hence gp: "real ?g > 0" by simp
1272     have "Inum bs ?sa = real ?g* ?r" by (simp add: reducecoeff)
1273     with sa have "Inum bs a \<noteq> 0 = (real ?g * ?r \<noteq> 0)" by simp
1274     also have "\<dots> = (?r \<noteq> 0)" using gp
1276     finally have ?case using H by (cases "?sa" , simp_all add: Let_def)}
1277   ultimately show ?case by blast
1278 next
1279   case (12 i a)  let ?sa = "simpnum a"   have sa: "Inum bs ?sa = Inum bs a" by simp
1280   have "i=0 \<or> (abs i = 1 \<and> check_int a) \<or> (i\<noteq>0 \<and> ((abs i \<noteq> 1) \<or> (\<not> check_int a)))" by auto
1281   {assume "i=0" hence ?case using "12.hyps" by (simp add: rdvd_left_0_eq Let_def)}
1282   moreover
1283   {assume ai1: "abs i = 1" and ai: "check_int a"
1284     hence "i=1 \<or> i= - 1" by arith
1285     moreover {assume i1: "i = 1"
1286       from rdvd_left1_int[OF check_int[OF ai, simplified isint_iff]]
1287       have ?case using i1 ai by simp }
1288     moreover {assume i1: "i = - 1"
1289       from rdvd_left1_int[OF check_int[OF ai, simplified isint_iff]]
1290         rdvd_abs1[where d="- 1" and t="Inum bs a"]
1291       have ?case using i1 ai by simp }
1292     ultimately have ?case by blast}
1293   moreover
1294   {assume inz: "i\<noteq>0" and cond: "(abs i \<noteq> 1) \<or> (\<not> check_int a)"
1295     {fix v assume "?sa = C v" hence ?case using sa[symmetric] inz cond
1296         by (cases "abs i = 1", auto simp add: int_rdvd_iff) }
1297     moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
1298       hence th: "simpfm (Dvd i a) = Dvd (fst (simpdvd i ?sa)) (snd (simpdvd i ?sa))" using inz cond by (cases ?sa, auto simp add: Let_def split_def)
1299       from simpnum_nz have nz:"nozerocoeff ?sa" by simp
1300       from simpdvd [OF nz inz] th have ?case using sa by simp}
1301     ultimately have ?case by blast}
1302   ultimately show ?case by blast
1303 next
1304   case (13 i a)  let ?sa = "simpnum a"   have sa: "Inum bs ?sa = Inum bs a" by simp
1305   have "i=0 \<or> (abs i = 1 \<and> check_int a) \<or> (i\<noteq>0 \<and> ((abs i \<noteq> 1) \<or> (\<not> check_int a)))" by auto
1306   {assume "i=0" hence ?case using "13.hyps" by (simp add: rdvd_left_0_eq Let_def)}
1307   moreover
1308   {assume ai1: "abs i = 1" and ai: "check_int a"
1309     hence "i=1 \<or> i= - 1" by arith
1310     moreover {assume i1: "i = 1"
1311       from rdvd_left1_int[OF check_int[OF ai, simplified isint_iff]]
1312       have ?case using i1 ai by simp }
1313     moreover {assume i1: "i = - 1"
1314       from rdvd_left1_int[OF check_int[OF ai, simplified isint_iff]]
1315         rdvd_abs1[where d="- 1" and t="Inum bs a"]
1316       have ?case using i1 ai by simp }
1317     ultimately have ?case by blast}
1318   moreover
1319   {assume inz: "i\<noteq>0" and cond: "(abs i \<noteq> 1) \<or> (\<not> check_int a)"
1320     {fix v assume "?sa = C v" hence ?case using sa[symmetric] inz cond
1321         by (cases "abs i = 1", auto simp add: int_rdvd_iff) }
1322     moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
1323       hence th: "simpfm (NDvd i a) = NDvd (fst (simpdvd i ?sa)) (snd (simpdvd i ?sa))" using inz cond
1324         by (cases ?sa, auto simp add: Let_def split_def)
1325       from simpnum_nz have nz:"nozerocoeff ?sa" by simp
1326       from simpdvd [OF nz inz] th have ?case using sa by simp}
1327     ultimately have ?case by blast}
1328   ultimately show ?case by blast
1329 qed (induct p rule: simpfm.induct, simp_all)
1331 lemma simpdvd_numbound0: "numbound0 t \<Longrightarrow> numbound0 (snd (simpdvd d t))"
1332   by (simp add: simpdvd_def Let_def split_def reducecoeffh_numbound0)
1334 lemma simpfm_bound0[simp]: "bound0 p \<Longrightarrow> bound0 (simpfm p)"
1335 proof(induct p rule: simpfm.induct)
1336   case (6 a) hence nb: "numbound0 a" by simp
1337   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
1338   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0)
1339 next
1340   case (7 a) hence nb: "numbound0 a" by simp
1341   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
1342   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0)
1343 next
1344   case (8 a) hence nb: "numbound0 a" by simp
1345   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
1346   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0)
1347 next
1348   case (9 a) hence nb: "numbound0 a" by simp
1349   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
1350   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0)
1351 next
1352   case (10 a) hence nb: "numbound0 a" by simp
1353   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
1354   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0)
1355 next
1356   case (11 a) hence nb: "numbound0 a" by simp
1357   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
1358   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0)
1359 next
1360   case (12 i a) hence nb: "numbound0 a" by simp
1361   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
1362   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0 simpdvd_numbound0 split_def)
1363 next
1364   case (13 i a) hence nb: "numbound0 a" by simp
1365   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
1366   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0 simpdvd_numbound0 split_def)
1367 qed(auto simp add: disj_def imp_def iff_def conj_def)
1369 lemma simpfm_qf[simp]: "qfree p \<Longrightarrow> qfree (simpfm p)"
1370 by (induct p rule: simpfm.induct, auto simp add: Let_def)
1371 (case_tac "simpnum a",auto simp add: split_def Let_def)+
1374   (* Generic quantifier elimination *)
1376 definition list_conj :: "fm list \<Rightarrow> fm" where
1377   "list_conj ps \<equiv> foldr conj ps T"
1378 lemma list_conj: "Ifm bs (list_conj ps) = (\<forall>p\<in> set ps. Ifm bs p)"
1379   by (induct ps, auto simp add: list_conj_def)
1380 lemma list_conj_qf: " \<forall>p\<in> set ps. qfree p \<Longrightarrow> qfree (list_conj ps)"
1381   by (induct ps, auto simp add: list_conj_def)
1382 lemma list_conj_nb: " \<forall>p\<in> set ps. bound0 p \<Longrightarrow> bound0 (list_conj ps)"
1383   by (induct ps, auto simp add: list_conj_def)
1384 definition CJNB :: "(fm \<Rightarrow> fm) \<Rightarrow> fm \<Rightarrow> fm" where
1385   "CJNB f p \<equiv> (let cjs = conjuncts p ; (yes,no) = List.partition bound0 cjs
1386                    in conj (decr (list_conj yes)) (f (list_conj no)))"
1388 lemma CJNB_qe:
1389   assumes qe: "\<forall> bs p. qfree p \<longrightarrow> qfree (qe p) \<and> (Ifm bs (qe p) = Ifm bs (E p))"
1390   shows "\<forall> bs p. qfree p \<longrightarrow> qfree (CJNB qe p) \<and> (Ifm bs ((CJNB qe p)) = Ifm bs (E p))"
1391 proof(clarify)
1392   fix bs p
1393   assume qfp: "qfree p"
1394   let ?cjs = "conjuncts p"
1395   let ?yes = "fst (List.partition bound0 ?cjs)"
1396   let ?no = "snd (List.partition bound0 ?cjs)"
1397   let ?cno = "list_conj ?no"
1398   let ?cyes = "list_conj ?yes"
1399   have part: "List.partition bound0 ?cjs = (?yes,?no)" by simp
1400   from partition_P[OF part] have "\<forall> q\<in> set ?yes. bound0 q" by blast
1401   hence yes_nb: "bound0 ?cyes" by (simp add: list_conj_nb)
1402   hence yes_qf: "qfree (decr ?cyes )" by (simp add: decr_qf)
1403   from conjuncts_qf[OF qfp] partition_set[OF part]
1404   have " \<forall>q\<in> set ?no. qfree q" by auto
1405   hence no_qf: "qfree ?cno"by (simp add: list_conj_qf)
1406   with qe have cno_qf:"qfree (qe ?cno )"
1407     and noE: "Ifm bs (qe ?cno) = Ifm bs (E ?cno)" by blast+
1408   from cno_qf yes_qf have qf: "qfree (CJNB qe p)"
1409     by (simp add: CJNB_def Let_def conj_qf split_def)
1410   {fix bs
1411     from conjuncts have "Ifm bs p = (\<forall>q\<in> set ?cjs. Ifm bs q)" by blast
1412     also have "\<dots> = ((\<forall>q\<in> set ?yes. Ifm bs q) \<and> (\<forall>q\<in> set ?no. Ifm bs q))"
1413       using partition_set[OF part] by auto
1414     finally have "Ifm bs p = ((Ifm bs ?cyes) \<and> (Ifm bs ?cno))" using list_conj by simp}
1415   hence "Ifm bs (E p) = (\<exists>x. (Ifm (x#bs) ?cyes) \<and> (Ifm (x#bs) ?cno))" by simp
1416   also fix y have "\<dots> = (\<exists>x. (Ifm (y#bs) ?cyes) \<and> (Ifm (x#bs) ?cno))"
1417     using bound0_I[OF yes_nb, where bs="bs" and b'="y"] by blast
1418   also have "\<dots> = (Ifm bs (decr ?cyes) \<and> Ifm bs (E ?cno))"
1419     by (auto simp add: decr[OF yes_nb] simp del: partition_filter_conv)
1420   also have "\<dots> = (Ifm bs (conj (decr ?cyes) (qe ?cno)))"
1421     using qe[rule_format, OF no_qf] by auto
1422   finally have "Ifm bs (E p) = Ifm bs (CJNB qe p)"
1423     by (simp add: Let_def CJNB_def split_def)
1424   with qf show "qfree (CJNB qe p) \<and> Ifm bs (CJNB qe p) = Ifm bs (E p)" by blast
1425 qed
1427 function (sequential) qelim :: "fm \<Rightarrow> (fm \<Rightarrow> fm) \<Rightarrow> fm" where
1428   "qelim (E p) = (\<lambda> qe. DJ (CJNB qe) (qelim p qe))"
1429 | "qelim (A p) = (\<lambda> qe. not (qe ((qelim (NOT p) qe))))"
1430 | "qelim (NOT p) = (\<lambda> qe. not (qelim p qe))"
1431 | "qelim (And p q) = (\<lambda> qe. conj (qelim p qe) (qelim q qe))"
1432 | "qelim (Or  p q) = (\<lambda> qe. disj (qelim p qe) (qelim q qe))"
1433 | "qelim (Imp p q) = (\<lambda> qe. disj (qelim (NOT p) qe) (qelim q qe))"
1434 | "qelim (Iff p q) = (\<lambda> qe. iff (qelim p qe) (qelim q qe))"
1435 | "qelim p = (\<lambda> y. simpfm p)"
1436 by pat_completeness auto
1437 termination by (relation "measure fmsize") auto
1439 lemma qelim_ci:
1440   assumes qe_inv: "\<forall> bs p. qfree p \<longrightarrow> qfree (qe p) \<and> (Ifm bs (qe p) = Ifm bs (E p))"
1441   shows "\<And> bs. qfree (qelim p qe) \<and> (Ifm bs (qelim p qe) = Ifm bs p)"
1442   using qe_inv DJ_qe[OF CJNB_qe[OF qe_inv]]
1443   by (induct p rule: qelim.induct) (auto simp del: simpfm.simps)
1446 text {* The @{text "\<int>"} Part *}
1447 text{* Linearity for fm where Bound 0 ranges over @{text "\<int>"} *}
1449 function zsplit0 :: "num \<Rightarrow> int \<times> num" (* splits the bounded from the unbounded part*) where
1450   "zsplit0 (C c) = (0,C c)"
1451 | "zsplit0 (Bound n) = (if n=0 then (1, C 0) else (0,Bound n))"
1452 | "zsplit0 (CN n c a) = zsplit0 (Add (Mul c (Bound n)) a)"
1453 | "zsplit0 (CF c a b) = zsplit0 (Add (Mul c (Floor a)) b)"
1454 | "zsplit0 (Neg a) = (let (i',a') =  zsplit0 a in (-i', Neg a'))"
1455 | "zsplit0 (Add a b) = (let (ia,a') =  zsplit0 a ;
1456                             (ib,b') =  zsplit0 b
1457                             in (ia+ib, Add a' b'))"
1458 | "zsplit0 (Sub a b) = (let (ia,a') =  zsplit0 a ;
1459                             (ib,b') =  zsplit0 b
1460                             in (ia-ib, Sub a' b'))"
1461 | "zsplit0 (Mul i a) = (let (i',a') =  zsplit0 a in (i*i', Mul i a'))"
1462 | "zsplit0 (Floor a) = (let (i',a') =  zsplit0 a in (i',Floor a'))"
1463 by pat_completeness auto
1464 termination by (relation "measure num_size") auto
1466 lemma zsplit0_I:
1467   shows "\<And> n a. zsplit0 t = (n,a) \<Longrightarrow> (Inum ((real (x::int)) #bs) (CN 0 n a) = Inum (real x #bs) t) \<and> numbound0 a"
1468   (is "\<And> n a. ?S t = (n,a) \<Longrightarrow> (?I x (CN 0 n a) = ?I x t) \<and> ?N a")
1469 proof(induct t rule: zsplit0.induct)
1470   case (1 c n a) thus ?case by auto
1471 next
1472   case (2 m n a) thus ?case by (cases "m=0") auto
1473 next
1474   case (3 n i a n a') thus ?case by auto
1475 next
1476   case (4 c a b n a') thus ?case by auto
1477 next
1478   case (5 t n a)
1479   let ?nt = "fst (zsplit0 t)"
1480   let ?at = "snd (zsplit0 t)"
1481   have abj: "zsplit0 t = (?nt,?at)" by simp hence th: "a=Neg ?at \<and> n=-?nt" using 5
1482     by (simp add: Let_def split_def)
1483   from abj prems  have th2: "(?I x (CN 0 ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
1484   from th2[simplified] th[simplified] show ?case by simp
1485 next
1486   case (6 s t n a)
1487   let ?ns = "fst (zsplit0 s)"
1488   let ?as = "snd (zsplit0 s)"
1489   let ?nt = "fst (zsplit0 t)"
1490   let ?at = "snd (zsplit0 t)"
1491   have abjs: "zsplit0 s = (?ns,?as)" by simp
1492   moreover have abjt:  "zsplit0 t = (?nt,?at)" by simp
1493   ultimately have th: "a=Add ?as ?at \<and> n=?ns + ?nt" using prems
1494     by (simp add: Let_def split_def)
1495   from abjs[symmetric] have bluddy: "\<exists> x y. (x,y) = zsplit0 s" by blast
1496   from prems have "(\<exists> x y. (x,y) = zsplit0 s) \<longrightarrow> (\<forall>xa xb. zsplit0 t = (xa, xb) \<longrightarrow> Inum (real x # bs) (CN 0 xa xb) = Inum (real x # bs) t \<and> numbound0 xb)" by blast (*FIXME*)
1497   with bluddy abjt have th3: "(?I x (CN 0 ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
1498   from abjs prems  have th2: "(?I x (CN 0 ?ns ?as) = ?I x s) \<and> ?N ?as" by blast
1499   from th3[simplified] th2[simplified] th[simplified] show ?case
1501 next
1502   case (7 s t n a)
1503   let ?ns = "fst (zsplit0 s)"
1504   let ?as = "snd (zsplit0 s)"
1505   let ?nt = "fst (zsplit0 t)"
1506   let ?at = "snd (zsplit0 t)"
1507   have abjs: "zsplit0 s = (?ns,?as)" by simp
1508   moreover have abjt:  "zsplit0 t = (?nt,?at)" by simp
1509   ultimately have th: "a=Sub ?as ?at \<and> n=?ns - ?nt" using prems
1510     by (simp add: Let_def split_def)
1511   from abjs[symmetric] have bluddy: "\<exists> x y. (x,y) = zsplit0 s" by blast
1512   from prems have "(\<exists> x y. (x,y) = zsplit0 s) \<longrightarrow> (\<forall>xa xb. zsplit0 t = (xa, xb) \<longrightarrow> Inum (real x # bs) (CN 0 xa xb) = Inum (real x # bs) t \<and> numbound0 xb)" by blast (*FIXME*)
1513   with bluddy abjt have th3: "(?I x (CN 0 ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
1514   from abjs prems  have th2: "(?I x (CN 0 ?ns ?as) = ?I x s) \<and> ?N ?as" by blast
1515   from th3[simplified] th2[simplified] th[simplified] show ?case
1517 next
1518   case (8 i t n a)
1519   let ?nt = "fst (zsplit0 t)"
1520   let ?at = "snd (zsplit0 t)"
1521   have abj: "zsplit0 t = (?nt,?at)" by simp hence th: "a=Mul i ?at \<and> n=i*?nt" using prems
1522     by (simp add: Let_def split_def)
1523   from abj prems  have th2: "(?I x (CN 0 ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
1524   hence " ?I x (Mul i t) = (real i) * ?I x (CN 0 ?nt ?at)" by simp
1525   also have "\<dots> = ?I x (CN 0 (i*?nt) (Mul i ?at))" by (simp add: right_distrib)
1526   finally show ?case using th th2 by simp
1527 next
1528   case (9 t n a)
1529   let ?nt = "fst (zsplit0 t)"
1530   let ?at = "snd (zsplit0 t)"
1531   have abj: "zsplit0 t = (?nt,?at)" by simp hence th: "a= Floor ?at \<and> n=?nt" using prems
1532     by (simp add: Let_def split_def)
1533   from abj prems  have th2: "(?I x (CN 0 ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
1534   hence na: "?N a" using th by simp
1535   have th': "(real ?nt)*(real x) = real (?nt * x)" by simp
1536   have "?I x (Floor t) = ?I x (Floor (CN 0 ?nt ?at))" using th2 by simp
1537   also have "\<dots> = real (floor ((real ?nt)* real(x) + ?I x ?at))" by simp
1538   also have "\<dots> = real (floor (?I x ?at + real (?nt* x)))" by (simp add: add_ac)
1539   also have "\<dots> = real (floor (?I x ?at) + (?nt* x))"
1540     using floor_add[where x="?I x ?at" and a="?nt* x"] by simp
1541   also have "\<dots> = real (?nt)*(real x) + real (floor (?I x ?at))" by (simp add: add_ac)
1542   finally have "?I x (Floor t) = ?I x (CN 0 n a)" using th by simp
1543   with na show ?case by simp
1544 qed
1546 consts
1547   iszlfm :: "fm \<Rightarrow> real list \<Rightarrow> bool"   (* Linearity test for fm *)
1548   zlfm :: "fm \<Rightarrow> fm"       (* Linearity transformation for fm *)
1549 recdef iszlfm "measure size"
1550   "iszlfm (And p q) = (\<lambda> bs. iszlfm p bs \<and> iszlfm q bs)"
1551   "iszlfm (Or p q) = (\<lambda> bs. iszlfm p bs \<and> iszlfm q bs)"
1552   "iszlfm (Eq  (CN 0 c e)) = (\<lambda> bs. c>0 \<and> numbound0 e \<and> isint e bs)"
1553   "iszlfm (NEq (CN 0 c e)) = (\<lambda> bs. c>0 \<and> numbound0 e \<and> isint e bs)"
1554   "iszlfm (Lt  (CN 0 c e)) = (\<lambda> bs. c>0 \<and> numbound0 e \<and> isint e bs)"
1555   "iszlfm (Le  (CN 0 c e)) = (\<lambda> bs. c>0 \<and> numbound0 e \<and> isint e bs)"
1556   "iszlfm (Gt  (CN 0 c e)) = (\<lambda> bs. c>0 \<and> numbound0 e \<and> isint e bs)"
1557   "iszlfm (Ge  (CN 0 c e)) = (\<lambda> bs. c>0 \<and> numbound0 e \<and> isint e bs)"
1558   "iszlfm (Dvd i (CN 0 c e)) =
1559                  (\<lambda> bs. c>0 \<and> i>0 \<and> numbound0 e \<and> isint e bs)"
1560   "iszlfm (NDvd i (CN 0 c e))=
1561                  (\<lambda> bs. c>0 \<and> i>0 \<and> numbound0 e \<and> isint e bs)"
1562   "iszlfm p = (\<lambda> bs. isatom p \<and> (bound0 p))"
1564 lemma zlin_qfree: "iszlfm p bs \<Longrightarrow> qfree p"
1565   by (induct p rule: iszlfm.induct) auto
1567 lemma iszlfm_gen:
1568   assumes lp: "iszlfm p (x#bs)"
1569   shows "\<forall> y. iszlfm p (y#bs)"
1570 proof
1571   fix y
1572   show "iszlfm p (y#bs)"
1573     using lp
1574   by(induct p rule: iszlfm.induct, simp_all add: numbound0_gen[rule_format, where x="x" and y="y"])
1575 qed
1577 lemma conj_zl[simp]: "iszlfm p bs \<Longrightarrow> iszlfm q bs \<Longrightarrow> iszlfm (conj p q) bs"
1578   using conj_def by (cases p,auto)
1579 lemma disj_zl[simp]: "iszlfm p bs \<Longrightarrow> iszlfm q bs \<Longrightarrow> iszlfm (disj p q) bs"
1580   using disj_def by (cases p,auto)
1582 recdef zlfm "measure fmsize"
1583   "zlfm (And p q) = conj (zlfm p) (zlfm q)"
1584   "zlfm (Or p q) = disj (zlfm p) (zlfm q)"
1585   "zlfm (Imp p q) = disj (zlfm (NOT p)) (zlfm q)"
1586   "zlfm (Iff p q) = disj (conj (zlfm p) (zlfm q)) (conj (zlfm (NOT p)) (zlfm (NOT q)))"
1587   "zlfm (Lt a) = (let (c,r) = zsplit0 a in
1588      if c=0 then Lt r else
1589      if c>0 then Or (Lt (CN 0 c (Neg (Floor (Neg r))))) (And (Eq (CN 0 c (Neg (Floor (Neg r))))) (Lt (Add (Floor (Neg r)) r)))
1590      else Or (Gt (CN 0 (-c) (Floor(Neg r)))) (And (Eq(CN 0 (-c) (Floor(Neg r)))) (Lt (Add (Floor (Neg r)) r))))"
1591   "zlfm (Le a) = (let (c,r) = zsplit0 a in
1592      if c=0 then Le r else
1593      if c>0 then Or (Le (CN 0 c (Neg (Floor (Neg r))))) (And (Eq (CN 0 c (Neg (Floor (Neg r))))) (Lt (Add (Floor (Neg r)) r)))
1594      else Or (Ge (CN 0 (-c) (Floor(Neg r)))) (And (Eq(CN 0 (-c) (Floor(Neg r)))) (Lt (Add (Floor (Neg r)) r))))"
1595   "zlfm (Gt a) = (let (c,r) = zsplit0 a in
1596      if c=0 then Gt r else
1597      if c>0 then Or (Gt (CN 0 c (Floor r))) (And (Eq (CN 0 c (Floor r))) (Lt (Sub (Floor r) r)))
1598      else Or (Lt (CN 0 (-c) (Neg (Floor r)))) (And (Eq(CN 0 (-c) (Neg (Floor r)))) (Lt (Sub (Floor r) r))))"
1599   "zlfm (Ge a) = (let (c,r) = zsplit0 a in
1600      if c=0 then Ge r else
1601      if c>0 then Or (Ge (CN 0 c (Floor r))) (And (Eq (CN 0 c (Floor r))) (Lt (Sub (Floor r) r)))
1602      else Or (Le (CN 0 (-c) (Neg (Floor r)))) (And (Eq(CN 0 (-c) (Neg (Floor r)))) (Lt (Sub (Floor r) r))))"
1603   "zlfm (Eq a) = (let (c,r) = zsplit0 a in
1604               if c=0 then Eq r else
1605       if c>0 then (And (Eq (CN 0 c (Neg (Floor (Neg r))))) (Eq (Add (Floor (Neg r)) r)))
1606       else (And (Eq (CN 0 (-c) (Floor (Neg r)))) (Eq (Add (Floor (Neg r)) r))))"
1607   "zlfm (NEq a) = (let (c,r) = zsplit0 a in
1608               if c=0 then NEq r else
1609       if c>0 then (Or (NEq (CN 0 c (Neg (Floor (Neg r))))) (NEq (Add (Floor (Neg r)) r)))
1610       else (Or (NEq (CN 0 (-c) (Floor (Neg r)))) (NEq (Add (Floor (Neg r)) r))))"
1611   "zlfm (Dvd i a) = (if i=0 then zlfm (Eq a)
1612   else (let (c,r) = zsplit0 a in
1613               if c=0 then Dvd (abs i) r else
1614       if c>0 then And (Eq (Sub (Floor r) r)) (Dvd (abs i) (CN 0 c (Floor r)))
1615       else And (Eq (Sub (Floor r) r)) (Dvd (abs i) (CN 0 (-c) (Neg (Floor r))))))"
1616   "zlfm (NDvd i a) = (if i=0 then zlfm (NEq a)
1617   else (let (c,r) = zsplit0 a in
1618               if c=0 then NDvd (abs i) r else
1619       if c>0 then Or (NEq (Sub (Floor r) r)) (NDvd (abs i) (CN 0 c (Floor r)))
1620       else Or (NEq (Sub (Floor r) r)) (NDvd (abs i) (CN 0 (-c) (Neg (Floor r))))))"
1621   "zlfm (NOT (And p q)) = disj (zlfm (NOT p)) (zlfm (NOT q))"
1622   "zlfm (NOT (Or p q)) = conj (zlfm (NOT p)) (zlfm (NOT q))"
1623   "zlfm (NOT (Imp p q)) = conj (zlfm p) (zlfm (NOT q))"
1624   "zlfm (NOT (Iff p q)) = disj (conj(zlfm p) (zlfm(NOT q))) (conj (zlfm(NOT p)) (zlfm q))"
1625   "zlfm (NOT (NOT p)) = zlfm p"
1626   "zlfm (NOT T) = F"
1627   "zlfm (NOT F) = T"
1628   "zlfm (NOT (Lt a)) = zlfm (Ge a)"
1629   "zlfm (NOT (Le a)) = zlfm (Gt a)"
1630   "zlfm (NOT (Gt a)) = zlfm (Le a)"
1631   "zlfm (NOT (Ge a)) = zlfm (Lt a)"
1632   "zlfm (NOT (Eq a)) = zlfm (NEq a)"
1633   "zlfm (NOT (NEq a)) = zlfm (Eq a)"
1634   "zlfm (NOT (Dvd i a)) = zlfm (NDvd i a)"
1635   "zlfm (NOT (NDvd i a)) = zlfm (Dvd i a)"
1636   "zlfm p = p" (hints simp add: fmsize_pos)
1638 lemma split_int_less_real:
1639   "(real (a::int) < b) = (a < floor b \<or> (a = floor b \<and> real (floor b) < b))"
1640 proof( auto)
1641   assume alb: "real a < b" and agb: "\<not> a < floor b"
1642   from agb have "floor b \<le> a" by simp hence th: "b < real a + 1" by (simp only: floor_le_eq)
1643   from floor_eq[OF alb th] show "a= floor b" by simp
1644 next
1645   assume alb: "a < floor b"
1646   hence "real a < real (floor b)" by simp
1647   moreover have "real (floor b) \<le> b" by simp ultimately show  "real a < b" by arith
1648 qed
1650 lemma split_int_less_real':
1651   "(real (a::int) + b < 0) = (real a - real (floor(-b)) < 0 \<or> (real a - real (floor (-b)) = 0 \<and> real (floor (-b)) + b < 0))"
1652 proof-
1653   have "(real a + b <0) = (real a < -b)" by arith
1654   with split_int_less_real[where a="a" and b="-b"] show ?thesis by arith
1655 qed
1657 lemma split_int_gt_real':
1658   "(real (a::int) + b > 0) = (real a + real (floor b) > 0 \<or> (real a + real (floor b) = 0 \<and> real (floor b) - b < 0))"
1659 proof-
1660   have th: "(real a + b >0) = (real (-a) + (-b)< 0)" by arith
1661   show ?thesis using myless[of _ "real (floor b)"]
1662     by (simp only:th split_int_less_real'[where a="-a" and b="-b"])
1664 qed
1666 lemma split_int_le_real:
1667   "(real (a::int) \<le> b) = (a \<le> floor b \<or> (a = floor b \<and> real (floor b) < b))"
1668 proof( auto)
1669   assume alb: "real a \<le> b" and agb: "\<not> a \<le> floor b"
1670   from alb have "floor (real a) \<le> floor b " by (simp only: floor_mono)
1671   hence "a \<le> floor b" by simp with agb show "False" by simp
1672 next
1673   assume alb: "a \<le> floor b"
1674   hence "real a \<le> real (floor b)" by (simp only: floor_mono)
1675   also have "\<dots>\<le> b" by simp  finally show  "real a \<le> b" .
1676 qed
1678 lemma split_int_le_real':
1679   "(real (a::int) + b \<le> 0) = (real a - real (floor(-b)) \<le> 0 \<or> (real a - real (floor (-b)) = 0 \<and> real (floor (-b)) + b < 0))"
1680 proof-
1681   have "(real a + b \<le>0) = (real a \<le> -b)" by arith
1682   with split_int_le_real[where a="a" and b="-b"] show ?thesis by arith
1683 qed
1685 lemma split_int_ge_real':
1686   "(real (a::int) + b \<ge> 0) = (real a + real (floor b) \<ge> 0 \<or> (real a + real (floor b) = 0 \<and> real (floor b) - b < 0))"
1687 proof-
1688   have th: "(real a + b \<ge>0) = (real (-a) + (-b) \<le> 0)" by arith
1689   show ?thesis by (simp only: th split_int_le_real'[where a="-a" and b="-b"])
1691 qed
1693 lemma split_int_eq_real: "(real (a::int) = b) = ( a = floor b \<and> b = real (floor b))" (is "?l = ?r")
1694 by auto
1696 lemma split_int_eq_real': "(real (a::int) + b = 0) = ( a - floor (-b) = 0 \<and> real (floor (-b)) + b = 0)" (is "?l = ?r")
1697 proof-
1698   have "?l = (real a = -b)" by arith
1699   with split_int_eq_real[where a="a" and b="-b"] show ?thesis by simp arith
1700 qed
1702 lemma zlfm_I:
1703   assumes qfp: "qfree p"
1704   shows "(Ifm (real i #bs) (zlfm p) = Ifm (real i# bs) p) \<and> iszlfm (zlfm p) (real (i::int) #bs)"
1705   (is "(?I (?l p) = ?I p) \<and> ?L (?l p)")
1706 using qfp
1707 proof(induct p rule: zlfm.induct)
1708   case (5 a)
1709   let ?c = "fst (zsplit0 a)"
1710   let ?r = "snd (zsplit0 a)"
1711   have spl: "zsplit0 a = (?c,?r)" by simp
1712   from zsplit0_I[OF spl, where x="i" and bs="bs"]
1713   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto
1714   let ?N = "\<lambda> t. Inum (real i#bs) t"
1715   have "?c = 0 \<or> (?c >0 \<and> ?c\<noteq>0) \<or> (?c<0 \<and> ?c\<noteq>0)" by arith
1716   moreover
1717   {assume "?c=0" hence ?case using zsplit0_I[OF spl, where x="i" and bs="bs"]
1718       by (cases "?r", simp_all add: Let_def split_def,case_tac "nat", simp_all)}
1719   moreover
1720   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Lt a))"
1721       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1722     have "?I (Lt a) = (real (?c * i) + (?N ?r) < 0)" using Ia by (simp add: Let_def split_def)
1723     also have "\<dots> = (?I (?l (Lt a)))" apply (simp only: split_int_less_real'[where a="?c*i" and b="?N ?r"]) by (simp add: Ia cp cnz Let_def split_def diff_minus)
1724     finally have ?case using l by simp}
1725   moreover
1726   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Lt a))"
1727       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1728     have "?I (Lt a) = (real (?c * i) + (?N ?r) < 0)" using Ia by (simp add: Let_def split_def)
1729     also from cn cnz have "\<dots> = (?I (?l (Lt a)))" by (simp only: split_int_less_real'[where a="?c*i" and b="?N ?r"]) (simp add: Ia Let_def split_def diff_minus[symmetric] add_ac, arith)
1730     finally have ?case using l by simp}
1731   ultimately show ?case by blast
1732 next
1733   case (6 a)
1734   let ?c = "fst (zsplit0 a)"
1735   let ?r = "snd (zsplit0 a)"
1736   have spl: "zsplit0 a = (?c,?r)" by simp
1737   from zsplit0_I[OF spl, where x="i" and bs="bs"]
1738   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto
1739   let ?N = "\<lambda> t. Inum (real i#bs) t"
1740   have "?c = 0 \<or> (?c >0 \<and> ?c\<noteq>0) \<or> (?c<0 \<and> ?c\<noteq>0)" by arith
1741   moreover
1742   {assume "?c=0" hence ?case using zsplit0_I[OF spl, where x="i" and bs="bs"]
1743       by (cases "?r", simp_all add: Let_def split_def, case_tac "nat",simp_all)}
1744   moreover
1745   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Le a))"
1746       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1747     have "?I (Le a) = (real (?c * i) + (?N ?r) \<le> 0)" using Ia by (simp add: Let_def split_def)
1748     also have "\<dots> = (?I (?l (Le a)))" by (simp only: split_int_le_real'[where a="?c*i" and b="?N ?r"]) (simp add: Ia cp cnz Let_def split_def diff_minus)
1749     finally have ?case using l by simp}
1750   moreover
1751   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Le a))"
1752       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1753     have "?I (Le a) = (real (?c * i) + (?N ?r) \<le> 0)" using Ia by (simp add: Let_def split_def)
1754     also from cn cnz have "\<dots> = (?I (?l (Le a)))" by (simp only: split_int_le_real'[where a="?c*i" and b="?N ?r"]) (simp add: Ia Let_def split_def diff_minus[symmetric] add_ac ,arith)
1755     finally have ?case using l by simp}
1756   ultimately show ?case by blast
1757 next
1758   case (7 a)
1759   let ?c = "fst (zsplit0 a)"
1760   let ?r = "snd (zsplit0 a)"
1761   have spl: "zsplit0 a = (?c,?r)" by simp
1762   from zsplit0_I[OF spl, where x="i" and bs="bs"]
1763   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto
1764   let ?N = "\<lambda> t. Inum (real i#bs) t"
1765   have "?c = 0 \<or> (?c >0 \<and> ?c\<noteq>0) \<or> (?c<0 \<and> ?c\<noteq>0)" by arith
1766   moreover
1767   {assume "?c=0" hence ?case using zsplit0_I[OF spl, where x="i" and bs="bs"]
1768       by (cases "?r", simp_all add: Let_def split_def, case_tac "nat", simp_all)}
1769   moreover
1770   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Gt a))"
1771       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1772     have "?I (Gt a) = (real (?c * i) + (?N ?r) > 0)" using Ia by (simp add: Let_def split_def)
1773     also have "\<dots> = (?I (?l (Gt a)))" by (simp only: split_int_gt_real'[where a="?c*i" and b="?N ?r"]) (simp add: Ia cp cnz Let_def split_def diff_minus)
1774     finally have ?case using l by simp}
1775   moreover
1776   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Gt a))"
1777       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1778     have "?I (Gt a) = (real (?c * i) + (?N ?r) > 0)" using Ia by (simp add: Let_def split_def)
1779     also from cn cnz have "\<dots> = (?I (?l (Gt a)))" by (simp only: split_int_gt_real'[where a="?c*i" and b="?N ?r"]) (simp add: Ia Let_def split_def diff_minus[symmetric] add_ac, arith)
1780     finally have ?case using l by simp}
1781   ultimately show ?case by blast
1782 next
1783   case (8 a)
1784    let ?c = "fst (zsplit0 a)"
1785   let ?r = "snd (zsplit0 a)"
1786   have spl: "zsplit0 a = (?c,?r)" by simp
1787   from zsplit0_I[OF spl, where x="i" and bs="bs"]
1788   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto
1789   let ?N = "\<lambda> t. Inum (real i#bs) t"
1790   have "?c = 0 \<or> (?c >0 \<and> ?c\<noteq>0) \<or> (?c<0 \<and> ?c\<noteq>0)" by arith
1791   moreover
1792   {assume "?c=0" hence ?case using zsplit0_I[OF spl, where x="i" and bs="bs"]
1793       by (cases "?r", simp_all add: Let_def split_def, case_tac "nat", simp_all)}
1794   moreover
1795   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Ge a))"
1796       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1797     have "?I (Ge a) = (real (?c * i) + (?N ?r) \<ge> 0)" using Ia by (simp add: Let_def split_def)
1798     also have "\<dots> = (?I (?l (Ge a)))" by (simp only: split_int_ge_real'[where a="?c*i" and b="?N ?r"]) (simp add: Ia cp cnz Let_def split_def diff_minus)
1799     finally have ?case using l by simp}
1800   moreover
1801   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Ge a))"
1802       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1803     have "?I (Ge a) = (real (?c * i) + (?N ?r) \<ge> 0)" using Ia by (simp add: Let_def split_def)
1804     also from cn cnz have "\<dots> = (?I (?l (Ge a)))" by (simp only: split_int_ge_real'[where a="?c*i" and b="?N ?r"]) (simp add: Ia Let_def split_def diff_minus[symmetric] add_ac, arith)
1805     finally have ?case using l by simp}
1806   ultimately show ?case by blast
1807 next
1808   case (9 a)
1809   let ?c = "fst (zsplit0 a)"
1810   let ?r = "snd (zsplit0 a)"
1811   have spl: "zsplit0 a = (?c,?r)" by simp
1812   from zsplit0_I[OF spl, where x="i" and bs="bs"]
1813   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto
1814   let ?N = "\<lambda> t. Inum (real i#bs) t"
1815   have "?c = 0 \<or> (?c >0 \<and> ?c\<noteq>0) \<or> (?c<0 \<and> ?c\<noteq>0)" by arith
1816   moreover
1817   {assume "?c=0" hence ?case using zsplit0_I[OF spl, where x="i" and bs="bs"]
1818       by (cases "?r", simp_all add: Let_def split_def, case_tac "nat", simp_all)}
1819   moreover
1820   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Eq a))"
1821       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1822     have "?I (Eq a) = (real (?c * i) + (?N ?r) = 0)" using Ia by (simp add: Let_def split_def)
1823     also have "\<dots> = (?I (?l (Eq a)))" using cp cnz  by (simp only: split_int_eq_real'[where a="?c*i" and b="?N ?r"]) (simp add: Let_def split_def Ia real_of_int_mult[symmetric] del: real_of_int_mult)
1824     finally have ?case using l by simp}
1825   moreover
1826   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Eq a))"
1827       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1828     have "?I (Eq a) = (real (?c * i) + (?N ?r) = 0)" using Ia by (simp add: Let_def split_def)
1829     also from cn cnz have "\<dots> = (?I (?l (Eq a)))" by (simp only: split_int_eq_real'[where a="?c*i" and b="?N ?r"]) (simp add: Let_def split_def Ia real_of_int_mult[symmetric] del: real_of_int_mult,arith)
1830     finally have ?case using l by simp}
1831   ultimately show ?case by blast
1832 next
1833   case (10 a)
1834   let ?c = "fst (zsplit0 a)"
1835   let ?r = "snd (zsplit0 a)"
1836   have spl: "zsplit0 a = (?c,?r)" by simp
1837   from zsplit0_I[OF spl, where x="i" and bs="bs"]
1838   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto
1839   let ?N = "\<lambda> t. Inum (real i#bs) t"
1840   have "?c = 0 \<or> (?c >0 \<and> ?c\<noteq>0) \<or> (?c<0 \<and> ?c\<noteq>0)" by arith
1841   moreover
1842   {assume "?c=0" hence ?case using zsplit0_I[OF spl, where x="i" and bs="bs"]
1843       by (cases "?r", simp_all add: Let_def split_def, case_tac "nat", simp_all)}
1844   moreover
1845   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (NEq a))"
1846       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1847     have "?I (NEq a) = (real (?c * i) + (?N ?r) \<noteq> 0)" using Ia by (simp add: Let_def split_def)
1848     also have "\<dots> = (?I (?l (NEq a)))" using cp cnz  by (simp only: split_int_eq_real'[where a="?c*i" and b="?N ?r"]) (simp add: Let_def split_def Ia real_of_int_mult[symmetric] del: real_of_int_mult)
1849     finally have ?case using l by simp}
1850   moreover
1851   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (NEq a))"
1852       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1853     have "?I (NEq a) = (real (?c * i) + (?N ?r) \<noteq> 0)" using Ia by (simp add: Let_def split_def)
1854     also from cn cnz have "\<dots> = (?I (?l (NEq a)))" by (simp only: split_int_eq_real'[where a="?c*i" and b="?N ?r"]) (simp add: Let_def split_def Ia real_of_int_mult[symmetric] del: real_of_int_mult,arith)
1855     finally have ?case using l by simp}
1856   ultimately show ?case by blast
1857 next
1858   case (11 j a)
1859   let ?c = "fst (zsplit0 a)"
1860   let ?r = "snd (zsplit0 a)"
1861   have spl: "zsplit0 a = (?c,?r)" by simp
1862   from zsplit0_I[OF spl, where x="i" and bs="bs"]
1863   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto
1864   let ?N = "\<lambda> t. Inum (real i#bs) t"
1865   have "j=0 \<or> (j\<noteq>0 \<and> ?c = 0) \<or> (j\<noteq>0 \<and> ?c >0 \<and> ?c\<noteq>0) \<or> (j\<noteq> 0 \<and> ?c<0 \<and> ?c\<noteq>0)" by arith
1866   moreover
1867   {assume "j=0" hence z: "zlfm (Dvd j a) = (zlfm (Eq a))" by (simp add: Let_def)
1868     hence ?case using prems by (simp del: zlfm.simps add: rdvd_left_0_eq)}
1869   moreover
1870   {assume "?c=0" and "j\<noteq>0" hence ?case
1871       using zsplit0_I[OF spl, where x="i" and bs="bs"] rdvd_abs1[where d="j"]
1872       by (cases "?r", simp_all add: Let_def split_def, case_tac "nat", simp_all)}
1873   moreover
1874   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" and jnz: "j\<noteq>0" hence l: "?L (?l (Dvd j a))"
1875       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1876     have "?I (Dvd j a) = (real j rdvd (real (?c * i) + (?N ?r)))"
1877       using Ia by (simp add: Let_def split_def)
1878     also have "\<dots> = (real (abs j) rdvd real (?c*i) + (?N ?r))"
1879       by (simp only: rdvd_abs1[where d="j" and t="real (?c*i) + ?N ?r", symmetric]) simp
1880     also have "\<dots> = ((abs j) dvd (floor ((?N ?r) + real (?c*i))) \<and>
1881        (real (floor ((?N ?r) + real (?c*i))) = (real (?c*i) + (?N ?r))))"
1882       by(simp only: int_rdvd_real[where i="abs j" and x="real (?c*i) + (?N ?r)"]) (simp only: add_ac)
1883     also have "\<dots> = (?I (?l (Dvd j a)))" using cp cnz jnz
1884       by (simp add: Let_def split_def int_rdvd_iff[symmetric]
1886     finally have ?case using l jnz  by simp }
1887   moreover
1888   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" and jnz: "j\<noteq>0" hence l: "?L (?l (Dvd j a))"
1889       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1890     have "?I (Dvd j a) = (real j rdvd (real (?c * i) + (?N ?r)))"
1891       using Ia by (simp add: Let_def split_def)
1892     also have "\<dots> = (real (abs j) rdvd real (?c*i) + (?N ?r))"
1893       by (simp only: rdvd_abs1[where d="j" and t="real (?c*i) + ?N ?r", symmetric]) simp
1894     also have "\<dots> = ((abs j) dvd (floor ((?N ?r) + real (?c*i))) \<and>
1895        (real (floor ((?N ?r) + real (?c*i))) = (real (?c*i) + (?N ?r))))"
1896       by(simp only: int_rdvd_real[where i="abs j" and x="real (?c*i) + (?N ?r)"]) (simp only: add_ac)
1897     also have "\<dots> = (?I (?l (Dvd j a)))" using cn cnz jnz
1898       using rdvd_minus [where d="abs j" and t="real (?c*i + floor (?N ?r))", simplified, symmetric]
1899       by (simp add: Let_def split_def int_rdvd_iff[symmetric]
1901     finally have ?case using l jnz by blast }
1902   ultimately show ?case by blast
1903 next
1904   case (12 j a)
1905   let ?c = "fst (zsplit0 a)"
1906   let ?r = "snd (zsplit0 a)"
1907   have spl: "zsplit0 a = (?c,?r)" by simp
1908   from zsplit0_I[OF spl, where x="i" and bs="bs"]
1909   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto
1910   let ?N = "\<lambda> t. Inum (real i#bs) t"
1911   have "j=0 \<or> (j\<noteq>0 \<and> ?c = 0) \<or> (j\<noteq>0 \<and> ?c >0 \<and> ?c\<noteq>0) \<or> (j\<noteq> 0 \<and> ?c<0 \<and> ?c\<noteq>0)" by arith
1912   moreover
1913   {assume "j=0" hence z: "zlfm (NDvd j a) = (zlfm (NEq a))" by (simp add: Let_def)
1914     hence ?case using prems by (simp del: zlfm.simps add: rdvd_left_0_eq)}
1915   moreover
1916   {assume "?c=0" and "j\<noteq>0" hence ?case
1917       using zsplit0_I[OF spl, where x="i" and bs="bs"] rdvd_abs1[where d="j"]
1918       by (cases "?r", simp_all add: Let_def split_def, case_tac "nat", simp_all)}
1919   moreover
1920   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" and jnz: "j\<noteq>0" hence l: "?L (?l (NDvd j a))"
1921       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1922     have "?I (NDvd j a) = (\<not> (real j rdvd (real (?c * i) + (?N ?r))))"
1923       using Ia by (simp add: Let_def split_def)
1924     also have "\<dots> = (\<not> (real (abs j) rdvd real (?c*i) + (?N ?r)))"
1925       by (simp only: rdvd_abs1[where d="j" and t="real (?c*i) + ?N ?r", symmetric]) simp
1926     also have "\<dots> = (\<not> ((abs j) dvd (floor ((?N ?r) + real (?c*i))) \<and>
1927        (real (floor ((?N ?r) + real (?c*i))) = (real (?c*i) + (?N ?r)))))"
1928       by(simp only: int_rdvd_real[where i="abs j" and x="real (?c*i) + (?N ?r)"]) (simp only: add_ac)
1929     also have "\<dots> = (?I (?l (NDvd j a)))" using cp cnz jnz
1930       by (simp add: Let_def split_def int_rdvd_iff[symmetric]
1932     finally have ?case using l jnz  by simp }
1933   moreover
1934   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" and jnz: "j\<noteq>0" hence l: "?L (?l (NDvd j a))"
1935       by (simp add: nb Let_def split_def isint_Floor isint_neg)
1936     have "?I (NDvd j a) = (\<not> (real j rdvd (real (?c * i) + (?N ?r))))"
1937       using Ia by (simp add: Let_def split_def)
1938     also have "\<dots> = (\<not> (real (abs j) rdvd real (?c*i) + (?N ?r)))"
1939       by (simp only: rdvd_abs1[where d="j" and t="real (?c*i) + ?N ?r", symmetric]) simp
1940     also have "\<dots> = (\<not> ((abs j) dvd (floor ((?N ?r) + real (?c*i))) \<and>
1941        (real (floor ((?N ?r) + real (?c*i))) = (real (?c*i) + (?N ?r)))))"
1942       by(simp only: int_rdvd_real[where i="abs j" and x="real (?c*i) + (?N ?r)"]) (simp only: add_ac)
1943     also have "\<dots> = (?I (?l (NDvd j a)))" using cn cnz jnz
1944       using rdvd_minus [where d="abs j" and t="real (?c*i + floor (?N ?r))", simplified, symmetric]
1945       by (simp add: Let_def split_def int_rdvd_iff[symmetric]
1947     finally have ?case using l jnz by blast }
1948   ultimately show ?case by blast
1949 qed auto
1951 text{* plusinf : Virtual substitution of @{text "+\<infinity>"}
1952        minusinf: Virtual substitution of @{text "-\<infinity>"}
1953        @{text "\<delta>"} Compute lcm @{text "d| Dvd d  c*x+t \<in> p"}
1954        @{text "d\<delta>"} checks if a given l divides all the ds above*}
1956 fun minusinf:: "fm \<Rightarrow> fm" where
1957   "minusinf (And p q) = conj (minusinf p) (minusinf q)"
1958 | "minusinf (Or p q) = disj (minusinf p) (minusinf q)"
1959 | "minusinf (Eq  (CN 0 c e)) = F"
1960 | "minusinf (NEq (CN 0 c e)) = T"
1961 | "minusinf (Lt  (CN 0 c e)) = T"
1962 | "minusinf (Le  (CN 0 c e)) = T"
1963 | "minusinf (Gt  (CN 0 c e)) = F"
1964 | "minusinf (Ge  (CN 0 c e)) = F"
1965 | "minusinf p = p"
1967 lemma minusinf_qfree: "qfree p \<Longrightarrow> qfree (minusinf p)"
1968   by (induct p rule: minusinf.induct, auto)
1970 fun plusinf:: "fm \<Rightarrow> fm" where
1971   "plusinf (And p q) = conj (plusinf p) (plusinf q)"
1972 | "plusinf (Or p q) = disj (plusinf p) (plusinf q)"
1973 | "plusinf (Eq  (CN 0 c e)) = F"
1974 | "plusinf (NEq (CN 0 c e)) = T"
1975 | "plusinf (Lt  (CN 0 c e)) = F"
1976 | "plusinf (Le  (CN 0 c e)) = F"
1977 | "plusinf (Gt  (CN 0 c e)) = T"
1978 | "plusinf (Ge  (CN 0 c e)) = T"
1979 | "plusinf p = p"
1981 fun \<delta> :: "fm \<Rightarrow> int" where
1982   "\<delta> (And p q) = lcm (\<delta> p) (\<delta> q)"
1983 | "\<delta> (Or p q) = lcm (\<delta> p) (\<delta> q)"
1984 | "\<delta> (Dvd i (CN 0 c e)) = i"
1985 | "\<delta> (NDvd i (CN 0 c e)) = i"
1986 | "\<delta> p = 1"
1988 fun d\<delta> :: "fm \<Rightarrow> int \<Rightarrow> bool" where
1989   "d\<delta> (And p q) = (\<lambda> d. d\<delta> p d \<and> d\<delta> q d)"
1990 | "d\<delta> (Or p q) = (\<lambda> d. d\<delta> p d \<and> d\<delta> q d)"
1991 | "d\<delta> (Dvd i (CN 0 c e)) = (\<lambda> d. i dvd d)"
1992 | "d\<delta> (NDvd i (CN 0 c e)) = (\<lambda> d. i dvd d)"
1993 | "d\<delta> p = (\<lambda> d. True)"
1995 lemma delta_mono:
1996   assumes lin: "iszlfm p bs"
1997   and d: "d dvd d'"
1998   and ad: "d\<delta> p d"
1999   shows "d\<delta> p d'"
2001 proof(induct p rule: iszlfm.induct)
2002   case (9 i c e)  thus ?case using d
2003     by (simp add: dvd_trans[of "i" "d" "d'"])
2004 next
2005   case (10 i c e) thus ?case using d
2006     by (simp add: dvd_trans[of "i" "d" "d'"])
2007 qed simp_all
2009 lemma \<delta> : assumes lin:"iszlfm p bs"
2010   shows "d\<delta> p (\<delta> p) \<and> \<delta> p >0"
2011 using lin
2012 proof (induct p rule: iszlfm.induct)
2013   case (1 p q)
2014   let ?d = "\<delta> (And p q)"
2015   from prems lcm_pos_int have dp: "?d >0" by simp
2016   have d1: "\<delta> p dvd \<delta> (And p q)" using prems by simp
2017    hence th: "d\<delta> p ?d"
2018      using delta_mono prems by(simp only: iszlfm.simps) blast
2019   have "\<delta> q dvd \<delta> (And p q)" using prems  by simp
2020   hence th': "d\<delta> q ?d" using delta_mono prems by(simp only: iszlfm.simps) blast
2021   from th th' dp show ?case by simp
2022 next
2023   case (2 p q)
2024   let ?d = "\<delta> (And p q)"
2025   from prems lcm_pos_int have dp: "?d >0" by simp
2026   have "\<delta> p dvd \<delta> (And p q)" using prems by simp hence th: "d\<delta> p ?d" using delta_mono prems
2027     by(simp only: iszlfm.simps) blast
2028   have "\<delta> q dvd \<delta> (And p q)" using prems by simp hence th': "d\<delta> q ?d" using delta_mono prems by(simp only: iszlfm.simps) blast
2029   from th th' dp show ?case by simp
2030 qed simp_all
2033 lemma minusinf_inf:
2034   assumes linp: "iszlfm p (a # bs)"
2035   shows "\<exists> (z::int). \<forall> x < z. Ifm ((real x)#bs) (minusinf p) = Ifm ((real x)#bs) p"
2036   (is "?P p" is "\<exists> (z::int). \<forall> x < z. ?I x (?M p) = ?I x p")
2037 using linp
2038 proof (induct p rule: minusinf.induct)
2039   case (1 f g)
2040   from prems have "?P f" by simp
2041   then obtain z1 where z1_def: "\<forall> x < z1. ?I x (?M f) = ?I x f" by blast
2042   from prems have "?P g" by simp
2043   then obtain z2 where z2_def: "\<forall> x < z2. ?I x (?M g) = ?I x g" by blast
2044   let ?z = "min z1 z2"
2045   from z1_def z2_def have "\<forall> x < ?z. ?I x (?M (And f g)) = ?I x (And f g)" by simp
2046   thus ?case by blast
2047 next
2048   case (2 f g)   from prems have "?P f" by simp
2049   then obtain z1 where z1_def: "\<forall> x < z1. ?I x (?M f) = ?I x f" by blast
2050   from prems have "?P g" by simp
2051   then obtain z2 where z2_def: "\<forall> x < z2. ?I x (?M g) = ?I x g" by blast
2052   let ?z = "min z1 z2"
2053   from z1_def z2_def have "\<forall> x < ?z. ?I x (?M (Or f g)) = ?I x (Or f g)" by simp
2054   thus ?case by blast
2055 next
2056   case (3 c e)
2057   from prems have "c > 0" by simp hence rcpos: "real c > 0" by simp
2058   from prems have nbe: "numbound0 e" by simp
2059   fix y
2060   have "\<forall> x < (floor (- (Inum (y#bs) e) / (real c))). ?I x (?M (Eq (CN 0 c e))) = ?I x (Eq (CN 0 c e))"
2061   proof (simp add: less_floor_eq , rule allI, rule impI)
2062     fix x
2063     assume A: "real x + (1\<Colon>real) \<le> - (Inum (y # bs) e / real c)"
2064     hence th1:"real x < - (Inum (y # bs) e / real c)" by simp
2065     with rcpos  have "(real c)*(real  x) < (real c)*(- (Inum (y # bs) e / real c))"
2066       by (simp only: mult_strict_left_mono [OF th1 rcpos])
2067     hence "real c * real x + Inum (y # bs) e \<noteq> 0"using rcpos  by simp
2068     thus "real c * real x + Inum (real x # bs) e \<noteq> 0"
2069       using numbound0_I[OF nbe, where b="y" and bs="bs" and b'="real x"]  by simp
2070   qed
2071   thus ?case by blast
2072 next
2073   case (4 c e)
2074   from prems have "c > 0" by simp hence rcpos: "real c > 0" by simp
2075   from prems have nbe: "numbound0 e" by simp
2076   fix y
2077   have "\<forall> x < (floor (- (Inum (y#bs) e) / (real c))). ?I x (?M (NEq (CN 0 c e))) = ?I x (NEq (CN 0 c e))"
2078   proof (simp add: less_floor_eq , rule allI, rule impI)
2079     fix x
2080     assume A: "real x + (1\<Colon>real) \<le> - (Inum (y # bs) e / real c)"
2081     hence th1:"real x < - (Inum (y # bs) e / real c)" by simp
2082     with rcpos  have "(real c)*(real  x) < (real c)*(- (Inum (y # bs) e / real c))"
2083       by (simp only: mult_strict_left_mono [OF th1 rcpos])
2084     hence "real c * real x + Inum (y # bs) e \<noteq> 0"using rcpos  by simp
2085     thus "real c * real x + Inum (real x # bs) e \<noteq> 0"
2086       using numbound0_I[OF nbe, where b="y" and bs="bs" and b'="real x"]  by simp
2087   qed
2088   thus ?case by blast
2089 next
2090   case (5 c e)
2091   from prems have "c > 0" by simp hence rcpos: "real c > 0" by simp
2092   from prems have nbe: "numbound0 e" by simp
2093   fix y
2094   have "\<forall> x < (floor (- (Inum (y#bs) e) / (real c))). ?I x (?M (Lt (CN 0 c e))) = ?I x (Lt (CN 0 c e))"
2095   proof (simp add: less_floor_eq , rule allI, rule impI)
2096     fix x
2097     assume A: "real x + (1\<Colon>real) \<le> - (Inum (y # bs) e / real c)"
2098     hence th1:"real x < - (Inum (y # bs) e / real c)" by simp
2099     with rcpos  have "(real c)*(real  x) < (real c)*(- (Inum (y # bs) e / real c))"
2100       by (simp only: mult_strict_left_mono [OF th1 rcpos])
2101     thus "real c * real x + Inum (real x # bs) e < 0"
2102       using numbound0_I[OF nbe, where b="y" and bs="bs" and b'="real x"] rcpos by simp
2103   qed
2104   thus ?case by blast
2105 next
2106   case (6 c e)
2107   from prems have "c > 0" by simp hence rcpos: "real c > 0" by simp
2108   from prems have nbe: "numbound0 e" by simp
2109   fix y
2110   have "\<forall> x < (floor (- (Inum (y#bs) e) / (real c))). ?I x (?M (Le (CN 0 c e))) = ?I x (Le (CN 0 c e))"
2111   proof (simp add: less_floor_eq , rule allI, rule impI)
2112     fix x
2113     assume A: "real x + (1\<Colon>real) \<le> - (Inum (y # bs) e / real c)"
2114     hence th1:"real x < - (Inum (y # bs) e / real c)" by simp
2115     with rcpos  have "(real c)*(real  x) < (real c)*(- (Inum (y # bs) e / real c))"
2116       by (simp only: mult_strict_left_mono [OF th1 rcpos])
2117     thus "real c * real x + Inum (real x # bs) e \<le> 0"
2118       using numbound0_I[OF nbe, where b="y" and bs="bs" and b'="real x"] rcpos by simp
2119   qed
2120   thus ?case by blast
2121 next
2122   case (7 c e)
2123   from prems have "c > 0" by simp hence rcpos: "real c > 0" by simp
2124   from prems have nbe: "numbound0 e" by simp
2125   fix y
2126   have "\<forall> x < (floor (- (Inum (y#bs) e) / (real c))). ?I x (?M (Gt (CN 0 c e))) = ?I x (Gt (CN 0 c e))"
2127   proof (simp add: less_floor_eq , rule allI, rule impI)
2128     fix x
2129     assume A: "real x + (1\<Colon>real) \<le> - (Inum (y # bs) e / real c)"
2130     hence th1:"real x < - (Inum (y # bs) e / real c)" by simp
2131     with rcpos  have "(real c)*(real  x) < (real c)*(- (Inum (y # bs) e / real c))"
2132       by (simp only: mult_strict_left_mono [OF th1 rcpos])
2133     thus "\<not> (real c * real x + Inum (real x # bs) e>0)"
2134       using numbound0_I[OF nbe, where b="y" and bs="bs" and b'="real x"] rcpos by simp
2135   qed
2136   thus ?case by blast
2137 next
2138   case (8 c e)
2139   from prems have "c > 0" by simp hence rcpos: "real c > 0" by simp
2140   from prems have nbe: "numbound0 e" by simp
2141   fix y
2142   have "\<forall> x < (floor (- (Inum (y#bs) e) / (real c))). ?I x (?M (Ge (CN 0 c e))) = ?I x (Ge (CN 0 c e))"
2143   proof (simp add: less_floor_eq , rule allI, rule impI)
2144     fix x
2145     assume A: "real x + (1\<Colon>real) \<le> - (Inum (y # bs) e / real c)"
2146     hence th1:"real x < - (Inum (y # bs) e / real c)" by simp
2147     with rcpos  have "(real c)*(real  x) < (real c)*(- (Inum (y # bs) e / real c))"
2148       by (simp only: mult_strict_left_mono [OF th1 rcpos])
2149     thus "\<not> real c * real x + Inum (real x # bs) e \<ge> 0"
2150       using numbound0_I[OF nbe, where b="y" and bs="bs" and b'="real x"] rcpos by simp
2151   qed
2152   thus ?case by blast
2153 qed simp_all
2155 lemma minusinf_repeats:
2156   assumes d: "d\<delta> p d" and linp: "iszlfm p (a # bs)"
2157   shows "Ifm ((real(x - k*d))#bs) (minusinf p) = Ifm (real x #bs) (minusinf p)"
2158 using linp d
2159 proof(induct p rule: iszlfm.induct)
2160   case (9 i c e) hence nbe: "numbound0 e"  and id: "i dvd d" by simp+
2161     hence "\<exists> k. d=i*k" by (simp add: dvd_def)
2162     then obtain "di" where di_def: "d=i*di" by blast
2163     show ?case
2164     proof(simp add: numbound0_I[OF nbe,where bs="bs" and b="real x - real k * real d" and b'="real x"] right_diff_distrib, rule iffI)
2165       assume
2166         "real i rdvd real c * real x - real c * (real k * real d) + Inum (real x # bs) e"
2167       (is "?ri rdvd ?rc*?rx - ?rc*(?rk*?rd) + ?I x e" is "?ri rdvd ?rt")
2168       hence "\<exists> (l::int). ?rt = ?ri * (real l)" by (simp add: rdvd_def)
2169       hence "\<exists> (l::int). ?rc*?rx+ ?I x e = ?ri*(real l)+?rc*(?rk * (real i) * (real di))"
2170         by (simp add: algebra_simps di_def)
2171       hence "\<exists> (l::int). ?rc*?rx+ ?I x e = ?ri*(real (l + c*k*di))"
2173       hence "\<exists> (l::int). ?rc*?rx+ ?I x e = ?ri* (real l)" by blast
2174       thus "real i rdvd real c * real x + Inum (real x # bs) e" using rdvd_def by simp
2175     next
2176       assume
2177         "real i rdvd real c * real x + Inum (real x # bs) e" (is "?ri rdvd ?rc*?rx+?e")
2178       hence "\<exists> (l::int). ?rc*?rx+?e = ?ri * (real l)" by (simp add: rdvd_def)
2179       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real l) - real c * (real k * real d)" by simp
2180       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real l) - real c * (real k * real i * real di)" by (simp add: di_def)
2181       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real (l - c*k*di))" by (simp add: algebra_simps)
2182       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real l)"
2183         by blast
2184       thus "real i rdvd real c * real x - real c * (real k * real d) + Inum (real x # bs) e" using rdvd_def by simp
2185     qed
2186 next
2187   case (10 i c e) hence nbe: "numbound0 e"  and id: "i dvd d" by simp+
2188     hence "\<exists> k. d=i*k" by (simp add: dvd_def)
2189     then obtain "di" where di_def: "d=i*di" by blast
2190     show ?case
2191     proof(simp add: numbound0_I[OF nbe,where bs="bs" and b="real x - real k * real d" and b'="real x"] right_diff_distrib, rule iffI)
2192       assume
2193         "real i rdvd real c * real x - real c * (real k * real d) + Inum (real x # bs) e"
2194       (is "?ri rdvd ?rc*?rx - ?rc*(?rk*?rd) + ?I x e" is "?ri rdvd ?rt")
2195       hence "\<exists> (l::int). ?rt = ?ri * (real l)" by (simp add: rdvd_def)
2196       hence "\<exists> (l::int). ?rc*?rx+ ?I x e = ?ri*(real l)+?rc*(?rk * (real i) * (real di))"
2197         by (simp add: algebra_simps di_def)
2198       hence "\<exists> (l::int). ?rc*?rx+ ?I x e = ?ri*(real (l + c*k*di))"
2200       hence "\<exists> (l::int). ?rc*?rx+ ?I x e = ?ri* (real l)" by blast
2201       thus "real i rdvd real c * real x + Inum (real x # bs) e" using rdvd_def by simp
2202     next
2203       assume
2204         "real i rdvd real c * real x + Inum (real x # bs) e" (is "?ri rdvd ?rc*?rx+?e")
2205       hence "\<exists> (l::int). ?rc*?rx+?e = ?ri * (real l)" by (simp add: rdvd_def)
2206       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real l) - real c * (real k * real d)" by simp
2207       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real l) - real c * (real k * real i * real di)" by (simp add: di_def)
2208       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real (l - c*k*di))" by (simp add: algebra_simps)
2209       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real l)"
2210         by blast
2211       thus "real i rdvd real c * real x - real c * (real k * real d) + Inum (real x # bs) e" using rdvd_def by simp
2212     qed
2213 qed (auto simp add: numbound0_I[where bs="bs" and b="real(x - k*d)" and b'="real x"] simp del: real_of_int_mult real_of_int_diff)
2215 lemma minusinf_ex:
2216   assumes lin: "iszlfm p (real (a::int) #bs)"
2217   and exmi: "\<exists> (x::int). Ifm (real x#bs) (minusinf p)" (is "\<exists> x. ?P1 x")
2218   shows "\<exists> (x::int). Ifm (real x#bs) p" (is "\<exists> x. ?P x")
2219 proof-
2220   let ?d = "\<delta> p"
2221   from \<delta> [OF lin] have dpos: "?d >0" by simp
2222   from \<delta> [OF lin] have alld: "d\<delta> p ?d" by simp
2223   from minusinf_repeats[OF alld lin] have th1:"\<forall> x k. ?P1 x = ?P1 (x - (k * ?d))" by simp
2224   from minusinf_inf[OF lin] have th2:"\<exists> z. \<forall> x. x<z \<longrightarrow> (?P x = ?P1 x)" by blast
2225   from minusinfinity [OF dpos th1 th2] exmi show ?thesis by blast
2226 qed
2228 lemma minusinf_bex:
2229   assumes lin: "iszlfm p (real (a::int) #bs)"
2230   shows "(\<exists> (x::int). Ifm (real x#bs) (minusinf p)) =
2231          (\<exists> (x::int)\<in> {1..\<delta> p}. Ifm (real x#bs) (minusinf p))"
2232   (is "(\<exists> x. ?P x) = _")
2233 proof-
2234   let ?d = "\<delta> p"
2235   from \<delta> [OF lin] have dpos: "?d >0" by simp
2236   from \<delta> [OF lin] have alld: "d\<delta> p ?d" by simp
2237   from minusinf_repeats[OF alld lin] have th1:"\<forall> x k. ?P x = ?P (x - (k * ?d))" by simp
2238   from periodic_finite_ex[OF dpos th1] show ?thesis by blast
2239 qed
2241 lemma dvd1_eq1: "x >0 \<Longrightarrow> (x::int) dvd 1 = (x = 1)" by auto
2243 consts
2244   a\<beta> :: "fm \<Rightarrow> int \<Rightarrow> fm" (* adjusts the coeffitients of a formula *)
2245   d\<beta> :: "fm \<Rightarrow> int \<Rightarrow> bool" (* tests if all coeffs c of c divide a given l*)
2246   \<zeta>  :: "fm \<Rightarrow> int" (* computes the lcm of all coefficients of x*)
2247   \<beta> :: "fm \<Rightarrow> num list"
2248   \<alpha> :: "fm \<Rightarrow> num list"
2250 recdef a\<beta> "measure size"
2251   "a\<beta> (And p q) = (\<lambda> k. And (a\<beta> p k) (a\<beta> q k))"
2252   "a\<beta> (Or p q) = (\<lambda> k. Or (a\<beta> p k) (a\<beta> q k))"
2253   "a\<beta> (Eq  (CN 0 c e)) = (\<lambda> k. Eq (CN 0 1 (Mul (k div c) e)))"
2254   "a\<beta> (NEq (CN 0 c e)) = (\<lambda> k. NEq (CN 0 1 (Mul (k div c) e)))"
2255   "a\<beta> (Lt  (CN 0 c e)) = (\<lambda> k. Lt (CN 0 1 (Mul (k div c) e)))"
2256   "a\<beta> (Le  (CN 0 c e)) = (\<lambda> k. Le (CN 0 1 (Mul (k div c) e)))"
2257   "a\<beta> (Gt  (CN 0 c e)) = (\<lambda> k. Gt (CN 0 1 (Mul (k div c) e)))"
2258   "a\<beta> (Ge  (CN 0 c e)) = (\<lambda> k. Ge (CN 0 1 (Mul (k div c) e)))"
2259   "a\<beta> (Dvd i (CN 0 c e)) =(\<lambda> k. Dvd ((k div c)*i) (CN 0 1 (Mul (k div c) e)))"
2260   "a\<beta> (NDvd i (CN 0 c e))=(\<lambda> k. NDvd ((k div c)*i) (CN 0 1 (Mul (k div c) e)))"
2261   "a\<beta> p = (\<lambda> k. p)"
2263 recdef d\<beta> "measure size"
2264   "d\<beta> (And p q) = (\<lambda> k. (d\<beta> p k) \<and> (d\<beta> q k))"
2265   "d\<beta> (Or p q) = (\<lambda> k. (d\<beta> p k) \<and> (d\<beta> q k))"
2266   "d\<beta> (Eq  (CN 0 c e)) = (\<lambda> k. c dvd k)"
2267   "d\<beta> (NEq (CN 0 c e)) = (\<lambda> k. c dvd k)"
2268   "d\<beta> (Lt  (CN 0 c e)) = (\<lambda> k. c dvd k)"
2269   "d\<beta> (Le  (CN 0 c e)) = (\<lambda> k. c dvd k)"
2270   "d\<beta> (Gt  (CN 0 c e)) = (\<lambda> k. c dvd k)"
2271   "d\<beta> (Ge  (CN 0 c e)) = (\<lambda> k. c dvd k)"
2272   "d\<beta> (Dvd i (CN 0 c e)) =(\<lambda> k. c dvd k)"
2273   "d\<beta> (NDvd i (CN 0 c e))=(\<lambda> k. c dvd k)"
2274   "d\<beta> p = (\<lambda> k. True)"
2276 recdef \<zeta> "measure size"
2277   "\<zeta> (And p q) = lcm (\<zeta> p) (\<zeta> q)"
2278   "\<zeta> (Or p q) = lcm (\<zeta> p) (\<zeta> q)"
2279   "\<zeta> (Eq  (CN 0 c e)) = c"
2280   "\<zeta> (NEq (CN 0 c e)) = c"
2281   "\<zeta> (Lt  (CN 0 c e)) = c"
2282   "\<zeta> (Le  (CN 0 c e)) = c"
2283   "\<zeta> (Gt  (CN 0 c e)) = c"
2284   "\<zeta> (Ge  (CN 0 c e)) = c"
2285   "\<zeta> (Dvd i (CN 0 c e)) = c"
2286   "\<zeta> (NDvd i (CN 0 c e))= c"
2287   "\<zeta> p = 1"
2289 recdef \<beta> "measure size"
2290   "\<beta> (And p q) = (\<beta> p @ \<beta> q)"
2291   "\<beta> (Or p q) = (\<beta> p @ \<beta> q)"
2292   "\<beta> (Eq  (CN 0 c e)) = [Sub (C -1) e]"
2293   "\<beta> (NEq (CN 0 c e)) = [Neg e]"
2294   "\<beta> (Lt  (CN 0 c e)) = []"
2295   "\<beta> (Le  (CN 0 c e)) = []"
2296   "\<beta> (Gt  (CN 0 c e)) = [Neg e]"
2297   "\<beta> (Ge  (CN 0 c e)) = [Sub (C -1) e]"
2298   "\<beta> p = []"
2300 recdef \<alpha> "measure size"
2301   "\<alpha> (And p q) = (\<alpha> p @ \<alpha> q)"
2302   "\<alpha> (Or p q) = (\<alpha> p @ \<alpha> q)"
2303   "\<alpha> (Eq  (CN 0 c e)) = [Add (C -1) e]"
2304   "\<alpha> (NEq (CN 0 c e)) = [e]"
2305   "\<alpha> (Lt  (CN 0 c e)) = [e]"
2306   "\<alpha> (Le  (CN 0 c e)) = [Add (C -1) e]"
2307   "\<alpha> (Gt  (CN 0 c e)) = []"
2308   "\<alpha> (Ge  (CN 0 c e)) = []"
2309   "\<alpha> p = []"
2310 consts mirror :: "fm \<Rightarrow> fm"
2311 recdef mirror "measure size"
2312   "mirror (And p q) = And (mirror p) (mirror q)"
2313   "mirror (Or p q) = Or (mirror p) (mirror q)"
2314   "mirror (Eq  (CN 0 c e)) = Eq (CN 0 c (Neg e))"
2315   "mirror (NEq (CN 0 c e)) = NEq (CN 0 c (Neg e))"
2316   "mirror (Lt  (CN 0 c e)) = Gt (CN 0 c (Neg e))"
2317   "mirror (Le  (CN 0 c e)) = Ge (CN 0 c (Neg e))"
2318   "mirror (Gt  (CN 0 c e)) = Lt (CN 0 c (Neg e))"
2319   "mirror (Ge  (CN 0 c e)) = Le (CN 0 c (Neg e))"
2320   "mirror (Dvd i (CN 0 c e)) = Dvd i (CN 0 c (Neg e))"
2321   "mirror (NDvd i (CN 0 c e)) = NDvd i (CN 0 c (Neg e))"
2322   "mirror p = p"
2324 lemma mirror\<alpha>\<beta>:
2325   assumes lp: "iszlfm p (a#bs)"
2326   shows "(Inum (real (i::int)#bs)) ` set (\<alpha> p) = (Inum (real i#bs)) ` set (\<beta> (mirror p))"
2327 using lp
2328 by (induct p rule: mirror.induct, auto)
2330 lemma mirror:
2331   assumes lp: "iszlfm p (a#bs)"
2332   shows "Ifm (real (x::int)#bs) (mirror p) = Ifm (real (- x)#bs) p"
2333 using lp
2334 proof(induct p rule: iszlfm.induct)
2335   case (9 j c e)
2336   have th: "(real j rdvd real c * real x - Inum (real x # bs) e) =
2337        (real j rdvd - (real c * real x - Inum (real x # bs) e))"
2338     by (simp only: rdvd_minus[symmetric])
2339   from prems th show  ?case
2341       numbound0_I[where bs="bs" and b'="real x" and b="- real x"])
2342 next
2343     case (10 j c e)
2344   have th: "(real j rdvd real c * real x - Inum (real x # bs) e) =
2345        (real j rdvd - (real c * real x - Inum (real x # bs) e))"
2346     by (simp only: rdvd_minus[symmetric])
2347   from prems th show  ?case
2349       numbound0_I[where bs="bs" and b'="real x" and b="- real x"])
2350 qed (auto simp add: numbound0_I[where bs="bs" and b="real x" and b'="- real x"])
2352 lemma mirror_l: "iszlfm p (a#bs) \<Longrightarrow> iszlfm (mirror p) (a#bs)"
2353 by (induct p rule: mirror.induct, auto simp add: isint_neg)
2355 lemma mirror_d\<beta>: "iszlfm p (a#bs) \<and> d\<beta> p 1
2356   \<Longrightarrow> iszlfm (mirror p) (a#bs) \<and> d\<beta> (mirror p) 1"
2357 by (induct p rule: mirror.induct, auto simp add: isint_neg)
2359 lemma mirror_\<delta>: "iszlfm p (a#bs) \<Longrightarrow> \<delta> (mirror p) = \<delta> p"
2360 by (induct p rule: mirror.induct,auto)
2363 lemma mirror_ex:
2364   assumes lp: "iszlfm p (real (i::int)#bs)"
2365   shows "(\<exists> (x::int). Ifm (real x#bs) (mirror p)) = (\<exists> (x::int). Ifm (real x#bs) p)"
2366   (is "(\<exists> x. ?I x ?mp) = (\<exists> x. ?I x p)")
2367 proof(auto)
2368   fix x assume "?I x ?mp" hence "?I (- x) p" using mirror[OF lp] by blast
2369   thus "\<exists> x. ?I x p" by blast
2370 next
2371   fix x assume "?I x p" hence "?I (- x) ?mp"
2372     using mirror[OF lp, where x="- x", symmetric] by auto
2373   thus "\<exists> x. ?I x ?mp" by blast
2374 qed
2376 lemma \<beta>_numbound0: assumes lp: "iszlfm p bs"
2377   shows "\<forall> b\<in> set (\<beta> p). numbound0 b"
2378   using lp by (induct p rule: \<beta>.induct,auto)
2380 lemma d\<beta>_mono:
2381   assumes linp: "iszlfm p (a #bs)"
2382   and dr: "d\<beta> p l"
2383   and d: "l dvd l'"
2384   shows "d\<beta> p l'"
2385 using dr linp dvd_trans[of _ "l" "l'", simplified d]
2386 by (induct p rule: iszlfm.induct) simp_all
2388 lemma \<alpha>_l: assumes lp: "iszlfm p (a#bs)"
2389   shows "\<forall> b\<in> set (\<alpha> p). numbound0 b \<and> isint b (a#bs)"
2390 using lp
2393 lemma \<zeta>:
2394   assumes linp: "iszlfm p (a #bs)"
2395   shows "\<zeta> p > 0 \<and> d\<beta> p (\<zeta> p)"
2396 using linp
2397 proof(induct p rule: iszlfm.induct)
2398   case (1 p q)
2399   from prems have dl1: "\<zeta> p dvd lcm (\<zeta> p) (\<zeta> q)" by simp
2400   from prems have dl2: "\<zeta> q dvd lcm (\<zeta> p) (\<zeta> q)" by simp
2401   from prems d\<beta>_mono[where p = "p" and l="\<zeta> p" and l'="lcm (\<zeta> p) (\<zeta> q)"]
2402     d\<beta>_mono[where p = "q" and l="\<zeta> q" and l'="lcm (\<zeta> p) (\<zeta> q)"]
2403     dl1 dl2 show ?case by (auto simp add: lcm_pos_int)
2404 next
2405   case (2 p q)
2406   from prems have dl1: "\<zeta> p dvd lcm (\<zeta> p) (\<zeta> q)" by simp
2407   from prems have dl2: "\<zeta> q dvd lcm (\<zeta> p) (\<zeta> q)" by simp
2408   from prems d\<beta>_mono[where p = "p" and l="\<zeta> p" and l'="lcm (\<zeta> p) (\<zeta> q)"]
2409     d\<beta>_mono[where p = "q" and l="\<zeta> q" and l'="lcm (\<zeta> p) (\<zeta> q)"]
2410     dl1 dl2 show ?case by (auto simp add: lcm_pos_int)
2411 qed (auto simp add: lcm_pos_int)
2413 lemma a\<beta>: assumes linp: "iszlfm p (a #bs)" and d: "d\<beta> p l" and lp: "l > 0"
2414   shows "iszlfm (a\<beta> p l) (a #bs) \<and> d\<beta> (a\<beta> p l) 1 \<and> (Ifm (real (l * x) #bs) (a\<beta> p l) = Ifm ((real x)#bs) p)"
2415 using linp d
2416 proof (induct p rule: iszlfm.induct)
2417   case (5 c e) hence cp: "c>0" and be: "numbound0 e" and ei:"isint e (a#bs)" and d': "c dvd l" by simp+
2418     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
2419     from cp have cnz: "c \<noteq> 0" by simp
2420     have "c div c\<le> l div c"
2421       by (simp add: zdiv_mono1[OF clel cp])
2422     then have ldcp:"0 < l div c"
2423       by (simp add: zdiv_self[OF cnz])
2424     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
2425     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric]
2426       by simp
2427     hence "(real l * real x + real (l div c) * Inum (real x # bs) e < (0\<Colon>real)) =
2428           (real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e < 0)"
2429       by simp
2430     also have "\<dots> = (real (l div c) * (real c * real x + Inum (real x # bs) e) < (real (l div c)) * 0)" by (simp add: algebra_simps)
2431     also have "\<dots> = (real c * real x + Inum (real x # bs) e < 0)"
2432     using mult_less_0_iff [where a="real (l div c)" and b="real c * real x + Inum (real x # bs) e"] ldcp by simp
2433   finally show ?case using numbound0_I[OF be,where b="real (l * x)" and b'="real x" and bs="bs"] be  isint_Mul[OF ei] by simp
2434 next
2435   case (6 c e) hence cp: "c>0" and be: "numbound0 e" and ei:"isint e (a#bs)" and d': "c dvd l" by simp+
2436     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
2437     from cp have cnz: "c \<noteq> 0" by simp
2438     have "c div c\<le> l div c"
2439       by (simp add: zdiv_mono1[OF clel cp])
2440     then have ldcp:"0 < l div c"
2441       by (simp add: zdiv_self[OF cnz])
2442     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
2443     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric]
2444       by simp
2445     hence "(real l * real x + real (l div c) * Inum (real x # bs) e \<le> (0\<Colon>real)) =
2446           (real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e \<le> 0)"
2447       by simp
2448     also have "\<dots> = (real (l div c) * (real c * real x + Inum (real x # bs) e) \<le> (real (l div c)) * 0)" by (simp add: algebra_simps)
2449     also have "\<dots> = (real c * real x + Inum (real x # bs) e \<le> 0)"
2450     using mult_le_0_iff [where a="real (l div c)" and b="real c * real x + Inum (real x # bs) e"] ldcp by simp
2451   finally show ?case using numbound0_I[OF be,where b="real (l * x)" and b'="real x" and bs="bs"]  be  isint_Mul[OF ei] by simp
2452 next
2453   case (7 c e) hence cp: "c>0" and be: "numbound0 e" and ei:"isint e (a#bs)" and d': "c dvd l" by simp+
2454     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
2455     from cp have cnz: "c \<noteq> 0" by simp
2456     have "c div c\<le> l div c"
2457       by (simp add: zdiv_mono1[OF clel cp])
2458     then have ldcp:"0 < l div c"
2459       by (simp add: zdiv_self[OF cnz])
2460     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
2461     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric]
2462       by simp
2463     hence "(real l * real x + real (l div c) * Inum (real x # bs) e > (0\<Colon>real)) =
2464           (real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e > 0)"
2465       by simp
2466     also have "\<dots> = (real (l div c) * (real c * real x + Inum (real x # bs) e) > (real (l div c)) * 0)" by (simp add: algebra_simps)
2467     also have "\<dots> = (real c * real x + Inum (real x # bs) e > 0)"
2468     using zero_less_mult_iff [where a="real (l div c)" and b="real c * real x + Inum (real x # bs) e"] ldcp by simp
2469   finally show ?case using numbound0_I[OF be,where b="real (l * x)" and b'="real x" and bs="bs"]  be  isint_Mul[OF ei] by simp
2470 next
2471   case (8 c e) hence cp: "c>0" and be: "numbound0 e"  and ei:"isint e (a#bs)" and d': "c dvd l" by simp+
2472     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
2473     from cp have cnz: "c \<noteq> 0" by simp
2474     have "c div c\<le> l div c"
2475       by (simp add: zdiv_mono1[OF clel cp])
2476     then have ldcp:"0 < l div c"
2477       by (simp add: zdiv_self[OF cnz])
2478     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
2479     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric]
2480       by simp
2481     hence "(real l * real x + real (l div c) * Inum (real x # bs) e \<ge> (0\<Colon>real)) =
2482           (real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e \<ge> 0)"
2483       by simp
2484     also have "\<dots> = (real (l div c) * (real c * real x + Inum (real x # bs) e) \<ge> (real (l div c)) * 0)" by (simp add: algebra_simps)
2485     also have "\<dots> = (real c * real x + Inum (real x # bs) e \<ge> 0)"
2486     using zero_le_mult_iff [where a="real (l div c)" and b="real c * real x + Inum (real x # bs) e"] ldcp by simp
2487   finally show ?case using numbound0_I[OF be,where b="real (l * x)" and b'="real x" and bs="bs"]  be  isint_Mul[OF ei] by simp
2488 next
2489   case (3 c e) hence cp: "c>0" and be: "numbound0 e" and ei:"isint e (a#bs)" and d': "c dvd l" by simp+
2490     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
2491     from cp have cnz: "c \<noteq> 0" by simp
2492     have "c div c\<le> l div c"
2493       by (simp add: zdiv_mono1[OF clel cp])
2494     then have ldcp:"0 < l div c"
2495       by (simp add: zdiv_self[OF cnz])
2496     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
2497     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric]
2498       by simp
2499     hence "(real l * real x + real (l div c) * Inum (real x # bs) e = (0\<Colon>real)) =
2500           (real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e = 0)"
2501       by simp
2502     also have "\<dots> = (real (l div c) * (real c * real x + Inum (real x # bs) e) = (real (l div c)) * 0)" by (simp add: algebra_simps)
2503     also have "\<dots> = (real c * real x + Inum (real x # bs) e = 0)"
2504     using mult_eq_0_iff [where a="real (l div c)" and b="real c * real x + Inum (real x # bs) e"] ldcp by simp
2505   finally show ?case using numbound0_I[OF be,where b="real (l * x)" and b'="real x" and bs="bs"]  be  isint_Mul[OF ei] by simp
2506 next
2507   case (4 c e) hence cp: "c>0" and be: "numbound0 e" and ei:"isint e (a#bs)" and d': "c dvd l" by simp+
2508     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
2509     from cp have cnz: "c \<noteq> 0" by simp
2510     have "c div c\<le> l div c"
2511       by (simp add: zdiv_mono1[OF clel cp])
2512     then have ldcp:"0 < l div c"
2513       by (simp add: zdiv_self[OF cnz])
2514     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
2515     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric]
2516       by simp
2517     hence "(real l * real x + real (l div c) * Inum (real x # bs) e \<noteq> (0\<Colon>real)) =
2518           (real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e \<noteq> 0)"
2519       by simp
2520     also have "\<dots> = (real (l div c) * (real c * real x + Inum (real x # bs) e) \<noteq> (real (l div c)) * 0)" by (simp add: algebra_simps)
2521     also have "\<dots> = (real c * real x + Inum (real x # bs) e \<noteq> 0)"
2522     using zero_le_mult_iff [where a="real (l div c)" and b="real c * real x + Inum (real x # bs) e"] ldcp by simp
2523   finally show ?case using numbound0_I[OF be,where b="real (l * x)" and b'="real x" and bs="bs"]  be  isint_Mul[OF ei] by simp
2524 next
2525   case (9 j c e) hence cp: "c>0" and be: "numbound0 e" and ei:"isint e (a#bs)" and jp: "j > 0" and d': "c dvd l" by simp+
2526     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
2527     from cp have cnz: "c \<noteq> 0" by simp
2528     have "c div c\<le> l div c"
2529       by (simp add: zdiv_mono1[OF clel cp])
2530     then have ldcp:"0 < l div c"
2531       by (simp add: zdiv_self[OF cnz])
2532     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
2533     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric]
2534       by simp
2535     hence "(\<exists> (k::int). real l * real x + real (l div c) * Inum (real x # bs) e = (real (l div c) * real j) * real k) = (\<exists> (k::int). real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e = (real (l div c) * real j) * real k)"  by simp
2536     also have "\<dots> = (\<exists> (k::int). real (l div c) * (real c * real x + Inum (real x # bs) e - real j * real k) = real (l div c)*0)" by (simp add: algebra_simps)
2537     also fix k have "\<dots> = (\<exists> (k::int). real c * real x + Inum (real x # bs) e - real j * real k = 0)"
2538     using zero_le_mult_iff [where a="real (l div c)" and b="real c * real x + Inum (real x # bs) e - real j * real k"] ldcp by simp
2539   also have "\<dots> = (\<exists> (k::int). real c * real x + Inum (real x # bs) e = real j * real k)" by simp
2540   finally show ?case using numbound0_I[OF be,where b="real (l * x)" and b'="real x" and bs="bs"] rdvd_def  be  isint_Mul[OF ei] mult_strict_mono[OF ldcp jp ldcp ] by simp
2541 next
2542   case (10 j c e) hence cp: "c>0" and be: "numbound0 e" and ei:"isint e (a#bs)" and jp: "j > 0" and d': "c dvd l" by simp+
2543     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
2544     from cp have cnz: "c \<noteq> 0" by simp
2545     have "c div c\<le> l div c"
2546       by (simp add: zdiv_mono1[OF clel cp])
2547     then have ldcp:"0 < l div c"
2548       by (simp add: zdiv_self[OF cnz])
2549     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
2550     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric]
2551       by simp
2552     hence "(\<exists> (k::int). real l * real x + real (l div c) * Inum (real x # bs) e = (real (l div c) * real j) * real k) = (\<exists> (k::int). real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e = (real (l div c) * real j) * real k)"  by simp
2553     also have "\<dots> = (\<exists> (k::int). real (l div c) * (real c * real x + Inum (real x # bs) e - real j * real k) = real (l div c)*0)" by (simp add: algebra_simps)
2554     also fix k have "\<dots> = (\<exists> (k::int). real c * real x + Inum (real x # bs) e - real j * real k = 0)"
2555     using zero_le_mult_iff [where a="real (l div c)" and b="real c * real x + Inum (real x # bs) e - real j * real k"] ldcp by simp
2556   also have "\<dots> = (\<exists> (k::int). real c * real x + Inum (real x # bs) e = real j * real k)" by simp
2557   finally show ?case using numbound0_I[OF be,where b="real (l * x)" and b'="real x" and bs="bs"] rdvd_def  be  isint_Mul[OF ei]  mult_strict_mono[OF ldcp jp ldcp ] by simp
2558 qed (simp_all add: numbound0_I[where bs="bs" and b="real (l * x)" and b'="real x"] isint_Mul del: real_of_int_mult)
2560 lemma a\<beta>_ex: assumes linp: "iszlfm p (a#bs)" and d: "d\<beta> p l" and lp: "l>0"
2561   shows "(\<exists> x. l dvd x \<and> Ifm (real x #bs) (a\<beta> p l)) = (\<exists> (x::int). Ifm (real x#bs) p)"
2562   (is "(\<exists> x. l dvd x \<and> ?P x) = (\<exists> x. ?P' x)")
2563 proof-
2564   have "(\<exists> x. l dvd x \<and> ?P x) = (\<exists> (x::int). ?P (l*x))"
2565     using unity_coeff_ex[where l="l" and P="?P", simplified] by simp
2566   also have "\<dots> = (\<exists> (x::int). ?P' x)" using a\<beta>[OF linp d lp] by simp
2567   finally show ?thesis  .
2568 qed
2570 lemma \<beta>:
2571   assumes lp: "iszlfm p (a#bs)"
2572   and u: "d\<beta> p 1"
2573   and d: "d\<delta> p d"
2574   and dp: "d > 0"
2575   and nob: "\<not>(\<exists>(j::int) \<in> {1 .. d}. \<exists> b\<in> (Inum (a#bs)) ` set(\<beta> p). real x = b + real j)"
2576   and p: "Ifm (real x#bs) p" (is "?P x")
2577   shows "?P (x - d)"
2578 using lp u d dp nob p
2579 proof(induct p rule: iszlfm.induct)
2580   case (5 c e) hence c1: "c=1" and  bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp+
2581     with dp p c1 numbound0_I[OF bn,where b="real (x-d)" and b'="real x" and bs="bs"] prems
2582     show ?case by (simp del: real_of_int_minus)
2583 next
2584   case (6 c e)  hence c1: "c=1" and  bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp+
2585     with dp p c1 numbound0_I[OF bn,where b="real (x-d)" and b'="real x" and bs="bs"] prems
2586     show ?case by (simp del: real_of_int_minus)
2587 next
2588   case (7 c e) hence p: "Ifm (real x #bs) (Gt (CN 0 c e))" and c1: "c=1" and bn:"numbound0 e" and ie1:"isint e (a#bs)" using dvd1_eq1[where x="c"] by simp+
2589     let ?e = "Inum (real x # bs) e"
2590     from ie1 have ie: "real (floor ?e) = ?e" using isint_iff[where n="e" and bs="a#bs"]
2591       numbound0_I[OF bn,where b="a" and b'="real x" and bs="bs"]
2593     {assume "real (x-d) +?e > 0" hence ?case using c1
2594       numbound0_I[OF bn,where b="real (x-d)" and b'="real x" and bs="bs"]
2595         by (simp del: real_of_int_minus)}
2596     moreover
2597     {assume H: "\<not> real (x-d) + ?e > 0"
2598       let ?v="Neg e"
2599       have vb: "?v \<in> set (\<beta> (Gt (CN 0 c e)))" by simp
2600       from prems(11)[simplified simp_thms Inum.simps \<beta>.simps set.simps bex_simps numbound0_I[OF bn,where b="a" and b'="real x" and bs="bs"]]
2601       have nob: "\<not> (\<exists> j\<in> {1 ..d}. real x =  - ?e + real j)" by auto
2602       from H p have "real x + ?e > 0 \<and> real x + ?e \<le> real d" by (simp add: c1)
2603       hence "real (x + floor ?e) > real (0::int) \<and> real (x + floor ?e) \<le> real d"
2604         using ie by simp
2605       hence "x + floor ?e \<ge> 1 \<and> x + floor ?e \<le> d"  by simp
2606       hence "\<exists> (j::int) \<in> {1 .. d}. j = x + floor ?e" by simp
2607       hence "\<exists> (j::int) \<in> {1 .. d}. real x = real (- floor ?e + j)"
2608         by (simp only: real_of_int_inject) (simp add: algebra_simps)
2609       hence "\<exists> (j::int) \<in> {1 .. d}. real x = - ?e + real j"
2610         by (simp add: ie[simplified isint_iff])
2611       with nob have ?case by auto}
2612     ultimately show ?case by blast
2613 next
2614   case (8 c e) hence p: "Ifm (real x #bs) (Ge (CN 0 c e))" and c1: "c=1" and bn:"numbound0 e"
2615     and ie1:"isint e (a #bs)" using dvd1_eq1[where x="c"] by simp+
2616     let ?e = "Inum (real x # bs) e"
2617     from ie1 have ie: "real (floor ?e) = ?e" using numbound0_I[OF bn,where b="real x" and b'="a" and bs="bs"] isint_iff[where n="e" and bs="(real x)#bs"]
2619     {assume "real (x-d) +?e \<ge> 0" hence ?case using  c1
2620       numbound0_I[OF bn,where b="real (x-d)" and b'="real x" and bs="bs"]
2621         by (simp del: real_of_int_minus)}
2622     moreover
2623     {assume H: "\<not> real (x-d) + ?e \<ge> 0"
2624       let ?v="Sub (C -1) e"
2625       have vb: "?v \<in> set (\<beta> (Ge (CN 0 c e)))" by simp
2626       from prems(11)[simplified simp_thms Inum.simps \<beta>.simps set.simps bex_simps numbound0_I[OF bn,where b="a" and b'="real x" and bs="bs"]]
2627       have nob: "\<not> (\<exists> j\<in> {1 ..d}. real x =  - ?e - 1 + real j)" by auto
2628       from H p have "real x + ?e \<ge> 0 \<and> real x + ?e < real d" by (simp add: c1)
2629       hence "real (x + floor ?e) \<ge> real (0::int) \<and> real (x + floor ?e) < real d"
2630         using ie by simp
2631       hence "x + floor ?e +1 \<ge> 1 \<and> x + floor ?e + 1 \<le> d"  by simp
2632       hence "\<exists> (j::int) \<in> {1 .. d}. j = x + floor ?e + 1" by simp
2633       hence "\<exists> (j::int) \<in> {1 .. d}. x= - floor ?e - 1 + j" by (simp add: algebra_simps)
2634       hence "\<exists> (j::int) \<in> {1 .. d}. real x= real (- floor ?e - 1 + j)"
2635         by (simp only: real_of_int_inject)
2636       hence "\<exists> (j::int) \<in> {1 .. d}. real x= - ?e - 1 + real j"
2637         by (simp add: ie[simplified isint_iff])
2638       with nob have ?case by simp }
2639     ultimately show ?case by blast
2640 next
2641   case (3 c e) hence p: "Ifm (real x #bs) (Eq (CN 0 c e))" (is "?p x") and c1: "c=1"
2642     and bn:"numbound0 e" and ie1: "isint e (a #bs)" using dvd1_eq1[where x="c"] by simp+
2643     let ?e = "Inum (real x # bs) e"
2644     let ?v="(Sub (C -1) e)"
2645     have vb: "?v \<in> set (\<beta> (Eq (CN 0 c e)))" by simp
2646     from p have "real x= - ?e" by (simp add: c1) with prems(11) show ?case using dp
2647       by simp (erule ballE[where x="1"],
2648         simp_all add:algebra_simps numbound0_I[OF bn,where b="real x"and b'="a"and bs="bs"])
2649 next
2650   case (4 c e)hence p: "Ifm (real x #bs) (NEq (CN 0 c e))" (is "?p x") and c1: "c=1"
2651     and bn:"numbound0 e" and ie1: "isint e (a #bs)" using dvd1_eq1[where x="c"] by simp+
2652     let ?e = "Inum (real x # bs) e"
2653     let ?v="Neg e"
2654     have vb: "?v \<in> set (\<beta> (NEq (CN 0 c e)))" by simp
2655     {assume "real x - real d + Inum ((real (x -d)) # bs) e \<noteq> 0"
2656       hence ?case by (simp add: c1)}
2657     moreover
2658     {assume H: "real x - real d + Inum ((real (x -d)) # bs) e = 0"
2659       hence "real x = - Inum ((real (x -d)) # bs) e + real d" by simp
2660       hence "real x = - Inum (a # bs) e + real d"
2661         by (simp add: numbound0_I[OF bn,where b="real x - real d"and b'="a"and bs="bs"])
2662        with prems(11) have ?case using dp by simp}
2663   ultimately show ?case by blast
2664 next
2665   case (9 j c e) hence p: "Ifm (real x #bs) (Dvd j (CN 0 c e))" (is "?p x") and c1: "c=1"
2666     and bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp+
2667     let ?e = "Inum (real x # bs) e"
2668     from prems have "isint e (a #bs)"  by simp
2669     hence ie: "real (floor ?e) = ?e" using isint_iff[where n="e" and bs="(real x)#bs"] numbound0_I[OF bn,where b="real x" and b'="a" and bs="bs"]
2671     from prems have id: "j dvd d" by simp
2672     from c1 ie[symmetric] have "?p x = (real j rdvd real (x+ floor ?e))" by simp
2673     also have "\<dots> = (j dvd x + floor ?e)"
2674       using int_rdvd_real[where i="j" and x="real (x+ floor ?e)"] by simp
2675     also have "\<dots> = (j dvd x - d + floor ?e)"
2676       using dvd_period[OF id, where x="x" and c="-1" and t="floor ?e"] by simp
2677     also have "\<dots> = (real j rdvd real (x - d + floor ?e))"
2678       using int_rdvd_real[where i="j" and x="real (x-d + floor ?e)",symmetric, simplified]
2679       ie by simp
2680     also have "\<dots> = (real j rdvd real x - real d + ?e)"
2681       using ie by simp
2682     finally show ?case
2683       using numbound0_I[OF bn,where b="real (x-d)" and b'="real x" and bs="bs"] c1 p by simp
2684 next
2685   case (10 j c e) hence p: "Ifm (real x #bs) (NDvd j (CN 0 c e))" (is "?p x") and c1: "c=1" and bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp+
2686     let ?e = "Inum (real x # bs) e"
2687     from prems have "isint e (a#bs)"  by simp
2688     hence ie: "real (floor ?e) = ?e" using numbound0_I[OF bn,where b="real x" and b'="a" and bs="bs"] isint_iff[where n="e" and bs="(real x)#bs"]
2690     from prems have id: "j dvd d" by simp
2691     from c1 ie[symmetric] have "?p x = (\<not> real j rdvd real (x+ floor ?e))" by simp
2692     also have "\<dots> = (\<not> j dvd x + floor ?e)"
2693       using int_rdvd_real[where i="j" and x="real (x+ floor ?e)"] by simp
2694     also have "\<dots> = (\<not> j dvd x - d + floor ?e)"
2695       using dvd_period[OF id, where x="x" and c="-1" and t="floor ?e"] by simp
2696     also have "\<dots> = (\<not> real j rdvd real (x - d + floor ?e))"
2697       using int_rdvd_real[where i="j" and x="real (x-d + floor ?e)",symmetric, simplified]
2698       ie by simp
2699     also have "\<dots> = (\<not> real j rdvd real x - real d + ?e)"
2700       using ie by simp
2701     finally show ?case using numbound0_I[OF bn,where b="real (x-d)" and b'="real x" and bs="bs"] c1 p by simp
2702 qed (auto simp add: numbound0_I[where bs="bs" and b="real (x - d)" and b'="real x"] simp del: real_of_int_diff)
2704 lemma \<beta>':
2705   assumes lp: "iszlfm p (a #bs)"
2706   and u: "d\<beta> p 1"
2707   and d: "d\<delta> p d"
2708   and dp: "d > 0"
2709   shows "\<forall> x. \<not>(\<exists>(j::int) \<in> {1 .. d}. \<exists> b\<in> set(\<beta> p). Ifm ((Inum (a#bs) b + real j) #bs) p) \<longrightarrow> Ifm (real x#bs) p \<longrightarrow> Ifm (real (x - d)#bs) p" (is "\<forall> x. ?b \<longrightarrow> ?P x \<longrightarrow> ?P (x - d)")
2710 proof(clarify)
2711   fix x
2712   assume nb:"?b" and px: "?P x"
2713   hence nb2: "\<not>(\<exists>(j::int) \<in> {1 .. d}. \<exists> b\<in> (Inum (a#bs)) ` set(\<beta> p). real x = b + real j)"
2714     by auto
2715   from  \<beta>[OF lp u d dp nb2 px] show "?P (x -d )" .
2716 qed
2718 lemma \<beta>_int: assumes lp: "iszlfm p bs"
2719   shows "\<forall> b\<in> set (\<beta> p). isint b bs"
2720 using lp by (induct p rule: iszlfm.induct) (auto simp add: isint_neg isint_sub)
2722 lemma cpmi_eq: "0 < D \<Longrightarrow> (EX z::int. ALL x. x < z --> (P x = P1 x))
2723 ==> ALL x.~(EX (j::int) : {1..D}. EX (b::int) : B. P(b+j)) --> P (x) --> P (x - D)
2724 ==> (ALL (x::int). ALL (k::int). ((P1 x)= (P1 (x-k*D))))
2725 ==> (EX (x::int). P(x)) = ((EX (j::int) : {1..D} . (P1(j))) | (EX (j::int) : {1..D}. EX (b::int) : B. P (b+j)))"
2726 apply(rule iffI)
2727 prefer 2
2728 apply(drule minusinfinity)
2729 apply assumption+
2730 apply(fastsimp)
2731 apply clarsimp
2732 apply(subgoal_tac "!!k. 0<=k \<Longrightarrow> !x. P x \<longrightarrow> P (x - k*D)")
2733 apply(frule_tac x = x and z=z in decr_lemma)
2734 apply(subgoal_tac "P1(x - (\<bar>x - z\<bar> + 1) * D)")
2735 prefer 2
2736 apply(subgoal_tac "0 <= (\<bar>x - z\<bar> + 1)")
2737 prefer 2 apply arith
2738  apply fastsimp
2739 apply(drule (1)  periodic_finite_ex)
2740 apply blast
2741 apply(blast dest:decr_mult_lemma)
2742 done
2745 theorem cp_thm:
2746   assumes lp: "iszlfm p (a #bs)"
2747   and u: "d\<beta> p 1"
2748   and d: "d\<delta> p d"
2749   and dp: "d > 0"
2750   shows "(\<exists> (x::int). Ifm (real x #bs) p) = (\<exists> j\<in> {1.. d}. Ifm (real j #bs) (minusinf p) \<or> (\<exists> b \<in> set (\<beta> p). Ifm ((Inum (a#bs) b + real j) #bs) p))"
2751   (is "(\<exists> (x::int). ?P (real x)) = (\<exists> j\<in> ?D. ?M j \<or> (\<exists> b\<in> ?B. ?P (?I b + real j)))")
2752 proof-
2753   from minusinf_inf[OF lp]
2754   have th: "\<exists>(z::int). \<forall>x<z. ?P (real x) = ?M x" by blast
2755   let ?B' = "{floor (?I b) | b. b\<in> ?B}"
2756   from \<beta>_int[OF lp] isint_iff[where bs="a # bs"] have B: "\<forall> b\<in> ?B. real (floor (?I b)) = ?I b" by simp
2757   from B[rule_format]
2758   have "(\<exists>j\<in>?D. \<exists>b\<in> ?B. ?P (?I b + real j)) = (\<exists>j\<in>?D. \<exists>b\<in> ?B. ?P (real (floor (?I b)) + real j))"
2759     by simp
2760   also have "\<dots> = (\<exists>j\<in>?D. \<exists>b\<in> ?B. ?P (real (floor (?I b) + j)))" by simp
2761   also have"\<dots> = (\<exists> j \<in> ?D. \<exists> b \<in> ?B'. ?P (real (b + j)))"  by blast
2762   finally have BB':
2763     "(\<exists>j\<in>?D. \<exists>b\<in> ?B. ?P (?I b + real j)) = (\<exists> j \<in> ?D. \<exists> b \<in> ?B'. ?P (real (b + j)))"
2764     by blast
2765   hence th2: "\<forall> x. \<not> (\<exists> j \<in> ?D. \<exists> b \<in> ?B'. ?P (real (b + j))) \<longrightarrow> ?P (real x) \<longrightarrow> ?P (real (x - d))" using \<beta>'[OF lp u d dp] by blast
2766   from minusinf_repeats[OF d lp]
2767   have th3: "\<forall> x k. ?M x = ?M (x-k*d)" by simp
2768   from cpmi_eq[OF dp th th2 th3] BB' show ?thesis by blast
2769 qed
2771     (* Reddy and Loveland *)
2774 consts
2775   \<rho> :: "fm \<Rightarrow> (num \<times> int) list" (* Compute the Reddy and Loveland Bset*)
2776   \<sigma>\<rho>:: "fm \<Rightarrow> num \<times> int \<Rightarrow> fm" (* Performs the modified substitution of Reddy and Loveland*)
2777   \<alpha>\<rho> :: "fm \<Rightarrow> (num\<times>int) list"
2778   a\<rho> :: "fm \<Rightarrow> int \<Rightarrow> fm"
2779 recdef \<rho> "measure size"
2780   "\<rho> (And p q) = (\<rho> p @ \<rho> q)"
2781   "\<rho> (Or p q) = (\<rho> p @ \<rho> q)"
2782   "\<rho> (Eq  (CN 0 c e)) = [(Sub (C -1) e,c)]"
2783   "\<rho> (NEq (CN 0 c e)) = [(Neg e,c)]"
2784   "\<rho> (Lt  (CN 0 c e)) = []"
2785   "\<rho> (Le  (CN 0 c e)) = []"
2786   "\<rho> (Gt  (CN 0 c e)) = [(Neg e, c)]"
2787   "\<rho> (Ge  (CN 0 c e)) = [(Sub (C (-1)) e, c)]"
2788   "\<rho> p = []"
2790 recdef \<sigma>\<rho> "measure size"
2791   "\<sigma>\<rho> (And p q) = (\<lambda> (t,k). And (\<sigma>\<rho> p (t,k)) (\<sigma>\<rho> q (t,k)))"
2792   "\<sigma>\<rho> (Or p q) = (\<lambda> (t,k). Or (\<sigma>\<rho> p (t,k)) (\<sigma>\<rho> q (t,k)))"
2793   "\<sigma>\<rho> (Eq  (CN 0 c e)) = (\<lambda> (t,k). if k dvd c then (Eq (Add (Mul (c div k) t) e))
2794                                             else (Eq (Add (Mul c t) (Mul k e))))"
2795   "\<sigma>\<rho> (NEq (CN 0 c e)) = (\<lambda> (t,k). if k dvd c then (NEq (Add (Mul (c div k) t) e))
2796                                             else (NEq (Add (Mul c t) (Mul k e))))"
2797   "\<sigma>\<rho> (Lt  (CN 0 c e)) = (\<lambda> (t,k). if k dvd c then (Lt (Add (Mul (c div k) t) e))
2798                                             else (Lt (Add (Mul c t) (Mul k e))))"
2799   "\<sigma>\<rho> (Le  (CN 0 c e)) = (\<lambda> (t,k). if k dvd c then (Le (Add (Mul (c div k) t) e))
2800                                             else (Le (Add (Mul c t) (Mul k e))))"
2801   "\<sigma>\<rho> (Gt  (CN 0 c e)) = (\<lambda> (t,k). if k dvd c then (Gt (Add (Mul (c div k) t) e))
2802                                             else (Gt (Add (Mul c t) (Mul k e))))"
2803   "\<sigma>\<rho> (Ge  (CN 0 c e)) = (\<lambda> (t,k). if k dvd c then (Ge (Add (Mul (c div k) t) e))
2804                                             else (Ge (Add (Mul c t) (Mul k e))))"
2805   "\<sigma>\<rho> (Dvd i (CN 0 c e)) =(\<lambda> (t,k). if k dvd c then (Dvd i (Add (Mul (c div k) t) e))
2806                                             else (Dvd (i*k) (Add (Mul c t) (Mul k e))))"
2807   "\<sigma>\<rho> (NDvd i (CN 0 c e))=(\<lambda> (t,k). if k dvd c then (NDvd i (Add (Mul (c div k) t) e))
2808                                             else (NDvd (i*k) (Add (Mul c t) (Mul k e))))"
2809   "\<sigma>\<rho> p = (\<lambda> (t,k). p)"
2811 recdef \<alpha>\<rho> "measure size"
2812   "\<alpha>\<rho> (And p q) = (\<alpha>\<rho> p @ \<alpha>\<rho> q)"
2813   "\<alpha>\<rho> (Or p q) = (\<alpha>\<rho> p @ \<alpha>\<rho> q)"
2814   "\<alpha>\<rho> (Eq  (CN 0 c e)) = [(Add (C -1) e,c)]"
2815   "\<alpha>\<rho> (NEq (CN 0 c e)) = [(e,c)]"
2816   "\<alpha>\<rho> (Lt  (CN 0 c e)) = [(e,c)]"
2817   "\<alpha>\<rho> (Le  (CN 0 c e)) = [(Add (C -1) e,c)]"
2818   "\<alpha>\<rho> p = []"
2820     (* Simulates normal substituion by modifying the formula see correctness theorem *)
2822 definition \<sigma> :: "fm \<Rightarrow> int \<Rightarrow> num \<Rightarrow> fm" where
2823   "\<sigma> p k t \<equiv> And (Dvd k t) (\<sigma>\<rho> p (t,k))"
2825 lemma \<sigma>\<rho>:
2826   assumes linp: "iszlfm p (real (x::int)#bs)"
2827   and kpos: "real k > 0"
2828   and tnb: "numbound0 t"
2829   and tint: "isint t (real x#bs)"
2830   and kdt: "k dvd floor (Inum (b'#bs) t)"
2831   shows "Ifm (real x#bs) (\<sigma>\<rho> p (t,k)) =
2832   (Ifm ((real ((floor (Inum (b'#bs) t)) div k))#bs) p)"
2833   (is "?I (real x) (?s p) = (?I (real ((floor (?N b' t)) div k)) p)" is "_ = (?I ?tk p)")
2834 using linp kpos tnb
2835 proof(induct p rule: \<sigma>\<rho>.induct)
2836   case (3 c e)
2837   from prems have cp: "c > 0" and nb: "numbound0 e" by auto
2838     {assume kdc: "k dvd c"
2839       from kpos have knz: "k\<noteq>0" by simp
2840       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2841       from prems have  ?case using real_of_int_div[OF knz kdc] real_of_int_div[OF knz kdt]
2842         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2843       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) }
2844     moreover
2845     {assume "\<not> k dvd c"
2846       from kpos have knz: "k\<noteq>0" by simp hence knz': "real k \<noteq> 0" by simp
2847       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2848       from prems have "?I (real x) (?s (Eq (CN 0 c e))) = ((real c * (?N (real x) t / real k) + ?N (real x) e)* real k = 0)"
2849         using real_of_int_div[OF knz kdt]
2850           numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2851           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti algebra_simps)
2852       also have "\<dots> = (?I ?tk (Eq (CN 0 c e)))" using nonzero_eq_divide_eq[OF knz', where a="real c * (?N (real x) t / real k) + ?N (real x) e" and b="0", symmetric] real_of_int_div[OF knz kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2853           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
2855       finally have ?case . }
2856     ultimately show ?case by blast
2857 next
2858   case (4 c e)
2859   from prems have cp: "c > 0" and nb: "numbound0 e" by auto
2860     {assume kdc: "k dvd c"
2861       from kpos have knz: "k\<noteq>0" by simp
2862       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2863       from prems have  ?case using real_of_int_div[OF knz kdc] real_of_int_div[OF knz kdt]
2864         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2865       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) }
2866     moreover
2867     {assume "\<not> k dvd c"
2868       from kpos have knz: "k\<noteq>0" by simp hence knz': "real k \<noteq> 0" by simp
2869       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2870       from prems have "?I (real x) (?s (NEq (CN 0 c e))) = ((real c * (?N (real x) t / real k) + ?N (real x) e)* real k \<noteq> 0)"
2871         using real_of_int_div[OF knz kdt]
2872           numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2873           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti algebra_simps)
2874       also have "\<dots> = (?I ?tk (NEq (CN 0 c e)))" using nonzero_eq_divide_eq[OF knz', where a="real c * (?N (real x) t / real k) + ?N (real x) e" and b="0", symmetric] real_of_int_div[OF knz kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2875           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
2877       finally have ?case . }
2878     ultimately show ?case by blast
2879 next
2880   case (5 c e)
2881   from prems have cp: "c > 0" and nb: "numbound0 e" by auto
2882     {assume kdc: "k dvd c"
2883       from kpos have knz: "k\<noteq>0" by simp
2884       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2885       from prems have  ?case using real_of_int_div[OF knz kdc] real_of_int_div[OF knz kdt]
2886         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2887       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) }
2888     moreover
2889     {assume "\<not> k dvd c"
2890       from kpos have knz: "k\<noteq>0" by simp
2891       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2892       from prems have "?I (real x) (?s (Lt (CN 0 c e))) = ((real c * (?N (real x) t / real k) + ?N (real x) e)* real k < 0)"
2893         using real_of_int_div[OF knz kdt]
2894           numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2895           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti algebra_simps)
2896       also have "\<dots> = (?I ?tk (Lt (CN 0 c e)))" using pos_less_divide_eq[OF kpos, where a="real c * (?N (real x) t / real k) + ?N (real x) e" and b="0", symmetric] real_of_int_div[OF knz kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2897           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
2899       finally have ?case . }
2900     ultimately show ?case by blast
2901 next
2902   case (6 c e)
2903   from prems have cp: "c > 0" and nb: "numbound0 e" by auto
2904     {assume kdc: "k dvd c"
2905       from kpos have knz: "k\<noteq>0" by simp
2906       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2907       from prems have  ?case using real_of_int_div[OF knz kdc] real_of_int_div[OF knz kdt]
2908         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2909       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) }
2910     moreover
2911     {assume "\<not> k dvd c"
2912       from kpos have knz: "k\<noteq>0" by simp
2913       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2914       from prems have "?I (real x) (?s (Le (CN 0 c e))) = ((real c * (?N (real x) t / real k) + ?N (real x) e)* real k \<le> 0)"
2915         using real_of_int_div[OF knz kdt]
2916           numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2917           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti algebra_simps)
2918       also have "\<dots> = (?I ?tk (Le (CN 0 c e)))" using pos_le_divide_eq[OF kpos, where a="real c * (?N (real x) t / real k) + ?N (real x) e" and b="0", symmetric] real_of_int_div[OF knz kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2919           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
2921       finally have ?case . }
2922     ultimately show ?case by blast
2923 next
2924   case (7 c e)
2925   from prems have cp: "c > 0" and nb: "numbound0 e" by auto
2926     {assume kdc: "k dvd c"
2927       from kpos have knz: "k\<noteq>0" by simp
2928       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2929       from prems have  ?case using real_of_int_div[OF knz kdc] real_of_int_div[OF knz kdt]
2930         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2931       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) }
2932     moreover
2933     {assume "\<not> k dvd c"
2934       from kpos have knz: "k\<noteq>0" by simp
2935       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2936       from prems have "?I (real x) (?s (Gt (CN 0 c e))) = ((real c * (?N (real x) t / real k) + ?N (real x) e)* real k > 0)"
2937         using real_of_int_div[OF knz kdt]
2938           numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2939           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti algebra_simps)
2940       also have "\<dots> = (?I ?tk (Gt (CN 0 c e)))" using pos_divide_less_eq[OF kpos, where a="real c * (?N (real x) t / real k) + ?N (real x) e" and b="0", symmetric] real_of_int_div[OF knz kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2941           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
2943       finally have ?case . }
2944     ultimately show ?case by blast
2945 next
2946   case (8 c e)
2947   from prems have cp: "c > 0" and nb: "numbound0 e" by auto
2948     {assume kdc: "k dvd c"
2949       from kpos have knz: "k\<noteq>0" by simp
2950       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2951       from prems have  ?case using real_of_int_div[OF knz kdc] real_of_int_div[OF knz kdt]
2952         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2953       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) }
2954     moreover
2955     {assume "\<not> k dvd c"
2956       from kpos have knz: "k\<noteq>0" by simp
2957       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2958       from prems have "?I (real x) (?s (Ge (CN 0 c e))) = ((real c * (?N (real x) t / real k) + ?N (real x) e)* real k \<ge> 0)"
2959         using real_of_int_div[OF knz kdt]
2960           numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2961           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti algebra_simps)
2962       also have "\<dots> = (?I ?tk (Ge (CN 0 c e)))" using pos_divide_le_eq[OF kpos, where a="real c * (?N (real x) t / real k) + ?N (real x) e" and b="0", symmetric] real_of_int_div[OF knz kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2963           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
2965       finally have ?case . }
2966     ultimately show ?case by blast
2967 next
2968   case (9 i c e)   from prems have cp: "c > 0" and nb: "numbound0 e" by auto
2969     {assume kdc: "k dvd c"
2970       from kpos have knz: "k\<noteq>0" by simp
2971       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2972       from prems have  ?case using real_of_int_div[OF knz kdc] real_of_int_div[OF knz kdt]
2973         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2974       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) }
2975     moreover
2976     {assume "\<not> k dvd c"
2977       from kpos have knz: "k\<noteq>0" by simp hence knz': "real k \<noteq> 0" by simp
2978       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2979       from prems have "?I (real x) (?s (Dvd i (CN 0 c e))) = (real i * real k rdvd (real c * (?N (real x) t / real k) + ?N (real x) e)* real k)"
2980         using real_of_int_div[OF knz kdt]
2981           numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2982           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti algebra_simps)
2983       also have "\<dots> = (?I ?tk (Dvd i (CN 0 c e)))" using rdvd_mult[OF knz, where n="i"] real_of_int_div[OF knz kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2984           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
2986       finally have ?case . }
2987     ultimately show ?case by blast
2988 next
2989   case (10 i c e)    from prems have cp: "c > 0" and nb: "numbound0 e" by auto
2990     {assume kdc: "k dvd c"
2991       from kpos have knz: "k\<noteq>0" by simp
2992       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
2993       from prems have  ?case using real_of_int_div[OF knz kdc] real_of_int_div[OF knz kdt]
2994         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
2995       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) }
2996     moreover
2997     {assume "\<not> k dvd c"
2998       from kpos have knz: "k\<noteq>0" by simp hence knz': "real k \<noteq> 0" by simp
2999       from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
3000       from prems have "?I (real x) (?s (NDvd i (CN 0 c e))) = (\<not> (real i * real k rdvd (real c * (?N (real x) t / real k) + ?N (real x) e)* real k))"
3001         using real_of_int_div[OF knz kdt]
3002           numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
3003           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti algebra_simps)
3004       also have "\<dots> = (?I ?tk (NDvd i (CN 0 c e)))" using rdvd_mult[OF knz, where n="i"] real_of_int_div[OF knz kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
3005           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
3007       finally have ?case . }
3008     ultimately show ?case by blast
3009 qed (simp_all add: bound0_I[where bs="bs" and b="real ((floor (?N b' t)) div k)" and b'="real x"] numbound0_I[where bs="bs" and b="real ((floor (?N b' t)) div k)" and b'="real x"])
3012 lemma \<sigma>\<rho>_nb: assumes lp:"iszlfm p (a#bs)" and nb: "numbound0 t"
3013   shows "bound0 (\<sigma>\<rho> p (t,k))"
3014   using lp
3015   by (induct p rule: iszlfm.induct, auto simp add: nb)
3017 lemma \<rho>_l:
3018   assumes lp: "iszlfm p (real (i::int)#bs)"
3019   shows "\<forall> (b,k) \<in> set (\<rho> p). k >0 \<and> numbound0 b \<and> isint b (real i#bs)"
3020 using lp by (induct p rule: \<rho>.induct, auto simp add: isint_sub isint_neg)
3022 lemma \<alpha>\<rho>_l:
3023   assumes lp: "iszlfm p (real (i::int)#bs)"
3024   shows "\<forall> (b,k) \<in> set (\<alpha>\<rho> p). k >0 \<and> numbound0 b \<and> isint b (real i#bs)"
3025 using lp isint_add [OF isint_c[where j="- 1"],where bs="real i#bs"]
3026  by (induct p rule: \<alpha>\<rho>.induct, auto)
3028 lemma \<rho>: assumes lp: "iszlfm p (real (i::int) #bs)"
3029   and pi: "Ifm (real i#bs) p"
3030   and d: "d\<delta> p d"
3031   and dp: "d > 0"
3032   and nob: "\<forall>(e,c) \<in> set (\<rho> p). \<forall> j\<in> {1 .. c*d}. real (c*i) \<noteq> Inum (real i#bs) e + real j"
3033   (is "\<forall>(e,c) \<in> set (\<rho> p). \<forall> j\<in> {1 .. c*d}. _ \<noteq> ?N i e + _")
3034   shows "Ifm (real(i - d)#bs) p"
3035   using lp pi d nob
3036 proof(induct p rule: iszlfm.induct)
3037   case (3 c e) hence cp: "c >0" and nb: "numbound0 e" and ei: "isint e (real i#bs)"
3038     and pi: "real (c*i) = - 1 -  ?N i e + real (1::int)" and nob: "\<forall> j\<in> {1 .. c*d}. real (c*i) \<noteq> -1 - ?N i e + real j"
3039     by simp+
3040   from mult_strict_left_mono[OF dp cp]  have one:"1 \<in> {1 .. c*d}" by auto
3041   from nob[rule_format, where j="1", OF one] pi show ?case by simp
3042 next
3043   case (4 c e)
3044   hence cp: "c >0" and nb: "numbound0 e" and ei: "isint e (real i#bs)"
3045     and nob: "\<forall> j\<in> {1 .. c*d}. real (c*i) \<noteq> - ?N i e + real j"
3046     by simp+
3047   {assume "real (c*i) \<noteq> - ?N i e + real (c*d)"
3048     with numbound0_I[OF nb, where bs="bs" and b="real i - real d" and b'="real i"]
3049     have ?case by (simp add: algebra_simps)}
3050   moreover
3051   {assume pi: "real (c*i) = - ?N i e + real (c*d)"
3052     from mult_strict_left_mono[OF dp cp] have d: "(c*d) \<in> {1 .. c*d}" by simp
3053     from nob[rule_format, where j="c*d", OF d] pi have ?case by simp }
3054   ultimately show ?case by blast
3055 next
3056   case (5 c e) hence cp: "c > 0" by simp
3057   from prems mult_strict_left_mono[OF dp cp, simplified real_of_int_less_iff[symmetric]
3058     real_of_int_mult]
3059   show ?case using prems dp
3060     by (simp add: add: numbound0_I[where bs="bs" and b="real i - real d" and b'="real i"]
3061       algebra_simps)
3062 next
3063   case (6 c e)  hence cp: "c > 0" by simp
3064   from prems mult_strict_left_mono[OF dp cp, simplified real_of_int_less_iff[symmetric]
3065     real_of_int_mult]
3066   show ?case using prems dp
3067     by (simp add: add: numbound0_I[where bs="bs" and b="real i - real d" and b'="real i"]
3068       algebra_simps)
3069 next
3070   case (7 c e) hence cp: "c >0" and nb: "numbound0 e" and ei: "isint e (real i#bs)"
3071     and nob: "\<forall> j\<in> {1 .. c*d}. real (c*i) \<noteq> - ?N i e + real j"
3072     and pi: "real (c*i) + ?N i e > 0" and cp': "real c >0"
3073     by simp+
3074   let ?fe = "floor (?N i e)"
3075   from pi cp have th:"(real i +?N i e / real c)*real c > 0" by (simp add: algebra_simps)
3076   from pi ei[simplified isint_iff] have "real (c*i + ?fe) > real (0::int)" by simp
3077   hence pi': "c*i + ?fe > 0" by (simp only: real_of_int_less_iff[symmetric])
3078   have "real (c*i) + ?N i e > real (c*d) \<or> real (c*i) + ?N i e \<le> real (c*d)" by auto
3079   moreover
3080   {assume "real (c*i) + ?N i e > real (c*d)" hence ?case
3082         numbound0_I[OF nb,where bs="bs" and b="real i - real d" and b'="real i"])}
3083   moreover
3084   {assume H:"real (c*i) + ?N i e \<le> real (c*d)"
3085     with ei[simplified isint_iff] have "real (c*i + ?fe) \<le> real (c*d)" by simp
3086     hence pid: "c*i + ?fe \<le> c*d" by (simp only: real_of_int_le_iff)
3087     with pi' have "\<exists> j1\<in> {1 .. c*d}. c*i + ?fe = j1" by auto
3088     hence "\<exists> j1\<in> {1 .. c*d}. real (c*i) = - ?N i e + real j1"
3089       by (simp only: diff_minus[symmetric] real_of_int_mult real_of_int_add real_of_int_inject[symmetric] ei[simplified isint_iff] algebra_simps)
3090     with nob  have ?case by blast }
3091   ultimately show ?case by blast
3092 next
3093   case (8 c e)  hence cp: "c >0" and nb: "numbound0 e" and ei: "isint e (real i#bs)"
3094     and nob: "\<forall> j\<in> {1 .. c*d}. real (c*i) \<noteq> - 1 - ?N i e + real j"
3095     and pi: "real (c*i) + ?N i e \<ge> 0" and cp': "real c >0"
3096     by simp+
3097   let ?fe = "floor (?N i e)"
3098   from pi cp have th:"(real i +?N i e / real c)*real c \<ge> 0" by (simp add: algebra_simps)
3099   from pi ei[simplified isint_iff] have "real (c*i + ?fe) \<ge> real (0::int)" by simp
3100   hence pi': "c*i + 1 + ?fe \<ge> 1" by (simp only: real_of_int_le_iff[symmetric])
3101   have "real (c*i) + ?N i e \<ge> real (c*d) \<or> real (c*i) + ?N i e < real (c*d)" by auto
3102   moreover
3103   {assume "real (c*i) + ?N i e \<ge> real (c*d)" hence ?case
3105         numbound0_I[OF nb,where bs="bs" and b="real i - real d" and b'="real i"])}
3106   moreover
3107   {assume H:"real (c*i) + ?N i e < real (c*d)"
3108     with ei[simplified isint_iff] have "real (c*i + ?fe) < real (c*d)" by simp
3109     hence pid: "c*i + 1 + ?fe \<le> c*d" by (simp only: real_of_int_le_iff)
3110     with pi' have "\<exists> j1\<in> {1 .. c*d}. c*i + 1+ ?fe = j1" by auto
3111     hence "\<exists> j1\<in> {1 .. c*d}. real (c*i) + 1= - ?N i e + real j1"
3112       by (simp only: diff_minus[symmetric] real_of_int_mult real_of_int_add real_of_int_inject[symmetric] ei[simplified isint_iff] algebra_simps real_of_one)
3113     hence "\<exists> j1\<in> {1 .. c*d}. real (c*i) = (- ?N i e + real j1) - 1"
3114       by (simp only: algebra_simps diff_minus[symmetric])
3115         hence "\<exists> j1\<in> {1 .. c*d}. real (c*i) = - 1 - ?N i e + real j1"
3116           by (simp only: add_ac diff_minus)
3117     with nob  have ?case by blast }
3118   ultimately show ?case by blast
3119 next
3120   case (9 j c e)  hence p: "real j rdvd real (c*i) + ?N i e" (is "?p x") and cp: "c > 0" and bn:"numbound0 e"  by simp+
3121     let ?e = "Inum (real i # bs) e"
3122     from prems have "isint e (real i #bs)"  by simp
3123     hence ie: "real (floor ?e) = ?e" using isint_iff[where n="e" and bs="(real i)#bs"] numbound0_I[OF bn,where b="real i" and b'="real i" and bs="bs"]
3125     from prems have id: "j dvd d" by simp
3126     from ie[symmetric] have "?p i = (real j rdvd real (c*i+ floor ?e))" by simp
3127     also have "\<dots> = (j dvd c*i + floor ?e)"
3128       using int_rdvd_iff [where i="j" and t="c*i+ floor ?e"] by simp
3129     also have "\<dots> = (j dvd c*i - c*d + floor ?e)"
3130       using dvd_period[OF id, where x="c*i" and c="-c" and t="floor ?e"] by simp
3131     also have "\<dots> = (real j rdvd real (c*i - c*d + floor ?e))"
3132       using int_rdvd_iff[where i="j" and t="(c*i - c*d + floor ?e)",symmetric, simplified]
3133       ie by simp
3134     also have "\<dots> = (real j rdvd real (c*(i - d)) + ?e)"
3135       using ie by (simp add:algebra_simps)
3136     finally show ?case
3137       using numbound0_I[OF bn,where b="real i - real d" and b'="real i" and bs="bs"] p
3139 next
3140   case (10 j c e)   hence p: "\<not> (real j rdvd real (c*i) + ?N i e)" (is "?p x") and cp: "c > 0" and bn:"numbound0 e"  by simp+
3141     let ?e = "Inum (real i # bs) e"
3142     from prems have "isint e (real i #bs)"  by simp
3143     hence ie: "real (floor ?e) = ?e" using isint_iff[where n="e" and bs="(real i)#bs"] numbound0_I[OF bn,where b="real i" and b'="real i" and bs="bs"]
3145     from prems have id: "j dvd d" by simp
3146     from ie[symmetric] have "?p i = (\<not> (real j rdvd real (c*i+ floor ?e)))" by simp
3147     also have "\<dots> = Not (j dvd c*i + floor ?e)"
3148       using int_rdvd_iff [where i="j" and t="c*i+ floor ?e"] by simp
3149     also have "\<dots> = Not (j dvd c*i - c*d + floor ?e)"
3150       using dvd_period[OF id, where x="c*i" and c="-c" and t="floor ?e"] by simp
3151     also have "\<dots> = Not (real j rdvd real (c*i - c*d + floor ?e))"
3152       using int_rdvd_iff[where i="j" and t="(c*i - c*d + floor ?e)",symmetric, simplified]
3153       ie by simp
3154     also have "\<dots> = Not (real j rdvd real (c*(i - d)) + ?e)"
3155       using ie by (simp add:algebra_simps)
3156     finally show ?case
3157       using numbound0_I[OF bn,where b="real i - real d" and b'="real i" and bs="bs"] p
3159 qed(auto simp add: numbound0_I[where bs="bs" and b="real i - real d" and b'="real i"])
3161 lemma \<sigma>_nb: assumes lp: "iszlfm p (a#bs)" and nb: "numbound0 t"
3162   shows "bound0 (\<sigma> p k t)"
3163   using \<sigma>\<rho>_nb[OF lp nb] nb by (simp add: \<sigma>_def)
3165 lemma \<rho>':   assumes lp: "iszlfm p (a #bs)"
3166   and d: "d\<delta> p d"
3167   and dp: "d > 0"
3168   shows "\<forall> x. \<not>(\<exists> (e,c) \<in> set(\<rho> p). \<exists>(j::int) \<in> {1 .. c*d}. Ifm (a #bs) (\<sigma> p c (Add e (C j)))) \<longrightarrow> Ifm (real x#bs) p \<longrightarrow> Ifm (real (x - d)#bs) p" (is "\<forall> x. ?b x \<longrightarrow> ?P x \<longrightarrow> ?P (x - d)")
3169 proof(clarify)
3170   fix x
3171   assume nob1:"?b x" and px: "?P x"
3172   from iszlfm_gen[OF lp, rule_format, where y="real x"] have lp': "iszlfm p (real x#bs)".
3173   have nob: "\<forall>(e, c)\<in>set (\<rho> p). \<forall>j\<in>{1..c * d}. real (c * x) \<noteq> Inum (real x # bs) e + real j"
3174   proof(clarify)
3175     fix e c j assume ecR: "(e,c) \<in> set (\<rho> p)" and jD: "j\<in> {1 .. c*d}"
3176       and cx: "real (c*x) = Inum (real x#bs) e + real j"
3177     let ?e = "Inum (real x#bs) e"
3178     let ?fe = "floor ?e"
3179     from \<rho>_l[OF lp'] ecR have ei:"isint e (real x#bs)" and cp:"c>0" and nb:"numbound0 e"
3180       by auto
3181     from numbound0_gen [OF nb ei, rule_format,where y="a"] have "isint e (a#bs)" .
3182     from cx ei[simplified isint_iff] have "real (c*x) = real (?fe + j)" by simp
3183     hence cx: "c*x = ?fe + j" by (simp only: real_of_int_inject)
3184     hence cdej:"c dvd ?fe + j" by (simp add: dvd_def) (rule_tac x="x" in exI, simp)
3185     hence "real c rdvd real (?fe + j)" by (simp only: int_rdvd_iff)
3186     hence rcdej: "real c rdvd ?e + real j" by (simp add: ei[simplified isint_iff])
3187     from cx have "(c*x) div c = (?fe + j) div c" by simp
3188     with cp have "x = (?fe + j) div c" by simp
3189     with px have th: "?P ((?fe + j) div c)" by auto
3190     from cp have cp': "real c > 0" by simp
3191     from cdej have cdej': "c dvd floor (Inum (real x#bs) (Add e (C j)))" by simp
3192     from nb have nb': "numbound0 (Add e (C j))" by simp
3193     have ji: "isint (C j) (real x#bs)" by (simp add: isint_def)
3194     from isint_add[OF ei ji] have ei':"isint (Add e (C j)) (real x#bs)" .
3195     from th \<sigma>\<rho>[where b'="real x", OF lp' cp' nb' ei' cdej',symmetric]
3196     have "Ifm (real x#bs) (\<sigma>\<rho> p (Add e (C j), c))" by simp
3197     with rcdej have th: "Ifm (real x#bs) (\<sigma> p c (Add e (C j)))" by (simp add: \<sigma>_def)
3198     from th bound0_I[OF \<sigma>_nb[OF lp nb', where k="c"],where bs="bs" and b="real x" and b'="a"]
3199     have "Ifm (a#bs) (\<sigma> p c (Add e (C j)))" by blast
3200       with ecR jD nob1    show "False" by blast
3201   qed
3202   from \<rho>[OF lp' px d dp nob] show "?P (x -d )" .
3203 qed
3206 lemma rl_thm:
3207   assumes lp: "iszlfm p (real (i::int)#bs)"
3208   shows "(\<exists> (x::int). Ifm (real x#bs) p) = ((\<exists> j\<in> {1 .. \<delta> p}. Ifm (real j#bs) (minusinf p)) \<or> (\<exists> (e,c) \<in> set (\<rho> p). \<exists> j\<in> {1 .. c*(\<delta> p)}. Ifm (a#bs) (\<sigma> p c (Add e (C j)))))"
3209   (is "(\<exists>(x::int). ?P x) = ((\<exists> j\<in> {1.. \<delta> p}. ?MP j)\<or>(\<exists> (e,c) \<in> ?R. \<exists> j\<in> _. ?SP c e j))"
3210     is "?lhs = (?MD \<or> ?RD)"  is "?lhs = ?rhs")
3211 proof-
3212   let ?d= "\<delta> p"
3213   from \<delta>[OF lp] have d:"d\<delta> p ?d" and dp: "?d > 0" by auto
3214   { assume H:"?MD" hence th:"\<exists> (x::int). ?MP x" by blast
3215     from H minusinf_ex[OF lp th] have ?thesis  by blast}
3216   moreover
3217   { fix e c j assume exR:"(e,c) \<in> ?R" and jD:"j\<in> {1 .. c*?d}" and spx:"?SP c e j"
3218     from exR \<rho>_l[OF lp] have nb: "numbound0 e" and ei:"isint e (real i#bs)" and cp: "c > 0"
3219       by auto
3220     have "isint (C j) (real i#bs)" by (simp add: isint_iff)
3221     with isint_add[OF numbound0_gen[OF nb ei,rule_format, where y="real i"]]
3222     have eji:"isint (Add e (C j)) (real i#bs)" by simp
3223     from nb have nb': "numbound0 (Add e (C j))" by simp
3224     from spx bound0_I[OF \<sigma>_nb[OF lp nb', where k="c"], where bs="bs" and b="a" and b'="real i"]
3225     have spx': "Ifm (real i # bs) (\<sigma> p c (Add e (C j)))" by blast
3226     from spx' have rcdej:"real c rdvd (Inum (real i#bs) (Add e (C j)))"
3227       and sr:"Ifm (real i#bs) (\<sigma>\<rho> p (Add e (C j),c))" by (simp add: \<sigma>_def)+
3228     from rcdej eji[simplified isint_iff]
3229     have "real c rdvd real (floor (Inum (real i#bs) (Add e (C j))))" by simp
3230     hence cdej:"c dvd floor (Inum (real i#bs) (Add e (C j)))" by (simp only: int_rdvd_iff)
3231     from cp have cp': "real c > 0" by simp
3232     from \<sigma>\<rho>[OF lp cp' nb' eji cdej] spx' have "?P (\<lfloor>Inum (real i # bs) (Add e (C j))\<rfloor> div c)"
3234     hence ?lhs by blast
3235     with exR jD spx have ?thesis by blast}
3236   moreover
3237   { fix x assume px: "?P x" and nob: "\<not> ?RD"
3238     from iszlfm_gen [OF lp,rule_format, where y="a"] have lp':"iszlfm p (a#bs)" .
3239     from \<rho>'[OF lp' d dp, rule_format, OF nob] have th:"\<forall> x. ?P x \<longrightarrow> ?P (x - ?d)" by blast
3240     from minusinf_inf[OF lp] obtain z where z:"\<forall> x<z. ?MP x = ?P x" by blast
3241     have zp: "abs (x - z) + 1 \<ge> 0" by arith
3242     from decr_lemma[OF dp,where x="x" and z="z"]
3243       decr_mult_lemma[OF dp th zp, rule_format, OF px] z have th:"\<exists> x. ?MP x" by auto
3244     with minusinf_bex[OF lp] px nob have ?thesis by blast}
3245   ultimately show ?thesis by blast
3246 qed
3248 lemma mirror_\<alpha>\<rho>:   assumes lp: "iszlfm p (a#bs)"
3249   shows "(\<lambda> (t,k). (Inum (a#bs) t, k)) ` set (\<alpha>\<rho> p) = (\<lambda> (t,k). (Inum (a#bs) t,k)) ` set (\<rho> (mirror p))"
3250 using lp
3251 by (induct p rule: mirror.induct, simp_all add: split_def image_Un )
3253 text {* The @{text "\<real>"} part*}
3255 text{* Linearity for fm where Bound 0 ranges over @{text "\<real>"}*}
3256 consts
3257   isrlfm :: "fm \<Rightarrow> bool"   (* Linearity test for fm *)
3258 recdef isrlfm "measure size"
3259   "isrlfm (And p q) = (isrlfm p \<and> isrlfm q)"
3260   "isrlfm (Or p q) = (isrlfm p \<and> isrlfm q)"
3261   "isrlfm (Eq  (CN 0 c e)) = (c>0 \<and> numbound0 e)"
3262   "isrlfm (NEq (CN 0 c e)) = (c>0 \<and> numbound0 e)"
3263   "isrlfm (Lt  (CN 0 c e)) = (c>0 \<and> numbound0 e)"
3264   "isrlfm (Le  (CN 0 c e)) = (c>0 \<and> numbound0 e)"
3265   "isrlfm (Gt  (CN 0 c e)) = (c>0 \<and> numbound0 e)"
3266   "isrlfm (Ge  (CN 0 c e)) = (c>0 \<and> numbound0 e)"
3267   "isrlfm p = (isatom p \<and> (bound0 p))"
3269 definition fp :: "fm \<Rightarrow> int \<Rightarrow> num \<Rightarrow> int \<Rightarrow> fm" where
3270   "fp p n s j \<equiv> (if n > 0 then
3271             (And p (And (Ge (CN 0 n (Sub s (Add (Floor s) (C j)))))
3272                         (Lt (CN 0 n (Sub s (Add (Floor s) (C (j+1))))))))
3273             else
3274             (And p (And (Le (CN 0 (-n) (Add (Neg s) (Add (Floor s) (C j)))))
3275                         (Gt (CN 0 (-n) (Add (Neg s) (Add (Floor s) (C (j + 1)))))))))"
3277   (* splits the bounded from the unbounded part*)
3278 function (sequential) rsplit0 :: "num \<Rightarrow> (fm \<times> int \<times> num) list" where
3279   "rsplit0 (Bound 0) = [(T,1,C 0)]"
3280 | "rsplit0 (Add a b) = (let acs = rsplit0 a ; bcs = rsplit0 b
3281               in map (\<lambda> ((p,n,t),(q,m,s)). (And p q, n+m, Add t s)) [(a,b). a\<leftarrow>acs,b\<leftarrow>bcs])"
3282 | "rsplit0 (Sub a b) = rsplit0 (Add a (Neg b))"
3283 | "rsplit0 (Neg a) = map (\<lambda> (p,n,s). (p,-n,Neg s)) (rsplit0 a)"
3284 | "rsplit0 (Floor a) = foldl (op @) [] (map
3285       (\<lambda> (p,n,s). if n=0 then [(p,0,Floor s)]
3286           else (map (\<lambda> j. (fp p n s j, 0, Add (Floor s) (C j))) (if n > 0 then [0 .. n] else [n .. 0])))
3287        (rsplit0 a))"
3288 | "rsplit0 (CN 0 c a) = map (\<lambda> (p,n,s). (p,n+c,s)) (rsplit0 a)"
3289 | "rsplit0 (CN m c a) = map (\<lambda> (p,n,s). (p,n,CN m c s)) (rsplit0 a)"
3290 | "rsplit0 (CF c t s) = rsplit0 (Add (Mul c (Floor t)) s)"
3291 | "rsplit0 (Mul c a) = map (\<lambda> (p,n,s). (p,c*n,Mul c s)) (rsplit0 a)"
3292 | "rsplit0 t = [(T,0,t)]"
3293 by pat_completeness auto
3294 termination by (relation "measure num_size") auto
3296 lemma conj_rl[simp]: "isrlfm p \<Longrightarrow> isrlfm q \<Longrightarrow> isrlfm (conj p q)"
3297   using conj_def by (cases p, auto)
3298 lemma disj_rl[simp]: "isrlfm p \<Longrightarrow> isrlfm q \<Longrightarrow> isrlfm (disj p q)"
3299   using disj_def by (cases p, auto)
3302 lemma rsplit0_cs:
3303   shows "\<forall> (p,n,s) \<in> set (rsplit0 t).
3304   (Ifm (x#bs) p \<longrightarrow>  (Inum (x#bs) t = Inum (x#bs) (CN 0 n s))) \<and> numbound0 s \<and> isrlfm p"
3305   (is "\<forall> (p,n,s) \<in> ?SS t. (?I p \<longrightarrow> ?N t = ?N (CN 0 n s)) \<and> _ \<and> _ ")
3306 proof(induct t rule: rsplit0.induct)
3307   case (5 a)
3308   let ?p = "\<lambda> (p,n,s) j. fp p n s j"
3309   let ?f = "(\<lambda> (p,n,s) j. (?p (p,n,s) j, (0::int),Add (Floor s) (C j)))"
3310   let ?J = "\<lambda> n. if n>0 then [0..n] else [n..0]"
3311   let ?ff=" (\<lambda> (p,n,s). if n= 0 then [(p,0,Floor s)] else map (?f (p,n,s)) (?J n))"
3312   have int_cases: "\<forall> (i::int). i= 0 \<or> i < 0 \<or> i > 0" by arith
3313   have U1: "(UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) =
3314     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set [(p,0,Floor s)]))" by auto
3315   have U2': "\<forall> (p,n,s) \<in> {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0}.
3316     ?ff (p,n,s) = map (?f(p,n,s)) [0..n]" by auto
3317   hence U2: "(UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) =
3318     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s).
3319     set (map (?f(p,n,s)) [0..n])))"
3320   proof-
3321     fix M :: "('a\<times>'b\<times>'c) set" and f :: "('a\<times>'b\<times>'c) \<Rightarrow> 'd list" and g
3322     assume "\<forall> (a,b,c) \<in> M. f (a,b,c) = g a b c"
3323     thus "(UNION M (\<lambda> (a,b,c). set (f (a,b,c)))) = (UNION M (\<lambda> (a,b,c). set (g a b c)))"
3324       by (auto simp add: split_def)
3325   qed
3326   have U3': "\<forall> (p,n,s) \<in> {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0}. ?ff (p,n,s) = map (?f(p,n,s)) [n..0]"
3327     by auto
3328   hence U3: "(UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) =
3329     (UNION {(p,n,s). (p,n,s)\<in> ?SS a\<and>n<0} (\<lambda>(p,n,s). set (map (?f(p,n,s)) [n..0])))"
3330       proof-
3331     fix M :: "('a\<times>'b\<times>'c) set" and f :: "('a\<times>'b\<times>'c) \<Rightarrow> 'd list" and g
3332     assume "\<forall> (a,b,c) \<in> M. f (a,b,c) = g a b c"
3333     thus "(UNION M (\<lambda> (a,b,c). set (f (a,b,c)))) = (UNION M (\<lambda> (a,b,c). set (g a b c)))"
3334       by (auto simp add: split_def)
3335   qed
3336   have "?SS (Floor a) = UNION (?SS a) (\<lambda>x. set (?ff x))"
3337     by (auto simp add: foldl_conv_concat)
3338   also have "\<dots> = UNION (?SS a) (\<lambda> (p,n,s). set (?ff (p,n,s)))" by blast
3339   also have "\<dots> =
3340     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) Un
3341     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) Un
3342     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). set (?ff (p,n,s)))))"
3343     using int_cases[rule_format] by blast
3344   also have "\<dots> =
3345     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set [(p,0,Floor s)])) Un
3346    (UNION {(p,n,s). (p,n,s)\<in> ?SS a\<and>n>0} (\<lambda>(p,n,s). set(map(?f(p,n,s)) [0..n]))) Un
3347    (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s).
3348     set (map (?f(p,n,s)) [n..0]))))" by (simp only: U1 U2 U3)
3349   also have "\<dots> =
3350     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). {(p,0,Floor s)})) Un
3351     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). (?f(p,n,s)) ` {0 .. n})) Un
3352     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). (?f(p,n,s)) ` {n .. 0})))"
3353     by (simp only: set_map set_upto set.simps)
3354   also have "\<dots> =
3355     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). {(p,0,Floor s)})) Un
3356     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). {?f(p,n,s) j| j. j\<in> {0 .. n}})) Un
3357     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s).  {?f(p,n,s) j| j. j\<in> {n .. 0}})))" by blast
3358   finally
3359   have FS: "?SS (Floor a) =
3360     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). {(p,0,Floor s)})) Un
3361     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). {?f(p,n,s) j| j. j\<in> {0 .. n}})) Un
3362     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s).  {?f(p,n,s) j| j. j\<in> {n .. 0}})))"    by blast
3363   show ?case
3364     proof(simp only: FS, clarsimp simp del: Ifm.simps Inum.simps, -)
3365       fix p n s
3366       let ?ths = "(?I p \<longrightarrow> (?N (Floor a) = ?N (CN 0 n s))) \<and> numbound0 s \<and> isrlfm p"
3367       assume "(\<exists>ba. (p, 0, ba) \<in> set (rsplit0 a) \<and> n = 0 \<and> s = Floor ba) \<or>
3368        (\<exists>ab ac ba.
3369            (ab, ac, ba) \<in> set (rsplit0 a) \<and>
3370            0 < ac \<and>
3371            (\<exists>j. p = fp ab ac ba j \<and>
3372                 n = 0 \<and> s = Add (Floor ba) (C j) \<and> 0 \<le> j \<and> j \<le> ac)) \<or>
3373        (\<exists>ab ac ba.
3374            (ab, ac, ba) \<in> set (rsplit0 a) \<and>
3375            ac < 0 \<and>
3376            (\<exists>j. p = fp ab ac ba j \<and>
3377                 n = 0 \<and> s = Add (Floor ba) (C j) \<and> ac \<le> j \<and> j \<le> 0))"
3378       moreover
3379       {fix s'
3380         assume "(p, 0, s') \<in> ?SS a" and "n = 0" and "s = Floor s'"
3381         hence ?ths using prems by auto}
3382       moreover
3383       { fix p' n' s' j
3384         assume pns: "(p', n', s') \<in> ?SS a"
3385           and np: "0 < n'"
3386           and p_def: "p = ?p (p',n',s') j"
3387           and n0: "n = 0"
3388           and s_def: "s = (Add (Floor s') (C j))"
3389           and jp: "0 \<le> j" and jn: "j \<le> n'"
3390         from prems pns have H:"(Ifm ((x\<Colon>real) # (bs\<Colon>real list)) p' \<longrightarrow>
3391           Inum (x # bs) a = Inum (x # bs) (CN 0 n' s')) \<and>
3392           numbound0 s' \<and> isrlfm p'" by blast
3393         hence nb: "numbound0 s'" by simp
3394         from H have nf: "isrlfm (?p (p',n',s') j)" using fp_def np by (simp add: numsub_nb)
3395         let ?nxs = "CN 0 n' s'"
3396         let ?l = "floor (?N s') + j"
3397         from H
3398         have "?I (?p (p',n',s') j) \<longrightarrow>
3399           (((?N ?nxs \<ge> real ?l) \<and> (?N ?nxs < real (?l + 1))) \<and> (?N a = ?N ?nxs ))"
3401         also have "\<dots> \<longrightarrow> ((floor (?N ?nxs) = ?l) \<and> (?N a = ?N ?nxs ))"
3402           using floor_int_eq[where x="?N ?nxs" and n="?l"] by simp
3403         moreover
3404         have "\<dots> \<longrightarrow> (?N (Floor a) = ?N ((Add (Floor s') (C j))))" by simp
3405         ultimately have "?I (?p (p',n',s') j) \<longrightarrow> (?N (Floor a) = ?N ((Add (Floor s') (C j))))"
3406           by blast
3407         with s_def n0 p_def nb nf have ?ths by auto}
3408       moreover
3409       {fix p' n' s' j
3410         assume pns: "(p', n', s') \<in> ?SS a"
3411           and np: "n' < 0"
3412           and p_def: "p = ?p (p',n',s') j"
3413           and n0: "n = 0"
3414           and s_def: "s = (Add (Floor s') (C j))"
3415           and jp: "n' \<le> j" and jn: "j \<le> 0"
3416         from prems pns have H:"(Ifm ((x\<Colon>real) # (bs\<Colon>real list)) p' \<longrightarrow>
3417           Inum (x # bs) a = Inum (x # bs) (CN 0 n' s')) \<and>
3418           numbound0 s' \<and> isrlfm p'" by blast
3419         hence nb: "numbound0 s'" by simp
3420         from H have nf: "isrlfm (?p (p',n',s') j)" using fp_def np by (simp add: numneg_nb)
3421         let ?nxs = "CN 0 n' s'"
3422         let ?l = "floor (?N s') + j"
3423         from H
3424         have "?I (?p (p',n',s') j) \<longrightarrow>
3425           (((?N ?nxs \<ge> real ?l) \<and> (?N ?nxs < real (?l + 1))) \<and> (?N a = ?N ?nxs ))"
3427         also have "\<dots> \<longrightarrow> ((floor (?N ?nxs) = ?l) \<and> (?N a = ?N ?nxs ))"
3428           using floor_int_eq[where x="?N ?nxs" and n="?l"] by simp
3429         moreover
3430         have "\<dots> \<longrightarrow> (?N (Floor a) = ?N ((Add (Floor s') (C j))))"  by simp
3431         ultimately have "?I (?p (p',n',s') j) \<longrightarrow> (?N (Floor a) = ?N ((Add (Floor s') (C j))))"
3432           by blast
3433         with s_def n0 p_def nb nf have ?ths by auto}
3434       ultimately show ?ths by auto
3435     qed
3436 next
3437   case (3 a b) then show ?case
3438   apply auto
3439   apply (erule_tac x = "(aa, aaa, ba)" in ballE) apply simp_all
3440   apply (erule_tac x = "(ab, ac, baa)" in ballE) apply simp_all
3441   done
3442 qed (auto simp add: Let_def split_def algebra_simps conj_rl)
3444 lemma real_in_int_intervals:
3445   assumes xb: "real m \<le> x \<and> x < real ((n::int) + 1)"
3446   shows "\<exists> j\<in> {m.. n}. real j \<le> x \<and> x < real (j+1)" (is "\<exists> j\<in> ?N. ?P j")
3447 by (rule bexI[where P="?P" and x="floor x" and A="?N"])
3448 (auto simp add: floor_less_eq[where x="x" and a="n+1", simplified] xb[simplified] floor_mono[where x="real m" and y="x", OF conjunct1[OF xb], simplified floor_real_of_int[where n="m"]])
3450 lemma rsplit0_complete:
3451   assumes xp:"0 \<le> x" and x1:"x < 1"
3452   shows "\<exists> (p,n,s) \<in> set (rsplit0 t). Ifm (x#bs) p" (is "\<exists> (p,n,s) \<in> ?SS t. ?I p")
3453 proof(induct t rule: rsplit0.induct)
3454   case (2 a b)
3455   from prems have "\<exists> (pa,na,sa) \<in> ?SS a. ?I pa" by auto
3456   then obtain "pa" "na" "sa" where pa: "(pa,na,sa)\<in> ?SS a \<and> ?I pa" by blast
3457   from prems have "\<exists> (pb,nb,sb) \<in> ?SS b. ?I pb" by blast
3458   then obtain "pb" "nb" "sb" where pb: "(pb,nb,sb)\<in> ?SS b \<and> ?I pb" by blast
3459   from pa pb have th: "((pa,na,sa),(pb,nb,sb)) \<in> set[(x,y). x\<leftarrow>rsplit0 a, y\<leftarrow>rsplit0 b]"
3460     by (auto)
3461   let ?f="(\<lambda> ((p,n,t),(q,m,s)). (And p q, n+m, Add t s))"
3462   from imageI[OF th, where f="?f"] have "?f ((pa,na,sa),(pb,nb,sb)) \<in> ?SS (Add a b)"
3464   hence "(And pa pb, na +nb, Add sa sb) \<in> ?SS (Add a b)" by simp
3465   moreover from pa pb have "?I (And pa pb)" by simp
3466   ultimately show ?case by blast
3467 next
3468   case (5 a)
3469   let ?p = "\<lambda> (p,n,s) j. fp p n s j"
3470   let ?f = "(\<lambda> (p,n,s) j. (?p (p,n,s) j, (0::int),(Add (Floor s) (C j))))"
3471   let ?J = "\<lambda> n. if n>0 then [0..n] else [n..0]"
3472   let ?ff=" (\<lambda> (p,n,s). if n= 0 then [(p,0,Floor s)] else map (?f (p,n,s)) (?J n))"
3473   have int_cases: "\<forall> (i::int). i= 0 \<or> i < 0 \<or> i > 0" by arith
3474   have U1: "(UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) = (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set [(p,0,Floor s)]))" by auto
3475   have U2': "\<forall> (p,n,s) \<in> {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0}. ?ff (p,n,s) = map (?f(p,n,s)) [0..n]"
3476     by auto
3477   hence U2: "(UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) = (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). set (map (?f(p,n,s)) [0..n])))"
3478   proof-
3479     fix M :: "('a\<times>'b\<times>'c) set" and f :: "('a\<times>'b\<times>'c) \<Rightarrow> 'd list" and g
3480     assume "\<forall> (a,b,c) \<in> M. f (a,b,c) = g a b c"
3481     thus "(UNION M (\<lambda> (a,b,c). set (f (a,b,c)))) = (UNION M (\<lambda> (a,b,c). set (g a b c)))"
3482       by (auto simp add: split_def)
3483   qed
3484   have U3': "\<forall> (p,n,s) \<in> {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0}. ?ff (p,n,s) = map (?f(p,n,s)) [n..0]"
3485     by auto
3486   hence U3: "(UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) = (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). set (map (?f(p,n,s)) [n..0])))"
3487   proof-
3488     fix M :: "('a\<times>'b\<times>'c) set" and f :: "('a\<times>'b\<times>'c) \<Rightarrow> 'd list" and g
3489     assume "\<forall> (a,b,c) \<in> M. f (a,b,c) = g a b c"
3490     thus "(UNION M (\<lambda> (a,b,c). set (f (a,b,c)))) = (UNION M (\<lambda> (a,b,c). set (g a b c)))"
3491       by (auto simp add: split_def)
3492   qed
3494   have "?SS (Floor a) = UNION (?SS a) (\<lambda>x. set (?ff x))" by (auto simp add: foldl_conv_concat)
3495   also have "\<dots> = UNION (?SS a) (\<lambda> (p,n,s). set (?ff (p,n,s)))" by blast
3496   also have "\<dots> =
3497     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) Un
3498     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) Un
3499     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). set (?ff (p,n,s)))))"
3500     using int_cases[rule_format] by blast
3501   also have "\<dots> =
3502     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set [(p,0,Floor s)])) Un
3503     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). set (map (?f(p,n,s)) [0..n]))) Un
3504     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). set (map (?f(p,n,s)) [n..0]))))" by (simp only: U1 U2 U3)
3505   also have "\<dots> =
3506     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). {(p,0,Floor s)})) Un
3507     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). (?f(p,n,s)) ` {0 .. n})) Un
3508     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). (?f(p,n,s)) ` {n .. 0})))"
3509     by (simp only: set_map set_upto set.simps)
3510   also have "\<dots> =
3511     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). {(p,0,Floor s)})) Un
3512     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). {?f(p,n,s) j| j. j\<in> {0 .. n}})) Un
3513     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s).  {?f(p,n,s) j| j. j\<in> {n .. 0}})))" by blast
3514   finally
3515   have FS: "?SS (Floor a) =
3516     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). {(p,0,Floor s)})) Un
3517     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). {?f(p,n,s) j| j. j\<in> {0 .. n}})) Un
3518     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s).  {?f(p,n,s) j| j. j\<in> {n .. 0}})))"    by blast
3519   from prems have "\<exists> (p,n,s) \<in> ?SS a. ?I p" by auto
3520   then obtain "p" "n" "s" where pns: "(p,n,s) \<in> ?SS a \<and> ?I p" by blast
3521   let ?N = "\<lambda> t. Inum (x#bs) t"
3522   from rsplit0_cs[rule_format] pns have ans:"(?N a = ?N (CN 0 n s)) \<and> numbound0 s \<and> isrlfm p"
3523     by auto
3525   have "n=0 \<or> n >0 \<or> n <0" by arith
3526   moreover {assume "n=0" hence ?case using pns by (simp only: FS) auto }
3527   moreover
3528   {
3529     assume np: "n > 0"
3530     from real_of_int_floor_le[where r="?N s"] have "?N (Floor s) \<le> ?N s" by simp
3531     also from mult_left_mono[OF xp] np have "?N s \<le> real n * x + ?N s" by simp
3532     finally have "?N (Floor s) \<le> real n * x + ?N s" .
3533     moreover
3534     {from x1 np have "real n *x + ?N s < real n + ?N s" by simp
3535       also from real_of_int_floor_add_one_gt[where r="?N s"]
3536       have "\<dots> < real n + ?N (Floor s) + 1" by simp
3537       finally have "real n *x + ?N s < ?N (Floor s) + real (n+1)" by simp}
3538     ultimately have "?N (Floor s) \<le> real n *x + ?N s\<and> real n *x + ?N s < ?N (Floor s) + real (n+1)" by simp
3539     hence th: "0 \<le> real n *x + ?N s - ?N (Floor s) \<and> real n *x + ?N s - ?N (Floor s) < real (n+1)" by simp
3540     from real_in_int_intervals th have  "\<exists> j\<in> {0 .. n}. real j \<le> real n *x + ?N s - ?N (Floor s)\<and> real n *x + ?N s - ?N (Floor s) < real (j+1)" by simp
3542     hence "\<exists> j\<in> {0 .. n}. 0 \<le> real n *x + ?N s - ?N (Floor s) - real j \<and> real n *x + ?N s - ?N (Floor s) - real (j+1) < 0"
3543       by(simp only: myle[of _ "real n * x + Inum (x # bs) s - Inum (x # bs) (Floor s)"] less_iff_diff_less_0[where a="real n *x + ?N s - ?N (Floor s)"])
3544     hence "\<exists> j\<in> {0.. n}. ?I (?p (p,n,s) j)"
3546     then obtain "j" where j_def: "j\<in> {0 .. n} \<and> ?I (?p (p,n,s) j)" by blast
3547     hence "\<exists>x \<in> {?p (p,n,s) j |j. 0\<le> j \<and> j \<le> n }. ?I x" by auto
3548     hence ?case using pns
3549       by (simp only: FS,simp add: bex_Un)
3550     (rule disjI2, rule disjI1,rule exI [where x="p"],
3551       rule exI [where x="n"],rule exI [where x="s"],simp_all add: np)
3552   }
3553   moreover
3554   { assume nn: "n < 0" hence np: "-n >0" by simp
3555     from real_of_int_floor_le[where r="?N s"] have "?N (Floor s) + 1 > ?N s" by simp
3556     moreover from mult_left_mono_neg[OF xp] nn have "?N s \<ge> real n * x + ?N s" by simp
3557     ultimately have "?N (Floor s) + 1 > real n * x + ?N s" by arith
3558     moreover
3559     {from x1 nn have "real n *x + ?N s \<ge> real n + ?N s" by simp
3560       moreover from real_of_int_floor_le[where r="?N s"]  have "real n + ?N s \<ge> real n + ?N (Floor s)" by simp
3561       ultimately have "real n *x + ?N s \<ge> ?N (Floor s) + real n"
3562         by (simp only: algebra_simps)}
3563     ultimately have "?N (Floor s) + real n \<le> real n *x + ?N s\<and> real n *x + ?N s < ?N (Floor s) + real (1::int)" by simp
3564     hence th: "real n \<le> real n *x + ?N s - ?N (Floor s) \<and> real n *x + ?N s - ?N (Floor s) < real (1::int)" by simp
3565     have th1: "\<forall> (a::real). (- a > 0) = (a < 0)" by auto
3566     have th2: "\<forall> (a::real). (0 \<ge> - a) = (a \<ge> 0)" by auto
3567     from real_in_int_intervals th  have  "\<exists> j\<in> {n .. 0}. real j \<le> real n *x + ?N s - ?N (Floor s)\<and> real n *x + ?N s - ?N (Floor s) < real (j+1)" by simp
3569     hence "\<exists> j\<in> {n .. 0}. 0 \<le> real n *x + ?N s - ?N (Floor s) - real j \<and> real n *x + ?N s - ?N (Floor s) - real (j+1) < 0"
3570       by(simp only: myle[of _ "real n * x + Inum (x # bs) s - Inum (x # bs) (Floor s)"] less_iff_diff_less_0[where a="real n *x + ?N s - ?N (Floor s)"])
3571     hence "\<exists> j\<in> {n .. 0}. 0 \<ge> - (real n *x + ?N s - ?N (Floor s) - real j) \<and> - (real n *x + ?N s - ?N (Floor s) - real (j+1)) > 0" by (simp only: th1[rule_format] th2[rule_format])
3572     hence "\<exists> j\<in> {n.. 0}. ?I (?p (p,n,s) j)"
3574         del: diff_less_0_iff_less diff_le_0_iff_le)
3575     then obtain "j" where j_def: "j\<in> {n .. 0} \<and> ?I (?p (p,n,s) j)" by blast
3576     hence "\<exists>x \<in> {?p (p,n,s) j |j. n\<le> j \<and> j \<le> 0 }. ?I x" by auto
3577     hence ?case using pns
3578       by (simp only: FS,simp add: bex_Un)
3579     (rule disjI2, rule disjI2,rule exI [where x="p"],
3580       rule exI [where x="n"],rule exI [where x="s"],simp_all add: nn)
3581   }
3582   ultimately show ?case by blast
3583 qed (auto simp add: Let_def split_def)
3585     (* Linearize a formula where Bound 0 ranges over [0,1) *)
3587 definition rsplit :: "(int \<Rightarrow> num \<Rightarrow> fm) \<Rightarrow> num \<Rightarrow> fm" where
3588   "rsplit f a \<equiv> foldr disj (map (\<lambda> (\<phi>, n, s). conj \<phi> (f n s)) (rsplit0 a)) F"
3590 lemma foldr_disj_map: "Ifm bs (foldr disj (map f xs) F) = (\<exists> x \<in> set xs. Ifm bs (f x))"
3591 by(induct xs, simp_all)
3593 lemma foldr_conj_map: "Ifm bs (foldr conj (map f xs) T) = (\<forall> x \<in> set xs. Ifm bs (f x))"
3594 by(induct xs, simp_all)
3596 lemma foldr_disj_map_rlfm:
3597   assumes lf: "\<forall> n s. numbound0 s \<longrightarrow> isrlfm (f n s)"
3598   and \<phi>: "\<forall> (\<phi>,n,s) \<in> set xs. numbound0 s \<and> isrlfm \<phi>"
3599   shows "isrlfm (foldr disj (map (\<lambda> (\<phi>, n, s). conj \<phi> (f n s)) xs) F)"
3600 using lf \<phi> by (induct xs, auto)
3602 lemma rsplit_ex: "Ifm bs (rsplit f a) = (\<exists> (\<phi>,n,s) \<in> set (rsplit0 a). Ifm bs (conj \<phi> (f n s)))"
3603 using foldr_disj_map[where xs="rsplit0 a"] rsplit_def by (simp add: split_def)
3605 lemma rsplit_l: assumes lf: "\<forall> n s. numbound0 s \<longrightarrow> isrlfm (f n s)"
3606   shows "isrlfm (rsplit f a)"
3607 proof-
3608   from rsplit0_cs[where t="a"] have th: "\<forall> (\<phi>,n,s) \<in> set (rsplit0 a). numbound0 s \<and> isrlfm \<phi>" by blast
3609   from foldr_disj_map_rlfm[OF lf th] rsplit_def show ?thesis by simp
3610 qed
3612 lemma rsplit:
3613   assumes xp: "x \<ge> 0" and x1: "x < 1"
3614   and f: "\<forall> a n s. Inum (x#bs) a = Inum (x#bs) (CN 0 n s) \<and> numbound0 s \<longrightarrow> (Ifm (x#bs) (f n s) = Ifm (x#bs) (g a))"
3615   shows "Ifm (x#bs) (rsplit f a) = Ifm (x#bs) (g a)"
3616 proof(auto)
3617   let ?I = "\<lambda>x p. Ifm (x#bs) p"
3618   let ?N = "\<lambda> x t. Inum (x#bs) t"
3619   assume "?I x (rsplit f a)"
3620   hence "\<exists> (\<phi>,n,s) \<in> set (rsplit0 a). ?I x (And \<phi> (f n s))" using rsplit_ex by simp
3621   then obtain "\<phi>" "n" "s" where fnsS:"(\<phi>,n,s) \<in> set (rsplit0 a)" and "?I x (And \<phi> (f n s))" by blast
3622   hence \<phi>: "?I x \<phi>" and fns: "?I x (f n s)" by auto
3623   from rsplit0_cs[where t="a" and bs="bs" and x="x", rule_format, OF fnsS] \<phi>
3624   have th: "(?N x a = ?N x (CN 0 n s)) \<and> numbound0 s" by auto
3625   from f[rule_format, OF th] fns show "?I x (g a)" by simp
3626 next
3627   let ?I = "\<lambda>x p. Ifm (x#bs) p"
3628   let ?N = "\<lambda> x t. Inum (x#bs) t"
3629   assume ga: "?I x (g a)"
3630   from rsplit0_complete[OF xp x1, where bs="bs" and t="a"]
3631   obtain "\<phi>" "n" "s" where fnsS:"(\<phi>,n,s) \<in> set (rsplit0 a)" and fx: "?I x \<phi>" by blast
3632   from rsplit0_cs[where t="a" and x="x" and bs="bs"] fnsS fx
3633   have ans: "?N x a = ?N x (CN 0 n s)" and nb: "numbound0 s" by auto
3634   with ga f have "?I x (f n s)" by auto
3635   with rsplit_ex fnsS fx show "?I x (rsplit f a)" by auto
3636 qed
3638 definition lt :: "int \<Rightarrow> num \<Rightarrow> fm" where
3639   lt_def: "lt c t = (if c = 0 then (Lt t) else if c > 0 then (Lt (CN 0 c t))
3640                         else (Gt (CN 0 (-c) (Neg t))))"
3642 definition  le :: "int \<Rightarrow> num \<Rightarrow> fm" where
3643   le_def: "le c t = (if c = 0 then (Le t) else if c > 0 then (Le (CN 0 c t))
3644                         else (Ge (CN 0 (-c) (Neg t))))"
3646 definition  gt :: "int \<Rightarrow> num \<Rightarrow> fm" where
3647   gt_def: "gt c t = (if c = 0 then (Gt t) else if c > 0 then (Gt (CN 0 c t))
3648                         else (Lt (CN 0 (-c) (Neg t))))"
3650 definition  ge :: "int \<Rightarrow> num \<Rightarrow> fm" where
3651   ge_def: "ge c t = (if c = 0 then (Ge t) else if c > 0 then (Ge (CN 0 c t))
3652                         else (Le (CN 0 (-c) (Neg t))))"
3654 definition  eq :: "int \<Rightarrow> num \<Rightarrow> fm" where
3655   eq_def: "eq c t = (if c = 0 then (Eq t) else if c > 0 then (Eq (CN 0 c t))
3656                         else (Eq (CN 0 (-c) (Neg t))))"
3658 definition neq :: "int \<Rightarrow> num \<Rightarrow> fm" where
3659   neq_def: "neq c t = (if c = 0 then (NEq t) else if c > 0 then (NEq (CN 0 c t))
3660                         else (NEq (CN 0 (-c) (Neg t))))"
3662 lemma lt_mono: "\<forall> a n s. Inum (x#bs) a = Inum (x#bs) (CN 0 n s) \<and> numbound0 s \<longrightarrow> Ifm (x#bs) (lt n s) = Ifm (x#bs) (Lt a)"
3663   (is "\<forall> a n s . ?N a = ?N (CN 0 n s) \<and> _\<longrightarrow> ?I (lt n s) = ?I (Lt a)")
3664 proof(clarify)
3665   fix a n s
3666   assume H: "?N a = ?N (CN 0 n s)"
3667   show "?I (lt n s) = ?I (Lt a)" using H by (cases "n=0", (simp add: lt_def))
3668   (cases "n > 0", simp_all add: lt_def algebra_simps myless[of _ "0"])
3669 qed
3671 lemma lt_l: "isrlfm (rsplit lt a)"
3672   by (rule rsplit_l[where f="lt" and a="a"], auto simp add: lt_def,
3673     case_tac s, simp_all, case_tac "nat", simp_all)
3675 lemma le_mono: "\<forall> a n s. Inum (x#bs) a = Inum (x#bs) (CN 0 n s) \<and> numbound0 s \<longrightarrow> Ifm (x#bs) (le n s) = Ifm (x#bs) (Le a)" (is "\<forall> a n s. ?N a = ?N (CN 0 n s) \<and> _ \<longrightarrow> ?I (le n s) = ?I (Le a)")
3676 proof(clarify)
3677   fix a n s
3678   assume H: "?N a = ?N (CN 0 n s)"
3679   show "?I (le n s) = ?I (Le a)" using H by (cases "n=0", (simp add: le_def))
3680   (cases "n > 0", simp_all add: le_def algebra_simps myle[of _ "0"])
3681 qed
3683 lemma le_l: "isrlfm (rsplit le a)"
3684   by (rule rsplit_l[where f="le" and a="a"], auto simp add: le_def)
3685 (case_tac s, simp_all, case_tac "nat",simp_all)
3687 lemma gt_mono: "\<forall> a n s. Inum (x#bs) a = Inum (x#bs) (CN 0 n s) \<and> numbound0 s \<longrightarrow> Ifm (x#bs) (gt n s) = Ifm (x#bs) (Gt a)" (is "\<forall> a n s. ?N a = ?N (CN 0 n s) \<and> _ \<longrightarrow> ?I (gt n s) = ?I (Gt a)")
3688 proof(clarify)
3689   fix a n s
3690   assume H: "?N a = ?N (CN 0 n s)"
3691   show "?I (gt n s) = ?I (Gt a)" using H by (cases "n=0", (simp add: gt_def))
3692   (cases "n > 0", simp_all add: gt_def algebra_simps myless[of _ "0"])
3693 qed
3694 lemma gt_l: "isrlfm (rsplit gt a)"
3695   by (rule rsplit_l[where f="gt" and a="a"], auto simp add: gt_def)
3696 (case_tac s, simp_all, case_tac "nat", simp_all)
3698 lemma ge_mono: "\<forall> a n s. Inum (x#bs) a = Inum (x#bs) (CN 0 n s) \<and> numbound0 s \<longrightarrow> Ifm (x#bs) (ge n s) = Ifm (x#bs) (Ge a)" (is "\<forall> a n s . ?N a = ?N (CN 0 n s) \<and> _ \<longrightarrow> ?I (ge n s) = ?I (Ge a)")
3699 proof(clarify)
3700   fix a n s
3701   assume H: "?N a = ?N (CN 0 n s)"
3702   show "?I (ge n s) = ?I (Ge a)" using H by (cases "n=0", (simp add: ge_def))
3703   (cases "n > 0", simp_all add: ge_def algebra_simps myle[of _ "0"])
3704 qed
3705 lemma ge_l: "isrlfm (rsplit ge a)"
3706   by (rule rsplit_l[where f="ge" and a="a"], auto simp add: ge_def)
3707 (case_tac s, simp_all, case_tac "nat", simp_all)
3709 lemma eq_mono: "\<forall> a n s. Inum (x#bs) a = Inum (x#bs) (CN 0 n s) \<and> numbound0 s \<longrightarrow> Ifm (x#bs) (eq n s) = Ifm (x#bs) (Eq a)" (is "\<forall> a n s. ?N a = ?N (CN 0 n s) \<and> _ \<longrightarrow> ?I (eq n s) = ?I (Eq a)")
3710 proof(clarify)
3711   fix a n s
3712   assume H: "?N a = ?N (CN 0 n s)"
3713   show "?I (eq n s) = ?I (Eq a)" using H by (auto simp add: eq_def algebra_simps)
3714 qed
3715 lemma eq_l: "isrlfm (rsplit eq a)"
3716   by (rule rsplit_l[where f="eq" and a="a"], auto simp add: eq_def)
3717 (case_tac s, simp_all, case_tac"nat", simp_all)
3719 lemma neq_mono: "\<forall> a n s. Inum (x#bs) a = Inum (x#bs) (CN 0 n s) \<and> numbound0 s \<longrightarrow> Ifm (x#bs) (neq n s) = Ifm (x#bs) (NEq a)" (is "\<forall> a n s. ?N a = ?N (CN 0 n s) \<and> _ \<longrightarrow> ?I (neq n s) = ?I (NEq a)")
3720 proof(clarify)
3721   fix a n s bs
3722   assume H: "?N a = ?N (CN 0 n s)"
3723   show "?I (neq n s) = ?I (NEq a)" using H by (auto simp add: neq_def algebra_simps)
3724 qed
3726 lemma neq_l: "isrlfm (rsplit neq a)"
3727   by (rule rsplit_l[where f="neq" and a="a"], auto simp add: neq_def)
3728 (case_tac s, simp_all, case_tac"nat", simp_all)
3730 lemma small_le:
3731   assumes u0:"0 \<le> u" and u1: "u < 1"
3732   shows "(-u \<le> real (n::int)) = (0 \<le> n)"
3733 using u0 u1  by auto
3735 lemma small_lt:
3736   assumes u0:"0 \<le> u" and u1: "u < 1"
3737   shows "(real (n::int) < real (m::int) - u) = (n < m)"
3738 using u0 u1  by auto
3740 lemma rdvd01_cs:
3741   assumes up: "u \<ge> 0" and u1: "u<1" and np: "real n > 0"
3742   shows "(real (i::int) rdvd real (n::int) * u - s) = (\<exists> j\<in> {0 .. n - 1}. real n * u = s - real (floor s) + real j \<and> real i rdvd real (j - floor s))" (is "?lhs = ?rhs")
3743 proof-
3744   let ?ss = "s - real (floor s)"
3745   from real_of_int_floor_add_one_gt[where r="s", simplified myless[of "s"]]
3746     real_of_int_floor_le[where r="s"]  have ss0:"?ss \<ge> 0" and ss1:"?ss < 1"
3747     by (auto simp add: myle[of _ "s", symmetric] myless[of "?ss"])
3748   from np have n0: "real n \<ge> 0" by simp
3749   from mult_left_mono[OF up n0] mult_strict_left_mono[OF u1 np]
3750   have nu0:"real n * u - s \<ge> -s" and nun:"real n * u -s < real n - s" by auto
3751   from int_rdvd_real[where i="i" and x="real (n::int) * u - s"]
3752   have "real i rdvd real n * u - s =
3753     (i dvd floor (real n * u -s) \<and> (real (floor (real n * u - s)) = real n * u - s ))"
3754     (is "_ = (?DE)" is "_ = (?D \<and> ?E)") by simp
3755   also have "\<dots> = (?DE \<and> real(floor (real n * u - s) + floor s)\<ge> -?ss
3756     \<and> real(floor (real n * u - s) + floor s)< real n - ?ss)" (is "_=(?DE \<and>real ?a \<ge> _ \<and> real ?a < _)")
3757     using nu0 nun  by auto
3758   also have "\<dots> = (?DE \<and> ?a \<ge> 0 \<and> ?a < n)" by(simp only: small_le[OF ss0 ss1] small_lt[OF ss0 ss1])
3759   also have "\<dots> = (?DE \<and> (\<exists> j\<in> {0 .. (n - 1)}. ?a = j))" by simp
3760   also have "\<dots> = (?DE \<and> (\<exists> j\<in> {0 .. (n - 1)}. real (\<lfloor>real n * u - s\<rfloor>) = real j - real \<lfloor>s\<rfloor> ))"
3761     by (simp only: algebra_simps real_of_int_diff[symmetric] real_of_int_inject del: real_of_int_diff)
3762   also have "\<dots> = ((\<exists> j\<in> {0 .. (n - 1)}. real n * u - s = real j - real \<lfloor>s\<rfloor> \<and> real i rdvd real n * u - s))" using int_rdvd_iff[where i="i" and t="\<lfloor>real n * u - s\<rfloor>"]
3763     by (auto cong: conj_cong)
3764   also have "\<dots> = ?rhs" by(simp cong: conj_cong) (simp add: algebra_simps )
3765   finally show ?thesis .
3766 qed
3768 definition
3769   DVDJ:: "int \<Rightarrow> int \<Rightarrow> num \<Rightarrow> fm"
3770 where
3771   DVDJ_def: "DVDJ i n s = (foldr disj (map (\<lambda> j. conj (Eq (CN 0 n (Add s (Sub (Floor (Neg s)) (C j))))) (Dvd i (Sub (C j) (Floor (Neg s))))) [0..n - 1]) F)"
3773 definition
3774   NDVDJ:: "int \<Rightarrow> int \<Rightarrow> num \<Rightarrow> fm"
3775 where
3776   NDVDJ_def: "NDVDJ i n s = (foldr conj (map (\<lambda> j. disj (NEq (CN 0 n (Add s (Sub (Floor (Neg s)) (C j))))) (NDvd i (Sub (C j) (Floor (Neg s))))) [0..n - 1]) T)"
3778 lemma DVDJ_DVD:
3779   assumes xp:"x\<ge> 0" and x1: "x < 1" and np:"real n > 0"
3780   shows "Ifm (x#bs) (DVDJ i n s) = Ifm (x#bs) (Dvd i (CN 0 n s))"
3781 proof-
3782   let ?f = "\<lambda> j. conj (Eq(CN 0 n (Add s (Sub(Floor (Neg s)) (C j))))) (Dvd i (Sub (C j) (Floor (Neg s))))"
3783   let ?s= "Inum (x#bs) s"
3784   from foldr_disj_map[where xs="[0..n - 1]" and bs="x#bs" and f="?f"]
3785   have "Ifm (x#bs) (DVDJ i n s) = (\<exists> j\<in> {0 .. (n - 1)}. Ifm (x#bs) (?f j))"
3786     by (simp add: np DVDJ_def)
3787   also have "\<dots> = (\<exists> j\<in> {0 .. (n - 1)}. real n * x = (- ?s) - real (floor (- ?s)) + real j \<and> real i rdvd real (j - floor (- ?s)))" by (simp add: algebra_simps diff_minus[symmetric])
3788   also from rdvd01_cs[OF xp x1 np, where i="i" and s="-?s"]
3789   have "\<dots> = (real i rdvd real n * x - (-?s))" by simp
3790   finally show ?thesis by simp
3791 qed
3793 lemma NDVDJ_NDVD:
3794   assumes xp:"x\<ge> 0" and x1: "x < 1" and np:"real n > 0"
3795   shows "Ifm (x#bs) (NDVDJ i n s) = Ifm (x#bs) (NDvd i (CN 0 n s))"
3796 proof-
3797   let ?f = "\<lambda> j. disj(NEq(CN 0 n (Add s (Sub (Floor (Neg s)) (C j))))) (NDvd i (Sub (C j) (Floor(Neg s))))"
3798   let ?s= "Inum (x#bs) s"
3799   from foldr_conj_map[where xs="[0..n - 1]" and bs="x#bs" and f="?f"]
3800   have "Ifm (x#bs) (NDVDJ i n s) = (\<forall> j\<in> {0 .. (n - 1)}. Ifm (x#bs) (?f j))"
3801     by (simp add: np NDVDJ_def)
3802   also have "\<dots> = (\<not> (\<exists> j\<in> {0 .. (n - 1)}. real n * x = (- ?s) - real (floor (- ?s)) + real j \<and> real i rdvd real (j - floor (- ?s))))" by (simp add: algebra_simps diff_minus[symmetric])
3803   also from rdvd01_cs[OF xp x1 np, where i="i" and s="-?s"]
3804   have "\<dots> = (\<not> (real i rdvd real n * x - (-?s)))" by simp
3805   finally show ?thesis by simp
3806 qed
3808 lemma foldr_disj_map_rlfm2:
3809   assumes lf: "\<forall> n . isrlfm (f n)"
3810   shows "isrlfm (foldr disj (map f xs) F)"
3811 using lf by (induct xs, auto)
3812 lemma foldr_And_map_rlfm2:
3813   assumes lf: "\<forall> n . isrlfm (f n)"
3814   shows "isrlfm (foldr conj (map f xs) T)"
3815 using lf by (induct xs, auto)
3817 lemma DVDJ_l: assumes ip: "i >0" and np: "n>0" and nb: "numbound0 s"
3818   shows "isrlfm (DVDJ i n s)"
3819 proof-
3820   let ?f="\<lambda>j. conj (Eq (CN 0 n (Add s (Sub (Floor (Neg s)) (C j)))))
3821                          (Dvd i (Sub (C j) (Floor (Neg s))))"
3822   have th: "\<forall> j. isrlfm (?f j)" using nb np by auto
3823   from DVDJ_def foldr_disj_map_rlfm2[OF th] show ?thesis by simp
3824 qed
3826 lemma NDVDJ_l: assumes ip: "i >0" and np: "n>0" and nb: "numbound0 s"
3827   shows "isrlfm (NDVDJ i n s)"
3828 proof-
3829   let ?f="\<lambda>j. disj (NEq (CN 0 n (Add s (Sub (Floor (Neg s)) (C j)))))
3830                       (NDvd i (Sub (C j) (Floor (Neg s))))"
3831   have th: "\<forall> j. isrlfm (?f j)" using nb np by auto
3832   from NDVDJ_def foldr_And_map_rlfm2[OF th] show ?thesis by auto
3833 qed
3835 definition DVD :: "int \<Rightarrow> int \<Rightarrow> num \<Rightarrow> fm" where
3836   DVD_def: "DVD i c t =
3837   (if i=0 then eq c t else
3838   if c = 0 then (Dvd i t) else if c >0 then DVDJ (abs i) c t else DVDJ (abs i) (-c) (Neg t))"
3840 definition  NDVD :: "int \<Rightarrow> int \<Rightarrow> num \<Rightarrow> fm" where
3841   "NDVD i c t =
3842   (if i=0 then neq c t else
3843   if c = 0 then (NDvd i t) else if c >0 then NDVDJ (abs i) c t else NDVDJ (abs i) (-c) (Neg t))"
3845 lemma DVD_mono:
3846   assumes xp: "0\<le> x" and x1: "x < 1"
3847   shows "\<forall> a n s. Inum (x#bs) a = Inum (x#bs) (CN 0 n s) \<and> numbound0 s \<longrightarrow> Ifm (x#bs) (DVD i n s) = Ifm (x#bs) (Dvd i a)"
3848   (is "\<forall> a n s. ?N a = ?N (CN 0 n s) \<and> _ \<longrightarrow> ?I (DVD i n s) = ?I (Dvd i a)")
3849 proof(clarify)
3850   fix a n s
3851   assume H: "?N a = ?N (CN 0 n s)" and nb: "numbound0 s"
3852   let ?th = "?I (DVD i n s) = ?I (Dvd i a)"
3853   have "i=0 \<or> (i\<noteq>0 \<and> n=0) \<or> (i\<noteq>0 \<and> n < 0) \<or> (i\<noteq>0 \<and> n > 0)" by arith
3854   moreover {assume iz: "i=0" hence ?th using eq_mono[rule_format, OF conjI[OF H nb]]
3855       by (simp add: DVD_def rdvd_left_0_eq)}
3856   moreover {assume inz: "i\<noteq>0" and "n=0" hence ?th by (simp add: H DVD_def) }
3857   moreover {assume inz: "i\<noteq>0" and "n<0" hence ?th
3858       by (simp add: DVD_def H DVDJ_DVD[OF xp x1] rdvd_abs1
3859         rdvd_minus[where d="i" and t="real n * x + Inum (x # bs) s"]) }
3860   moreover {assume inz: "i\<noteq>0" and "n>0" hence ?th by (simp add:DVD_def H DVDJ_DVD[OF xp x1] rdvd_abs1)}
3861   ultimately show ?th by blast
3862 qed
3864 lemma NDVD_mono:   assumes xp: "0\<le> x" and x1: "x < 1"
3865   shows "\<forall> a n s. Inum (x#bs) a = Inum (x#bs) (CN 0 n s) \<and> numbound0 s \<longrightarrow> Ifm (x#bs) (NDVD i n s) = Ifm (x#bs) (NDvd i a)"
3866   (is "\<forall> a n s. ?N a = ?N (CN 0 n s) \<and> _ \<longrightarrow> ?I (NDVD i n s) = ?I (NDvd i a)")
3867 proof(clarify)
3868   fix a n s
3869   assume H: "?N a = ?N (CN 0 n s)" and nb: "numbound0 s"
3870   let ?th = "?I (NDVD i n s) = ?I (NDvd i a)"
3871   have "i=0 \<or> (i\<noteq>0 \<and> n=0) \<or> (i\<noteq>0 \<and> n < 0) \<or> (i\<noteq>0 \<and> n > 0)" by arith
3872   moreover {assume iz: "i=0" hence ?th using neq_mono[rule_format, OF conjI[OF H nb]]
3873       by (simp add: NDVD_def rdvd_left_0_eq)}
3874   moreover {assume inz: "i\<noteq>0" and "n=0" hence ?th by (simp add: H NDVD_def) }
3875   moreover {assume inz: "i\<noteq>0" and "n<0" hence ?th
3876       by (simp add: NDVD_def H NDVDJ_NDVD[OF xp x1] rdvd_abs1
3877         rdvd_minus[where d="i" and t="real n * x + Inum (x # bs) s"]) }
3878   moreover {assume inz: "i\<noteq>0" and "n>0" hence ?th
3879       by (simp add:NDVD_def H NDVDJ_NDVD[OF xp x1] rdvd_abs1)}
3880   ultimately show ?th by blast
3881 qed
3883 lemma DVD_l: "isrlfm (rsplit (DVD i) a)"
3884   by (rule rsplit_l[where f="DVD i" and a="a"], auto simp add: DVD_def eq_def DVDJ_l)
3885 (case_tac s, simp_all, case_tac "nat", simp_all)
3887 lemma NDVD_l: "isrlfm (rsplit (NDVD i) a)"
3888   by (rule rsplit_l[where f="NDVD i" and a="a"], auto simp add: NDVD_def neq_def NDVDJ_l)
3889 (case_tac s, simp_all, case_tac "nat", simp_all)
3891 consts rlfm :: "fm \<Rightarrow> fm"
3892 recdef rlfm "measure fmsize"
3893   "rlfm (And p q) = conj (rlfm p) (rlfm q)"
3894   "rlfm (Or p q) = disj (rlfm p) (rlfm q)"
3895   "rlfm (Imp p q) = disj (rlfm (NOT p)) (rlfm q)"
3896   "rlfm (Iff p q) = disj (conj(rlfm p) (rlfm q)) (conj(rlfm (NOT p)) (rlfm (NOT q)))"
3897   "rlfm (Lt a) = rsplit lt a"
3898   "rlfm (Le a) = rsplit le a"
3899   "rlfm (Gt a) = rsplit gt a"
3900   "rlfm (Ge a) = rsplit ge a"
3901   "rlfm (Eq a) = rsplit eq a"
3902   "rlfm (NEq a) = rsplit neq a"
3903   "rlfm (Dvd i a) = rsplit (\<lambda> t. DVD i t) a"
3904   "rlfm (NDvd i a) = rsplit (\<lambda> t. NDVD i t) a"
3905   "rlfm (NOT (And p q)) = disj (rlfm (NOT p)) (rlfm (NOT q))"
3906   "rlfm (NOT (Or p q)) = conj (rlfm (NOT p)) (rlfm (NOT q))"
3907   "rlfm (NOT (Imp p q)) = conj (rlfm p) (rlfm (NOT q))"
3908   "rlfm (NOT (Iff p q)) = disj (conj(rlfm p) (rlfm(NOT q))) (conj(rlfm(NOT p)) (rlfm q))"
3909   "rlfm (NOT (NOT p)) = rlfm p"
3910   "rlfm (NOT T) = F"
3911   "rlfm (NOT F) = T"
3912   "rlfm (NOT (Lt a)) = simpfm (rlfm (Ge a))"
3913   "rlfm (NOT (Le a)) = simpfm (rlfm (Gt a))"
3914   "rlfm (NOT (Gt a)) = simpfm (rlfm (Le a))"
3915   "rlfm (NOT (Ge a)) = simpfm (rlfm (Lt a))"
3916   "rlfm (NOT (Eq a)) = simpfm (rlfm (NEq a))"
3917   "rlfm (NOT (NEq a)) = simpfm (rlfm (Eq a))"
3918   "rlfm (NOT (Dvd i a)) = simpfm (rlfm (NDvd i a))"
3919   "rlfm (NOT (NDvd i a)) = simpfm (rlfm (Dvd i a))"
3920   "rlfm p = p" (hints simp add: fmsize_pos)
3922 lemma bound0at_l : "\<lbrakk>isatom p ; bound0 p\<rbrakk> \<Longrightarrow> isrlfm p"
3923   by (induct p rule: isrlfm.induct, auto)
3925 lemma simpfm_rl: "isrlfm p \<Longrightarrow> isrlfm (simpfm p)"
3926 proof (induct p)
3927   case (Lt a)
3928   hence "bound0 (Lt a) \<or> (\<exists> c e. a = CN 0 c e \<and> c > 0 \<and> numbound0 e)"
3929     by (cases a,simp_all, case_tac "nat", simp_all)
3930   moreover
3931   {assume "bound0 (Lt a)" hence bn:"bound0 (simpfm (Lt a))"
3932       using simpfm_bound0 by blast
3933     have "isatom (simpfm (Lt a))" by (cases "simpnum a", auto simp add: Let_def)
3934     with bn bound0at_l have ?case by blast}
3935   moreover
3936   {fix c e assume "a = CN 0 c e" and "c>0" and "numbound0 e"
3937     {
3938       assume cn1:"numgcd (CN 0 c (simpnum e)) \<noteq> 1" and cnz:"numgcd (CN 0 c (simpnum e)) \<noteq> 0"
3939       with numgcd_pos[where t="CN 0 c (simpnum e)"]
3940       have th1:"numgcd (CN 0 c (simpnum e)) > 0" by simp
3941       from prems have th:"numgcd (CN 0 c (simpnum e)) \<le> c"
3943       from prems have th': "c\<noteq>0" by auto
3944       from prems have cp: "c \<ge> 0" by simp
3945       from zdiv_mono2[OF cp th1 th, simplified zdiv_self[OF th']]
3946         have "0 < c div numgcd (CN 0 c (simpnum e))" by simp
3947     }
3948     with prems have ?case
3949       by (simp add: Let_def reducecoeff_def reducecoeffh_numbound0)}
3950   ultimately show ?case by blast
3951 next
3952   case (Le a)
3953   hence "bound0 (Le a) \<or> (\<exists> c e. a = CN 0 c e \<and> c > 0 \<and> numbound0 e)"
3954     by (cases a,simp_all, case_tac "nat", simp_all)
3955   moreover
3956   {assume "bound0 (Le a)" hence bn:"bound0 (simpfm (Le a))"
3957       using simpfm_bound0 by blast
3958     have "isatom (simpfm (Le a))" by (cases "simpnum a", auto simp add: Let_def)
3959     with bn bound0at_l have ?case by blast}
3960   moreover
3961   {fix c e assume "a = CN 0 c e" and "c>0" and "numbound0 e"
3962     {
3963       assume cn1:"numgcd (CN 0 c (simpnum e)) \<noteq> 1" and cnz:"numgcd (CN 0 c (simpnum e)) \<noteq> 0"
3964       with numgcd_pos[where t="CN 0 c (simpnum e)"]
3965       have th1:"numgcd (CN 0 c (simpnum e)) > 0" by simp
3966       from prems have th:"numgcd (CN 0 c (simpnum e)) \<le> c"
3968       from prems have th': "c\<noteq>0" by auto
3969       from prems have cp: "c \<ge> 0" by simp
3970       from zdiv_mono2[OF cp th1 th, simplified zdiv_self[OF th']]
3971         have "0 < c div numgcd (CN 0 c (simpnum e))" by simp
3972     }
3973     with prems have ?case
3974       by (simp add: Let_def reducecoeff_def simpnum_numbound0 reducecoeffh_numbound0)}
3975   ultimately show ?case by blast
3976 next
3977   case (Gt a)
3978   hence "bound0 (Gt a) \<or> (\<exists> c e. a = CN 0 c e \<and> c > 0 \<and> numbound0 e)"
3979     by (cases a,simp_all, case_tac "nat", simp_all)
3980   moreover
3981   {assume "bound0 (Gt a)" hence bn:"bound0 (simpfm (Gt a))"
3982       using simpfm_bound0 by blast
3983     have "isatom (simpfm (Gt a))" by (cases "simpnum a", auto simp add: Let_def)
3984     with bn bound0at_l have ?case by blast}
3985   moreover
3986   {fix c e assume "a = CN 0 c e" and "c>0" and "numbound0 e"
3987     {
3988       assume cn1:"numgcd (CN 0 c (simpnum e)) \<noteq> 1" and cnz:"numgcd (CN 0 c (simpnum e)) \<noteq> 0"
3989       with numgcd_pos[where t="CN 0 c (simpnum e)"]
3990       have th1:"numgcd (CN 0 c (simpnum e)) > 0" by simp
3991       from prems have th:"numgcd (CN 0 c (simpnum e)) \<le> c"
3993       from prems have th': "c\<noteq>0" by auto
3994       from prems have cp: "c \<ge> 0" by simp
3995       from zdiv_mono2[OF cp th1 th, simplified zdiv_self[OF th']]
3996         have "0 < c div numgcd (CN 0 c (simpnum e))" by simp
3997     }
3998     with prems have ?case
3999       by (simp add: Let_def reducecoeff_def simpnum_numbound0 reducecoeffh_numbound0)}
4000   ultimately show ?case by blast
4001 next
4002   case (Ge a)
4003   hence "bound0 (Ge a) \<or> (\<exists> c e. a = CN 0 c e \<and> c > 0 \<and> numbound0 e)"
4004     by (cases a,simp_all, case_tac "nat", simp_all)
4005   moreover
4006   {assume "bound0 (Ge a)" hence bn:"bound0 (simpfm (Ge a))"
4007       using simpfm_bound0 by blast
4008     have "isatom (simpfm (Ge a))" by (cases "simpnum a", auto simp add: Let_def)
4009     with bn bound0at_l have ?case by blast}
4010   moreover
4011   {fix c e assume "a = CN 0 c e" and "c>0" and "numbound0 e"
4012     {
4013       assume cn1:"numgcd (CN 0 c (simpnum e)) \<noteq> 1" and cnz:"numgcd (CN 0 c (simpnum e)) \<noteq> 0"
4014       with numgcd_pos[where t="CN 0 c (simpnum e)"]
4015       have th1:"numgcd (CN 0 c (simpnum e)) > 0" by simp
4016       from prems have th:"numgcd (CN 0 c (simpnum e)) \<le> c"
4018       from prems have th': "c\<noteq>0" by auto
4019       from prems have cp: "c \<ge> 0" by simp
4020       from zdiv_mono2[OF cp th1 th, simplified zdiv_self[OF th']]
4021         have "0 < c div numgcd (CN 0 c (simpnum e))" by simp
4022     }
4023     with prems have ?case
4024       by (simp add: Let_def reducecoeff_def simpnum_numbound0 reducecoeffh_numbound0)}
4025   ultimately show ?case by blast
4026 next
4027   case (Eq a)
4028   hence "bound0 (Eq a) \<or> (\<exists> c e. a = CN 0 c e \<and> c > 0 \<and> numbound0 e)"
4029     by (cases a,simp_all, case_tac "nat", simp_all)
4030   moreover
4031   {assume "bound0 (Eq a)" hence bn:"bound0 (simpfm (Eq a))"
4032       using simpfm_bound0 by blast
4033     have "isatom (simpfm (Eq a))" by (cases "simpnum a", auto simp add: Let_def)
4034     with bn bound0at_l have ?case by blast}
4035   moreover
4036   {fix c e assume "a = CN 0 c e" and "c>0" and "numbound0 e"
4037     {
4038       assume cn1:"numgcd (CN 0 c (simpnum e)) \<noteq> 1" and cnz:"numgcd (CN 0 c (simpnum e)) \<noteq> 0"
4039       with numgcd_pos[where t="CN 0 c (simpnum e)"]
4040       have th1:"numgcd (CN 0 c (simpnum e)) > 0" by simp
4041       from prems have th:"numgcd (CN 0 c (simpnum e)) \<le> c"
4043       from prems have th': "c\<noteq>0" by auto
4044       from prems have cp: "c \<ge> 0" by simp
4045       from zdiv_mono2[OF cp th1 th, simplified zdiv_self[OF th']]
4046         have "0 < c div numgcd (CN 0 c (simpnum e))" by simp
4047     }
4048     with prems have ?case
4049       by (simp add: Let_def reducecoeff_def simpnum_numbound0 reducecoeffh_numbound0)}
4050   ultimately show ?case by blast
4051 next
4052   case (NEq a)
4053   hence "bound0 (NEq a) \<or> (\<exists> c e. a = CN 0 c e \<and> c > 0 \<and> numbound0 e)"
4054     by (cases a,simp_all, case_tac "nat", simp_all)
4055   moreover
4056   {assume "bound0 (NEq a)" hence bn:"bound0 (simpfm (NEq a))"
4057       using simpfm_bound0 by blast
4058     have "isatom (simpfm (NEq a))" by (cases "simpnum a", auto simp add: Let_def)
4059     with bn bound0at_l have ?case by blast}
4060   moreover
4061   {fix c e assume "a = CN 0 c e" and "c>0" and "numbound0 e"
4062     {
4063       assume cn1:"numgcd (CN 0 c (simpnum e)) \<noteq> 1" and cnz:"numgcd (CN 0 c (simpnum e)) \<noteq> 0"
4064       with numgcd_pos[where t="CN 0 c (simpnum e)"]
4065       have th1:"numgcd (CN 0 c (simpnum e)) > 0" by simp
4066       from prems have th:"numgcd (CN 0 c (simpnum e)) \<le> c"
4068       from prems have th': "c\<noteq>0" by auto
4069       from prems have cp: "c \<ge> 0" by simp
4070       from zdiv_mono2[OF cp th1 th, simplified zdiv_self[OF th']]
4071         have "0 < c div numgcd (CN 0 c (simpnum e))" by simp
4072     }
4073     with prems have ?case
4074       by (simp add: Let_def reducecoeff_def simpnum_numbound0 reducecoeffh_numbound0)}
4075   ultimately show ?case by blast
4076 next
4077   case (Dvd i a) hence "bound0 (Dvd i a)" by auto hence bn:"bound0 (simpfm (Dvd i a))"
4078     using simpfm_bound0 by blast
4079   have "isatom (simpfm (Dvd i a))" by (cases "simpnum a", auto simp add: Let_def split_def)
4080   with bn bound0at_l show ?case by blast
4081 next
4082   case (NDvd i a)  hence "bound0 (NDvd i a)" by auto hence bn:"bound0 (simpfm (NDvd i a))"
4083     using simpfm_bound0 by blast
4084   have "isatom (simpfm (NDvd i a))" by (cases "simpnum a", auto simp add: Let_def split_def)
4085   with bn bound0at_l show ?case by blast
4086 qed(auto simp add: conj_def imp_def disj_def iff_def Let_def simpfm_bound0 numadd_nb numneg_nb)
4088 lemma rlfm_I:
4089   assumes qfp: "qfree p"
4090   and xp: "0 \<le> x" and x1: "x < 1"
4091   shows "(Ifm (x#bs) (rlfm p) = Ifm (x# bs) p) \<and> isrlfm (rlfm p)"
4092   using qfp
4093 by (induct p rule: rlfm.induct)
4094 (auto simp add: rsplit[OF xp x1 lt_mono] lt_l rsplit[OF xp x1 le_mono] le_l rsplit[OF xp x1 gt_mono] gt_l
4095                rsplit[OF xp x1 ge_mono] ge_l rsplit[OF xp x1 eq_mono] eq_l rsplit[OF xp x1 neq_mono] neq_l
4096                rsplit[OF xp x1 DVD_mono[OF xp x1]] DVD_l rsplit[OF xp x1 NDVD_mono[OF xp x1]] NDVD_l simpfm_rl)
4097 lemma rlfm_l:
4098   assumes qfp: "qfree p"
4099   shows "isrlfm (rlfm p)"
4100   using qfp lt_l gt_l ge_l le_l eq_l neq_l DVD_l NDVD_l
4101 by (induct p rule: rlfm.induct,auto simp add: simpfm_rl)
4103     (* Operations needed for Ferrante and Rackoff *)
4104 lemma rminusinf_inf:
4105   assumes lp: "isrlfm p"
4106   shows "\<exists> z. \<forall> x < z. Ifm (x#bs) (minusinf p) = Ifm (x#bs) p" (is "\<exists> z. \<forall> x. ?P z x p")
4107 using lp
4108 proof (induct p rule: minusinf.induct)
4109   case (1 p q) thus ?case by (auto,rule_tac x= "min z za" in exI) auto
4110 next
4111   case (2 p q) thus ?case by (auto,rule_tac x= "min z za" in exI) auto
4112 next
4113   case (3 c e)
4114   from prems have nb: "numbound0 e" by simp
4115   from prems have cp: "real c > 0" by simp
4116   fix a
4117   let ?e="Inum (a#bs) e"
4118   let ?z = "(- ?e) / real c"
4119   {fix x
4120     assume xz: "x < ?z"
4121     hence "(real c * x < - ?e)"
4122       by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="- ?e"] mult_ac)
4123     hence "real c * x + ?e < 0" by arith
4124     hence "real c * x + ?e \<noteq> 0" by simp
4125     with xz have "?P ?z x (Eq (CN 0 c e))"
4126       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp  }
4127   hence "\<forall> x < ?z. ?P ?z x (Eq (CN 0 c e))" by simp
4128   thus ?case by blast
4129 next
4130   case (4 c e)
4131   from prems have nb: "numbound0 e" by simp
4132   from prems have cp: "real c > 0" by simp
4133   fix a
4134   let ?e="Inum (a#bs) e"
4135   let ?z = "(- ?e) / real c"
4136   {fix x
4137     assume xz: "x < ?z"
4138     hence "(real c * x < - ?e)"
4139       by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="- ?e"] mult_ac)
4140     hence "real c * x + ?e < 0" by arith
4141     hence "real c * x + ?e \<noteq> 0" by simp
4142     with xz have "?P ?z x (NEq (CN 0 c e))"
4143       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
4144   hence "\<forall> x < ?z. ?P ?z x (NEq (CN 0 c e))" by simp
4145   thus ?case by blast
4146 next
4147   case (5 c e)
4148     from prems have nb: "numbound0 e" by simp
4149   from prems have cp: "real c > 0" by simp
4150   fix a
4151   let ?e="Inum (a#bs) e"
4152   let ?z = "(- ?e) / real c"
4153   {fix x
4154     assume xz: "x < ?z"
4155     hence "(real c * x < - ?e)"
4156       by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="- ?e"] mult_ac)
4157     hence "real c * x + ?e < 0" by arith
4158     with xz have "?P ?z x (Lt (CN 0 c e))"
4159       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"]  by simp }
4160   hence "\<forall> x < ?z. ?P ?z x (Lt (CN 0 c e))" by simp
4161   thus ?case by blast
4162 next
4163   case (6 c e)
4164     from prems have nb: "numbound0 e" by simp
4165   from prems have cp: "real c > 0" by simp
4166   fix a
4167   let ?e="Inum (a#bs) e"
4168   let ?z = "(- ?e) / real c"
4169   {fix x
4170     assume xz: "x < ?z"
4171     hence "(real c * x < - ?e)"
4172       by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="- ?e"] mult_ac)
4173     hence "real c * x + ?e < 0" by arith
4174     with xz have "?P ?z x (Le (CN 0 c e))"
4175       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
4176   hence "\<forall> x < ?z. ?P ?z x (Le (CN 0 c e))" by simp
4177   thus ?case by blast
4178 next
4179   case (7 c e)
4180     from prems have nb: "numbound0 e" by simp
4181   from prems have cp: "real c > 0" by simp
4182   fix a
4183   let ?e="Inum (a#bs) e"
4184   let ?z = "(- ?e) / real c"
4185   {fix x
4186     assume xz: "x < ?z"
4187     hence "(real c * x < - ?e)"
4188       by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="- ?e"] mult_ac)
4189     hence "real c * x + ?e < 0" by arith
4190     with xz have "?P ?z x (Gt (CN 0 c e))"
4191       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
4192   hence "\<forall> x < ?z. ?P ?z x (Gt (CN 0 c e))" by simp
4193   thus ?case by blast
4194 next
4195   case (8 c e)
4196     from prems have nb: "numbound0 e" by simp
4197   from prems have cp: "real c > 0" by simp
4198   fix a
4199   let ?e="Inum (a#bs) e"
4200   let ?z = "(- ?e) / real c"
4201   {fix x
4202     assume xz: "x < ?z"
4203     hence "(real c * x < - ?e)"
4204       by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="- ?e"] mult_ac)
4205     hence "real c * x + ?e < 0" by arith
4206     with xz have "?P ?z x (Ge (CN 0 c e))"
4207       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
4208   hence "\<forall> x < ?z. ?P ?z x (Ge (CN 0 c e))" by simp
4209   thus ?case by blast
4210 qed simp_all
4212 lemma rplusinf_inf:
4213   assumes lp: "isrlfm p"
4214   shows "\<exists> z. \<forall> x > z. Ifm (x#bs) (plusinf p) = Ifm (x#bs) p" (is "\<exists> z. \<forall> x. ?P z x p")
4215 using lp
4216 proof (induct p rule: isrlfm.induct)
4217   case (1 p q) thus ?case by (auto,rule_tac x= "max z za" in exI) auto
4218 next
4219   case (2 p q) thus ?case by (auto,rule_tac x= "max z za" in exI) auto
4220 next
4221   case (3 c e)
4222   from prems have nb: "numbound0 e" by simp
4223   from prems have cp: "real c > 0" by simp
4224   fix a
4225   let ?e="Inum (a#bs) e"
4226   let ?z = "(- ?e) / real c"
4227   {fix x
4228     assume xz: "x > ?z"
4229     with mult_strict_right_mono [OF xz cp] cp
4230     have "(real c * x > - ?e)" by (simp add: mult_ac)
4231     hence "real c * x + ?e > 0" by arith
4232     hence "real c * x + ?e \<noteq> 0" by simp
4233     with xz have "?P ?z x (Eq (CN 0 c e))"
4234       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
4235   hence "\<forall> x > ?z. ?P ?z x (Eq (CN 0 c e))" by simp
4236   thus ?case by blast
4237 next
4238   case (4 c e)
4239   from prems have nb: "numbound0 e" by simp
4240   from prems have cp: "real c > 0" by simp
4241   fix a
4242   let ?e="Inum (a#bs) e"
4243   let ?z = "(- ?e) / real c"
4244   {fix x
4245     assume xz: "x > ?z"
4246     with mult_strict_right_mono [OF xz cp] cp
4247     have "(real c * x > - ?e)" by (simp add: mult_ac)
4248     hence "real c * x + ?e > 0" by arith
4249     hence "real c * x + ?e \<noteq> 0" by simp
4250     with xz have "?P ?z x (NEq (CN 0 c e))"
4251       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
4252   hence "\<forall> x > ?z. ?P ?z x (NEq (CN 0 c e))" by simp
4253   thus ?case by blast
4254 next
4255   case (5 c e)
4256   from prems have nb: "numbound0 e" by simp
4257   from prems have cp: "real c > 0" by simp
4258   fix a
4259   let ?e="Inum (a#bs) e"
4260   let ?z = "(- ?e) / real c"
4261   {fix x
4262     assume xz: "x > ?z"
4263     with mult_strict_right_mono [OF xz cp] cp
4264     have "(real c * x > - ?e)" by (simp add: mult_ac)
4265     hence "real c * x + ?e > 0" by arith
4266     with xz have "?P ?z x (Lt (CN 0 c e))"
4267       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
4268   hence "\<forall> x > ?z. ?P ?z x (Lt (CN 0 c e))" by simp
4269   thus ?case by blast
4270 next
4271   case (6 c e)
4272   from prems have nb: "numbound0 e" by simp
4273   from prems have cp: "real c > 0" by simp
4274   fix a
4275   let ?e="Inum (a#bs) e"
4276   let ?z = "(- ?e) / real c"
4277   {fix x
4278     assume xz: "x > ?z"
4279     with mult_strict_right_mono [OF xz cp] cp
4280     have "(real c * x > - ?e)" by (simp add: mult_ac)
4281     hence "real c * x + ?e > 0" by arith
4282     with xz have "?P ?z x (Le (CN 0 c e))"
4283       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
4284   hence "\<forall> x > ?z. ?P ?z x (Le (CN 0 c e))" by simp
4285   thus ?case by blast
4286 next
4287   case (7 c e)
4288   from prems have nb: "numbound0 e" by simp
4289   from prems have cp: "real c > 0" by simp
4290   fix a
4291   let ?e="Inum (a#bs) e"
4292   let ?z = "(- ?e) / real c"
4293   {fix x
4294     assume xz: "x > ?z"
4295     with mult_strict_right_mono [OF xz cp] cp
4296     have "(real c * x > - ?e)" by (simp add: mult_ac)
4297     hence "real c * x + ?e > 0" by arith
4298     with xz have "?P ?z x (Gt (CN 0 c e))"
4299       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
4300   hence "\<forall> x > ?z. ?P ?z x (Gt (CN 0 c e))" by simp
4301   thus ?case by blast
4302 next
4303   case (8 c e)
4304   from prems have nb: "numbound0 e" by simp
4305   from prems have cp: "real c > 0" by simp
4306   fix a
4307   let ?e="Inum (a#bs) e"
4308   let ?z = "(- ?e) / real c"
4309   {fix x
4310     assume xz: "x > ?z"
4311     with mult_strict_right_mono [OF xz cp] cp
4312     have "(real c * x > - ?e)" by (simp add: mult_ac)
4313     hence "real c * x + ?e > 0" by arith
4314     with xz have "?P ?z x (Ge (CN 0 c e))"
4315       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"]   by simp }
4316   hence "\<forall> x > ?z. ?P ?z x (Ge (CN 0 c e))" by simp
4317   thus ?case by blast
4318 qed simp_all
4320 lemma rminusinf_bound0:
4321   assumes lp: "isrlfm p"
4322   shows "bound0 (minusinf p)"
4323   using lp
4324   by (induct p rule: minusinf.induct) simp_all
4326 lemma rplusinf_bound0:
4327   assumes lp: "isrlfm p"
4328   shows "bound0 (plusinf p)"
4329   using lp
4330   by (induct p rule: plusinf.induct) simp_all
4332 lemma rminusinf_ex:
4333   assumes lp: "isrlfm p"
4334   and ex: "Ifm (a#bs) (minusinf p)"
4335   shows "\<exists> x. Ifm (x#bs) p"
4336 proof-
4337   from bound0_I [OF rminusinf_bound0[OF lp], where b="a" and bs ="bs"] ex
4338   have th: "\<forall> x. Ifm (x#bs) (minusinf p)" by auto
4339   from rminusinf_inf[OF lp, where bs="bs"]
4340   obtain z where z_def: "\<forall>x<z. Ifm (x # bs) (minusinf p) = Ifm (x # bs) p" by blast
4341   from th have "Ifm ((z - 1)#bs) (minusinf p)" by simp
4342   moreover have "z - 1 < z" by simp
4343   ultimately show ?thesis using z_def by auto
4344 qed
4346 lemma rplusinf_ex:
4347   assumes lp: "isrlfm p"
4348   and ex: "Ifm (a#bs) (plusinf p)"
4349   shows "\<exists> x. Ifm (x#bs) p"
4350 proof-
4351   from bound0_I [OF rplusinf_bound0[OF lp], where b="a" and bs ="bs"] ex
4352   have th: "\<forall> x. Ifm (x#bs) (plusinf p)" by auto
4353   from rplusinf_inf[OF lp, where bs="bs"]
4354   obtain z where z_def: "\<forall>x>z. Ifm (x # bs) (plusinf p) = Ifm (x # bs) p" by blast
4355   from th have "Ifm ((z + 1)#bs) (plusinf p)" by simp
4356   moreover have "z + 1 > z" by simp
4357   ultimately show ?thesis using z_def by auto
4358 qed
4360 consts
4361   \<Upsilon>:: "fm \<Rightarrow> (num \<times> int) list"
4362   \<upsilon> :: "fm \<Rightarrow> (num \<times> int) \<Rightarrow> fm "
4363 recdef \<Upsilon> "measure size"
4364   "\<Upsilon> (And p q) = (\<Upsilon> p @ \<Upsilon> q)"
4365   "\<Upsilon> (Or p q) = (\<Upsilon> p @ \<Upsilon> q)"
4366   "\<Upsilon> (Eq  (CN 0 c e)) = [(Neg e,c)]"
4367   "\<Upsilon> (NEq (CN 0 c e)) = [(Neg e,c)]"
4368   "\<Upsilon> (Lt  (CN 0 c e)) = [(Neg e,c)]"
4369   "\<Upsilon> (Le  (CN 0 c e)) = [(Neg e,c)]"
4370   "\<Upsilon> (Gt  (CN 0 c e)) = [(Neg e,c)]"
4371   "\<Upsilon> (Ge  (CN 0 c e)) = [(Neg e,c)]"
4372   "\<Upsilon> p = []"
4374 recdef \<upsilon> "measure size"
4375   "\<upsilon> (And p q) = (\<lambda> (t,n). And (\<upsilon> p (t,n)) (\<upsilon> q (t,n)))"
4376   "\<upsilon> (Or p q) = (\<lambda> (t,n). Or (\<upsilon> p (t,n)) (\<upsilon> q (t,n)))"
4377   "\<upsilon> (Eq (CN 0 c e)) = (\<lambda> (t,n). Eq (Add (Mul c t) (Mul n e)))"
4378   "\<upsilon> (NEq (CN 0 c e)) = (\<lambda> (t,n). NEq (Add (Mul c t) (Mul n e)))"
4379   "\<upsilon> (Lt (CN 0 c e)) = (\<lambda> (t,n). Lt (Add (Mul c t) (Mul n e)))"
4380   "\<upsilon> (Le (CN 0 c e)) = (\<lambda> (t,n). Le (Add (Mul c t) (Mul n e)))"
4381   "\<upsilon> (Gt (CN 0 c e)) = (\<lambda> (t,n). Gt (Add (Mul c t) (Mul n e)))"
4382   "\<upsilon> (Ge (CN 0 c e)) = (\<lambda> (t,n). Ge (Add (Mul c t) (Mul n e)))"
4383   "\<upsilon> p = (\<lambda> (t,n). p)"
4385 lemma \<upsilon>_I: assumes lp: "isrlfm p"
4386   and np: "real n > 0" and nbt: "numbound0 t"
4387   shows "(Ifm (x#bs) (\<upsilon> p (t,n)) = Ifm (((Inum (x#bs) t)/(real n))#bs) p) \<and> bound0 (\<upsilon> p (t,n))" (is "(?I x (\<upsilon> p (t,n)) = ?I ?u p) \<and> ?B p" is "(_ = ?I (?t/?n) p) \<and> _" is "(_ = ?I (?N x t /_) p) \<and> _")
4388   using lp
4389 proof(induct p rule: \<upsilon>.induct)
4390   case (5 c e) from prems have cp: "c >0" and nb: "numbound0 e" by simp+
4391   have "?I ?u (Lt (CN 0 c e)) = (real c *(?t/?n) + (?N x e) < 0)"
4392     using numbound0_I[OF nb, where bs="bs" and b="?u" and b'="x"] by simp
4393   also have "\<dots> = (?n*(real c *(?t/?n)) + ?n*(?N x e) < 0)"
4394     by (simp only: pos_less_divide_eq[OF np, where a="real c *(?t/?n) + (?N x e)"
4395       and b="0", simplified divide_zero_left]) (simp only: algebra_simps)
4396   also have "\<dots> = (real c *?t + ?n* (?N x e) < 0)"
4397     using np by simp
4398   finally show ?case using nbt nb by (simp add: algebra_simps)
4399 next
4400   case (6 c e) from prems have cp: "c >0" and nb: "numbound0 e" by simp+
4401   have "?I ?u (Le (CN 0 c e)) = (real c *(?t/?n) + (?N x e) \<le> 0)"
4402     using numbound0_I[OF nb, where bs="bs" and b="?u" and b'="x"] by simp
4403   also have "\<dots> = (?n*(real c *(?t/?n)) + ?n*(?N x e) \<le> 0)"
4404     by (simp only: pos_le_divide_eq[OF np, where a="real c *(?t/?n) + (?N x e)"
4405       and b="0", simplified divide_zero_left]) (simp only: algebra_simps)
4406   also have "\<dots> = (real c *?t + ?n* (?N x e) \<le> 0)"
4407     using np by simp
4408   finally show ?case using nbt nb by (simp add: algebra_simps)
4409 next
4410   case (7 c e) from prems have cp: "c >0" and nb: "numbound0 e" by simp+
4411   have "?I ?u (Gt (CN 0 c e)) = (real c *(?t/?n) + (?N x e) > 0)"
4412     using numbound0_I[OF nb, where bs="bs" and b="?u" and b'="x"] by simp
4413   also have "\<dots> = (?n*(real c *(?t/?n)) + ?n*(?N x e) > 0)"
4414     by (simp only: pos_divide_less_eq[OF np, where a="real c *(?t/?n) + (?N x e)"
4415       and b="0", simplified divide_zero_left]) (simp only: algebra_simps)
4416   also have "\<dots> = (real c *?t + ?n* (?N x e) > 0)"
4417     using np by simp
4418   finally show ?case using nbt nb by (simp add: algebra_simps)
4419 next
4420   case (8 c e) from prems have cp: "c >0" and nb: "numbound0 e" by simp+
4421   have "?I ?u (Ge (CN 0 c e)) = (real c *(?t/?n) + (?N x e) \<ge> 0)"
4422     using numbound0_I[OF nb, where bs="bs" and b="?u" and b'="x"] by simp
4423   also have "\<dots> = (?n*(real c *(?t/?n)) + ?n*(?N x e) \<ge> 0)"
4424     by (simp only: pos_divide_le_eq[OF np, where a="real c *(?t/?n) + (?N x e)"
4425       and b="0", simplified divide_zero_left]) (simp only: algebra_simps)
4426   also have "\<dots> = (real c *?t + ?n* (?N x e) \<ge> 0)"
4427     using np by simp
4428   finally show ?case using nbt nb by (simp add: algebra_simps)
4429 next
4430   case (3 c e) from prems have cp: "c >0" and nb: "numbound0 e" by simp+
4431   from np have np: "real n \<noteq> 0" by simp
4432   have "?I ?u (Eq (CN 0 c e)) = (real c *(?t/?n) + (?N x e) = 0)"
4433     using numbound0_I[OF nb, where bs="bs" and b="?u" and b'="x"] by simp
4434   also have "\<dots> = (?n*(real c *(?t/?n)) + ?n*(?N x e) = 0)"
4435     by (simp only: nonzero_eq_divide_eq[OF np, where a="real c *(?t/?n) + (?N x e)"
4436       and b="0", simplified divide_zero_left]) (simp only: algebra_simps)
4437   also have "\<dots> = (real c *?t + ?n* (?N x e) = 0)"
4438     using np by simp
4439   finally show ?case using nbt nb by (simp add: algebra_simps)
4440 next
4441   case (4 c e) from prems have cp: "c >0" and nb: "numbound0 e" by simp+
4442   from np have np: "real n \<noteq> 0" by simp
4443   have "?I ?u (NEq (CN 0 c e)) = (real c *(?t/?n) + (?N x e) \<noteq> 0)"
4444     using numbound0_I[OF nb, where bs="bs" and b="?u" and b'="x"] by simp
4445   also have "\<dots> = (?n*(real c *(?t/?n)) + ?n*(?N x e) \<noteq> 0)"
4446     by (simp only: nonzero_eq_divide_eq[OF np, where a="real c *(?t/?n) + (?N x e)"
4447       and b="0", simplified divide_zero_left]) (simp only: algebra_simps)
4448   also have "\<dots> = (real c *?t + ?n* (?N x e) \<noteq> 0)"
4449     using np by simp
4450   finally show ?case using nbt nb by (simp add: algebra_simps)
4451 qed(simp_all add: nbt numbound0_I[where bs ="bs" and b="(Inum (x#bs) t)/ real n" and b'="x"])
4453 lemma \<Upsilon>_l:
4454   assumes lp: "isrlfm p"
4455   shows "\<forall> (t,k) \<in> set (\<Upsilon> p). numbound0 t \<and> k >0"
4456 using lp
4457 by(induct p rule: \<Upsilon>.induct)  auto
4459 lemma rminusinf_\<Upsilon>:
4460   assumes lp: "isrlfm p"
4461   and nmi: "\<not> (Ifm (a#bs) (minusinf p))" (is "\<not> (Ifm (a#bs) (?M p))")
4462   and ex: "Ifm (x#bs) p" (is "?I x p")
4463   shows "\<exists> (s,m) \<in> set (\<Upsilon> p). x \<ge> Inum (a#bs) s / real m" (is "\<exists> (s,m) \<in> ?U p. x \<ge> ?N a s / real m")
4464 proof-
4465   have "\<exists> (s,m) \<in> set (\<Upsilon> p). real m * x \<ge> Inum (a#bs) s " (is "\<exists> (s,m) \<in> ?U p. real m *x \<ge> ?N a s")
4466     using lp nmi ex
4467     by (induct p rule: minusinf.induct, auto simp add:numbound0_I[where bs="bs" and b="a" and b'="x"])
4468   then obtain s m where smU: "(s,m) \<in> set (\<Upsilon> p)" and mx: "real m * x \<ge> ?N a s" by blast
4469   from \<Upsilon>_l[OF lp] smU have mp: "real m > 0" by auto
4470   from pos_divide_le_eq[OF mp, where a="x" and b="?N a s", symmetric] mx have "x \<ge> ?N a s / real m"
4471     by (auto simp add: mult_commute)
4472   thus ?thesis using smU by auto
4473 qed
4475 lemma rplusinf_\<Upsilon>:
4476   assumes lp: "isrlfm p"
4477   and nmi: "\<not> (Ifm (a#bs) (plusinf p))" (is "\<not> (Ifm (a#bs) (?M p))")
4478   and ex: "Ifm (x#bs) p" (is "?I x p")
4479   shows "\<exists> (s,m) \<in> set (\<Upsilon> p). x \<le> Inum (a#bs) s / real m" (is "\<exists> (s,m) \<in> ?U p. x \<le> ?N a s / real m")
4480 proof-
4481   have "\<exists> (s,m) \<in> set (\<Upsilon> p). real m * x \<le> Inum (a#bs) s " (is "\<exists> (s,m) \<in> ?U p. real m *x \<le> ?N a s")
4482     using lp nmi ex
4483     by (induct p rule: minusinf.induct, auto simp add:numbound0_I[where bs="bs" and b="a" and b'="x"])
4484   then obtain s m where smU: "(s,m) \<in> set (\<Upsilon> p)" and mx: "real m * x \<le> ?N a s" by blast
4485   from \<Upsilon>_l[OF lp] smU have mp: "real m > 0" by auto
4486   from pos_le_divide_eq[OF mp, where a="x" and b="?N a s", symmetric] mx have "x \<le> ?N a s / real m"
4487     by (auto simp add: mult_commute)
4488   thus ?thesis using smU by auto
4489 qed
4491 lemma lin_dense:
4492   assumes lp: "isrlfm p"
4493   and noS: "\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> (\<lambda> (t,n). Inum (x#bs) t / real n) ` set (\<Upsilon> p)"
4494   (is "\<forall> t. _ \<and> _ \<longrightarrow> t \<notin> (\<lambda> (t,n). ?N x t / real n ) ` (?U p)")
4495   and lx: "l < x" and xu:"x < u" and px:" Ifm (x#bs) p"
4496   and ly: "l < y" and yu: "y < u"
4497   shows "Ifm (y#bs) p"
4498 using lp px noS
4499 proof (induct p rule: isrlfm.induct)
4500   case (5 c e) hence cp: "real c > 0" and nb: "numbound0 e" by simp+
4501     from prems have "x * real c + ?N x e < 0" by (simp add: algebra_simps)
4502     hence pxc: "x < (- ?N x e) / real c"
4503       by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="-?N x e"])
4504     from prems have noSc:"\<forall> t. l < t \<and> t < u \<longrightarrow> t \<noteq> (- ?N x e) / real c" by auto
4505     with ly yu have yne: "y \<noteq> - ?N x e / real c" by auto
4506     hence "y < (- ?N x e) / real c \<or> y > (-?N x e) / real c" by auto
4507     moreover {assume y: "y < (-?N x e)/ real c"
4508       hence "y * real c < - ?N x e"
4509         by (simp add: pos_less_divide_eq[OF cp, where a="y" and b="-?N x e", symmetric])
4510       hence "real c * y + ?N x e < 0" by (simp add: algebra_simps)
4511       hence ?case using numbound0_I[OF nb, where bs="bs" and b="x" and b'="y"] by simp}
4512     moreover {assume y: "y > (- ?N x e) / real c"
4513       with yu have eu: "u > (- ?N x e) / real c" by auto
4514       with noSc ly yu have "(- ?N x e) / real c \<le> l" by (cases "(- ?N x e) / real c > l", auto)
4515       with lx pxc have "False" by auto
4516       hence ?case by simp }
4517     ultimately show ?case by blast
4518 next
4519   case (6 c e) hence cp: "real c > 0" and nb: "numbound0 e" by simp +
4520     from prems have "x * real c + ?N x e \<le> 0" by (simp add: algebra_simps)
4521     hence pxc: "x \<le> (- ?N x e) / real c"
4522       by (simp only: pos_le_divide_eq[OF cp, where a="x" and b="-?N x e"])
4523     from prems have noSc:"\<forall> t. l < t \<and> t < u \<longrightarrow> t \<noteq> (- ?N x e) / real c" by auto
4524     with ly yu have yne: "y \<noteq> - ?N x e / real c" by auto
4525     hence "y < (- ?N x e) / real c \<or> y > (-?N x e) / real c" by auto
4526     moreover {assume y: "y < (-?N x e)/ real c"
4527       hence "y * real c < - ?N x e"
4528         by (simp add: pos_less_divide_eq[OF cp, where a="y" and b="-?N x e", symmetric])
4529       hence "real c * y + ?N x e < 0" by (simp add: algebra_simps)
4530       hence ?case using numbound0_I[OF nb, where bs="bs" and b="x" and b'="y"] by simp}
4531     moreover {assume y: "y > (- ?N x e) / real c"
4532       with yu have eu: "u > (- ?N x e) / real c" by auto
4533       with noSc ly yu have "(- ?N x e) / real c \<le> l" by (cases "(- ?N x e) / real c > l", auto)
4534       with lx pxc have "False" by auto
4535       hence ?case by simp }
4536     ultimately show ?case by blast
4537 next
4538   case (7 c e) hence cp: "real c > 0" and nb: "numbound0 e" by simp+
4539     from prems have "x * real c + ?N x e > 0" by (simp add: algebra_simps)
4540     hence pxc: "x > (- ?N x e) / real c"
4541       by (simp only: pos_divide_less_eq[OF cp, where a="x" and b="-?N x e"])
4542     from prems have noSc:"\<forall> t. l < t \<and> t < u \<longrightarrow> t \<noteq> (- ?N x e) / real c" by auto
4543     with ly yu have yne: "y \<noteq> - ?N x e / real c" by auto
4544     hence "y < (- ?N x e) / real c \<or> y > (-?N x e) / real c" by auto
4545     moreover {assume y: "y > (-?N x e)/ real c"
4546       hence "y * real c > - ?N x e"
4547         by (simp add: pos_divide_less_eq[OF cp, where a="y" and b="-?N x e", symmetric])
4548       hence "real c * y + ?N x e > 0" by (simp add: algebra_simps)
4549       hence ?case using numbound0_I[OF nb, where bs="bs" and b="x" and b'="y"] by simp}
4550     moreover {assume y: "y < (- ?N x e) / real c"
4551       with ly have eu: "l < (- ?N x e) / real c" by auto
4552       with noSc ly yu have "(- ?N x e) / real c \<ge> u" by (cases "(- ?N x e) / real c > l", auto)
4553       with xu pxc have "False" by auto
4554       hence ?case by simp }
4555     ultimately show ?case by blast
4556 next
4557   case (8 c e) hence cp: "real c > 0" and nb: "numbound0 e" by simp+
4558     from prems have "x * real c + ?N x e \<ge> 0" by (simp add: algebra_simps)
4559     hence pxc: "x \<ge> (- ?N x e) / real c"
4560       by (simp only: pos_divide_le_eq[OF cp, where a="x" and b="-?N x e"])
4561     from prems have noSc:"\<forall> t. l < t \<and> t < u \<longrightarrow> t \<noteq> (- ?N x e) / real c" by auto
4562     with ly yu have yne: "y \<noteq> - ?N x e / real c" by auto
4563     hence "y < (- ?N x e) / real c \<or> y > (-?N x e) / real c" by auto
4564     moreover {assume y: "y > (-?N x e)/ real c"
4565       hence "y * real c > - ?N x e"
4566         by (simp add: pos_divide_less_eq[OF cp, where a="y" and b="-?N x e", symmetric])
4567       hence "real c * y + ?N x e > 0" by (simp add: algebra_simps)
4568       hence ?case using numbound0_I[OF nb, where bs="bs" and b="x" and b'="y"] by simp}
4569     moreover {assume y: "y < (- ?N x e) / real c"
4570       with ly have eu: "l < (- ?N x e) / real c" by auto
4571       with noSc ly yu have "(- ?N x e) / real c \<ge> u" by (cases "(- ?N x e) / real c > l", auto)
4572       with xu pxc have "False" by auto
4573       hence ?case by simp }
4574     ultimately show ?case by blast
4575 next
4576   case (3 c e) hence cp: "real c > 0" and nb: "numbound0 e" by simp+
4577     from cp have cnz: "real c \<noteq> 0" by simp
4578     from prems have "x * real c + ?N x e = 0" by (simp add: algebra_simps)
4579     hence pxc: "x = (- ?N x e) / real c"
4580       by (simp only: nonzero_eq_divide_eq[OF cnz, where a="x" and b="-?N x e"])
4581     from prems have noSc:"\<forall> t. l < t \<and> t < u \<longrightarrow> t \<noteq> (- ?N x e) / real c" by auto
4582     with lx xu have yne: "x \<noteq> - ?N x e / real c" by auto
4583     with pxc show ?case by simp
4584 next
4585   case (4 c e) hence cp: "real c > 0" and nb: "numbound0 e" by simp+
4586     from cp have cnz: "real c \<noteq> 0" by simp
4587     from prems have noSc:"\<forall> t. l < t \<and> t < u \<longrightarrow> t \<noteq> (- ?N x e) / real c" by auto
4588     with ly yu have yne: "y \<noteq> - ?N x e / real c" by auto
4589     hence "y* real c \<noteq> -?N x e"
4590       by (simp only: nonzero_eq_divide_eq[OF cnz, where a="y" and b="-?N x e"]) simp
4591     hence "y* real c + ?N x e \<noteq> 0" by (simp add: algebra_simps)
4592     thus ?case using numbound0_I[OF nb, where bs="bs" and b="x" and b'="y"]
4594 qed (auto simp add: numbound0_I[where bs="bs" and b="y" and b'="x"])
4596 lemma rinf_\<Upsilon>:
4597   assumes lp: "isrlfm p"
4598   and nmi: "\<not> (Ifm (x#bs) (minusinf p))" (is "\<not> (Ifm (x#bs) (?M p))")
4599   and npi: "\<not> (Ifm (x#bs) (plusinf p))" (is "\<not> (Ifm (x#bs) (?P p))")
4600   and ex: "\<exists> x.  Ifm (x#bs) p" (is "\<exists> x. ?I x p")
4601   shows "\<exists> (l,n) \<in> set (\<Upsilon> p). \<exists> (s,m) \<in> set (\<Upsilon> p). ?I ((Inum (x#bs) l / real n + Inum (x#bs) s / real m) / 2) p"
4602 proof-
4603   let ?N = "\<lambda> x t. Inum (x#bs) t"
4604   let ?U = "set (\<Upsilon> p)"
4605   from ex obtain a where pa: "?I a p" by blast
4606   from bound0_I[OF rminusinf_bound0[OF lp], where bs="bs" and b="x" and b'="a"] nmi
4607   have nmi': "\<not> (?I a (?M p))" by simp
4608   from bound0_I[OF rplusinf_bound0[OF lp], where bs="bs" and b="x" and b'="a"] npi
4609   have npi': "\<not> (?I a (?P p))" by simp
4610   have "\<exists> (l,n) \<in> set (\<Upsilon> p). \<exists> (s,m) \<in> set (\<Upsilon> p). ?I ((?N a l/real n + ?N a s /real m) / 2) p"
4611   proof-
4612     let ?M = "(\<lambda> (t,c). ?N a t / real c) ` ?U"
4613     have fM: "finite ?M" by auto
4614     from rminusinf_\<Upsilon>[OF lp nmi pa] rplusinf_\<Upsilon>[OF lp npi pa]
4615     have "\<exists> (l,n) \<in> set (\<Upsilon> p). \<exists> (s,m) \<in> set (\<Upsilon> p). a \<le> ?N x l / real n \<and> a \<ge> ?N x s / real m" by blast
4616     then obtain "t" "n" "s" "m" where
4617       tnU: "(t,n) \<in> ?U" and smU: "(s,m) \<in> ?U"
4618       and xs1: "a \<le> ?N x s / real m" and tx1: "a \<ge> ?N x t / real n" by blast
4619     from \<Upsilon>_l[OF lp] tnU smU numbound0_I[where bs="bs" and b="x" and b'="a"] xs1 tx1 have xs: "a \<le> ?N a s / real m" and tx: "a \<ge> ?N a t / real n" by auto
4620     from tnU have Mne: "?M \<noteq> {}" by auto
4621     hence Une: "?U \<noteq> {}" by simp
4622     let ?l = "Min ?M"
4623     let ?u = "Max ?M"
4624     have linM: "?l \<in> ?M" using fM Mne by simp
4625     have uinM: "?u \<in> ?M" using fM Mne by simp
4626     have tnM: "?N a t / real n \<in> ?M" using tnU by auto
4627     have smM: "?N a s / real m \<in> ?M" using smU by auto
4628     have lM: "\<forall> t\<in> ?M. ?l \<le> t" using Mne fM by auto
4629     have Mu: "\<forall> t\<in> ?M. t \<le> ?u" using Mne fM by auto
4630     have "?l \<le> ?N a t / real n" using tnM Mne by simp hence lx: "?l \<le> a" using tx by simp
4631     have "?N a s / real m \<le> ?u" using smM Mne by simp hence xu: "a \<le> ?u" using xs by simp
4632     from finite_set_intervals2[where P="\<lambda> x. ?I x p",OF pa lx xu linM uinM fM lM Mu]
4633     have "(\<exists> s\<in> ?M. ?I s p) \<or>
4634       (\<exists> t1\<in> ?M. \<exists> t2 \<in> ?M. (\<forall> y. t1 < y \<and> y < t2 \<longrightarrow> y \<notin> ?M) \<and> t1 < a \<and> a < t2 \<and> ?I a p)" .
4635     moreover { fix u assume um: "u\<in> ?M" and pu: "?I u p"
4636       hence "\<exists> (tu,nu) \<in> ?U. u = ?N a tu / real nu" by auto
4637       then obtain "tu" "nu" where tuU: "(tu,nu) \<in> ?U" and tuu:"u= ?N a tu / real nu" by blast
4638       have "(u + u) / 2 = u" by auto with pu tuu
4639       have "?I (((?N a tu / real nu) + (?N a tu / real nu)) / 2) p" by simp
4640       with tuU have ?thesis by blast}
4641     moreover{
4642       assume "\<exists> t1\<in> ?M. \<exists> t2 \<in> ?M. (\<forall> y. t1 < y \<and> y < t2 \<longrightarrow> y \<notin> ?M) \<and> t1 < a \<and> a < t2 \<and> ?I a p"
4643       then obtain t1 and t2 where t1M: "t1 \<in> ?M" and t2M: "t2\<in> ?M"
4644         and noM: "\<forall> y. t1 < y \<and> y < t2 \<longrightarrow> y \<notin> ?M" and t1x: "t1 < a" and xt2: "a < t2" and px: "?I a p"
4645         by blast
4646       from t1M have "\<exists> (t1u,t1n) \<in> ?U. t1 = ?N a t1u / real t1n" by auto
4647       then obtain "t1u" "t1n" where t1uU: "(t1u,t1n) \<in> ?U" and t1u: "t1 = ?N a t1u / real t1n" by blast
4648       from t2M have "\<exists> (t2u,t2n) \<in> ?U. t2 = ?N a t2u / real t2n" by auto
4649       then obtain "t2u" "t2n" where t2uU: "(t2u,t2n) \<in> ?U" and t2u: "t2 = ?N a t2u / real t2n" by blast
4650       from t1x xt2 have t1t2: "t1 < t2" by simp
4651       let ?u = "(t1 + t2) / 2"
4652       from less_half_sum[OF t1t2] gt_half_sum[OF t1t2] have t1lu: "t1 < ?u" and ut2: "?u < t2" by auto
4653       from lin_dense[OF lp noM t1x xt2 px t1lu ut2] have "?I ?u p" .
4654       with t1uU t2uU t1u t2u have ?thesis by blast}
4655     ultimately show ?thesis by blast
4656   qed
4657   then obtain "l" "n" "s"  "m" where lnU: "(l,n) \<in> ?U" and smU:"(s,m) \<in> ?U"
4658     and pu: "?I ((?N a l / real n + ?N a s / real m) / 2) p" by blast
4659   from lnU smU \<Upsilon>_l[OF lp] have nbl: "numbound0 l" and nbs: "numbound0 s" by auto
4660   from numbound0_I[OF nbl, where bs="bs" and b="a" and b'="x"]
4661     numbound0_I[OF nbs, where bs="bs" and b="a" and b'="x"] pu
4662   have "?I ((?N x l / real n + ?N x s / real m) / 2) p" by simp
4663   with lnU smU
4664   show ?thesis by auto
4665 qed
4666     (* The Ferrante - Rackoff Theorem *)
4668 theorem fr_eq:
4669   assumes lp: "isrlfm p"
4670   shows "(\<exists> x. Ifm (x#bs) p) = ((Ifm (x#bs) (minusinf p)) \<or> (Ifm (x#bs) (plusinf p)) \<or> (\<exists> (t,n) \<in> set (\<Upsilon> p). \<exists> (s,m) \<in> set (\<Upsilon> p). Ifm ((((Inum (x#bs) t)/  real n + (Inum (x#bs) s) / real m) /2)#bs) p))"
4671   (is "(\<exists> x. ?I x p) = (?M \<or> ?P \<or> ?F)" is "?E = ?D")
4672 proof
4673   assume px: "\<exists> x. ?I x p"
4674   have "?M \<or> ?P \<or> (\<not> ?M \<and> \<not> ?P)" by blast
4675   moreover {assume "?M \<or> ?P" hence "?D" by blast}
4676   moreover {assume nmi: "\<not> ?M" and npi: "\<not> ?P"
4677     from rinf_\<Upsilon>[OF lp nmi npi] have "?F" using px by blast hence "?D" by blast}
4678   ultimately show "?D" by blast
4679 next
4680   assume "?D"
4681   moreover {assume m:"?M" from rminusinf_ex[OF lp m] have "?E" .}
4682   moreover {assume p: "?P" from rplusinf_ex[OF lp p] have "?E" . }
4683   moreover {assume f:"?F" hence "?E" by blast}
4684   ultimately show "?E" by blast
4685 qed
4688 lemma fr_eq\<upsilon>:
4689   assumes lp: "isrlfm p"
4690   shows "(\<exists> x. Ifm (x#bs) p) = ((Ifm (x#bs) (minusinf p)) \<or> (Ifm (x#bs) (plusinf p)) \<or> (\<exists> (t,k) \<in> set (\<Upsilon> p). \<exists> (s,l) \<in> set (\<Upsilon> p). Ifm (x#bs) (\<upsilon> p (Add(Mul l t) (Mul k s) , 2*k*l))))"
4691   (is "(\<exists> x. ?I x p) = (?M \<or> ?P \<or> ?F)" is "?E = ?D")
4692 proof
4693   assume px: "\<exists> x. ?I x p"
4694   have "?M \<or> ?P \<or> (\<not> ?M \<and> \<not> ?P)" by blast
4695   moreover {assume "?M \<or> ?P" hence "?D" by blast}
4696   moreover {assume nmi: "\<not> ?M" and npi: "\<not> ?P"
4697     let ?f ="\<lambda> (t,n). Inum (x#bs) t / real n"
4698     let ?N = "\<lambda> t. Inum (x#bs) t"
4699     {fix t n s m assume "(t,n)\<in> set (\<Upsilon> p)" and "(s,m) \<in> set (\<Upsilon> p)"
4700       with \<Upsilon>_l[OF lp] have tnb: "numbound0 t" and np:"real n > 0" and snb: "numbound0 s" and mp:"real m > 0"
4701         by auto
4702       let ?st = "Add (Mul m t) (Mul n s)"
4703       from mult_pos_pos[OF np mp] have mnp: "real (2*n*m) > 0"
4705       from tnb snb have st_nb: "numbound0 ?st" by simp
4706       have st: "(?N t / real n + ?N s / real m)/2 = ?N ?st / real (2*n*m)"
4708       from \<upsilon>_I[OF lp mnp st_nb, where x="x" and bs="bs"]
4709       have "?I x (\<upsilon> p (?st,2*n*m)) = ?I ((?N t / real n + ?N s / real m) /2) p" by (simp only: st[symmetric])}
4710     with rinf_\<Upsilon>[OF lp nmi npi px] have "?F" by blast hence "?D" by blast}
4711   ultimately show "?D" by blast
4712 next
4713   assume "?D"
4714   moreover {assume m:"?M" from rminusinf_ex[OF lp m] have "?E" .}
4715   moreover {assume p: "?P" from rplusinf_ex[OF lp p] have "?E" . }
4716   moreover {fix t k s l assume "(t,k) \<in> set (\<Upsilon> p)" and "(s,l) \<in> set (\<Upsilon> p)"
4717     and px:"?I x (\<upsilon> p (Add (Mul l t) (Mul k s), 2*k*l))"
4718     with \<Upsilon>_l[OF lp] have tnb: "numbound0 t" and np:"real k > 0" and snb: "numbound0 s" and mp:"real l > 0" by auto
4719     let ?st = "Add (Mul l t) (Mul k s)"
4720     from mult_pos_pos[OF np mp] have mnp: "real (2*k*l) > 0"
4722     from tnb snb have st_nb: "numbound0 ?st" by simp
4723     from \<upsilon>_I[OF lp mnp st_nb, where bs="bs"] px have "?E" by auto}
4724   ultimately show "?E" by blast
4725 qed
4727 text{* The overall Part *}
4729 lemma real_ex_int_real01:
4730   shows "(\<exists> (x::real). P x) = (\<exists> (i::int) (u::real). 0\<le> u \<and> u< 1 \<and> P (real i + u))"
4731 proof(auto)
4732   fix x
4733   assume Px: "P x"
4734   let ?i = "floor x"
4735   let ?u = "x - real ?i"
4736   have "x = real ?i + ?u" by simp
4737   hence "P (real ?i + ?u)" using Px by simp
4738   moreover have "real ?i \<le> x" using real_of_int_floor_le by simp hence "0 \<le> ?u" by arith
4739   moreover have "?u < 1" using real_of_int_floor_add_one_gt[where r="x"] by arith
4740   ultimately show "(\<exists> (i::int) (u::real). 0\<le> u \<and> u< 1 \<and> P (real i + u))" by blast
4741 qed
4743 fun exsplitnum :: "num \<Rightarrow> num" where
4744   "exsplitnum (C c) = (C c)"
4745 | "exsplitnum (Bound 0) = Add (Bound 0) (Bound 1)"
4746 | "exsplitnum (Bound n) = Bound (n+1)"
4747 | "exsplitnum (Neg a) = Neg (exsplitnum a)"
4748 | "exsplitnum (Add a b) = Add (exsplitnum a) (exsplitnum b) "
4749 | "exsplitnum (Sub a b) = Sub (exsplitnum a) (exsplitnum b) "
4750 | "exsplitnum (Mul c a) = Mul c (exsplitnum a)"
4751 | "exsplitnum (Floor a) = Floor (exsplitnum a)"
4752 | "exsplitnum (CN 0 c a) = CN 0 c (Add (Mul c (Bound 1)) (exsplitnum a))"
4753 | "exsplitnum (CN n c a) = CN (n+1) c (exsplitnum a)"
4754 | "exsplitnum (CF c s t) = CF c (exsplitnum s) (exsplitnum t)"
4756 fun exsplit :: "fm \<Rightarrow> fm" where
4757   "exsplit (Lt a) = Lt (exsplitnum a)"
4758 | "exsplit (Le a) = Le (exsplitnum a)"
4759 | "exsplit (Gt a) = Gt (exsplitnum a)"
4760 | "exsplit (Ge a) = Ge (exsplitnum a)"
4761 | "exsplit (Eq a) = Eq (exsplitnum a)"
4762 | "exsplit (NEq a) = NEq (exsplitnum a)"
4763 | "exsplit (Dvd i a) = Dvd i (exsplitnum a)"
4764 | "exsplit (NDvd i a) = NDvd i (exsplitnum a)"
4765 | "exsplit (And p q) = And (exsplit p) (exsplit q)"
4766 | "exsplit (Or p q) = Or (exsplit p) (exsplit q)"
4767 | "exsplit (Imp p q) = Imp (exsplit p) (exsplit q)"
4768 | "exsplit (Iff p q) = Iff (exsplit p) (exsplit q)"
4769 | "exsplit (NOT p) = NOT (exsplit p)"
4770 | "exsplit p = p"
4772 lemma exsplitnum:
4773   "Inum (x#y#bs) (exsplitnum t) = Inum ((x+y) #bs) t"
4774   by(induct t rule: exsplitnum.induct) (simp_all add: algebra_simps)
4776 lemma exsplit:
4777   assumes qfp: "qfree p"
4778   shows "Ifm (x#y#bs) (exsplit p) = Ifm ((x+y)#bs) p"
4779 using qfp exsplitnum[where x="x" and y="y" and bs="bs"]
4780 by(induct p rule: exsplit.induct) simp_all
4782 lemma splitex:
4783   assumes qf: "qfree p"
4784   shows "(Ifm bs (E p)) = (\<exists> (i::int). Ifm (real i#bs) (E (And (And (Ge(CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) (exsplit p))))" (is "?lhs = ?rhs")
4785 proof-
4786   have "?rhs = (\<exists> (i::int). \<exists> x. 0\<le> x \<and> x < 1 \<and> Ifm (x#(real i)#bs) (exsplit p))"
4787     by (simp add: myless[of _ "1"] myless[of _ "0"] add_ac diff_minus)
4788   also have "\<dots> = (\<exists> (i::int). \<exists> x. 0\<le> x \<and> x < 1 \<and> Ifm ((real i + x) #bs) p)"
4789     by (simp only: exsplit[OF qf] add_ac)
4790   also have "\<dots> = (\<exists> x. Ifm (x#bs) p)"
4791     by (simp only: real_ex_int_real01[where P="\<lambda> x. Ifm (x#bs) p"])
4792   finally show ?thesis by simp
4793 qed
4795     (* Implement the right hand sides of Cooper's theorem and Ferrante and Rackoff. *)
4797 definition ferrack01 :: "fm \<Rightarrow> fm" where
4798   "ferrack01 p \<equiv> (let p' = rlfm(And (And (Ge(CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) p);
4799                     U = remdups(map simp_num_pair
4800                      (map (\<lambda> ((t,n),(s,m)). (Add (Mul m t) (Mul n s) , 2*n*m))
4801                            (alluopairs (\<Upsilon> p'))))
4802   in decr (evaldjf (\<upsilon> p') U ))"
4804 lemma fr_eq_01:
4805   assumes qf: "qfree p"
4806   shows "(\<exists> x. Ifm (x#bs) (And (And (Ge(CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) p)) = (\<exists> (t,n) \<in> set (\<Upsilon> (rlfm (And (And (Ge(CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) p))). \<exists> (s,m) \<in> set (\<Upsilon> (rlfm (And (And (Ge(CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) p))). Ifm (x#bs) (\<upsilon> (rlfm (And (And (Ge(CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) p)) (Add (Mul m t) (Mul n s), 2*n*m)))"
4807   (is "(\<exists> x. ?I x ?q) = ?F")
4808 proof-
4809   let ?rq = "rlfm ?q"
4810   let ?M = "?I x (minusinf ?rq)"
4811   let ?P = "?I x (plusinf ?rq)"
4812   have MF: "?M = False"
4813     apply (simp add: Let_def reducecoeff_def numgcd_def rsplit_def ge_def lt_def conj_def disj_def)
4814     by (cases "rlfm p = And (Ge (CN 0 1 (C 0))) (Lt (CN 0 1 (C -1)))", simp_all)
4815   have PF: "?P = False" apply (simp add: Let_def reducecoeff_def numgcd_def rsplit_def ge_def lt_def conj_def disj_def)
4816     by (cases "rlfm p = And (Ge (CN 0 1 (C 0))) (Lt (CN 0 1 (C -1)))", simp_all)
4817   have "(\<exists> x. ?I x ?q ) =
4818     ((?I x (minusinf ?rq)) \<or> (?I x (plusinf ?rq )) \<or> (\<exists> (t,n) \<in> set (\<Upsilon> ?rq). \<exists> (s,m) \<in> set (\<Upsilon> ?rq ). ?I x (\<upsilon> ?rq (Add (Mul m t) (Mul n s), 2*n*m))))"
4819     (is "(\<exists> x. ?I x ?q) = (?M \<or> ?P \<or> ?F)" is "?E = ?D")
4820   proof
4821     assume "\<exists> x. ?I x ?q"
4822     then obtain x where qx: "?I x ?q" by blast
4823     hence xp: "0\<le> x" and x1: "x< 1" and px: "?I x p"
4824       by (auto simp add: rsplit_def lt_def ge_def rlfm_I[OF qf])
4825     from qx have "?I x ?rq "
4826       by (simp add: rsplit_def lt_def ge_def rlfm_I[OF qf xp x1])
4827     hence lqx: "?I x ?rq " using simpfm[where p="?rq" and bs="x#bs"] by auto
4828     from qf have qfq:"isrlfm ?rq"
4829       by (auto simp add: rsplit_def lt_def ge_def rlfm_I[OF qf xp x1])
4830     with lqx fr_eq\<upsilon>[OF qfq] show "?M \<or> ?P \<or> ?F" by blast
4831   next
4832     assume D: "?D"
4833     let ?U = "set (\<Upsilon> ?rq )"
4834     from MF PF D have "?F" by auto
4835     then obtain t n s m where aU:"(t,n) \<in> ?U" and bU:"(s,m)\<in> ?U" and rqx: "?I x (\<upsilon> ?rq (Add (Mul m t) (Mul n s), 2*n*m))" by blast
4836     from qf have lrq:"isrlfm ?rq"using rlfm_l[OF qf]
4837       by (auto simp add: rsplit_def lt_def ge_def)
4838     from aU bU \<Upsilon>_l[OF lrq] have tnb: "numbound0 t" and np:"real n > 0" and snb: "numbound0 s" and mp:"real m > 0" by (auto simp add: split_def)
4839     let ?st = "Add (Mul m t) (Mul n s)"
4840     from tnb snb have stnb: "numbound0 ?st" by simp
4841     from mult_pos_pos[OF np mp] have mnp: "real (2*n*m) > 0"
4843     from conjunct1[OF \<upsilon>_I[OF lrq mnp stnb, where bs="bs" and x="x"], symmetric] rqx
4844     have "\<exists> x. ?I x ?rq" by auto
4845     thus "?E"
4846       using rlfm_I[OF qf] by (auto simp add: rsplit_def lt_def ge_def)
4847   qed
4848   with MF PF show ?thesis by blast
4849 qed
4851 lemma \<Upsilon>_cong_aux:
4852   assumes Ul: "\<forall> (t,n) \<in> set U. numbound0 t \<and> n >0"
4853   shows "((\<lambda> (t,n). Inum (x#bs) t /real n) ` (set (map (\<lambda> ((t,n),(s,m)). (Add (Mul m t) (Mul n s) , 2*n*m)) (alluopairs U)))) = ((\<lambda> ((t,n),(s,m)). (Inum (x#bs) t /real n + Inum (x#bs) s /real m)/2) ` (set U \<times> set U))"
4854   (is "?lhs = ?rhs")
4855 proof(auto)
4856   fix t n s m
4857   assume "((t,n),(s,m)) \<in> set (alluopairs U)"
4858   hence th: "((t,n),(s,m)) \<in> (set U \<times> set U)"
4859     using alluopairs_set1[where xs="U"] by blast
4860   let ?N = "\<lambda> t. Inum (x#bs) t"
4861   let ?st= "Add (Mul m t) (Mul n s)"
4862   from Ul th have mnz: "m \<noteq> 0" by auto
4863   from Ul th have  nnz: "n \<noteq> 0" by auto
4864   have st: "(?N t / real n + ?N s / real m)/2 = ?N ?st / real (2*n*m)"
4867   thus "(real m *  Inum (x # bs) t + real n * Inum (x # bs) s) /
4868        (2 * real n * real m)
4869        \<in> (\<lambda>((t, n), s, m).
4870              (Inum (x # bs) t / real n + Inum (x # bs) s / real m) / 2) `
4871          (set U \<times> set U)"using mnz nnz th
4873     by (rule_tac x="(s,m)" in bexI,simp_all)
4874   (rule_tac x="(t,n)" in bexI,simp_all)
4875 next
4876   fix t n s m
4877   assume tnU: "(t,n) \<in> set U" and smU:"(s,m) \<in> set U"
4878   let ?N = "\<lambda> t. Inum (x#bs) t"
4879   let ?st= "Add (Mul m t) (Mul n s)"
4880   from Ul smU have mnz: "m \<noteq> 0" by auto
4881   from Ul tnU have  nnz: "n \<noteq> 0" by auto
4882   have st: "(?N t / real n + ?N s / real m)/2 = ?N ?st / real (2*n*m)"
4884  let ?P = "\<lambda> (t',n') (s',m'). (Inum (x # bs) t / real n + Inum (x # bs) s / real m)/2 = (Inum (x # bs) t' / real n' + Inum (x # bs) s' / real m')/2"
4885  have Pc:"\<forall> a b. ?P a b = ?P b a"
4886    by auto
4887  from Ul alluopairs_set1 have Up:"\<forall> ((t,n),(s,m)) \<in> set (alluopairs U). n \<noteq> 0 \<and> m \<noteq> 0" by blast
4888  from alluopairs_ex[OF Pc, where xs="U"] tnU smU
4889  have th':"\<exists> ((t',n'),(s',m')) \<in> set (alluopairs U). ?P (t',n') (s',m')"
4890    by blast
4891  then obtain t' n' s' m' where ts'_U: "((t',n'),(s',m')) \<in> set (alluopairs U)"
4892    and Pts': "?P (t',n') (s',m')" by blast
4893  from ts'_U Up have mnz': "m' \<noteq> 0" and nnz': "n'\<noteq> 0" by auto
4894  let ?st' = "Add (Mul m' t') (Mul n' s')"
4895    have st': "(?N t' / real n' + ?N s' / real m')/2 = ?N ?st' / real (2*n'*m')"
4897  from Pts' have
4898    "(Inum (x # bs) t / real n + Inum (x # bs) s / real m)/2 = (Inum (x # bs) t' / real n' + Inum (x # bs) s' / real m')/2" by simp
4899  also have "\<dots> = ((\<lambda>(t, n). Inum (x # bs) t / real n) ((\<lambda>((t, n), s, m). (Add (Mul m t) (Mul n s), 2 * n * m)) ((t',n'),(s',m'))))" by (simp add: st')
4900  finally show "(Inum (x # bs) t / real n + Inum (x # bs) s / real m) / 2
4901           \<in> (\<lambda>(t, n). Inum (x # bs) t / real n) `
4902             (\<lambda>((t, n), s, m). (Add (Mul m t) (Mul n s), 2 * n * m)) `
4903             set (alluopairs U)"
4904    using ts'_U by blast
4905 qed
4907 lemma \<Upsilon>_cong:
4908   assumes lp: "isrlfm p"
4909   and UU': "((\<lambda> (t,n). Inum (x#bs) t /real n) ` U') = ((\<lambda> ((t,n),(s,m)). (Inum (x#bs) t /real n + Inum (x#bs) s /real m)/2) ` (U \<times> U))" (is "?f ` U' = ?g ` (U\<times>U)")
4910   and U: "\<forall> (t,n) \<in> U. numbound0 t \<and> n > 0"
4911   and U': "\<forall> (t,n) \<in> U'. numbound0 t \<and> n > 0"
4912   shows "(\<exists> (t,n) \<in> U. \<exists> (s,m) \<in> U. Ifm (x#bs) (\<upsilon> p (Add (Mul m t) (Mul n s),2*n*m))) = (\<exists> (t,n) \<in> U'. Ifm (x#bs) (\<upsilon> p (t,n)))"
4913   (is "?lhs = ?rhs")
4914 proof
4915   assume ?lhs
4916   then obtain t n s m where tnU: "(t,n) \<in> U" and smU:"(s,m) \<in> U" and
4917     Pst: "Ifm (x#bs) (\<upsilon> p (Add (Mul m t) (Mul n s),2*n*m))" by blast
4918   let ?N = "\<lambda> t. Inum (x#bs) t"
4919   from tnU smU U have tnb: "numbound0 t" and np: "n > 0"
4920     and snb: "numbound0 s" and mp:"m > 0"  by auto
4921   let ?st= "Add (Mul m t) (Mul n s)"
4922   from mult_pos_pos[OF np mp] have mnp: "real (2*n*m) > 0"
4923       by (simp add: mult_commute real_of_int_mult[symmetric] del: real_of_int_mult)
4924     from tnb snb have stnb: "numbound0 ?st" by simp
4925   have st: "(?N t / real n + ?N s / real m)/2 = ?N ?st / real (2*n*m)"
4927   from tnU smU UU' have "?g ((t,n),(s,m)) \<in> ?f ` U'" by blast
4928   hence "\<exists> (t',n') \<in> U'. ?g ((t,n),(s,m)) = ?f (t',n')"
4929     by auto (rule_tac x="(a,b)" in bexI, auto)
4930   then obtain t' n' where tnU': "(t',n') \<in> U'" and th: "?g ((t,n),(s,m)) = ?f (t',n')" by blast
4931   from U' tnU' have tnb': "numbound0 t'" and np': "real n' > 0" by auto
4932   from \<upsilon>_I[OF lp mnp stnb, where bs="bs" and x="x"] Pst
4933   have Pst2: "Ifm (Inum (x # bs) (Add (Mul m t) (Mul n s)) / real (2 * n * m) # bs) p" by simp
4934   from conjunct1[OF \<upsilon>_I[OF lp np' tnb', where bs="bs" and x="x"], symmetric] th[simplified split_def fst_conv snd_conv,symmetric] Pst2[simplified st[symmetric]]
4935   have "Ifm (x # bs) (\<upsilon> p (t', n')) " by (simp only: st)
4936   then show ?rhs using tnU' by auto
4937 next
4938   assume ?rhs
4939   then obtain t' n' where tnU': "(t',n') \<in> U'" and Pt': "Ifm (x # bs) (\<upsilon> p (t', n'))"
4940     by blast
4941   from tnU' UU' have "?f (t',n') \<in> ?g ` (U\<times>U)" by blast
4942   hence "\<exists> ((t,n),(s,m)) \<in> (U\<times>U). ?f (t',n') = ?g ((t,n),(s,m))"
4943     by auto (rule_tac x="(a,b)" in bexI, auto)
4944   then obtain t n s m where tnU: "(t,n) \<in> U" and smU:"(s,m) \<in> U" and
4945     th: "?f (t',n') = ?g((t,n),(s,m)) "by blast
4946     let ?N = "\<lambda> t. Inum (x#bs) t"
4947   from tnU smU U have tnb: "numbound0 t" and np: "n > 0"
4948     and snb: "numbound0 s" and mp:"m > 0"  by auto
4949   let ?st= "Add (Mul m t) (Mul n s)"
4950   from mult_pos_pos[OF np mp] have mnp: "real (2*n*m) > 0"
4951       by (simp add: mult_commute real_of_int_mult[symmetric] del: real_of_int_mult)
4952     from tnb snb have stnb: "numbound0 ?st" by simp
4953   have st: "(?N t / real n + ?N s / real m)/2 = ?N ?st / real (2*n*m)"
4955   from U' tnU' have tnb': "numbound0 t'" and np': "real n' > 0" by auto
4956   from \<upsilon>_I[OF lp np' tnb', where bs="bs" and x="x",simplified th[simplified split_def fst_conv snd_conv] st] Pt'
4957   have Pst2: "Ifm (Inum (x # bs) (Add (Mul m t) (Mul n s)) / real (2 * n * m) # bs) p" by simp
4958   with \<upsilon>_I[OF lp mnp stnb, where x="x" and bs="bs"] tnU smU show ?lhs by blast
4959 qed
4961 lemma ferrack01:
4962   assumes qf: "qfree p"
4963   shows "((\<exists> x. Ifm (x#bs) (And (And (Ge(CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) p)) = (Ifm bs (ferrack01 p))) \<and> qfree (ferrack01 p)" (is "(?lhs = ?rhs) \<and> _")
4964 proof-
4965   let ?I = "\<lambda> x p. Ifm (x#bs) p"
4966   fix x
4967   let ?N = "\<lambda> t. Inum (x#bs) t"
4968   let ?q = "rlfm (And (And (Ge(CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) p)"
4969   let ?U = "\<Upsilon> ?q"
4970   let ?Up = "alluopairs ?U"
4971   let ?g = "\<lambda> ((t,n),(s,m)). (Add (Mul m t) (Mul n s) , 2*n*m)"
4972   let ?S = "map ?g ?Up"
4973   let ?SS = "map simp_num_pair ?S"
4974   let ?Y = "remdups ?SS"
4975   let ?f= "(\<lambda> (t,n). ?N t / real n)"
4976   let ?h = "\<lambda> ((t,n),(s,m)). (?N t/real n + ?N s/ real m) /2"
4977   let ?F = "\<lambda> p. \<exists> a \<in> set (\<Upsilon> p). \<exists> b \<in> set (\<Upsilon> p). ?I x (\<upsilon> p (?g(a,b)))"
4978   let ?ep = "evaldjf (\<upsilon> ?q) ?Y"
4979   from rlfm_l[OF qf] have lq: "isrlfm ?q"
4980     by (simp add: rsplit_def lt_def ge_def conj_def disj_def Let_def reducecoeff_def numgcd_def)
4981   from alluopairs_set1[where xs="?U"] have UpU: "set ?Up \<le> (set ?U \<times> set ?U)" by simp
4982   from \<Upsilon>_l[OF lq] have U_l: "\<forall> (t,n) \<in> set ?U. numbound0 t \<and> n > 0" .
4983   from U_l UpU
4984   have Up_: "\<forall> ((t,n),(s,m)) \<in> set ?Up. numbound0 t \<and> n> 0 \<and> numbound0 s \<and> m > 0" by auto
4985   hence Snb: "\<forall> (t,n) \<in> set ?S. numbound0 t \<and> n > 0 "
4986     by (auto simp add: mult_pos_pos)
4987   have Y_l: "\<forall> (t,n) \<in> set ?Y. numbound0 t \<and> n > 0"
4988   proof-
4989     { fix t n assume tnY: "(t,n) \<in> set ?Y"
4990       hence "(t,n) \<in> set ?SS" by simp
4991       hence "\<exists> (t',n') \<in> set ?S. simp_num_pair (t',n') = (t,n)"
4992         by (auto simp add: split_def simp del: map_map)
4993            (rule_tac x="((aa,ba),(ab,bb))" in bexI, simp_all)
4994       then obtain t' n' where tn'S: "(t',n') \<in> set ?S" and tns: "simp_num_pair (t',n') = (t,n)" by blast
4995       from tn'S Snb have tnb: "numbound0 t'" and np: "n' > 0" by auto
4996       from simp_num_pair_l[OF tnb np tns]
4997       have "numbound0 t \<and> n > 0" . }
4998     thus ?thesis by blast
4999   qed
5001   have YU: "(?f ` set ?Y) = (?h ` (set ?U \<times> set ?U))"
5002   proof-
5003      from simp_num_pair_ci[where bs="x#bs"] have
5004     "\<forall>x. (?f o simp_num_pair) x = ?f x" by auto
5005      hence th: "?f o simp_num_pair = ?f" using ext by blast
5006     have "(?f ` set ?Y) = ((?f o simp_num_pair) ` set ?S)" by (simp add: image_compose)
5007     also have "\<dots> = (?f ` set ?S)" by (simp add: th)
5008     also have "\<dots> = ((?f o ?g) ` set ?Up)"
5009       by (simp only: set_map o_def image_compose[symmetric])
5010     also have "\<dots> = (?h ` (set ?U \<times> set ?U))"
5011       using \<Upsilon>_cong_aux[OF U_l, where x="x" and bs="bs", simplified set_map image_compose[symmetric]] by blast
5012     finally show ?thesis .
5013   qed
5014   have "\<forall> (t,n) \<in> set ?Y. bound0 (\<upsilon> ?q (t,n))"
5015   proof-
5016     { fix t n assume tnY: "(t,n) \<in> set ?Y"
5017       with Y_l have tnb: "numbound0 t" and np: "real n > 0" by auto
5018       from \<upsilon>_I[OF lq np tnb]
5019     have "bound0 (\<upsilon> ?q (t,n))"  by simp}
5020     thus ?thesis by blast
5021   qed
5022   hence ep_nb: "bound0 ?ep"  using evaldjf_bound0[where xs="?Y" and f="\<upsilon> ?q"]
5023     by auto
5025   from fr_eq_01[OF qf, where bs="bs" and x="x"] have "?lhs = ?F ?q"
5026     by (simp only: split_def fst_conv snd_conv)
5027   also have "\<dots> = (\<exists> (t,n) \<in> set ?Y. ?I x (\<upsilon> ?q (t,n)))" using \<Upsilon>_cong[OF lq YU U_l Y_l]
5028     by (simp only: split_def fst_conv snd_conv)
5029   also have "\<dots> = (Ifm (x#bs) ?ep)"
5030     using evaldjf_ex[where ps="?Y" and bs = "x#bs" and f="\<upsilon> ?q",symmetric]
5031     by (simp only: split_def pair_collapse)
5032   also have "\<dots> = (Ifm bs (decr ?ep))" using decr[OF ep_nb] by blast
5033   finally have lr: "?lhs = ?rhs" by (simp only: ferrack01_def Let_def)
5034   from decr_qf[OF ep_nb] have "qfree (ferrack01 p)" by (simp only: Let_def ferrack01_def)
5035   with lr show ?thesis by blast
5036 qed
5038 lemma cp_thm':
5039   assumes lp: "iszlfm p (real (i::int)#bs)"
5040   and up: "d\<beta> p 1" and dd: "d\<delta> p d" and dp: "d > 0"
5041   shows "(\<exists> (x::int). Ifm (real x#bs) p) = ((\<exists> j\<in> {1 .. d}. Ifm (real j#bs) (minusinf p)) \<or> (\<exists> j\<in> {1.. d}. \<exists> b\<in> (Inum (real i#bs)) ` set (\<beta> p). Ifm ((b+real j)#bs) p))"
5042   using cp_thm[OF lp up dd dp] by auto
5044 definition unit :: "fm \<Rightarrow> fm \<times> num list \<times> int" where
5045   "unit p \<equiv> (let p' = zlfm p ; l = \<zeta> p' ; q = And (Dvd l (CN 0 1 (C 0))) (a\<beta> p' l); d = \<delta> q;
5046              B = remdups (map simpnum (\<beta> q)) ; a = remdups (map simpnum (\<alpha> q))
5047              in if length B \<le> length a then (q,B,d) else (mirror q, a,d))"
5049 lemma unit: assumes qf: "qfree p"
5050   shows "\<And> q B d. unit p = (q,B,d) \<Longrightarrow> ((\<exists> (x::int). Ifm (real x#bs) p) = (\<exists> (x::int). Ifm (real x#bs) q)) \<and> (Inum (real i#bs)) ` set B = (Inum (real i#bs)) ` set (\<beta> q) \<and> d\<beta> q 1 \<and> d\<delta> q d \<and> d >0 \<and> iszlfm q (real (i::int)#bs) \<and> (\<forall> b\<in> set B. numbound0 b)"
5051 proof-
5052   fix q B d
5053   assume qBd: "unit p = (q,B,d)"
5054   let ?thes = "((\<exists> (x::int). Ifm (real x#bs) p) = (\<exists> (x::int). Ifm (real x#bs) q)) \<and>
5055     Inum (real i#bs) ` set B = Inum (real i#bs) ` set (\<beta> q) \<and>
5056     d\<beta> q 1 \<and> d\<delta> q d \<and> 0 < d \<and> iszlfm q (real i # bs) \<and> (\<forall> b\<in> set B. numbound0 b)"
5057   let ?I = "\<lambda> (x::int) p. Ifm (real x#bs) p"
5058   let ?p' = "zlfm p"
5059   let ?l = "\<zeta> ?p'"
5060   let ?q = "And (Dvd ?l (CN 0 1 (C 0))) (a\<beta> ?p' ?l)"
5061   let ?d = "\<delta> ?q"
5062   let ?B = "set (\<beta> ?q)"
5063   let ?B'= "remdups (map simpnum (\<beta> ?q))"
5064   let ?A = "set (\<alpha> ?q)"
5065   let ?A'= "remdups (map simpnum (\<alpha> ?q))"
5066   from conjunct1[OF zlfm_I[OF qf, where bs="bs"]]
5067   have pp': "\<forall> i. ?I i ?p' = ?I i p" by auto
5068   from iszlfm_gen[OF conjunct2[OF zlfm_I[OF qf, where bs="bs" and i="i"]]]
5069   have lp': "\<forall> (i::int). iszlfm ?p' (real i#bs)" by simp
5070   hence lp'': "iszlfm ?p' (real (i::int)#bs)" by simp
5071   from lp' \<zeta>[where p="?p'" and bs="bs"] have lp: "?l >0" and dl: "d\<beta> ?p' ?l" by auto
5072   from a\<beta>_ex[where p="?p'" and l="?l" and bs="bs", OF lp'' dl lp] pp'
5073   have pq_ex:"(\<exists> (x::int). ?I x p) = (\<exists> x. ?I x ?q)" by (simp add: int_rdvd_iff)
5074   from lp'' lp a\<beta>[OF lp'' dl lp] have lq:"iszlfm ?q (real i#bs)" and uq: "d\<beta> ?q 1"
5075     by (auto simp add: isint_def)
5076   from \<delta>[OF lq] have dp:"?d >0" and dd: "d\<delta> ?q ?d" by blast+
5077   let ?N = "\<lambda> t. Inum (real (i::int)#bs) t"
5078   have "?N ` set ?B' = ((?N o simpnum) ` ?B)" by (simp add:image_compose)
5079   also have "\<dots> = ?N ` ?B" using simpnum_ci[where bs="real i #bs"] by auto
5080   finally have BB': "?N ` set ?B' = ?N ` ?B" .
5081   have "?N ` set ?A' = ((?N o simpnum) ` ?A)" by (simp add:image_compose)
5082   also have "\<dots> = ?N ` ?A" using simpnum_ci[where bs="real i #bs"] by auto
5083   finally have AA': "?N ` set ?A' = ?N ` ?A" .
5084   from \<beta>_numbound0[OF lq] have B_nb:"\<forall> b\<in> set ?B'. numbound0 b"
5086   from \<alpha>_l[OF lq] have A_nb: "\<forall> b\<in> set ?A'. numbound0 b"
5088     {assume "length ?B' \<le> length ?A'"
5089     hence q:"q=?q" and "B = ?B'" and d:"d = ?d"
5090       using qBd by (auto simp add: Let_def unit_def)
5091     with BB' B_nb have b: "?N ` (set B) = ?N ` set (\<beta> q)"
5092       and bn: "\<forall>b\<in> set B. numbound0 b" by simp+
5093   with pq_ex dp uq dd lq q d have ?thes by simp}
5094   moreover
5095   {assume "\<not> (length ?B' \<le> length ?A')"
5096     hence q:"q=mirror ?q" and "B = ?A'" and d:"d = ?d"
5097       using qBd by (auto simp add: Let_def unit_def)
5098     with AA' mirror\<alpha>\<beta>[OF lq] A_nb have b:"?N ` (set B) = ?N ` set (\<beta> q)"
5099       and bn: "\<forall>b\<in> set B. numbound0 b" by simp+
5100     from mirror_ex[OF lq] pq_ex q
5101     have pqm_eq:"(\<exists> (x::int). ?I x p) = (\<exists> (x::int). ?I x q)" by simp
5102     from lq uq q mirror_d\<beta> [where p="?q" and bs="bs" and a="real i"]
5103     have lq': "iszlfm q (real i#bs)" and uq: "d\<beta> q 1" by auto
5104     from \<delta>[OF lq'] mirror_\<delta>[OF lq] q d have dq:"d\<delta> q d " by auto
5105     from pqm_eq b bn uq lq' dp dq q dp d have ?thes by simp
5106   }
5107   ultimately show ?thes by blast
5108 qed
5109     (* Cooper's Algorithm *)
5111 definition cooper :: "fm \<Rightarrow> fm" where
5112   "cooper p \<equiv>
5113   (let (q,B,d) = unit p; js = [1..d];
5114        mq = simpfm (minusinf q);
5115        md = evaldjf (\<lambda> j. simpfm (subst0 (C j) mq)) js
5116    in if md = T then T else
5117     (let qd = evaldjf (\<lambda> t. simpfm (subst0 t q))
5118                                (remdups (map (\<lambda> (b,j). simpnum (Add b (C j)))
5119                                             [(b,j). b\<leftarrow>B,j\<leftarrow>js]))
5120      in decr (disj md qd)))"
5121 lemma cooper: assumes qf: "qfree p"
5122   shows "((\<exists> (x::int). Ifm (real x#bs) p) = (Ifm bs (cooper p))) \<and> qfree (cooper p)"
5123   (is "(?lhs = ?rhs) \<and> _")
5124 proof-
5126   let ?I = "\<lambda> (x::int) p. Ifm (real x#bs) p"
5127   let ?q = "fst (unit p)"
5128   let ?B = "fst (snd(unit p))"
5129   let ?d = "snd (snd (unit p))"
5130   let ?js = "[1..?d]"
5131   let ?mq = "minusinf ?q"
5132   let ?smq = "simpfm ?mq"
5133   let ?md = "evaldjf (\<lambda> j. simpfm (subst0 (C j) ?smq)) ?js"
5134   fix i
5135   let ?N = "\<lambda> t. Inum (real (i::int)#bs) t"
5136   let ?bjs = "[(b,j). b\<leftarrow>?B,j\<leftarrow>?js]"
5137   let ?sbjs = "map (\<lambda> (b,j). simpnum (Add b (C j))) ?bjs"
5138   let ?qd = "evaldjf (\<lambda> t. simpfm (subst0 t ?q)) (remdups ?sbjs)"
5139   have qbf:"unit p = (?q,?B,?d)" by simp
5140   from unit[OF qf qbf] have pq_ex: "(\<exists>(x::int). ?I x p) = (\<exists> (x::int). ?I x ?q)" and
5141     B:"?N ` set ?B = ?N ` set (\<beta> ?q)" and
5142     uq:"d\<beta> ?q 1" and dd: "d\<delta> ?q ?d" and dp: "?d > 0" and
5143     lq: "iszlfm ?q (real i#bs)" and
5144     Bn: "\<forall> b\<in> set ?B. numbound0 b" by auto
5145   from zlin_qfree[OF lq] have qfq: "qfree ?q" .
5146   from simpfm_qf[OF minusinf_qfree[OF qfq]] have qfmq: "qfree ?smq".
5147   have jsnb: "\<forall> j \<in> set ?js. numbound0 (C j)" by simp
5148   hence "\<forall> j\<in> set ?js. bound0 (subst0 (C j) ?smq)"
5149     by (auto simp only: subst0_bound0[OF qfmq])
5150   hence th: "\<forall> j\<in> set ?js. bound0 (simpfm (subst0 (C j) ?smq))"
5151     by (auto simp add: simpfm_bound0)
5152   from evaldjf_bound0[OF th] have mdb: "bound0 ?md" by simp
5153   from Bn jsnb have "\<forall> (b,j) \<in> set ?bjs. numbound0 (Add b (C j))"
5154     by simp
5155   hence "\<forall> (b,j) \<in> set ?bjs. numbound0 (simpnum (Add b (C j)))"
5156     using simpnum_numbound0 by blast
5157   hence "\<forall> t \<in> set ?sbjs. numbound0 t" by simp
5158   hence "\<forall> t \<in> set (remdups ?sbjs). bound0 (subst0 t ?q)"
5159     using subst0_bound0[OF qfq] by auto
5160   hence th': "\<forall> t \<in> set (remdups ?sbjs). bound0 (simpfm (subst0 t ?q))"
5161     using simpfm_bound0 by blast
5162   from evaldjf_bound0 [OF th'] have qdb: "bound0 ?qd" by simp
5163   from mdb qdb
5164   have mdqdb: "bound0 (disj ?md ?qd)" by (simp only: disj_def, cases "?md=T \<or> ?qd=T", simp_all)
5165   from trans [OF pq_ex cp_thm'[OF lq uq dd dp]] B
5166   have "?lhs = (\<exists> j\<in> {1.. ?d}. ?I j ?mq \<or> (\<exists> b\<in> ?N ` set ?B. Ifm ((b+ real j)#bs) ?q))" by auto
5167   also have "\<dots> = ((\<exists> j\<in> set ?js. ?I j ?smq) \<or> (\<exists> (b,j) \<in> (?N ` set ?B \<times> set ?js). Ifm ((b+ real j)#bs) ?q))" by auto
5168   also have "\<dots>= ((\<exists> j\<in> set ?js. ?I j ?smq) \<or> (\<exists> t \<in> (\<lambda> (b,j). ?N (Add b (C j))) ` set ?bjs. Ifm (t #bs) ?q))" by simp
5169   also have "\<dots>= ((\<exists> j\<in> set ?js. ?I j ?smq) \<or> (\<exists> t \<in> (\<lambda> (b,j). ?N (simpnum (Add b (C j)))) ` set ?bjs. Ifm (t #bs) ?q))" by (simp only: simpnum_ci)
5170   also  have "\<dots>= ((\<exists> j\<in> set ?js. ?I j ?smq) \<or> (\<exists> t \<in> set ?sbjs. Ifm (?N t #bs) ?q))"
5171     by (auto simp add: split_def)
5172   also have "\<dots> = ((\<exists> j\<in> set ?js. (\<lambda> j. ?I i (simpfm (subst0 (C j) ?smq))) j) \<or> (\<exists> t \<in> set (remdups ?sbjs). (\<lambda> t. ?I i (simpfm (subst0 t ?q))) t))" by (simp only: simpfm subst0_I[OF qfq] simpfm Inum.simps subst0_I[OF qfmq] set_remdups)
5173   also have "\<dots> = ((?I i (evaldjf (\<lambda> j. simpfm (subst0 (C j) ?smq)) ?js)) \<or> (?I i (evaldjf (\<lambda> t. simpfm (subst0 t ?q)) (remdups ?sbjs))))" by (simp only: evaldjf_ex)
5174   finally have mdqd: "?lhs = (?I i (disj ?md ?qd))" by (simp add: disj)
5175   hence mdqd2: "?lhs = (Ifm bs (decr (disj ?md ?qd)))" using decr [OF mdqdb] by simp
5176   {assume mdT: "?md = T"
5177     hence cT:"cooper p = T"
5178       by (simp only: cooper_def unit_def split_def Let_def if_True) simp
5179     from mdT mdqd have lhs:"?lhs" by (auto simp add: disj)
5180     from mdT have "?rhs" by (simp add: cooper_def unit_def split_def)
5181     with lhs cT have ?thesis by simp }
5182   moreover
5183   {assume mdT: "?md \<noteq> T" hence "cooper p = decr (disj ?md ?qd)"
5184       by (simp only: cooper_def unit_def split_def Let_def if_False)
5185     with mdqd2 decr_qf[OF mdqdb] have ?thesis by simp }
5186   ultimately show ?thesis by blast
5187 qed
5189 lemma DJcooper:
5190   assumes qf: "qfree p"
5191   shows "((\<exists> (x::int). Ifm (real x#bs) p) = (Ifm bs (DJ cooper p))) \<and> qfree (DJ cooper p)"
5192 proof-
5193   from cooper have cqf: "\<forall> p. qfree p \<longrightarrow> qfree (cooper p)" by  blast
5194   from DJ_qf[OF cqf] qf have thqf:"qfree (DJ cooper p)" by blast
5195   have "Ifm bs (DJ cooper p) = (\<exists> q\<in> set (disjuncts p). Ifm bs (cooper q))"
5196      by (simp add: DJ_def evaldjf_ex)
5197   also have "\<dots> = (\<exists> q \<in> set(disjuncts p). \<exists> (x::int). Ifm (real x#bs)  q)"
5198     using cooper disjuncts_qf[OF qf] by blast
5199   also have "\<dots> = (\<exists> (x::int). Ifm (real x#bs) p)" by (induct p rule: disjuncts.induct, auto)
5200   finally show ?thesis using thqf by blast
5201 qed
5203     (* Redy and Loveland *)
5205 lemma \<sigma>\<rho>_cong: assumes lp: "iszlfm p (a#bs)" and tt': "Inum (a#bs) t = Inum (a#bs) t'"
5206   shows "Ifm (a#bs) (\<sigma>\<rho> p (t,c)) = Ifm (a#bs) (\<sigma>\<rho> p (t',c))"
5207   using lp
5208   by (induct p rule: iszlfm.induct, auto simp add: tt')
5210 lemma \<sigma>_cong: assumes lp: "iszlfm p (a#bs)" and tt': "Inum (a#bs) t = Inum (a#bs) t'"
5211   shows "Ifm (a#bs) (\<sigma> p c t) = Ifm (a#bs) (\<sigma> p c t')"
5212   by (simp add: \<sigma>_def tt' \<sigma>\<rho>_cong[OF lp tt'])
5214 lemma \<rho>_cong: assumes lp: "iszlfm p (a#bs)"
5215   and RR: "(\<lambda>(b,k). (Inum (a#bs) b,k)) ` R =  (\<lambda>(b,k). (Inum (a#bs) b,k)) ` set (\<rho> p)"
5216   shows "(\<exists> (e,c) \<in> R. \<exists> j\<in> {1.. c*(\<delta> p)}. Ifm (a#bs) (\<sigma> p c (Add e (C j)))) = (\<exists> (e,c) \<in> set (\<rho> p). \<exists> j\<in> {1.. c*(\<delta> p)}. Ifm (a#bs) (\<sigma> p c (Add e (C j))))"
5217   (is "?lhs = ?rhs")
5218 proof
5219   let ?d = "\<delta> p"
5220   assume ?lhs then obtain e c j where ecR: "(e,c) \<in> R" and jD:"j \<in> {1 .. c*?d}"
5221     and px: "Ifm (a#bs) (\<sigma> p c (Add e (C j)))" (is "?sp c e j") by blast
5222   from ecR have "(Inum (a#bs) e,c) \<in> (\<lambda>(b,k). (Inum (a#bs) b,k)) ` R" by auto
5223   hence "(Inum (a#bs) e,c) \<in> (\<lambda>(b,k). (Inum (a#bs) b,k)) ` set (\<rho> p)" using RR by simp
5224   hence "\<exists> (e',c') \<in> set (\<rho> p). Inum (a#bs) e = Inum (a#bs) e' \<and> c = c'" by auto
5225   then obtain e' c' where ecRo:"(e',c') \<in> set (\<rho> p)" and ee':"Inum (a#bs) e = Inum (a#bs) e'"
5226     and cc':"c = c'" by blast
5227   from ee' have tt': "Inum (a#bs) (Add e (C j)) = Inum (a#bs) (Add e' (C j))" by simp
5229   from \<sigma>_cong[OF lp tt', where c="c"] px have px':"?sp c e' j" by simp
5230   from ecRo jD px' cc'  show ?rhs apply auto
5231     by (rule_tac x="(e', c')" in bexI,simp_all)
5232   (rule_tac x="j" in bexI, simp_all add: cc'[symmetric])
5233 next
5234   let ?d = "\<delta> p"
5235   assume ?rhs then obtain e c j where ecR: "(e,c) \<in> set (\<rho> p)" and jD:"j \<in> {1 .. c*?d}"
5236     and px: "Ifm (a#bs) (\<sigma> p c (Add e (C j)))" (is "?sp c e j") by blast
5237   from ecR have "(Inum (a#bs) e,c) \<in> (\<lambda>(b,k). (Inum (a#bs) b,k)) ` set (\<rho> p)" by auto
5238   hence "(Inum (a#bs) e,c) \<in> (\<lambda>(b,k). (Inum (a#bs) b,k)) ` R" using RR by simp
5239   hence "\<exists> (e',c') \<in> R. Inum (a#bs) e = Inum (a#bs) e' \<and> c = c'" by auto
5240   then obtain e' c' where ecRo:"(e',c') \<in> R" and ee':"Inum (a#bs) e = Inum (a#bs) e'"
5241     and cc':"c = c'" by blast
5242   from ee' have tt': "Inum (a#bs) (Add e (C j)) = Inum (a#bs) (Add e' (C j))" by simp
5243   from \<sigma>_cong[OF lp tt', where c="c"] px have px':"?sp c e' j" by simp
5244   from ecRo jD px' cc'  show ?lhs apply auto
5245     by (rule_tac x="(e', c')" in bexI,simp_all)
5246   (rule_tac x="j" in bexI, simp_all add: cc'[symmetric])
5247 qed
5249 lemma rl_thm':
5250   assumes lp: "iszlfm p (real (i::int)#bs)"
5251   and R: "(\<lambda>(b,k). (Inum (a#bs) b,k)) ` R =  (\<lambda>(b,k). (Inum (a#bs) b,k)) ` set (\<rho> p)"
5252   shows "(\<exists> (x::int). Ifm (real x#bs) p) = ((\<exists> j\<in> {1 .. \<delta> p}. Ifm (real j#bs) (minusinf p)) \<or> (\<exists> (e,c) \<in> R. \<exists> j\<in> {1.. c*(\<delta> p)}. Ifm (a#bs) (\<sigma> p c (Add e (C j)))))"
5253   using rl_thm[OF lp] \<rho>_cong[OF iszlfm_gen[OF lp, rule_format, where y="a"] R] by simp
5255 definition chooset :: "fm \<Rightarrow> fm \<times> ((num\<times>int) list) \<times> int" where
5256   "chooset p \<equiv> (let q = zlfm p ; d = \<delta> q;
5257              B = remdups (map (\<lambda> (t,k). (simpnum t,k)) (\<rho> q)) ;
5258              a = remdups (map (\<lambda> (t,k). (simpnum t,k)) (\<alpha>\<rho> q))
5259              in if length B \<le> length a then (q,B,d) else (mirror q, a,d))"
5261 lemma chooset: assumes qf: "qfree p"
5262   shows "\<And> q B d. chooset p = (q,B,d) \<Longrightarrow> ((\<exists> (x::int). Ifm (real x#bs) p) = (\<exists> (x::int). Ifm (real x#bs) q)) \<and> ((\<lambda>(t,k). (Inum (real i#bs) t,k)) ` set B = (\<lambda>(t,k). (Inum (real i#bs) t,k)) ` set (\<rho> q)) \<and> (\<delta> q = d) \<and> d >0 \<and> iszlfm q (real (i::int)#bs) \<and> (\<forall> (e,c)\<in> set B. numbound0 e \<and> c>0)"
5263 proof-
5264   fix q B d
5265   assume qBd: "chooset p = (q,B,d)"
5266   let ?thes = "((\<exists> (x::int). Ifm (real x#bs) p) = (\<exists> (x::int). Ifm (real x#bs) q)) \<and> ((\<lambda>(t,k). (Inum (real i#bs) t,k)) ` set B = (\<lambda>(t,k). (Inum (real i#bs) t,k)) ` set (\<rho> q)) \<and> (\<delta> q = d) \<and> d >0 \<and> iszlfm q (real (i::int)#bs) \<and> (\<forall> (e,c)\<in> set B. numbound0 e \<and> c>0)"
5267   let ?I = "\<lambda> (x::int) p. Ifm (real x#bs) p"
5268   let ?q = "zlfm p"
5269   let ?d = "\<delta> ?q"
5270   let ?B = "set (\<rho> ?q)"
5271   let ?f = "\<lambda> (t,k). (simpnum t,k)"
5272   let ?B'= "remdups (map ?f (\<rho> ?q))"
5273   let ?A = "set (\<alpha>\<rho> ?q)"
5274   let ?A'= "remdups (map ?f (\<alpha>\<rho> ?q))"
5275   from conjunct1[OF zlfm_I[OF qf, where bs="bs"]]
5276   have pp': "\<forall> i. ?I i ?q = ?I i p" by auto
5277   hence pq_ex:"(\<exists> (x::int). ?I x p) = (\<exists> x. ?I x ?q)" by simp
5278   from iszlfm_gen[OF conjunct2[OF zlfm_I[OF qf, where bs="bs" and i="i"]], rule_format, where y="real i"]
5279   have lq: "iszlfm ?q (real (i::int)#bs)" .
5280   from \<delta>[OF lq] have dp:"?d >0" by blast
5281   let ?N = "\<lambda> (t,c). (Inum (real (i::int)#bs) t,c)"
5282   have "?N ` set ?B' = ((?N o ?f) ` ?B)" by (simp add: split_def image_compose)
5283   also have "\<dots> = ?N ` ?B"
5284     by(simp add: split_def image_compose simpnum_ci[where bs="real i #bs"] image_def)
5285   finally have BB': "?N ` set ?B' = ?N ` ?B" .
5286   have "?N ` set ?A' = ((?N o ?f) ` ?A)" by (simp add: split_def image_compose)
5287   also have "\<dots> = ?N ` ?A" using simpnum_ci[where bs="real i #bs"]
5288     by(simp add: split_def image_compose simpnum_ci[where bs="real i #bs"] image_def)
5289   finally have AA': "?N ` set ?A' = ?N ` ?A" .
5290   from \<rho>_l[OF lq] have B_nb:"\<forall> (e,c)\<in> set ?B'. numbound0 e \<and> c > 0"
5291     by (simp add: simpnum_numbound0 split_def)
5292   from \<alpha>\<rho>_l[OF lq] have A_nb: "\<forall> (e,c)\<in> set ?A'. numbound0 e \<and> c > 0"
5293     by (simp add: simpnum_numbound0 split_def)
5294     {assume "length ?B' \<le> length ?A'"
5295     hence q:"q=?q" and "B = ?B'" and d:"d = ?d"
5296       using qBd by (auto simp add: Let_def chooset_def)
5297     with BB' B_nb have b: "?N ` (set B) = ?N ` set (\<rho> q)"
5298       and bn: "\<forall>(e,c)\<in> set B. numbound0 e \<and> c > 0" by auto
5299   with pq_ex dp lq q d have ?thes by simp}
5300   moreover
5301   {assume "\<not> (length ?B' \<le> length ?A')"
5302     hence q:"q=mirror ?q" and "B = ?A'" and d:"d = ?d"
5303       using qBd by (auto simp add: Let_def chooset_def)
5304     with AA' mirror_\<alpha>\<rho>[OF lq] A_nb have b:"?N ` (set B) = ?N ` set (\<rho> q)"
5305       and bn: "\<forall>(e,c)\<in> set B. numbound0 e \<and> c > 0" by auto
5306     from mirror_ex[OF lq] pq_ex q
5307     have pqm_eq:"(\<exists> (x::int). ?I x p) = (\<exists> (x::int). ?I x q)" by simp
5308     from lq q mirror_l [where p="?q" and bs="bs" and a="real i"]
5309     have lq': "iszlfm q (real i#bs)" by auto
5310     from mirror_\<delta>[OF lq] pqm_eq b bn lq' dp q dp d have ?thes by simp
5311   }
5312   ultimately show ?thes by blast
5313 qed
5315 definition stage :: "fm \<Rightarrow> int \<Rightarrow> (num \<times> int) \<Rightarrow> fm" where
5316   "stage p d \<equiv> (\<lambda> (e,c). evaldjf (\<lambda> j. simpfm (\<sigma> p c (Add e (C j)))) [1..c*d])"
5317 lemma stage:
5318   shows "Ifm bs (stage p d (e,c)) = (\<exists> j\<in>{1 .. c*d}. Ifm bs (\<sigma> p c (Add e (C j))))"
5319   by (unfold stage_def split_def ,simp only: evaldjf_ex simpfm) simp
5321 lemma stage_nb: assumes lp: "iszlfm p (a#bs)" and cp: "c >0" and nb:"numbound0 e"
5322   shows "bound0 (stage p d (e,c))"
5323 proof-
5324   let ?f = "\<lambda> j. simpfm (\<sigma> p c (Add e (C j)))"
5325   have th: "\<forall> j\<in> set [1..c*d]. bound0 (?f j)"
5326   proof
5327     fix j
5328     from nb have nb':"numbound0 (Add e (C j))" by simp
5329     from simpfm_bound0[OF \<sigma>_nb[OF lp nb', where k="c"]]
5330     show "bound0 (simpfm (\<sigma> p c (Add e (C j))))" .
5331   qed
5332   from evaldjf_bound0[OF th] show ?thesis by (unfold stage_def split_def) simp
5333 qed
5335 definition redlove :: "fm \<Rightarrow> fm" where
5336   "redlove p \<equiv>
5337   (let (q,B,d) = chooset p;
5338        mq = simpfm (minusinf q);
5339        md = evaldjf (\<lambda> j. simpfm (subst0 (C j) mq)) [1..d]
5340    in if md = T then T else
5341     (let qd = evaldjf (stage q d) B
5342      in decr (disj md qd)))"
5344 lemma redlove: assumes qf: "qfree p"
5345   shows "((\<exists> (x::int). Ifm (real x#bs) p) = (Ifm bs (redlove p))) \<and> qfree (redlove p)"
5346   (is "(?lhs = ?rhs) \<and> _")
5347 proof-
5349   let ?I = "\<lambda> (x::int) p. Ifm (real x#bs) p"
5350   let ?q = "fst (chooset p)"
5351   let ?B = "fst (snd(chooset p))"
5352   let ?d = "snd (snd (chooset p))"
5353   let ?js = "[1..?d]"
5354   let ?mq = "minusinf ?q"
5355   let ?smq = "simpfm ?mq"
5356   let ?md = "evaldjf (\<lambda> j. simpfm (subst0 (C j) ?smq)) ?js"
5357   fix i
5358   let ?N = "\<lambda> (t,k). (Inum (real (i::int)#bs) t,k)"
5359   let ?qd = "evaldjf (stage ?q ?d) ?B"
5360   have qbf:"chooset p = (?q,?B,?d)" by simp
5361   from chooset[OF qf qbf] have pq_ex: "(\<exists>(x::int). ?I x p) = (\<exists> (x::int). ?I x ?q)" and
5362     B:"?N ` set ?B = ?N ` set (\<rho> ?q)" and dd: "\<delta> ?q = ?d" and dp: "?d > 0" and
5363     lq: "iszlfm ?q (real i#bs)" and
5364     Bn: "\<forall> (e,c)\<in> set ?B. numbound0 e \<and> c > 0" by auto
5365   from zlin_qfree[OF lq] have qfq: "qfree ?q" .
5366   from simpfm_qf[OF minusinf_qfree[OF qfq]] have qfmq: "qfree ?smq".
5367   have jsnb: "\<forall> j \<in> set ?js. numbound0 (C j)" by simp
5368   hence "\<forall> j\<in> set ?js. bound0 (subst0 (C j) ?smq)"
5369     by (auto simp only: subst0_bound0[OF qfmq])
5370   hence th: "\<forall> j\<in> set ?js. bound0 (simpfm (subst0 (C j) ?smq))"
5371     by (auto simp add: simpfm_bound0)
5372   from evaldjf_bound0[OF th] have mdb: "bound0 ?md" by simp
5373   from Bn stage_nb[OF lq] have th:"\<forall> x \<in> set ?B. bound0 (stage ?q ?d x)" by auto
5374   from evaldjf_bound0[OF th]  have qdb: "bound0 ?qd" .
5375   from mdb qdb
5376   have mdqdb: "bound0 (disj ?md ?qd)" by (simp only: disj_def, cases "?md=T \<or> ?qd=T", simp_all)
5377   from trans [OF pq_ex rl_thm'[OF lq B]] dd
5378   have "?lhs = ((\<exists> j\<in> {1.. ?d}. ?I j ?mq) \<or> (\<exists> (e,c)\<in> set ?B. \<exists> j\<in> {1 .. c*?d}. Ifm (real i#bs) (\<sigma> ?q c (Add e (C j)))))" by auto
5379   also have "\<dots> = ((\<exists> j\<in> {1.. ?d}. ?I j ?smq) \<or> (\<exists> (e,c)\<in> set ?B. ?I i (stage ?q ?d (e,c) )))"
5380     by (simp add: simpfm stage split_def)
5381   also have "\<dots> = ((\<exists> j\<in> {1 .. ?d}. ?I i (subst0 (C j) ?smq))  \<or> ?I i ?qd)"
5382     by (simp add: evaldjf_ex subst0_I[OF qfmq])
5383   finally have mdqd:"?lhs = (?I i ?md \<or> ?I i ?qd)" by (simp only: evaldjf_ex set_upto simpfm)
5384   also have "\<dots> = (?I i (disj ?md ?qd))" by (simp add: disj)
5385   also have "\<dots> = (Ifm bs (decr (disj ?md ?qd)))" by (simp only: decr [OF mdqdb])
5386   finally have mdqd2: "?lhs = (Ifm bs (decr (disj ?md ?qd)))" .
5387   {assume mdT: "?md = T"
5388     hence cT:"redlove p = T" by (simp add: redlove_def Let_def chooset_def split_def)
5389     from mdT have lhs:"?lhs" using mdqd by simp
5390     from mdT have "?rhs" by (simp add: redlove_def chooset_def split_def)
5391     with lhs cT have ?thesis by simp }
5392   moreover
5393   {assume mdT: "?md \<noteq> T" hence "redlove p = decr (disj ?md ?qd)"
5394       by (simp add: redlove_def chooset_def split_def Let_def)
5395     with mdqd2 decr_qf[OF mdqdb] have ?thesis by simp }
5396   ultimately show ?thesis by blast
5397 qed
5399 lemma DJredlove:
5400   assumes qf: "qfree p"
5401   shows "((\<exists> (x::int). Ifm (real x#bs) p) = (Ifm bs (DJ redlove p))) \<and> qfree (DJ redlove p)"
5402 proof-
5403   from redlove have cqf: "\<forall> p. qfree p \<longrightarrow> qfree (redlove p)" by  blast
5404   from DJ_qf[OF cqf] qf have thqf:"qfree (DJ redlove p)" by blast
5405   have "Ifm bs (DJ redlove p) = (\<exists> q\<in> set (disjuncts p). Ifm bs (redlove q))"
5406      by (simp add: DJ_def evaldjf_ex)
5407   also have "\<dots> = (\<exists> q \<in> set(disjuncts p). \<exists> (x::int). Ifm (real x#bs)  q)"
5408     using redlove disjuncts_qf[OF qf] by blast
5409   also have "\<dots> = (\<exists> (x::int). Ifm (real x#bs) p)" by (induct p rule: disjuncts.induct, auto)
5410   finally show ?thesis using thqf by blast
5411 qed
5414 lemma exsplit_qf: assumes qf: "qfree p"
5415   shows "qfree (exsplit p)"
5416 using qf by (induct p rule: exsplit.induct, auto)
5418 definition mircfr :: "fm \<Rightarrow> fm" where
5419   "mircfr = DJ cooper o ferrack01 o simpfm o exsplit"
5421 definition mirlfr :: "fm \<Rightarrow> fm" where
5422   "mirlfr = DJ redlove o ferrack01 o simpfm o exsplit"
5424 lemma mircfr: "\<forall> bs p. qfree p \<longrightarrow> qfree (mircfr p) \<and> Ifm bs (mircfr p) = Ifm bs (E p)"
5425 proof(clarsimp simp del: Ifm.simps)
5426   fix bs p
5427   assume qf: "qfree p"
5428   show "qfree (mircfr p)\<and>(Ifm bs (mircfr p) = Ifm bs (E p))" (is "_ \<and> (?lhs = ?rhs)")
5429   proof-
5430     let ?es = "(And (And (Ge (CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) (simpfm (exsplit p)))"
5431     have "?rhs = (\<exists> (i::int). \<exists> x. Ifm (x#real i#bs) ?es)"
5432       using splitex[OF qf] by simp
5433     with ferrack01[OF simpfm_qf[OF exsplit_qf[OF qf]]] have th1: "?rhs = (\<exists> (i::int). Ifm (real i#bs) (ferrack01 (simpfm (exsplit p))))" and qf':"qfree (ferrack01 (simpfm (exsplit p)))" by simp+
5434     with DJcooper[OF qf'] show ?thesis by (simp add: mircfr_def)
5435   qed
5436 qed
5438 lemma mirlfr: "\<forall> bs p. qfree p \<longrightarrow> qfree(mirlfr p) \<and> Ifm bs (mirlfr p) = Ifm bs (E p)"
5439 proof(clarsimp simp del: Ifm.simps)
5440   fix bs p
5441   assume qf: "qfree p"
5442   show "qfree (mirlfr p)\<and>(Ifm bs (mirlfr p) = Ifm bs (E p))" (is "_ \<and> (?lhs = ?rhs)")
5443   proof-
5444     let ?es = "(And (And (Ge (CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) (simpfm (exsplit p)))"
5445     have "?rhs = (\<exists> (i::int). \<exists> x. Ifm (x#real i#bs) ?es)"
5446       using splitex[OF qf] by simp
5447     with ferrack01[OF simpfm_qf[OF exsplit_qf[OF qf]]] have th1: "?rhs = (\<exists> (i::int). Ifm (real i#bs) (ferrack01 (simpfm (exsplit p))))" and qf':"qfree (ferrack01 (simpfm (exsplit p)))" by simp+
5448     with DJredlove[OF qf'] show ?thesis by (simp add: mirlfr_def)
5449   qed
5450 qed
5452 definition mircfrqe:: "fm \<Rightarrow> fm" where
5453   "mircfrqe p = qelim (prep p) mircfr"
5455 definition mirlfrqe:: "fm \<Rightarrow> fm" where
5456   "mirlfrqe p = qelim (prep p) mirlfr"
5458 theorem mircfrqe: "(Ifm bs (mircfrqe p) = Ifm bs p) \<and> qfree (mircfrqe p)"
5459   using qelim_ci[OF mircfr] prep by (auto simp add: mircfrqe_def)
5461 theorem mirlfrqe: "(Ifm bs (mirlfrqe p) = Ifm bs p) \<and> qfree (mirlfrqe p)"
5462   using qelim_ci[OF mirlfr] prep by (auto simp add: mirlfrqe_def)
5464 definition
5465   "problem1 = A (And (Le (Sub (Floor (Bound 0)) (Bound 0))) (Le (Add (Bound 0) (Floor (Neg (Bound 0))))))"
5467 definition
5468   "problem2 = A (Iff (Eq (Add (Floor (Bound 0)) (Floor (Neg (Bound 0))))) (Eq (Sub (Floor (Bound 0)) (Bound 0))))"
5470 definition
5471   "problem3 = A (And (Le (Sub (Floor (Bound 0)) (Bound 0))) (Le (Add (Bound 0) (Floor (Neg (Bound 0))))))"
5473 definition
5474   "problem4 = E (And (Ge (Sub (Bound 1) (Bound 0))) (Eq (Add (Floor (Bound 1)) (Floor (Neg (Bound 0))))))"
5476 ML {* @{code mircfrqe} @{code problem1} *}
5477 ML {* @{code mirlfrqe} @{code problem1} *}
5478 ML {* @{code mircfrqe} @{code problem2} *}
5479 ML {* @{code mirlfrqe} @{code problem2} *}
5480 ML {* @{code mircfrqe} @{code problem3} *}
5481 ML {* @{code mirlfrqe} @{code problem3} *}
5482 ML {* @{code mircfrqe} @{code problem4} *}
5483 ML {* @{code mirlfrqe} @{code problem4} *}
5485 (*code_reflect Mir
5486   functions mircfrqe mirlfrqe
5487   file "mir.ML"*)
5489 oracle mirfr_oracle = {* fn (proofs, ct) =>
5490 let
5492 fun num_of_term vs (t as Free (xn, xT)) = (case AList.lookup (op =) vs t
5494       | SOME n => @{code Bound} n)
5495   | num_of_term vs @{term "real (0::int)"} = @{code C} 0
5496   | num_of_term vs @{term "real (1::int)"} = @{code C} 1
5497   | num_of_term vs @{term "0::real"} = @{code C} 0
5498   | num_of_term vs @{term "1::real"} = @{code C} 1
5499   | num_of_term vs (Bound i) = @{code Bound} i
5500   | num_of_term vs (@{term "uminus :: real \<Rightarrow> real"} \$ t') = @{code Neg} (num_of_term vs t')
5501   | num_of_term vs (@{term "op + :: real \<Rightarrow> real \<Rightarrow> real"} \$ t1 \$ t2) =
5502       @{code Add} (num_of_term vs t1, num_of_term vs t2)
5503   | num_of_term vs (@{term "op - :: real \<Rightarrow> real \<Rightarrow> real"} \$ t1 \$ t2) =
5504       @{code Sub} (num_of_term vs t1, num_of_term vs t2)
5505   | num_of_term vs (@{term "op * :: real \<Rightarrow> real \<Rightarrow> real"} \$ t1 \$ t2) =
5506       (case (num_of_term vs t1)
5507        of @{code C} i => @{code Mul} (i, num_of_term vs t2)
5508         | _ => error "num_of_term: unsupported Multiplication")
5509   | num_of_term vs (@{term "real :: int \<Rightarrow> real"} \$ (@{term "number_of :: int \<Rightarrow> int"} \$ t')) =
5510       @{code C} (HOLogic.dest_numeral t')
5511   | num_of_term vs (@{term "real :: int \<Rightarrow> real"} \$ (@{term "floor :: real \<Rightarrow> int"} \$ t')) =
5512       @{code Floor} (num_of_term vs t')
5513   | num_of_term vs (@{term "real :: int \<Rightarrow> real"} \$ (@{term "ceiling :: real \<Rightarrow> int"} \$ t')) =
5514       @{code Neg} (@{code Floor} (@{code Neg} (num_of_term vs t')))
5515   | num_of_term vs (@{term "number_of :: int \<Rightarrow> real"} \$ t') =
5516       @{code C} (HOLogic.dest_numeral t')
5517   | num_of_term vs t = error ("num_of_term: unknown term " ^ Syntax.string_of_term @{context} t);
5519 fun fm_of_term vs @{term True} = @{code T}
5520   | fm_of_term vs @{term False} = @{code F}
5521   | fm_of_term vs (@{term "op < :: real \<Rightarrow> real \<Rightarrow> bool"} \$ t1 \$ t2) =
5522       @{code Lt} (@{code Sub} (num_of_term vs t1, num_of_term vs t2))
5523   | fm_of_term vs (@{term "op \<le> :: real \<Rightarrow> real \<Rightarrow> bool"} \$ t1 \$ t2) =
5524       @{code Le} (@{code Sub} (num_of_term vs t1, num_of_term vs t2))
5525   | fm_of_term vs (@{term "op = :: real \<Rightarrow> real \<Rightarrow> bool"} \$ t1 \$ t2) =
5526       @{code Eq} (@{code Sub} (num_of_term vs t1, num_of_term vs t2))
5527   | fm_of_term vs (@{term "op rdvd"} \$ (@{term "real :: int \<Rightarrow> real"} \$ (@{term "number_of :: int \<Rightarrow> int"} \$ t1)) \$ t2) =
5528       @{code Dvd} (HOLogic.dest_numeral t1, num_of_term vs t2)
5529   | fm_of_term vs (@{term "op = :: bool \<Rightarrow> bool \<Rightarrow> bool"} \$ t1 \$ t2) =
5530       @{code Iff} (fm_of_term vs t1, fm_of_term vs t2)
5531   | fm_of_term vs (@{term HOL.conj} \$ t1 \$ t2) =
5532       @{code And} (fm_of_term vs t1, fm_of_term vs t2)
5533   | fm_of_term vs (@{term HOL.disj} \$ t1 \$ t2) =
5534       @{code Or} (fm_of_term vs t1, fm_of_term vs t2)
5535   | fm_of_term vs (@{term HOL.implies} \$ t1 \$ t2) =
5536       @{code Imp} (fm_of_term vs t1, fm_of_term vs t2)
5537   | fm_of_term vs (@{term "Not"} \$ t') =
5538       @{code NOT} (fm_of_term vs t')
5539   | fm_of_term vs (Const (@{const_name Ex}, _) \$ Abs (xn, xT, p)) =