src/HOL/Decision_Procs/MIR.thy
author blanchet
Thu Sep 11 18:54:36 2014 +0200 (2014-09-11)
changeset 58306 117ba6cbe414
parent 58259 52c35a59bbf5
child 58310 91ea607a34d8
permissions -rw-r--r--
renamed 'rep_datatype' to 'old_rep_datatype' (HOL)
     1 (*  Title:      HOL/Decision_Procs/MIR.thy
     2     Author:     Amine Chaieb
     3 *)
     4 
     5 theory MIR
     6 imports Complex_Main Dense_Linear_Order DP_Library
     7   "~~/src/HOL/Library/Code_Target_Numeral" "~~/src/HOL/Library/Old_Recdef"
     8 begin
     9 
    10 section {* Quantifier elimination for @{text "\<real> (0, 1, +, floor, <)"} *}
    11 
    12 declare real_of_int_floor_cancel [simp del]
    13 
    14 lemma myle:
    15   fixes a b :: "'a::{ordered_ab_group_add}"
    16   shows "(a \<le> b) = (0 \<le> b - a)"
    17   by (metis add_0_left add_le_cancel_right diff_add_cancel)
    18 
    19 lemma myless:
    20   fixes a b :: "'a::{ordered_ab_group_add}"
    21   shows "(a < b) = (0 < b - a)"
    22   by (metis le_iff_diff_le_0 less_le_not_le myle)
    23 
    24   (* Maybe should be added to the library \<dots> *)
    25 lemma floor_int_eq: "(real n\<le> x \<and> x < real (n+1)) = (floor x = n)"
    26 proof( auto)
    27   assume lb: "real n \<le> x"
    28     and ub: "x < real n + 1"
    29   have "real (floor x) \<le> x" by simp 
    30   hence "real (floor x) < real (n + 1) " using ub by arith
    31   hence "floor x < n+1" by simp
    32   moreover from lb have "n \<le> floor x" using floor_mono[where x="real n" and y="x"] 
    33     by simp ultimately show "floor x = n" by simp
    34 qed
    35 
    36 (* Periodicity of dvd *)
    37 lemma dvd_period:
    38   assumes advdd: "(a::int) dvd d"
    39   shows "(a dvd (x + t)) = (a dvd ((x+ c*d) + t))"
    40   using advdd  
    41 proof-
    42   { fix x k
    43     from inf_period(3)[OF advdd, rule_format, where x=x and k="-k"]  
    44     have " ((a::int) dvd (x + t)) = (a dvd (x+k*d + t))" by simp}
    45   hence "\<forall>x.\<forall>k. ((a::int) dvd (x + t)) = (a dvd (x+k*d + t))"  by simp
    46   then show ?thesis by simp
    47 qed
    48 
    49 (* The Divisibility relation between reals *)
    50 definition rdvd:: "real \<Rightarrow> real \<Rightarrow> bool" (infixl "rdvd" 50)
    51   where "x rdvd y \<longleftrightarrow> (\<exists>k\<Colon>int. y = x * real k)"
    52 
    53 lemma int_rdvd_real: 
    54   "real (i::int) rdvd x = (i dvd (floor x) \<and> real (floor x) = x)" (is "?l = ?r")
    55 proof
    56   assume "?l" 
    57   hence th: "\<exists> k. x=real (i*k)" by (simp add: rdvd_def)
    58   hence th': "real (floor x) = x" by (auto simp del: real_of_int_mult)
    59   with th have "\<exists> k. real (floor x) = real (i*k)" by simp
    60   hence "\<exists> k. floor x = i*k" by (simp only: real_of_int_inject)
    61   thus ?r  using th' by (simp add: dvd_def) 
    62 next
    63   assume "?r" hence "(i\<Colon>int) dvd \<lfloor>x\<Colon>real\<rfloor>" ..
    64   hence "\<exists> k. real (floor x) = real (i*k)" 
    65     by (simp only: real_of_int_inject) (simp add: dvd_def)
    66   thus ?l using `?r` by (simp add: rdvd_def)
    67 qed
    68 
    69 lemma int_rdvd_iff: "(real (i::int) rdvd real t) = (i dvd t)"
    70   by (auto simp add: rdvd_def dvd_def) (rule_tac x="k" in exI, simp only: real_of_int_mult[symmetric])
    71 
    72 
    73 lemma rdvd_abs1: "(abs (real d) rdvd t) = (real (d ::int) rdvd t)"
    74 proof
    75   assume d: "real d rdvd t"
    76   from d int_rdvd_real have d2: "d dvd (floor t)" and ti: "real (floor t) = t"
    77     by auto
    78 
    79   from iffD2[OF abs_dvd_iff] d2 have "(abs d) dvd (floor t)" by blast
    80   with ti int_rdvd_real[symmetric] have "real (abs d) rdvd t" by blast 
    81   thus "abs (real d) rdvd t" by simp
    82 next
    83   assume "abs (real d) rdvd t" hence "real (abs d) rdvd t" by simp
    84   with int_rdvd_real[where i="abs d" and x="t"] have d2: "abs d dvd floor t" and ti: "real (floor t) =t"
    85     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
    89 
    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
    95 
    96 lemma rdvd_left_0_eq: "(0 rdvd t) = (t=0)"
    97   by (auto simp add: rdvd_def)
    98 
    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)
   103 
   104   (*********************************************************************************)
   105   (****                            SHADOW SYNTAX AND SEMANTICS                  ****)
   106   (*********************************************************************************)
   107 
   108 datatype_new 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
   110 
   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"
   122 
   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"
   135 
   136 lemma isint_iff: "isint n bs = (real (floor (Inum bs n)) = Inum bs n)"
   137   by (simp add: isint_def)
   138 
   139 lemma isint_Floor: "isint (Floor n) bs"
   140   by (simp add: isint_iff)
   141 
   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
   152 
   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
   160   finally show "isint (Neg e) bs" by (simp add: isint_def th)
   161 qed
   162 
   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
   170   finally show "isint (Sub (C c) e) bs" by (simp add: isint_def th)
   171 qed
   172 
   173 lemma isint_add:
   174   assumes ai: "isint a bs" and bi: "isint b bs"
   175   shows "isint (Add a b) bs"
   176 proof-
   177   let ?a = "Inum bs a"
   178   let ?b = "Inum bs b"
   179   from ai bi isint_iff have "real (floor (?a + ?b)) = real (floor (real (floor ?a) + real (floor ?b)))"
   180     by simp
   181   also have "\<dots> = real (floor ?a) + real (floor ?b)" by simp
   182   also have "\<dots> = ?a + ?b" using ai bi isint_iff by simp
   183   finally show "isint (Add a b) bs" by (simp add: isint_iff)
   184 qed
   185 
   186 lemma isint_c: "isint (C j) bs"
   187   by (simp add: isint_iff)
   188 
   189 
   190     (* FORMULAE *)
   191 datatype_new fm  = 
   192   T| F| Lt num| Le num| Gt num| Ge num| Eq num| NEq num| Dvd int num| NDvd int num|
   193   NOT fm| And fm fm|  Or fm fm| Imp fm fm| Iff fm fm| E fm| A fm
   194 
   195 
   196   (* A size for fm *)
   197 fun fmsize :: "fm \<Rightarrow> nat" where
   198  "fmsize (NOT p) = 1 + fmsize p"
   199 | "fmsize (And p q) = 1 + fmsize p + fmsize q"
   200 | "fmsize (Or p q) = 1 + fmsize p + fmsize q"
   201 | "fmsize (Imp p q) = 3 + fmsize p + fmsize q"
   202 | "fmsize (Iff p q) = 3 + 2*(fmsize p + fmsize q)"
   203 | "fmsize (E p) = 1 + fmsize p"
   204 | "fmsize (A p) = 4+ fmsize p"
   205 | "fmsize (Dvd i t) = 2"
   206 | "fmsize (NDvd i t) = 2"
   207 | "fmsize p = 1"
   208   (* several lemmas about fmsize *)
   209 lemma fmsize_pos: "fmsize p > 0"
   210   by (induct p rule: fmsize.induct) simp_all
   211 
   212   (* Semantics of formulae (fm) *)
   213 primrec Ifm ::"real list \<Rightarrow> fm \<Rightarrow> bool" where
   214   "Ifm bs T = True"
   215 | "Ifm bs F = False"
   216 | "Ifm bs (Lt a) = (Inum bs a < 0)"
   217 | "Ifm bs (Gt a) = (Inum bs a > 0)"
   218 | "Ifm bs (Le a) = (Inum bs a \<le> 0)"
   219 | "Ifm bs (Ge a) = (Inum bs a \<ge> 0)"
   220 | "Ifm bs (Eq a) = (Inum bs a = 0)"
   221 | "Ifm bs (NEq a) = (Inum bs a \<noteq> 0)"
   222 | "Ifm bs (Dvd i b) = (real i rdvd Inum bs b)"
   223 | "Ifm bs (NDvd i b) = (\<not>(real i rdvd Inum bs b))"
   224 | "Ifm bs (NOT p) = (\<not> (Ifm bs p))"
   225 | "Ifm bs (And p q) = (Ifm bs p \<and> Ifm bs q)"
   226 | "Ifm bs (Or p q) = (Ifm bs p \<or> Ifm bs q)"
   227 | "Ifm bs (Imp p q) = ((Ifm bs p) \<longrightarrow> (Ifm bs q))"
   228 | "Ifm bs (Iff p q) = (Ifm bs p = Ifm bs q)"
   229 | "Ifm bs (E p) = (\<exists> x. Ifm (x#bs) p)"
   230 | "Ifm bs (A p) = (\<forall> x. Ifm (x#bs) p)"
   231 
   232 consts prep :: "fm \<Rightarrow> fm"
   233 recdef prep "measure fmsize"
   234   "prep (E T) = T"
   235   "prep (E F) = F"
   236   "prep (E (Or p q)) = Or (prep (E p)) (prep (E q))"
   237   "prep (E (Imp p q)) = Or (prep (E (NOT p))) (prep (E q))"
   238   "prep (E (Iff p q)) = Or (prep (E (And p q))) (prep (E (And (NOT p) (NOT q))))" 
   239   "prep (E (NOT (And p q))) = Or (prep (E (NOT p))) (prep (E(NOT q)))"
   240   "prep (E (NOT (Imp p q))) = prep (E (And p (NOT q)))"
   241   "prep (E (NOT (Iff p q))) = Or (prep (E (And p (NOT q)))) (prep (E(And (NOT p) q)))"
   242   "prep (E p) = E (prep p)"
   243   "prep (A (And p q)) = And (prep (A p)) (prep (A q))"
   244   "prep (A p) = prep (NOT (E (NOT p)))"
   245   "prep (NOT (NOT p)) = prep p"
   246   "prep (NOT (And p q)) = Or (prep (NOT p)) (prep (NOT q))"
   247   "prep (NOT (A p)) = prep (E (NOT p))"
   248   "prep (NOT (Or p q)) = And (prep (NOT p)) (prep (NOT q))"
   249   "prep (NOT (Imp p q)) = And (prep p) (prep (NOT q))"
   250   "prep (NOT (Iff p q)) = Or (prep (And p (NOT q))) (prep (And (NOT p) q))"
   251   "prep (NOT p) = NOT (prep p)"
   252   "prep (Or p q) = Or (prep p) (prep q)"
   253   "prep (And p q) = And (prep p) (prep q)"
   254   "prep (Imp p q) = prep (Or (NOT p) q)"
   255   "prep (Iff p q) = Or (prep (And p q)) (prep (And (NOT p) (NOT q)))"
   256   "prep p = p"
   257 (hints simp add: fmsize_pos)
   258 lemma prep: "\<And> bs. Ifm bs (prep p) = Ifm bs p"
   259   by (induct p rule: prep.induct) auto
   260 
   261 
   262   (* Quantifier freeness *)
   263 fun qfree:: "fm \<Rightarrow> bool" where
   264   "qfree (E p) = False"
   265   | "qfree (A p) = False"
   266   | "qfree (NOT p) = qfree p" 
   267   | "qfree (And p q) = (qfree p \<and> qfree q)" 
   268   | "qfree (Or  p q) = (qfree p \<and> qfree q)" 
   269   | "qfree (Imp p q) = (qfree p \<and> qfree q)" 
   270   | "qfree (Iff p q) = (qfree p \<and> qfree q)"
   271   | "qfree p = True"
   272 
   273   (* Boundedness and substitution *)
   274 primrec numbound0 :: "num \<Rightarrow> bool" (* a num is INDEPENDENT of Bound 0 *) where
   275   "numbound0 (C c) = True"
   276   | "numbound0 (Bound n) = (n>0)"
   277   | "numbound0 (CN n i a) = (n > 0 \<and> numbound0 a)"
   278   | "numbound0 (Neg a) = numbound0 a"
   279   | "numbound0 (Add a b) = (numbound0 a \<and> numbound0 b)"
   280   | "numbound0 (Sub a b) = (numbound0 a \<and> numbound0 b)" 
   281   | "numbound0 (Mul i a) = numbound0 a"
   282   | "numbound0 (Floor a) = numbound0 a"
   283   | "numbound0 (CF c a b) = (numbound0 a \<and> numbound0 b)" 
   284 
   285 lemma numbound0_I:
   286   assumes nb: "numbound0 a"
   287   shows "Inum (b#bs) a = Inum (b'#bs) a"
   288   using nb by (induct a) auto
   289 
   290 lemma numbound0_gen: 
   291   assumes nb: "numbound0 t" and ti: "isint t (x#bs)"
   292   shows "\<forall> y. isint t (y#bs)"
   293   using nb ti 
   294 proof(clarify)
   295   fix y
   296   from numbound0_I[OF nb, where bs="bs" and b="y" and b'="x"] ti[simplified isint_def]
   297   show "isint t (y#bs)"
   298     by (simp add: isint_def)
   299 qed
   300 
   301 primrec bound0:: "fm \<Rightarrow> bool" (* A Formula is independent of Bound 0 *) where
   302   "bound0 T = True"
   303   | "bound0 F = True"
   304   | "bound0 (Lt a) = numbound0 a"
   305   | "bound0 (Le a) = numbound0 a"
   306   | "bound0 (Gt a) = numbound0 a"
   307   | "bound0 (Ge a) = numbound0 a"
   308   | "bound0 (Eq a) = numbound0 a"
   309   | "bound0 (NEq a) = numbound0 a"
   310   | "bound0 (Dvd i a) = numbound0 a"
   311   | "bound0 (NDvd i a) = numbound0 a"
   312   | "bound0 (NOT p) = bound0 p"
   313   | "bound0 (And p q) = (bound0 p \<and> bound0 q)"
   314   | "bound0 (Or p q) = (bound0 p \<and> bound0 q)"
   315   | "bound0 (Imp p q) = ((bound0 p) \<and> (bound0 q))"
   316   | "bound0 (Iff p q) = (bound0 p \<and> bound0 q)"
   317   | "bound0 (E p) = False"
   318   | "bound0 (A p) = False"
   319 
   320 lemma bound0_I:
   321   assumes bp: "bound0 p"
   322   shows "Ifm (b#bs) p = Ifm (b'#bs) p"
   323   using bp numbound0_I [where b="b" and bs="bs" and b'="b'"]
   324   by (induct p) auto
   325 
   326 primrec numsubst0:: "num \<Rightarrow> num \<Rightarrow> num" (* substitute a num into a num for Bound 0 *) where
   327   "numsubst0 t (C c) = (C c)"
   328   | "numsubst0 t (Bound n) = (if n=0 then t else Bound n)"
   329   | "numsubst0 t (CN n i a) = (if n=0 then Add (Mul i t) (numsubst0 t a) else CN n i (numsubst0 t a))"
   330   | "numsubst0 t (CF i a b) = CF i (numsubst0 t a) (numsubst0 t b)"
   331   | "numsubst0 t (Neg a) = Neg (numsubst0 t a)"
   332   | "numsubst0 t (Add a b) = Add (numsubst0 t a) (numsubst0 t b)"
   333   | "numsubst0 t (Sub a b) = Sub (numsubst0 t a) (numsubst0 t b)" 
   334   | "numsubst0 t (Mul i a) = Mul i (numsubst0 t a)"
   335   | "numsubst0 t (Floor a) = Floor (numsubst0 t a)"
   336 
   337 lemma numsubst0_I:
   338   shows "Inum (b#bs) (numsubst0 a t) = Inum ((Inum (b#bs) a)#bs) t"
   339   by (induct t) simp_all
   340 
   341 primrec subst0:: "num \<Rightarrow> fm \<Rightarrow> fm" (* substitue a num into a formula for Bound 0 *) where
   342   "subst0 t T = T"
   343   | "subst0 t F = F"
   344   | "subst0 t (Lt a) = Lt (numsubst0 t a)"
   345   | "subst0 t (Le a) = Le (numsubst0 t a)"
   346   | "subst0 t (Gt a) = Gt (numsubst0 t a)"
   347   | "subst0 t (Ge a) = Ge (numsubst0 t a)"
   348   | "subst0 t (Eq a) = Eq (numsubst0 t a)"
   349   | "subst0 t (NEq a) = NEq (numsubst0 t a)"
   350   | "subst0 t (Dvd i a) = Dvd i (numsubst0 t a)"
   351   | "subst0 t (NDvd i a) = NDvd i (numsubst0 t a)"
   352   | "subst0 t (NOT p) = NOT (subst0 t p)"
   353   | "subst0 t (And p q) = And (subst0 t p) (subst0 t q)"
   354   | "subst0 t (Or p q) = Or (subst0 t p) (subst0 t q)"
   355   | "subst0 t (Imp p q) = Imp (subst0 t p) (subst0 t q)"
   356   | "subst0 t (Iff p q) = Iff (subst0 t p) (subst0 t q)"
   357 
   358 lemma subst0_I: assumes qfp: "qfree p"
   359   shows "Ifm (b#bs) (subst0 a p) = Ifm ((Inum (b#bs) a)#bs) p"
   360   using qfp numsubst0_I[where b="b" and bs="bs" and a="a"]
   361   by (induct p) simp_all
   362 
   363 fun decrnum:: "num \<Rightarrow> num" where
   364   "decrnum (Bound n) = Bound (n - 1)"
   365 | "decrnum (Neg a) = Neg (decrnum a)"
   366 | "decrnum (Add a b) = Add (decrnum a) (decrnum b)"
   367 | "decrnum (Sub a b) = Sub (decrnum a) (decrnum b)"
   368 | "decrnum (Mul c a) = Mul c (decrnum a)"
   369 | "decrnum (Floor a) = Floor (decrnum a)"
   370 | "decrnum (CN n c a) = CN (n - 1) c (decrnum a)"
   371 | "decrnum (CF c a b) = CF c (decrnum a) (decrnum b)"
   372 | "decrnum a = a"
   373 
   374 fun decr :: "fm \<Rightarrow> fm" where
   375   "decr (Lt a) = Lt (decrnum a)"
   376 | "decr (Le a) = Le (decrnum a)"
   377 | "decr (Gt a) = Gt (decrnum a)"
   378 | "decr (Ge a) = Ge (decrnum a)"
   379 | "decr (Eq a) = Eq (decrnum a)"
   380 | "decr (NEq a) = NEq (decrnum a)"
   381 | "decr (Dvd i a) = Dvd i (decrnum a)"
   382 | "decr (NDvd i a) = NDvd i (decrnum a)"
   383 | "decr (NOT p) = NOT (decr p)" 
   384 | "decr (And p q) = And (decr p) (decr q)"
   385 | "decr (Or p q) = Or (decr p) (decr q)"
   386 | "decr (Imp p q) = Imp (decr p) (decr q)"
   387 | "decr (Iff p q) = Iff (decr p) (decr q)"
   388 | "decr p = p"
   389 
   390 lemma decrnum: assumes nb: "numbound0 t"
   391   shows "Inum (x#bs) t = Inum bs (decrnum t)"
   392   using nb by (induct t rule: decrnum.induct) simp_all
   393 
   394 lemma decr: assumes nb: "bound0 p"
   395   shows "Ifm (x#bs) p = Ifm bs (decr p)"
   396   using nb by (induct p rule: decr.induct) (simp_all add: decrnum)
   397 
   398 lemma decr_qf: "bound0 p \<Longrightarrow> qfree (decr p)"
   399   by (induct p) simp_all
   400 
   401 fun isatom :: "fm \<Rightarrow> bool" (* test for atomicity *) where
   402   "isatom T = True"
   403 | "isatom F = True"
   404 | "isatom (Lt a) = True"
   405 | "isatom (Le a) = True"
   406 | "isatom (Gt a) = True"
   407 | "isatom (Ge a) = True"
   408 | "isatom (Eq a) = True"
   409 | "isatom (NEq a) = True"
   410 | "isatom (Dvd i b) = True"
   411 | "isatom (NDvd i b) = True"
   412 | "isatom p = False"
   413 
   414 lemma numsubst0_numbound0:
   415   assumes nb: "numbound0 t"
   416   shows "numbound0 (numsubst0 t a)"
   417   using nb by (induct a) auto
   418 
   419 lemma subst0_bound0:
   420   assumes qf: "qfree p" and nb: "numbound0 t"
   421   shows "bound0 (subst0 t p)"
   422   using qf numsubst0_numbound0[OF nb] by (induct p) auto
   423 
   424 lemma bound0_qf: "bound0 p \<Longrightarrow> qfree p"
   425   by (induct p) simp_all
   426 
   427 
   428 definition djf:: "('a \<Rightarrow> fm) \<Rightarrow> 'a \<Rightarrow> fm \<Rightarrow> fm" where
   429   "djf f p q = (if q=T then T else if q=F then f p else 
   430   (let fp = f p in case fp of T \<Rightarrow> T | F \<Rightarrow> q | _ \<Rightarrow> Or fp q))"
   431 
   432 definition evaldjf:: "('a \<Rightarrow> fm) \<Rightarrow> 'a list \<Rightarrow> fm" where
   433   "evaldjf f ps = foldr (djf f) ps F"
   434 
   435 lemma djf_Or: "Ifm bs (djf f p q) = Ifm bs (Or (f p) q)"
   436   by (cases "q=T", simp add: djf_def,cases "q=F",simp add: djf_def) 
   437   (cases "f p", simp_all add: Let_def djf_def) 
   438 
   439 lemma evaldjf_ex: "Ifm bs (evaldjf f ps) = (\<exists> p \<in> set ps. Ifm bs (f p))"
   440   by (induct ps) (simp_all add: evaldjf_def djf_Or)
   441 
   442 lemma evaldjf_bound0: 
   443   assumes nb: "\<forall> x\<in> set xs. bound0 (f x)"
   444   shows "bound0 (evaldjf f xs)"
   445   using nb
   446   apply (induct xs)
   447   apply (auto simp add: evaldjf_def djf_def Let_def)
   448   apply (case_tac "f a")
   449   apply auto
   450   done
   451 
   452 lemma evaldjf_qf: 
   453   assumes nb: "\<forall> x\<in> set xs. qfree (f x)"
   454   shows "qfree (evaldjf f xs)"
   455   using nb
   456   apply (induct xs)
   457   apply (auto simp add: evaldjf_def djf_def Let_def)
   458   apply (case_tac "f a")
   459   apply auto
   460   done
   461 
   462 fun disjuncts :: "fm \<Rightarrow> fm list" where
   463   "disjuncts (Or p q) = (disjuncts p) @ (disjuncts q)"
   464 | "disjuncts F = []"
   465 | "disjuncts p = [p]"
   466 
   467 fun conjuncts :: "fm \<Rightarrow> fm list" where
   468   "conjuncts (And p q) = (conjuncts p) @ (conjuncts q)"
   469 | "conjuncts T = []"
   470 | "conjuncts p = [p]"
   471 
   472 lemma conjuncts: "(\<forall> q\<in> set (conjuncts p). Ifm bs q) = Ifm bs p"
   473   by (induct p rule: conjuncts.induct) auto
   474 
   475 lemma disjuncts_qf: "qfree p \<Longrightarrow> \<forall> q\<in> set (disjuncts p). qfree q"
   476 proof -
   477   assume qf: "qfree p"
   478   hence "list_all qfree (disjuncts p)"
   479     by (induct p rule: disjuncts.induct, auto)
   480   thus ?thesis by (simp only: list_all_iff)
   481 qed
   482 
   483 lemma conjuncts_qf: "qfree p \<Longrightarrow> \<forall> q\<in> set (conjuncts p). qfree q"
   484 proof-
   485   assume qf: "qfree p"
   486   hence "list_all qfree (conjuncts p)"
   487     by (induct p rule: conjuncts.induct, auto)
   488   thus ?thesis by (simp only: list_all_iff)
   489 qed
   490 
   491 definition DJ :: "(fm \<Rightarrow> fm) \<Rightarrow> fm \<Rightarrow> fm" where
   492   "DJ f p \<equiv> evaldjf f (disjuncts p)"
   493 
   494 lemma DJ: assumes fdj: "\<forall> p q. f (Or p q) = Or (f p) (f q)"
   495   and fF: "f F = F"
   496   shows "Ifm bs (DJ f p) = Ifm bs (f p)"
   497 proof -
   498   have "Ifm bs (DJ f p) = (\<exists> q \<in> set (disjuncts p). Ifm bs (f q))"
   499     by (simp add: DJ_def evaldjf_ex) 
   500   also have "\<dots> = Ifm bs (f p)" using fdj fF by (induct p rule: disjuncts.induct, auto)
   501   finally show ?thesis .
   502 qed
   503 
   504 lemma DJ_qf: assumes 
   505   fqf: "\<forall> p. qfree p \<longrightarrow> qfree (f p)"
   506   shows "\<forall>p. qfree p \<longrightarrow> qfree (DJ f p) "
   507 proof(clarify)
   508   fix  p assume qf: "qfree p"
   509   have th: "DJ f p = evaldjf f (disjuncts p)" by (simp add: DJ_def)
   510   from disjuncts_qf[OF qf] have "\<forall> q\<in> set (disjuncts p). qfree q" .
   511   with fqf have th':"\<forall> q\<in> set (disjuncts p). qfree (f q)" by blast
   512   
   513   from evaldjf_qf[OF th'] th show "qfree (DJ f p)" by simp
   514 qed
   515 
   516 lemma DJ_qe: assumes qe: "\<forall> bs p. qfree p \<longrightarrow> qfree (qe p) \<and> (Ifm bs (qe p) = Ifm bs (E p))"
   517   shows "\<forall> bs p. qfree p \<longrightarrow> qfree (DJ qe p) \<and> (Ifm bs ((DJ qe p)) = Ifm bs (E p))"
   518 proof(clarify)
   519   fix p::fm and bs
   520   assume qf: "qfree p"
   521   from qe have qth: "\<forall> p. qfree p \<longrightarrow> qfree (qe p)" by blast
   522   from DJ_qf[OF qth] qf have qfth:"qfree (DJ qe p)" by auto
   523   have "Ifm bs (DJ qe p) = (\<exists> q\<in> set (disjuncts p). Ifm bs (qe q))"
   524     by (simp add: DJ_def evaldjf_ex)
   525   also have "\<dots> = (\<exists> q \<in> set(disjuncts p). Ifm bs (E q))" using qe disjuncts_qf[OF qf] by auto
   526   also have "\<dots> = Ifm bs (E p)" by (induct p rule: disjuncts.induct, auto)
   527   finally show "qfree (DJ qe p) \<and> Ifm bs (DJ qe p) = Ifm bs (E p)" using qfth by blast
   528 qed
   529   (* Simplification *)
   530 
   531   (* Algebraic simplifications for nums *)
   532 fun bnds:: "num \<Rightarrow> nat list" where
   533   "bnds (Bound n) = [n]"
   534 | "bnds (CN n c a) = n#(bnds a)"
   535 | "bnds (Neg a) = bnds a"
   536 | "bnds (Add a b) = (bnds a)@(bnds b)"
   537 | "bnds (Sub a b) = (bnds a)@(bnds b)"
   538 | "bnds (Mul i a) = bnds a"
   539 | "bnds (Floor a) = bnds a"
   540 | "bnds (CF c a b) = (bnds a)@(bnds b)"
   541 | "bnds a = []"
   542 fun lex_ns:: "nat list \<Rightarrow> nat list \<Rightarrow> bool" where
   543   "lex_ns [] ms = True"
   544 | "lex_ns ns [] = False"
   545 | "lex_ns (n#ns) (m#ms) = (n<m \<or> ((n = m) \<and> lex_ns ns ms)) "
   546 definition lex_bnd :: "num \<Rightarrow> num \<Rightarrow> bool" where
   547   "lex_bnd t s \<equiv> lex_ns (bnds t) (bnds s)"
   548 
   549 fun maxcoeff:: "num \<Rightarrow> int" where
   550   "maxcoeff (C i) = abs i"
   551 | "maxcoeff (CN n c t) = max (abs c) (maxcoeff t)"
   552 | "maxcoeff (CF c t s) = max (abs c) (maxcoeff s)"
   553 | "maxcoeff t = 1"
   554 
   555 lemma maxcoeff_pos: "maxcoeff t \<ge> 0"
   556   by (induct t rule: maxcoeff.induct) auto
   557 
   558 fun numgcdh:: "num \<Rightarrow> int \<Rightarrow> int" where
   559   "numgcdh (C i) = (\<lambda>g. gcd i g)"
   560 | "numgcdh (CN n c t) = (\<lambda>g. gcd c (numgcdh t g))"
   561 | "numgcdh (CF c s t) = (\<lambda>g. gcd c (numgcdh t g))"
   562 | "numgcdh t = (\<lambda>g. 1)"
   563 
   564 definition numgcd :: "num \<Rightarrow> int"
   565   where "numgcd t = numgcdh t (maxcoeff t)"
   566 
   567 fun reducecoeffh:: "num \<Rightarrow> int \<Rightarrow> num" where
   568   "reducecoeffh (C i) = (\<lambda> g. C (i div g))"
   569 | "reducecoeffh (CN n c t) = (\<lambda> g. CN n (c div g) (reducecoeffh t g))"
   570 | "reducecoeffh (CF c s t) = (\<lambda> g. CF (c div g)  s (reducecoeffh t g))"
   571 | "reducecoeffh t = (\<lambda>g. t)"
   572 
   573 definition reducecoeff :: "num \<Rightarrow> num"
   574 where
   575   "reducecoeff t =
   576     (let g = numgcd t in 
   577      if g = 0 then C 0 else if g=1 then t else reducecoeffh t g)"
   578 
   579 fun dvdnumcoeff:: "num \<Rightarrow> int \<Rightarrow> bool" where
   580   "dvdnumcoeff (C i) = (\<lambda> g. g dvd i)"
   581 | "dvdnumcoeff (CN n c t) = (\<lambda> g. g dvd c \<and> (dvdnumcoeff t g))"
   582 | "dvdnumcoeff (CF c s t) = (\<lambda> g. g dvd c \<and> (dvdnumcoeff t g))"
   583 | "dvdnumcoeff t = (\<lambda>g. False)"
   584 
   585 lemma dvdnumcoeff_trans: 
   586   assumes gdg: "g dvd g'" and dgt':"dvdnumcoeff t g'"
   587   shows "dvdnumcoeff t g"
   588   using dgt' gdg 
   589   by (induct t rule: dvdnumcoeff.induct) (simp_all add: gdg dvd_trans[OF gdg])
   590 
   591 declare dvd_trans [trans add]
   592 
   593 lemma numgcd0:
   594   assumes g0: "numgcd t = 0"
   595   shows "Inum bs t = 0"
   596 proof-
   597   have "\<And>x. numgcdh t x= 0 \<Longrightarrow> Inum bs t = 0"
   598     by (induct t rule: numgcdh.induct, auto)
   599   thus ?thesis using g0[simplified numgcd_def] by blast
   600 qed
   601 
   602 lemma numgcdh_pos: assumes gp: "g \<ge> 0" shows "numgcdh t g \<ge> 0"
   603   using gp by (induct t rule: numgcdh.induct) auto
   604 
   605 lemma numgcd_pos: "numgcd t \<ge>0"
   606   by (simp add: numgcd_def numgcdh_pos maxcoeff_pos)
   607 
   608 lemma reducecoeffh:
   609   assumes gt: "dvdnumcoeff t g" and gp: "g > 0" 
   610   shows "real g *(Inum bs (reducecoeffh t g)) = Inum bs t"
   611   using gt
   612 proof(induct t rule: reducecoeffh.induct) 
   613   case (1 i) hence gd: "g dvd i" by simp
   614   from assms 1 show ?case by (simp add: real_of_int_div[OF gd])
   615 next
   616   case (2 n c t)  hence gd: "g dvd c" by simp
   617   from assms 2 show ?case by (simp add: real_of_int_div[OF gd] algebra_simps)
   618 next
   619   case (3 c s t)  hence gd: "g dvd c" by simp
   620   from assms 3 show ?case by (simp add: real_of_int_div[OF gd] algebra_simps) 
   621 qed (auto simp add: numgcd_def gp)
   622 
   623 fun ismaxcoeff:: "num \<Rightarrow> int \<Rightarrow> bool" where
   624   "ismaxcoeff (C i) = (\<lambda> x. abs i \<le> x)"
   625 | "ismaxcoeff (CN n c t) = (\<lambda>x. abs c \<le> x \<and> (ismaxcoeff t x))"
   626 | "ismaxcoeff (CF c s t) = (\<lambda>x. abs c \<le> x \<and> (ismaxcoeff t x))"
   627 | "ismaxcoeff t = (\<lambda>x. True)"
   628 
   629 lemma ismaxcoeff_mono: "ismaxcoeff t c \<Longrightarrow> c \<le> c' \<Longrightarrow> ismaxcoeff t c'"
   630   by (induct t rule: ismaxcoeff.induct) auto
   631 
   632 lemma maxcoeff_ismaxcoeff: "ismaxcoeff t (maxcoeff t)"
   633 proof (induct t rule: maxcoeff.induct)
   634   case (2 n c t)
   635   hence H:"ismaxcoeff t (maxcoeff t)" .
   636   have thh: "maxcoeff t \<le> max (abs c) (maxcoeff t)" by simp
   637   from ismaxcoeff_mono[OF H thh] show ?case by simp
   638 next
   639   case (3 c t s) 
   640   hence H1:"ismaxcoeff s (maxcoeff s)" by auto
   641   have thh1: "maxcoeff s \<le> max \<bar>c\<bar> (maxcoeff s)" by (simp add: max_def)
   642   from ismaxcoeff_mono[OF H1 thh1] show ?case by simp
   643 qed simp_all
   644 
   645 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))"
   646   apply (unfold gcd_int_def)
   647   apply (cases "i = 0", simp_all)
   648   apply (cases "j = 0", simp_all)
   649   apply (cases "abs i = 1", simp_all)
   650   apply (cases "abs j = 1", simp_all)
   651   apply auto
   652   done
   653 
   654 lemma numgcdh0:"numgcdh t m = 0 \<Longrightarrow>  m =0"
   655   by (induct t rule: numgcdh.induct) auto
   656 
   657 lemma dvdnumcoeff_aux:
   658   assumes "ismaxcoeff t m" and mp:"m \<ge> 0" and "numgcdh t m > 1"
   659   shows "dvdnumcoeff t (numgcdh t m)"
   660 using assms
   661 proof(induct t rule: numgcdh.induct)
   662   case (2 n c t) 
   663   let ?g = "numgcdh t m"
   664   from 2 have th:"gcd c ?g > 1" by simp
   665   from zgcd_gt1[OF th] numgcdh_pos[OF mp, where t="t"]
   666   have "(abs c > 1 \<and> ?g > 1) \<or> (abs c = 0 \<and> ?g > 1) \<or> (abs c > 1 \<and> ?g = 0)" by simp
   667   moreover {assume "abs c > 1" and gp: "?g > 1" with 2
   668     have th: "dvdnumcoeff t ?g" by simp
   669     have th': "gcd c ?g dvd ?g" by simp
   670     from dvdnumcoeff_trans[OF th' th] have ?case by simp }
   671   moreover {assume "abs c = 0 \<and> ?g > 1"
   672     with 2 have th: "dvdnumcoeff t ?g" by simp
   673     have th': "gcd c ?g dvd ?g" by simp
   674     from dvdnumcoeff_trans[OF th' th] have ?case by simp
   675     hence ?case by simp }
   676   moreover {assume "abs c > 1" and g0:"?g = 0" 
   677     from numgcdh0[OF g0] have "m=0". with 2 g0 have ?case by simp }
   678   ultimately show ?case by blast
   679 next
   680   case (3 c s t) 
   681   let ?g = "numgcdh t m"
   682   from 3 have th:"gcd c ?g > 1" by simp
   683   from zgcd_gt1[OF th] numgcdh_pos[OF mp, where t="t"]
   684   have "(abs c > 1 \<and> ?g > 1) \<or> (abs c = 0 \<and> ?g > 1) \<or> (abs c > 1 \<and> ?g = 0)" by simp
   685   moreover {assume "abs c > 1" and gp: "?g > 1" with 3
   686     have th: "dvdnumcoeff t ?g" by simp
   687     have th': "gcd c ?g dvd ?g" by simp
   688     from dvdnumcoeff_trans[OF th' th] have ?case by simp }
   689   moreover {assume "abs c = 0 \<and> ?g > 1"
   690     with 3 have th: "dvdnumcoeff t ?g" by simp
   691     have th': "gcd c ?g dvd ?g" by simp
   692     from dvdnumcoeff_trans[OF th' th] have ?case by simp
   693     hence ?case by simp }
   694   moreover {assume "abs c > 1" and g0:"?g = 0" 
   695     from numgcdh0[OF g0] have "m=0". with 3 g0 have ?case by simp }
   696   ultimately show ?case by blast
   697 qed auto
   698 
   699 lemma dvdnumcoeff_aux2:
   700   assumes "numgcd t > 1" shows "dvdnumcoeff t (numgcd t) \<and> numgcd t > 0"
   701   using assms 
   702 proof (simp add: numgcd_def)
   703   let ?mc = "maxcoeff t"
   704   let ?g = "numgcdh t ?mc"
   705   have th1: "ismaxcoeff t ?mc" by (rule maxcoeff_ismaxcoeff)
   706   have th2: "?mc \<ge> 0" by (rule maxcoeff_pos)
   707   assume H: "numgcdh t ?mc > 1"
   708   from dvdnumcoeff_aux[OF th1 th2 H] show "dvdnumcoeff t ?g" .
   709 qed
   710 
   711 lemma reducecoeff: "real (numgcd t) * (Inum bs (reducecoeff t)) = Inum bs t"
   712 proof-
   713   let ?g = "numgcd t"
   714   have "?g \<ge> 0"  by (simp add: numgcd_pos)
   715   hence "?g = 0 \<or> ?g = 1 \<or> ?g > 1" by auto
   716   moreover {assume "?g = 0" hence ?thesis by (simp add: numgcd0)} 
   717   moreover {assume "?g = 1" hence ?thesis by (simp add: reducecoeff_def)} 
   718   moreover { assume g1:"?g > 1"
   719     from dvdnumcoeff_aux2[OF g1] have th1:"dvdnumcoeff t ?g" and g0: "?g > 0" by blast+
   720     from reducecoeffh[OF th1 g0, where bs="bs"] g1 have ?thesis 
   721       by (simp add: reducecoeff_def Let_def)} 
   722   ultimately show ?thesis by blast
   723 qed
   724 
   725 lemma reducecoeffh_numbound0: "numbound0 t \<Longrightarrow> numbound0 (reducecoeffh t g)"
   726   by (induct t rule: reducecoeffh.induct) auto
   727 
   728 lemma reducecoeff_numbound0: "numbound0 t \<Longrightarrow> numbound0 (reducecoeff t)"
   729   using reducecoeffh_numbound0 by (simp add: reducecoeff_def Let_def)
   730 
   731 consts numadd:: "num \<times> num \<Rightarrow> num"
   732 recdef numadd "measure (\<lambda> (t,s). size t + size s)"
   733   "numadd (CN n1 c1 r1,CN n2 c2 r2) =
   734   (if n1=n2 then 
   735   (let c = c1 + c2
   736   in (if c=0 then numadd(r1,r2) else CN n1 c (numadd (r1,r2))))
   737   else if n1 \<le> n2 then CN n1 c1 (numadd (r1,CN n2 c2 r2))
   738   else (CN n2 c2 (numadd (CN n1 c1 r1,r2))))"
   739   "numadd (CN n1 c1 r1,t) = CN n1 c1 (numadd (r1, t))"  
   740   "numadd (t,CN n2 c2 r2) = CN n2 c2 (numadd (t,r2))" 
   741   "numadd (CF c1 t1 r1,CF c2 t2 r2) = 
   742    (if t1 = t2 then 
   743     (let c=c1+c2; s= numadd(r1,r2) in (if c=0 then s else CF c t1 s))
   744    else if lex_bnd t1 t2 then CF c1 t1 (numadd(r1,CF c2 t2 r2))
   745    else CF c2 t2 (numadd(CF c1 t1 r1,r2)))"
   746   "numadd (CF c1 t1 r1,C c) = CF c1 t1 (numadd (r1, C c))"
   747   "numadd (C c,CF c1 t1 r1) = CF c1 t1 (numadd (r1, C c))"
   748   "numadd (C b1, C b2) = C (b1+b2)"
   749   "numadd (a,b) = Add a b"
   750 
   751 lemma numadd[simp]: "Inum bs (numadd (t,s)) = Inum bs (Add t s)"
   752 apply (induct t s rule: numadd.induct, simp_all add: Let_def)
   753  apply (case_tac "c1+c2 = 0",case_tac "n1 \<le> n2", simp_all)
   754   apply (case_tac "n1 = n2", simp_all add: algebra_simps)
   755   apply (simp only: distrib_right[symmetric])
   756  apply simp
   757 apply (case_tac "lex_bnd t1 t2", simp_all)
   758  apply (case_tac "c1+c2 = 0")
   759   apply (case_tac "t1 = t2")
   760    apply (simp_all add: algebra_simps distrib_right[symmetric] real_of_int_mult[symmetric] real_of_int_add[symmetric]del: real_of_int_mult real_of_int_add distrib_right)
   761   done
   762 
   763 lemma numadd_nb[simp]: "\<lbrakk> numbound0 t ; numbound0 s\<rbrakk> \<Longrightarrow> numbound0 (numadd (t,s))"
   764   by (induct t s rule: numadd.induct) (auto simp add: Let_def)
   765 
   766 fun nummul:: "num \<Rightarrow> int \<Rightarrow> num" where
   767   "nummul (C j) = (\<lambda> i. C (i*j))"
   768 | "nummul (CN n c t) = (\<lambda> i. CN n (c*i) (nummul t i))"
   769 | "nummul (CF c t s) = (\<lambda> i. CF (c*i) t (nummul s i))"
   770 | "nummul (Mul c t) = (\<lambda> i. nummul t (i*c))"
   771 | "nummul t = (\<lambda> i. Mul i t)"
   772 
   773 lemma nummul[simp]: "\<And> i. Inum bs (nummul t i) = Inum bs (Mul i t)"
   774   by (induct t rule: nummul.induct) (auto simp add: algebra_simps)
   775 
   776 lemma nummul_nb[simp]: "\<And> i. numbound0 t \<Longrightarrow> numbound0 (nummul t i)"
   777   by (induct t rule: nummul.induct) auto
   778 
   779 definition numneg :: "num \<Rightarrow> num"
   780   where "numneg t \<equiv> nummul t (- 1)"
   781 
   782 definition numsub :: "num \<Rightarrow> num \<Rightarrow> num"
   783   where "numsub s t \<equiv> (if s = t then C 0 else numadd (s,numneg t))"
   784 
   785 lemma numneg[simp]: "Inum bs (numneg t) = Inum bs (Neg t)"
   786   using numneg_def nummul by simp
   787 
   788 lemma numneg_nb[simp]: "numbound0 t \<Longrightarrow> numbound0 (numneg t)"
   789   using numneg_def by simp
   790 
   791 lemma numsub[simp]: "Inum bs (numsub a b) = Inum bs (Sub a b)"
   792   using numsub_def by simp
   793 
   794 lemma numsub_nb[simp]: "\<lbrakk> numbound0 t ; numbound0 s\<rbrakk> \<Longrightarrow> numbound0 (numsub t s)"
   795   using numsub_def by simp
   796 
   797 lemma isint_CF: assumes si: "isint s bs" shows "isint (CF c t s) bs"
   798 proof-
   799   have cti: "isint (Mul c (Floor t)) bs" by (simp add: isint_Mul isint_Floor)
   800   
   801   have "?thesis = isint (Add (Mul c (Floor t)) s) bs" by (simp add: isint_def)
   802   also have "\<dots>" by (simp add: isint_add cti si)
   803   finally show ?thesis .
   804 qed
   805 
   806 fun split_int:: "num \<Rightarrow> num \<times> num" where
   807   "split_int (C c) = (C 0, C c)"
   808 | "split_int (CN n c b) = 
   809      (let (bv,bi) = split_int b 
   810        in (CN n c bv, bi))"
   811 | "split_int (CF c a b) = 
   812      (let (bv,bi) = split_int b 
   813        in (bv, CF c a bi))"
   814 | "split_int a = (a,C 0)"
   815 
   816 lemma split_int: "\<And>tv ti. split_int t = (tv,ti) \<Longrightarrow> (Inum bs (Add tv ti) = Inum bs t) \<and> isint ti bs"
   817 proof (induct t rule: split_int.induct)
   818   case (2 c n b tv ti)
   819   let ?bv = "fst (split_int b)"
   820   let ?bi = "snd (split_int b)"
   821   have "split_int b = (?bv,?bi)" by simp
   822   with 2(1) have b:"Inum bs (Add ?bv ?bi) = Inum bs b" and bii: "isint ?bi bs" by blast+
   823   from 2(2) have tibi: "ti = ?bi" by (simp add: Let_def split_def)
   824   from 2(2) b[symmetric] bii show ?case by (auto simp add: Let_def split_def)
   825 next
   826   case (3 c a b tv ti) 
   827   let ?bv = "fst (split_int b)"
   828   let ?bi = "snd (split_int b)"
   829   have "split_int b = (?bv,?bi)" by simp
   830   with 3(1) have b:"Inum bs (Add ?bv ?bi) = Inum bs b" and bii: "isint ?bi bs" by blast+
   831   from 3(2) have tibi: "ti = CF c a ?bi"
   832     by (simp add: Let_def split_def)
   833   from 3(2) b[symmetric] bii show ?case
   834     by (auto simp add: Let_def split_def isint_Floor isint_add isint_Mul isint_CF)
   835 qed (auto simp add: Let_def isint_iff isint_Floor isint_add isint_Mul split_def algebra_simps)
   836 
   837 lemma split_int_nb: "numbound0 t \<Longrightarrow> numbound0 (fst (split_int t)) \<and> numbound0 (snd (split_int t)) "
   838   by (induct t rule: split_int.induct) (auto simp add: Let_def split_def)
   839 
   840 definition numfloor:: "num \<Rightarrow> num"
   841 where
   842   "numfloor t = (let (tv,ti) = split_int t in 
   843   (case tv of C i \<Rightarrow> numadd (tv,ti) 
   844   | _ \<Rightarrow> numadd(CF 1 tv (C 0),ti)))"
   845 
   846 lemma numfloor[simp]: "Inum bs (numfloor t) = Inum bs (Floor t)" (is "?n t = ?N (Floor t)")
   847 proof-
   848   let ?tv = "fst (split_int t)"
   849   let ?ti = "snd (split_int t)"
   850   have tvti:"split_int t = (?tv,?ti)" by simp
   851   {assume H: "\<forall> v. ?tv \<noteq> C v"
   852     hence th1: "?n t = ?N (Add (Floor ?tv) ?ti)" 
   853       by (cases ?tv) (auto simp add: numfloor_def Let_def split_def)
   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 using th1 by simp}
   860   moreover {fix v assume H:"?tv = C v" 
   861     from split_int[OF tvti] have "?N (Floor t) = ?N (Floor(Add ?tv ?ti))" and tii:"isint ?ti bs" by simp+
   862     hence "?N (Floor t) = real (floor (?N (Add ?tv ?ti)))" by simp 
   863     also have "\<dots> = real (floor (?N ?tv) + (floor (?N ?ti)))"
   864       by (simp,subst tii[simplified isint_iff, symmetric]) simp
   865     also have "\<dots> = ?N (Add (Floor ?tv) ?ti)" by (simp add: tii[simplified isint_iff])
   866     finally have ?thesis by (simp add: H numfloor_def Let_def split_def) }
   867   ultimately show ?thesis by auto
   868 qed
   869 
   870 lemma numfloor_nb[simp]: "numbound0 t \<Longrightarrow> numbound0 (numfloor t)"
   871   using split_int_nb[where t="t"]
   872   by (cases "fst (split_int t)") (auto simp add: numfloor_def Let_def split_def)
   873 
   874 function simpnum:: "num \<Rightarrow> num" where
   875   "simpnum (C j) = C j"
   876 | "simpnum (Bound n) = CN n 1 (C 0)"
   877 | "simpnum (Neg t) = numneg (simpnum t)"
   878 | "simpnum (Add t s) = numadd (simpnum t,simpnum s)"
   879 | "simpnum (Sub t s) = numsub (simpnum t) (simpnum s)"
   880 | "simpnum (Mul i t) = (if i = 0 then (C 0) else nummul (simpnum t) i)"
   881 | "simpnum (Floor t) = numfloor (simpnum t)"
   882 | "simpnum (CN n c t) = (if c=0 then simpnum t else CN n c (simpnum t))"
   883 | "simpnum (CF c t s) = simpnum(Add (Mul c (Floor t)) s)"
   884 by pat_completeness auto
   885 termination by (relation "measure num_size") auto
   886 
   887 lemma simpnum_ci[simp]: "Inum bs (simpnum t) = Inum bs t"
   888   by (induct t rule: simpnum.induct) auto
   889 
   890 lemma simpnum_numbound0[simp]: "numbound0 t \<Longrightarrow> numbound0 (simpnum t)"
   891   by (induct t rule: simpnum.induct) auto
   892 
   893 fun nozerocoeff:: "num \<Rightarrow> bool" where
   894   "nozerocoeff (C c) = True"
   895 | "nozerocoeff (CN n c t) = (c\<noteq>0 \<and> nozerocoeff t)"
   896 | "nozerocoeff (CF c s t) = (c \<noteq> 0 \<and> nozerocoeff t)"
   897 | "nozerocoeff (Mul c t) = (c\<noteq>0 \<and> nozerocoeff t)"
   898 | "nozerocoeff t = True"
   899 
   900 lemma numadd_nz : "nozerocoeff a \<Longrightarrow> nozerocoeff b \<Longrightarrow> nozerocoeff (numadd (a,b))"
   901   by (induct a b rule: numadd.induct) (auto simp add: Let_def)
   902 
   903 lemma nummul_nz : "\<And> i. i\<noteq>0 \<Longrightarrow> nozerocoeff a \<Longrightarrow> nozerocoeff (nummul a i)"
   904   by (induct a rule: nummul.induct) (auto simp add: Let_def numadd_nz)
   905 
   906 lemma numneg_nz : "nozerocoeff a \<Longrightarrow> nozerocoeff (numneg a)"
   907   by (simp add: numneg_def nummul_nz)
   908 
   909 lemma numsub_nz: "nozerocoeff a \<Longrightarrow> nozerocoeff b \<Longrightarrow> nozerocoeff (numsub a b)"
   910   by (simp add: numsub_def numneg_nz numadd_nz)
   911 
   912 lemma split_int_nz: "nozerocoeff t \<Longrightarrow> nozerocoeff (fst (split_int t)) \<and> nozerocoeff (snd (split_int t))"
   913   by (induct t rule: split_int.induct) (auto simp add: Let_def split_def)
   914 
   915 lemma numfloor_nz: "nozerocoeff t \<Longrightarrow> nozerocoeff (numfloor t)"
   916   by (simp add: numfloor_def Let_def split_def)
   917     (cases "fst (split_int t)", simp_all add: split_int_nz numadd_nz)
   918 
   919 lemma simpnum_nz: "nozerocoeff (simpnum t)"
   920   by (induct t rule: simpnum.induct)
   921     (auto simp add: numadd_nz numneg_nz numsub_nz nummul_nz numfloor_nz)
   922 
   923 lemma maxcoeff_nz: "nozerocoeff t \<Longrightarrow> maxcoeff t = 0 \<Longrightarrow> t = C 0"
   924 proof (induct t rule: maxcoeff.induct)
   925   case (2 n c t)
   926   hence cnz: "c \<noteq>0" and mx: "max (abs c) (maxcoeff t) = 0" by simp+
   927   have "max (abs c) (maxcoeff t) \<ge> abs c" by simp
   928   with cnz have "max (abs c) (maxcoeff t) > 0" by arith
   929   with 2 show ?case by simp
   930 next
   931   case (3 c s t) 
   932   hence cnz: "c \<noteq>0" and mx: "max (abs c) (maxcoeff t) = 0" by simp+
   933   have "max (abs c) (maxcoeff t) \<ge> abs c" by simp
   934   with cnz have "max (abs c) (maxcoeff t) > 0" by arith
   935   with 3 show ?case by simp
   936 qed auto
   937 
   938 lemma numgcd_nz: assumes nz: "nozerocoeff t" and g0: "numgcd t = 0" shows "t = C 0"
   939 proof-
   940   from g0 have th:"numgcdh t (maxcoeff t) = 0" by (simp add: numgcd_def)
   941   from numgcdh0[OF th]  have th:"maxcoeff t = 0" .
   942   from maxcoeff_nz[OF nz th] show ?thesis .
   943 qed
   944 
   945 definition simp_num_pair :: "(num \<times> int) \<Rightarrow> num \<times> int" where
   946   "simp_num_pair \<equiv> (\<lambda> (t,n). (if n = 0 then (C 0, 0) else
   947    (let t' = simpnum t ; g = numgcd t' in 
   948       if g > 1 then (let g' = gcd n g in 
   949         if g' = 1 then (t',n) 
   950         else (reducecoeffh t' g', n div g')) 
   951       else (t',n))))"
   952 
   953 lemma simp_num_pair_ci:
   954   shows "((\<lambda> (t,n). Inum bs t / real n) (simp_num_pair (t,n))) = ((\<lambda> (t,n). Inum bs t / real n) (t,n))"
   955   (is "?lhs = ?rhs")
   956 proof-
   957   let ?t' = "simpnum t"
   958   let ?g = "numgcd ?t'"
   959   let ?g' = "gcd n ?g"
   960   {assume nz: "n = 0" hence ?thesis by (simp add: Let_def simp_num_pair_def)}
   961   moreover
   962   { assume nnz: "n \<noteq> 0"
   963     {assume "\<not> ?g > 1" hence ?thesis by (simp add: Let_def simp_num_pair_def)}
   964     moreover
   965     {assume g1:"?g>1" hence g0: "?g > 0" by simp
   966       from g1 nnz have gp0: "?g' \<noteq> 0" by simp
   967       hence g'p: "?g' > 0" using gcd_ge_0_int[where x="n" and y="numgcd ?t'"] by arith
   968       hence "?g'= 1 \<or> ?g' > 1" by arith
   969       moreover {assume "?g'=1" hence ?thesis by (simp add: Let_def simp_num_pair_def)}
   970       moreover {assume g'1:"?g'>1"
   971         from dvdnumcoeff_aux2[OF g1] have th1:"dvdnumcoeff ?t' ?g" ..
   972         let ?tt = "reducecoeffh ?t' ?g'"
   973         let ?t = "Inum bs ?tt"
   974         have gpdg: "?g' dvd ?g" by simp
   975         have gpdd: "?g' dvd n" by simp
   976         have gpdgp: "?g' dvd ?g'" by simp
   977         from reducecoeffh[OF dvdnumcoeff_trans[OF gpdg th1] g'p] 
   978         have th2:"real ?g' * ?t = Inum bs ?t'" by simp
   979         from nnz g1 g'1 have "?lhs = ?t / real (n div ?g')" by (simp add: simp_num_pair_def Let_def)
   980         also have "\<dots> = (real ?g' * ?t) / (real ?g' * (real (n div ?g')))" by simp
   981         also have "\<dots> = (Inum bs ?t' / real n)"
   982           using real_of_int_div[OF gpdd] th2 gp0 by simp
   983         finally have "?lhs = Inum bs t / real n" by simp
   984         then have ?thesis using nnz g1 g'1 by (simp add: simp_num_pair_def) }
   985       ultimately have ?thesis by blast }
   986     ultimately have ?thesis by blast }
   987   ultimately show ?thesis by blast
   988 qed
   989 
   990 lemma simp_num_pair_l:
   991   assumes tnb: "numbound0 t" and np: "n >0" and tn: "simp_num_pair (t,n) = (t',n')"
   992   shows "numbound0 t' \<and> n' >0"
   993 proof-
   994   let ?t' = "simpnum t"
   995   let ?g = "numgcd ?t'"
   996   let ?g' = "gcd n ?g"
   997   { assume nz: "n = 0" hence ?thesis using assms by (simp add: Let_def simp_num_pair_def) }
   998   moreover
   999   { assume nnz: "n \<noteq> 0"
  1000     {assume "\<not> ?g > 1" hence ?thesis using assms by (auto simp add: Let_def simp_num_pair_def) }
  1001     moreover
  1002     {assume g1:"?g>1" hence g0: "?g > 0" by simp
  1003       from g1 nnz have gp0: "?g' \<noteq> 0" by simp
  1004       hence g'p: "?g' > 0" using gcd_ge_0_int[where x="n" and y="numgcd ?t'"] by arith
  1005       hence "?g'= 1 \<or> ?g' > 1" by arith
  1006       moreover {assume "?g'=1" hence ?thesis using assms g1 g0
  1007           by (auto simp add: Let_def simp_num_pair_def) }
  1008       moreover {assume g'1:"?g'>1"
  1009         have gpdg: "?g' dvd ?g" by simp
  1010         have gpdd: "?g' dvd n" by simp
  1011         have gpdgp: "?g' dvd ?g'" by simp
  1012         from zdvd_imp_le[OF gpdd np] have g'n: "?g' \<le> n" .
  1013         from zdiv_mono1[OF g'n g'p, simplified div_self[OF gp0]]
  1014         have "n div ?g' >0" by simp
  1015         hence ?thesis using assms g1 g'1
  1016           by(auto simp add: simp_num_pair_def Let_def reducecoeffh_numbound0)}
  1017       ultimately have ?thesis by blast }
  1018     ultimately have ?thesis by blast } 
  1019   ultimately show ?thesis by blast
  1020 qed
  1021 
  1022 fun not:: "fm \<Rightarrow> fm" where
  1023   "not (NOT p) = p"
  1024 | "not T = F"
  1025 | "not F = T"
  1026 | "not (Lt t) = Ge t"
  1027 | "not (Le t) = Gt t"
  1028 | "not (Gt t) = Le t"
  1029 | "not (Ge t) = Lt t"
  1030 | "not (Eq t) = NEq t"
  1031 | "not (NEq t) = Eq t"
  1032 | "not (Dvd i t) = NDvd i t"
  1033 | "not (NDvd i t) = Dvd i t"
  1034 | "not (And p q) = Or (not p) (not q)"
  1035 | "not (Or p q) = And (not p) (not q)"
  1036 | "not p = NOT p"
  1037 lemma not[simp]: "Ifm bs (not p) = Ifm bs (NOT p)"
  1038   by (induct p) auto
  1039 lemma not_qf[simp]: "qfree p \<Longrightarrow> qfree (not p)"
  1040   by (induct p) auto
  1041 lemma not_nb[simp]: "bound0 p \<Longrightarrow> bound0 (not p)"
  1042   by (induct p) auto
  1043 
  1044 definition conj :: "fm \<Rightarrow> fm \<Rightarrow> fm" where
  1045   "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 
  1046    if p = q then p else And p q)"
  1047 lemma conj[simp]: "Ifm bs (conj p q) = Ifm bs (And p q)"
  1048   by (cases "p=F \<or> q=F", simp_all add: conj_def) (cases p, simp_all)
  1049 
  1050 lemma conj_qf[simp]: "\<lbrakk>qfree p ; qfree q\<rbrakk> \<Longrightarrow> qfree (conj p q)"
  1051   using conj_def by auto 
  1052 lemma conj_nb[simp]: "\<lbrakk>bound0 p ; bound0 q\<rbrakk> \<Longrightarrow> bound0 (conj p q)"
  1053   using conj_def by auto 
  1054 
  1055 definition disj :: "fm \<Rightarrow> fm \<Rightarrow> fm" where
  1056   "disj p q \<equiv> (if (p = T \<or> q=T) then T else if p=F then q else if q=F then p 
  1057        else if p=q then p else Or p q)"
  1058 
  1059 lemma disj[simp]: "Ifm bs (disj p q) = Ifm bs (Or p q)"
  1060   by (cases "p=T \<or> q=T",simp_all add: disj_def) (cases p,simp_all)
  1061 lemma disj_qf[simp]: "\<lbrakk>qfree p ; qfree q\<rbrakk> \<Longrightarrow> qfree (disj p q)"
  1062   using disj_def by auto 
  1063 lemma disj_nb[simp]: "\<lbrakk>bound0 p ; bound0 q\<rbrakk> \<Longrightarrow> bound0 (disj p q)"
  1064   using disj_def by auto 
  1065 
  1066 definition imp :: "fm \<Rightarrow> fm \<Rightarrow> fm" where
  1067   "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 
  1068     else Imp p q)"
  1069 lemma imp[simp]: "Ifm bs (imp p q) = Ifm bs (Imp p q)"
  1070   by (cases "p=F \<or> q=T",simp_all add: imp_def)
  1071 lemma imp_qf[simp]: "\<lbrakk>qfree p ; qfree q\<rbrakk> \<Longrightarrow> qfree (imp p q)"
  1072   using imp_def by (cases "p=F \<or> q=T",simp_all add: imp_def)
  1073 
  1074 definition iff :: "fm \<Rightarrow> fm \<Rightarrow> fm" where
  1075   "iff p q \<equiv> (if (p = q) then T else if (p = not q \<or> not p = q) then F else 
  1076        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 
  1077   Iff p q)"
  1078 lemma iff[simp]: "Ifm bs (iff p q) = Ifm bs (Iff p q)"
  1079   by (unfold iff_def,cases "p=q", simp,cases "p=not q", simp) 
  1080 (cases "not p= q", auto simp add:not)
  1081 lemma iff_qf[simp]: "\<lbrakk>qfree p ; qfree q\<rbrakk> \<Longrightarrow> qfree (iff p q)"
  1082   by (unfold iff_def,cases "p=q", auto)
  1083 
  1084 fun check_int:: "num \<Rightarrow> bool" where
  1085   "check_int (C i) = True"
  1086 | "check_int (Floor t) = True"
  1087 | "check_int (Mul i t) = check_int t"
  1088 | "check_int (Add t s) = (check_int t \<and> check_int s)"
  1089 | "check_int (Neg t) = check_int t"
  1090 | "check_int (CF c t s) = check_int s"
  1091 | "check_int t = False"
  1092 lemma check_int: "check_int t \<Longrightarrow> isint t bs"
  1093   by (induct t) (auto simp add: isint_add isint_Floor isint_Mul isint_neg isint_c isint_CF)
  1094 
  1095 lemma rdvd_left1_int: "real \<lfloor>t\<rfloor> = t \<Longrightarrow> 1 rdvd t"
  1096   by (simp add: rdvd_def,rule_tac x="\<lfloor>t\<rfloor>" in exI) simp
  1097 
  1098 lemma rdvd_reduce: 
  1099   assumes gd:"g dvd d" and gc:"g dvd c" and gp: "g > 0"
  1100   shows "real (d::int) rdvd real (c::int)*t = (real (d div g) rdvd real (c div g)*t)"
  1101 proof
  1102   assume d: "real d rdvd real c * t"
  1103   from d rdvd_def obtain k where k_def: "real c * t = real d* real (k::int)" by auto
  1104   from gd dvd_def obtain kd where kd_def: "d = g * kd" by auto
  1105   from gc dvd_def obtain kc where kc_def: "c = g * kc" by auto
  1106   from k_def kd_def kc_def have "real g * real kc * t = real g * real kd * real k" by simp
  1107   hence "real kc * t = real kd * real k" using gp by simp
  1108   hence th:"real kd rdvd real kc * t" using rdvd_def by blast
  1109   from kd_def gp have th':"kd = d div g" by simp
  1110   from kc_def gp have "kc = c div g" by simp
  1111   with th th' show "real (d div g) rdvd real (c div g) * t" by simp
  1112 next
  1113   assume d: "real (d div g) rdvd real (c div g) * t"
  1114   from gp have gnz: "g \<noteq> 0" by simp
  1115   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 gd] real_of_int_div[OF gc] by simp
  1116 qed
  1117 
  1118 definition simpdvd :: "int \<Rightarrow> num \<Rightarrow> (int \<times> num)" where
  1119   "simpdvd d t \<equiv> 
  1120    (let g = numgcd t in 
  1121       if g > 1 then (let g' = gcd d g in 
  1122         if g' = 1 then (d, t) 
  1123         else (d div g',reducecoeffh t g')) 
  1124       else (d, t))"
  1125 lemma simpdvd: 
  1126   assumes tnz: "nozerocoeff t" and dnz: "d \<noteq> 0"
  1127   shows "Ifm bs (Dvd (fst (simpdvd d t)) (snd (simpdvd d t))) = Ifm bs (Dvd d t)"
  1128 proof-
  1129   let ?g = "numgcd t"
  1130   let ?g' = "gcd d ?g"
  1131   {assume "\<not> ?g > 1" hence ?thesis by (simp add: Let_def simpdvd_def)}
  1132   moreover
  1133   {assume g1:"?g>1" hence g0: "?g > 0" by simp
  1134     from g1 dnz have gp0: "?g' \<noteq> 0" by simp
  1135     hence g'p: "?g' > 0" using gcd_ge_0_int[where x="d" and y="numgcd t"] by arith
  1136     hence "?g'= 1 \<or> ?g' > 1" by arith
  1137     moreover {assume "?g'=1" hence ?thesis by (simp add: Let_def simpdvd_def)}
  1138     moreover {assume g'1:"?g'>1"
  1139       from dvdnumcoeff_aux2[OF g1] have th1:"dvdnumcoeff t ?g" ..
  1140       let ?tt = "reducecoeffh t ?g'"
  1141       let ?t = "Inum bs ?tt"
  1142       have gpdg: "?g' dvd ?g" by simp
  1143       have gpdd: "?g' dvd d" by simp
  1144       have gpdgp: "?g' dvd ?g'" by simp
  1145       from reducecoeffh[OF dvdnumcoeff_trans[OF gpdg th1] g'p] 
  1146       have th2:"real ?g' * ?t = Inum bs t" by simp
  1147       from assms g1 g0 g'1
  1148       have "Ifm bs (Dvd (fst (simpdvd d t)) (snd(simpdvd d t))) = Ifm bs (Dvd (d div ?g') ?tt)"
  1149         by (simp add: simpdvd_def Let_def)
  1150       also have "\<dots> = (real d rdvd (Inum bs t))"
  1151         using rdvd_reduce[OF gpdd gpdgp g'p, where t="?t", simplified div_self[OF gp0]] 
  1152           th2[symmetric] by simp
  1153       finally have ?thesis by simp  }
  1154     ultimately have ?thesis by blast
  1155   }
  1156   ultimately show ?thesis by blast
  1157 qed
  1158 
  1159 function (sequential) simpfm :: "fm \<Rightarrow> fm" where
  1160   "simpfm (And p q) = conj (simpfm p) (simpfm q)"
  1161 | "simpfm (Or p q) = disj (simpfm p) (simpfm q)"
  1162 | "simpfm (Imp p q) = imp (simpfm p) (simpfm q)"
  1163 | "simpfm (Iff p q) = iff (simpfm p) (simpfm q)"
  1164 | "simpfm (NOT p) = not (simpfm p)"
  1165 | "simpfm (Lt a) = (let a' = simpnum a in case a' of C v \<Rightarrow> if (v < 0) then T else F 
  1166   | _ \<Rightarrow> Lt (reducecoeff a'))"
  1167 | "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'))"
  1168 | "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'))"
  1169 | "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'))"
  1170 | "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'))"
  1171 | "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'))"
  1172 | "simpfm (Dvd i a) = (if i=0 then simpfm (Eq a)
  1173              else if (abs i = 1) \<and> check_int a then T
  1174              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))"
  1175 | "simpfm (NDvd i a) = (if i=0 then simpfm (NEq a) 
  1176              else if (abs i = 1) \<and> check_int a then F
  1177              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))"
  1178 | "simpfm p = p"
  1179 by pat_completeness auto
  1180 termination by (relation "measure fmsize") auto
  1181 
  1182 lemma simpfm[simp]: "Ifm bs (simpfm p) = Ifm bs p"
  1183 proof(induct p rule: simpfm.induct)
  1184   case (6 a) let ?sa = "simpnum a" have sa: "Inum bs ?sa = Inum bs a" by simp
  1185   {fix v assume "?sa = C v" hence ?case using sa by simp }
  1186   moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
  1187     let ?g = "numgcd ?sa"
  1188     let ?rsa = "reducecoeff ?sa"
  1189     let ?r = "Inum bs ?rsa"
  1190     have sa_nz: "nozerocoeff ?sa" by (rule simpnum_nz)
  1191     {assume gz: "?g=0" from numgcd_nz[OF sa_nz gz] H have "False" by auto}
  1192     with numgcd_pos[where t="?sa"] have "?g > 0" by (cases "?g=0", auto)
  1193     hence gp: "real ?g > 0" by simp
  1194     have "Inum bs ?sa = real ?g* ?r" by (simp add: reducecoeff)
  1195     with sa have "Inum bs a < 0 = (real ?g * ?r < real ?g * 0)" by simp
  1196     also have "\<dots> = (?r < 0)" using gp
  1197       by (simp only: mult_less_cancel_left) simp
  1198     finally have ?case using H by (cases "?sa" , simp_all add: Let_def)}
  1199   ultimately show ?case by blast
  1200 next
  1201   case (7 a)  let ?sa = "simpnum a" have sa: "Inum bs ?sa = Inum bs a" by simp
  1202   {fix v assume "?sa = C v" hence ?case using sa by simp }
  1203   moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
  1204     let ?g = "numgcd ?sa"
  1205     let ?rsa = "reducecoeff ?sa"
  1206     let ?r = "Inum bs ?rsa"
  1207     have sa_nz: "nozerocoeff ?sa" by (rule simpnum_nz)
  1208     {assume gz: "?g=0" from numgcd_nz[OF sa_nz gz] H have "False" by auto}
  1209     with numgcd_pos[where t="?sa"] have "?g > 0" by (cases "?g=0", auto)
  1210     hence gp: "real ?g > 0" by simp
  1211     have "Inum bs ?sa = real ?g* ?r" by (simp add: reducecoeff)
  1212     with sa have "Inum bs a \<le> 0 = (real ?g * ?r \<le> real ?g * 0)" by simp
  1213     also have "\<dots> = (?r \<le> 0)" using gp
  1214       by (simp only: mult_le_cancel_left) simp
  1215     finally have ?case using H by (cases "?sa" , simp_all add: Let_def)}
  1216   ultimately show ?case by blast
  1217 next
  1218   case (8 a)  let ?sa = "simpnum a" have sa: "Inum bs ?sa = Inum bs a" by simp
  1219   {fix v assume "?sa = C v" hence ?case using sa by simp }
  1220   moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
  1221     let ?g = "numgcd ?sa"
  1222     let ?rsa = "reducecoeff ?sa"
  1223     let ?r = "Inum bs ?rsa"
  1224     have sa_nz: "nozerocoeff ?sa" by (rule simpnum_nz)
  1225     {assume gz: "?g=0" from numgcd_nz[OF sa_nz gz] H have "False" by auto}
  1226     with numgcd_pos[where t="?sa"] have "?g > 0" by (cases "?g=0", auto)
  1227     hence gp: "real ?g > 0" by simp
  1228     have "Inum bs ?sa = real ?g* ?r" by (simp add: reducecoeff)
  1229     with sa have "Inum bs a > 0 = (real ?g * ?r > real ?g * 0)" by simp
  1230     also have "\<dots> = (?r > 0)" using gp
  1231       by (simp only: mult_less_cancel_left) simp
  1232     finally have ?case using H by (cases "?sa" , simp_all add: Let_def)}
  1233   ultimately show ?case by blast
  1234 next
  1235   case (9 a)  let ?sa = "simpnum a" have sa: "Inum bs ?sa = Inum bs a" by simp
  1236   {fix v assume "?sa = C v" hence ?case using sa by simp }
  1237   moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
  1238     let ?g = "numgcd ?sa"
  1239     let ?rsa = "reducecoeff ?sa"
  1240     let ?r = "Inum bs ?rsa"
  1241     have sa_nz: "nozerocoeff ?sa" by (rule simpnum_nz)
  1242     {assume gz: "?g=0" from numgcd_nz[OF sa_nz gz] H have "False" by auto}
  1243     with numgcd_pos[where t="?sa"] have "?g > 0" by (cases "?g=0", auto)
  1244     hence gp: "real ?g > 0" by simp
  1245     have "Inum bs ?sa = real ?g* ?r" by (simp add: reducecoeff)
  1246     with sa have "Inum bs a \<ge> 0 = (real ?g * ?r \<ge> real ?g * 0)" by simp
  1247     also have "\<dots> = (?r \<ge> 0)" using gp
  1248       by (simp only: mult_le_cancel_left) simp
  1249     finally have ?case using H by (cases "?sa" , simp_all add: Let_def)}
  1250   ultimately show ?case by blast
  1251 next
  1252   case (10 a)  let ?sa = "simpnum a" have sa: "Inum bs ?sa = Inum bs a" by simp
  1253   {fix v assume "?sa = C v" hence ?case using sa by simp }
  1254   moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
  1255     let ?g = "numgcd ?sa"
  1256     let ?rsa = "reducecoeff ?sa"
  1257     let ?r = "Inum bs ?rsa"
  1258     have sa_nz: "nozerocoeff ?sa" by (rule simpnum_nz)
  1259     {assume gz: "?g=0" from numgcd_nz[OF sa_nz gz] H have "False" by auto}
  1260     with numgcd_pos[where t="?sa"] have "?g > 0" by (cases "?g=0", auto)
  1261     hence gp: "real ?g > 0" by simp
  1262     have "Inum bs ?sa = real ?g* ?r" by (simp add: reducecoeff)
  1263     with sa have "Inum bs a = 0 = (real ?g * ?r = 0)" by simp
  1264     also have "\<dots> = (?r = 0)" using gp
  1265       by simp
  1266     finally have ?case using H by (cases "?sa" , simp_all add: Let_def)}
  1267   ultimately show ?case by blast
  1268 next
  1269   case (11 a)  let ?sa = "simpnum a" have sa: "Inum bs ?sa = Inum bs a" by simp
  1270   {fix v assume "?sa = C v" hence ?case using sa by simp }
  1271   moreover {assume H:"\<not> (\<exists> v. ?sa = C v)"
  1272     let ?g = "numgcd ?sa"
  1273     let ?rsa = "reducecoeff ?sa"
  1274     let ?r = "Inum bs ?rsa"
  1275     have sa_nz: "nozerocoeff ?sa" by (rule simpnum_nz)
  1276     {assume gz: "?g=0" from numgcd_nz[OF sa_nz gz] H have "False" by auto}
  1277     with numgcd_pos[where t="?sa"] have "?g > 0" by (cases "?g=0", auto)
  1278     hence gp: "real ?g > 0" by simp
  1279     have "Inum bs ?sa = real ?g* ?r" by (simp add: reducecoeff)
  1280     with sa have "Inum bs a \<noteq> 0 = (real ?g * ?r \<noteq> 0)" by simp
  1281     also have "\<dots> = (?r \<noteq> 0)" using gp
  1282       by simp
  1283     finally have ?case using H by (cases "?sa") (simp_all add: Let_def) }
  1284   ultimately show ?case by blast
  1285 next
  1286   case (12 i a)  let ?sa = "simpnum a"   have sa: "Inum bs ?sa = Inum bs a" by simp
  1287   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
  1288   {assume "i=0" hence ?case using "12.hyps" by (simp add: rdvd_left_0_eq Let_def)}
  1289   moreover 
  1290   {assume ai1: "abs i = 1" and ai: "check_int a" 
  1291     hence "i=1 \<or> i= - 1" by arith
  1292     moreover {assume i1: "i = 1" 
  1293       from rdvd_left1_int[OF check_int[OF ai, simplified isint_iff]] 
  1294       have ?case using i1 ai by simp }
  1295     moreover {assume i1: "i = - 1" 
  1296       from rdvd_left1_int[OF check_int[OF ai, simplified isint_iff]] 
  1297         rdvd_abs1[where d="- 1" and t="Inum bs a"]
  1298       have ?case using i1 ai by simp }
  1299     ultimately have ?case by blast}
  1300   moreover   
  1301   {assume inz: "i\<noteq>0" and cond: "(abs i \<noteq> 1) \<or> (\<not> check_int a)"
  1302     {fix v assume "?sa = C v" hence ?case using sa[symmetric] inz cond
  1303         by (cases "abs i = 1", auto simp add: int_rdvd_iff) }
  1304     moreover {assume H:"\<not> (\<exists> v. ?sa = C v)" 
  1305       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)
  1306       from simpnum_nz have nz:"nozerocoeff ?sa" by simp
  1307       from simpdvd [OF nz inz] th have ?case using sa by simp}
  1308     ultimately have ?case by blast}
  1309   ultimately show ?case by blast
  1310 next
  1311   case (13 i a)  let ?sa = "simpnum a"   have sa: "Inum bs ?sa = Inum bs a" by simp
  1312   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
  1313   {assume "i=0" hence ?case using "13.hyps" by (simp add: rdvd_left_0_eq Let_def)}
  1314   moreover 
  1315   {assume ai1: "abs i = 1" and ai: "check_int a" 
  1316     hence "i=1 \<or> i= - 1" by arith
  1317     moreover {assume i1: "i = 1" 
  1318       from rdvd_left1_int[OF check_int[OF ai, simplified isint_iff]] 
  1319       have ?case using i1 ai by simp }
  1320     moreover {assume i1: "i = - 1" 
  1321       from rdvd_left1_int[OF check_int[OF ai, simplified isint_iff]] 
  1322         rdvd_abs1[where d="- 1" and t="Inum bs a"]
  1323       have ?case using i1 ai by simp }
  1324     ultimately have ?case by blast}
  1325   moreover   
  1326   {assume inz: "i\<noteq>0" and cond: "(abs i \<noteq> 1) \<or> (\<not> check_int a)"
  1327     {fix v assume "?sa = C v" hence ?case using sa[symmetric] inz cond
  1328         by (cases "abs i = 1", auto simp add: int_rdvd_iff) }
  1329     moreover {assume H:"\<not> (\<exists> v. ?sa = C v)" 
  1330       hence th: "simpfm (NDvd i a) = NDvd (fst (simpdvd i ?sa)) (snd (simpdvd i ?sa))" using inz cond 
  1331         by (cases ?sa, auto simp add: Let_def split_def)
  1332       from simpnum_nz have nz:"nozerocoeff ?sa" by simp
  1333       from simpdvd [OF nz inz] th have ?case using sa by simp}
  1334     ultimately have ?case by blast}
  1335   ultimately show ?case by blast
  1336 qed (induct p rule: simpfm.induct, simp_all)
  1337 
  1338 lemma simpdvd_numbound0: "numbound0 t \<Longrightarrow> numbound0 (snd (simpdvd d t))"
  1339   by (simp add: simpdvd_def Let_def split_def reducecoeffh_numbound0)
  1340 
  1341 lemma simpfm_bound0[simp]: "bound0 p \<Longrightarrow> bound0 (simpfm p)"
  1342 proof(induct p rule: simpfm.induct)
  1343   case (6 a) hence nb: "numbound0 a" by simp
  1344   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  1345   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0)
  1346 next
  1347   case (7 a) hence nb: "numbound0 a" by simp
  1348   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  1349   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0)
  1350 next
  1351   case (8 a) hence nb: "numbound0 a" by simp
  1352   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  1353   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0)
  1354 next
  1355   case (9 a) hence nb: "numbound0 a" by simp
  1356   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  1357   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0)
  1358 next
  1359   case (10 a) hence nb: "numbound0 a" by simp
  1360   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  1361   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0)
  1362 next
  1363   case (11 a) hence nb: "numbound0 a" by simp
  1364   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  1365   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0)
  1366 next
  1367   case (12 i a) hence nb: "numbound0 a" by simp
  1368   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  1369   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0 simpdvd_numbound0 split_def)
  1370 next
  1371   case (13 i a) hence nb: "numbound0 a" by simp
  1372   hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  1373   thus ?case by (cases "simpnum a", auto simp add: Let_def reducecoeff_numbound0 simpdvd_numbound0 split_def)
  1374 qed(auto simp add: disj_def imp_def iff_def conj_def)
  1375 
  1376 lemma simpfm_qf[simp]: "qfree p \<Longrightarrow> qfree (simpfm p)"
  1377 by (induct p rule: simpfm.induct, auto simp add: Let_def)
  1378 (case_tac "simpnum a",auto simp add: split_def Let_def)+
  1379 
  1380 
  1381   (* Generic quantifier elimination *)
  1382 
  1383 definition list_conj :: "fm list \<Rightarrow> fm" where
  1384   "list_conj ps \<equiv> foldr conj ps T"
  1385 lemma list_conj: "Ifm bs (list_conj ps) = (\<forall>p\<in> set ps. Ifm bs p)"
  1386   by (induct ps, auto simp add: list_conj_def)
  1387 lemma list_conj_qf: " \<forall>p\<in> set ps. qfree p \<Longrightarrow> qfree (list_conj ps)"
  1388   by (induct ps, auto simp add: list_conj_def)
  1389 lemma list_conj_nb: " \<forall>p\<in> set ps. bound0 p \<Longrightarrow> bound0 (list_conj ps)"
  1390   by (induct ps, auto simp add: list_conj_def)
  1391 definition CJNB :: "(fm \<Rightarrow> fm) \<Rightarrow> fm \<Rightarrow> fm" where
  1392   "CJNB f p \<equiv> (let cjs = conjuncts p ; (yes,no) = List.partition bound0 cjs
  1393                    in conj (decr (list_conj yes)) (f (list_conj no)))"
  1394 
  1395 lemma CJNB_qe: 
  1396   assumes qe: "\<forall> bs p. qfree p \<longrightarrow> qfree (qe p) \<and> (Ifm bs (qe p) = Ifm bs (E p))"
  1397   shows "\<forall> bs p. qfree p \<longrightarrow> qfree (CJNB qe p) \<and> (Ifm bs ((CJNB qe p)) = Ifm bs (E p))"
  1398 proof(clarify)
  1399   fix bs p
  1400   assume qfp: "qfree p"
  1401   let ?cjs = "conjuncts p"
  1402   let ?yes = "fst (List.partition bound0 ?cjs)"
  1403   let ?no = "snd (List.partition bound0 ?cjs)"
  1404   let ?cno = "list_conj ?no"
  1405   let ?cyes = "list_conj ?yes"
  1406   have part: "List.partition bound0 ?cjs = (?yes,?no)" by simp
  1407   from partition_P[OF part] have "\<forall> q\<in> set ?yes. bound0 q" by blast 
  1408   hence yes_nb: "bound0 ?cyes" by (simp add: list_conj_nb) 
  1409   hence yes_qf: "qfree (decr ?cyes )" by (simp add: decr_qf)
  1410   from conjuncts_qf[OF qfp] partition_set[OF part] 
  1411   have " \<forall>q\<in> set ?no. qfree q" by auto
  1412   hence no_qf: "qfree ?cno"by (simp add: list_conj_qf)
  1413   with qe have cno_qf:"qfree (qe ?cno )" 
  1414     and noE: "Ifm bs (qe ?cno) = Ifm bs (E ?cno)" by blast+
  1415   from cno_qf yes_qf have qf: "qfree (CJNB qe p)" 
  1416     by (simp add: CJNB_def Let_def split_def)
  1417   {fix bs
  1418     from conjuncts have "Ifm bs p = (\<forall>q\<in> set ?cjs. Ifm bs q)" by blast
  1419     also have "\<dots> = ((\<forall>q\<in> set ?yes. Ifm bs q) \<and> (\<forall>q\<in> set ?no. Ifm bs q))"
  1420       using partition_set[OF part] by auto
  1421     finally have "Ifm bs p = ((Ifm bs ?cyes) \<and> (Ifm bs ?cno))" using list_conj by simp}
  1422   hence "Ifm bs (E p) = (\<exists>x. (Ifm (x#bs) ?cyes) \<and> (Ifm (x#bs) ?cno))" by simp
  1423   also fix y have "\<dots> = (\<exists>x. (Ifm (y#bs) ?cyes) \<and> (Ifm (x#bs) ?cno))"
  1424     using bound0_I[OF yes_nb, where bs="bs" and b'="y"] by blast
  1425   also have "\<dots> = (Ifm bs (decr ?cyes) \<and> Ifm bs (E ?cno))"
  1426     by (auto simp add: decr[OF yes_nb] simp del: partition_filter_conv)
  1427   also have "\<dots> = (Ifm bs (conj (decr ?cyes) (qe ?cno)))"
  1428     using qe[rule_format, OF no_qf] by auto
  1429   finally have "Ifm bs (E p) = Ifm bs (CJNB qe p)" 
  1430     by (simp add: Let_def CJNB_def split_def)
  1431   with qf show "qfree (CJNB qe p) \<and> Ifm bs (CJNB qe p) = Ifm bs (E p)" by blast
  1432 qed
  1433 
  1434 function (sequential) qelim :: "fm \<Rightarrow> (fm \<Rightarrow> fm) \<Rightarrow> fm" where
  1435   "qelim (E p) = (\<lambda> qe. DJ (CJNB qe) (qelim p qe))"
  1436 | "qelim (A p) = (\<lambda> qe. not (qe ((qelim (NOT p) qe))))"
  1437 | "qelim (NOT p) = (\<lambda> qe. not (qelim p qe))"
  1438 | "qelim (And p q) = (\<lambda> qe. conj (qelim p qe) (qelim q qe))" 
  1439 | "qelim (Or  p q) = (\<lambda> qe. disj (qelim p qe) (qelim q qe))" 
  1440 | "qelim (Imp p q) = (\<lambda> qe. disj (qelim (NOT p) qe) (qelim q qe))"
  1441 | "qelim (Iff p q) = (\<lambda> qe. iff (qelim p qe) (qelim q qe))"
  1442 | "qelim p = (\<lambda> y. simpfm p)"
  1443 by pat_completeness auto
  1444 termination by (relation "measure fmsize") auto
  1445 
  1446 lemma qelim_ci:
  1447   assumes qe_inv: "\<forall> bs p. qfree p \<longrightarrow> qfree (qe p) \<and> (Ifm bs (qe p) = Ifm bs (E p))"
  1448   shows "\<And> bs. qfree (qelim p qe) \<and> (Ifm bs (qelim p qe) = Ifm bs p)"
  1449   using qe_inv DJ_qe[OF CJNB_qe[OF qe_inv]] 
  1450   by (induct p rule: qelim.induct) (auto simp del: simpfm.simps)
  1451 
  1452 
  1453 text {* The @{text "\<int>"} Part *}
  1454 text{* Linearity for fm where Bound 0 ranges over @{text "\<int>"} *}
  1455 
  1456 function zsplit0 :: "num \<Rightarrow> int \<times> num" (* splits the bounded from the unbounded part*) where
  1457   "zsplit0 (C c) = (0,C c)"
  1458 | "zsplit0 (Bound n) = (if n=0 then (1, C 0) else (0,Bound n))"
  1459 | "zsplit0 (CN n c a) = zsplit0 (Add (Mul c (Bound n)) a)"
  1460 | "zsplit0 (CF c a b) = zsplit0 (Add (Mul c (Floor a)) b)"
  1461 | "zsplit0 (Neg a) = (let (i',a') =  zsplit0 a in (-i', Neg a'))"
  1462 | "zsplit0 (Add a b) = (let (ia,a') =  zsplit0 a ; 
  1463                             (ib,b') =  zsplit0 b 
  1464                             in (ia+ib, Add a' b'))"
  1465 | "zsplit0 (Sub a b) = (let (ia,a') =  zsplit0 a ; 
  1466                             (ib,b') =  zsplit0 b 
  1467                             in (ia-ib, Sub a' b'))"
  1468 | "zsplit0 (Mul i a) = (let (i',a') =  zsplit0 a in (i*i', Mul i a'))"
  1469 | "zsplit0 (Floor a) = (let (i',a') =  zsplit0 a in (i',Floor a'))"
  1470 by pat_completeness auto
  1471 termination by (relation "measure num_size") auto
  1472 
  1473 lemma zsplit0_I:
  1474   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"
  1475   (is "\<And> n a. ?S t = (n,a) \<Longrightarrow> (?I x (CN 0 n a) = ?I x t) \<and> ?N a")
  1476 proof(induct t rule: zsplit0.induct)
  1477   case (1 c n a) thus ?case by auto 
  1478 next
  1479   case (2 m n a) thus ?case by (cases "m=0") auto
  1480 next
  1481   case (3 n i a n a') thus ?case by auto
  1482 next 
  1483   case (4 c a b n a') thus ?case by auto
  1484 next
  1485   case (5 t n a)
  1486   let ?nt = "fst (zsplit0 t)"
  1487   let ?at = "snd (zsplit0 t)"
  1488   have abj: "zsplit0 t = (?nt,?at)" by simp hence th: "a=Neg ?at \<and> n=-?nt" using 5 
  1489     by (simp add: Let_def split_def)
  1490   from abj 5 have th2: "(?I x (CN 0 ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
  1491   from th2[simplified] th[simplified] show ?case by simp
  1492 next
  1493   case (6 s t n a)
  1494   let ?ns = "fst (zsplit0 s)"
  1495   let ?as = "snd (zsplit0 s)"
  1496   let ?nt = "fst (zsplit0 t)"
  1497   let ?at = "snd (zsplit0 t)"
  1498   have abjs: "zsplit0 s = (?ns,?as)" by simp 
  1499   moreover have abjt:  "zsplit0 t = (?nt,?at)" by simp 
  1500   ultimately have th: "a=Add ?as ?at \<and> n=?ns + ?nt" using 6
  1501     by (simp add: Let_def split_def)
  1502   from abjs[symmetric] have bluddy: "\<exists> x y. (x,y) = zsplit0 s" by blast
  1503   from 6 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*)
  1504   with bluddy abjt have th3: "(?I x (CN 0 ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
  1505   from abjs 6  have th2: "(?I x (CN 0 ?ns ?as) = ?I x s) \<and> ?N ?as" by blast
  1506   from th3[simplified] th2[simplified] th[simplified] show ?case 
  1507     by (simp add: distrib_right)
  1508 next
  1509   case (7 s t n a)
  1510   let ?ns = "fst (zsplit0 s)"
  1511   let ?as = "snd (zsplit0 s)"
  1512   let ?nt = "fst (zsplit0 t)"
  1513   let ?at = "snd (zsplit0 t)"
  1514   have abjs: "zsplit0 s = (?ns,?as)" by simp 
  1515   moreover have abjt:  "zsplit0 t = (?nt,?at)" by simp 
  1516   ultimately have th: "a=Sub ?as ?at \<and> n=?ns - ?nt" using 7
  1517     by (simp add: Let_def split_def)
  1518   from abjs[symmetric] have bluddy: "\<exists> x y. (x,y) = zsplit0 s" by blast
  1519   from 7 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*)
  1520   with bluddy abjt have th3: "(?I x (CN 0 ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
  1521   from abjs 7 have th2: "(?I x (CN 0 ?ns ?as) = ?I x s) \<and> ?N ?as" by blast
  1522   from th3[simplified] th2[simplified] th[simplified] show ?case 
  1523     by (simp add: left_diff_distrib)
  1524 next
  1525   case (8 i t n a)
  1526   let ?nt = "fst (zsplit0 t)"
  1527   let ?at = "snd (zsplit0 t)"
  1528   have abj: "zsplit0 t = (?nt,?at)" by simp hence th: "a=Mul i ?at \<and> n=i*?nt" using 8
  1529     by (simp add: Let_def split_def)
  1530   from abj 8 have th2: "(?I x (CN 0 ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
  1531   hence "?I x (Mul i t) = (real i) * ?I x (CN 0 ?nt ?at)" by simp
  1532   also have "\<dots> = ?I x (CN 0 (i*?nt) (Mul i ?at))" by (simp add: distrib_left)
  1533   finally show ?case using th th2 by simp
  1534 next
  1535   case (9 t n a)
  1536   let ?nt = "fst (zsplit0 t)"
  1537   let ?at = "snd (zsplit0 t)"
  1538   have abj: "zsplit0 t = (?nt,?at)" by simp hence th: "a= Floor ?at \<and> n=?nt" using 9
  1539     by (simp add: Let_def split_def)
  1540   from abj 9 have th2: "(?I x (CN 0 ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
  1541   hence na: "?N a" using th by simp
  1542   have th': "(real ?nt)*(real x) = real (?nt * x)" by simp
  1543   have "?I x (Floor t) = ?I x (Floor (CN 0 ?nt ?at))" using th2 by simp
  1544   also have "\<dots> = real (floor ((real ?nt)* real(x) + ?I x ?at))" by simp
  1545   also have "\<dots> = real (floor (?I x ?at + real (?nt* x)))" by (simp add: ac_simps)
  1546   also have "\<dots> = real (floor (?I x ?at) + (?nt* x))" 
  1547     using floor_add[where x="?I x ?at" and a="?nt* x"] by simp 
  1548   also have "\<dots> = real (?nt)*(real x) + real (floor (?I x ?at))" by (simp add: ac_simps)
  1549   finally have "?I x (Floor t) = ?I x (CN 0 n a)" using th by simp
  1550   with na show ?case by simp
  1551 qed
  1552 
  1553 consts
  1554   iszlfm :: "fm \<Rightarrow> real list \<Rightarrow> bool"   (* Linearity test for fm *)
  1555   zlfm :: "fm \<Rightarrow> fm"       (* Linearity transformation for fm *)
  1556 recdef iszlfm "measure size"
  1557   "iszlfm (And p q) = (\<lambda> bs. iszlfm p bs \<and> iszlfm q bs)" 
  1558   "iszlfm (Or p q) = (\<lambda> bs. iszlfm p bs \<and> iszlfm q bs)" 
  1559   "iszlfm (Eq  (CN 0 c e)) = (\<lambda> bs. c>0 \<and> numbound0 e \<and> isint e bs)"
  1560   "iszlfm (NEq (CN 0 c e)) = (\<lambda> bs. c>0 \<and> numbound0 e \<and> isint e bs)"
  1561   "iszlfm (Lt  (CN 0 c e)) = (\<lambda> bs. c>0 \<and> numbound0 e \<and> isint e bs)"
  1562   "iszlfm (Le  (CN 0 c e)) = (\<lambda> bs. c>0 \<and> numbound0 e \<and> isint e bs)"
  1563   "iszlfm (Gt  (CN 0 c e)) = (\<lambda> bs. c>0 \<and> numbound0 e \<and> isint e bs)"
  1564   "iszlfm (Ge  (CN 0 c e)) = (\<lambda> bs. c>0 \<and> numbound0 e \<and> isint e bs)"
  1565   "iszlfm (Dvd i (CN 0 c e)) = 
  1566                  (\<lambda> bs. c>0 \<and> i>0 \<and> numbound0 e \<and> isint e bs)"
  1567   "iszlfm (NDvd i (CN 0 c e))= 
  1568                  (\<lambda> bs. c>0 \<and> i>0 \<and> numbound0 e \<and> isint e bs)"
  1569   "iszlfm p = (\<lambda> bs. isatom p \<and> (bound0 p))"
  1570 
  1571 lemma zlin_qfree: "iszlfm p bs \<Longrightarrow> qfree p"
  1572   by (induct p rule: iszlfm.induct) auto
  1573 
  1574 lemma iszlfm_gen:
  1575   assumes lp: "iszlfm p (x#bs)"
  1576   shows "\<forall> y. iszlfm p (y#bs)"
  1577 proof
  1578   fix y
  1579   show "iszlfm p (y#bs)"
  1580     using lp
  1581   by(induct p rule: iszlfm.induct, simp_all add: numbound0_gen[rule_format, where x="x" and y="y"])
  1582 qed
  1583 
  1584 lemma conj_zl[simp]: "iszlfm p bs \<Longrightarrow> iszlfm q bs \<Longrightarrow> iszlfm (conj p q) bs"
  1585   using conj_def by (cases p,auto)
  1586 lemma disj_zl[simp]: "iszlfm p bs \<Longrightarrow> iszlfm q bs \<Longrightarrow> iszlfm (disj p q) bs"
  1587   using disj_def by (cases p,auto)
  1588 
  1589 recdef zlfm "measure fmsize"
  1590   "zlfm (And p q) = conj (zlfm p) (zlfm q)"
  1591   "zlfm (Or p q) = disj (zlfm p) (zlfm q)"
  1592   "zlfm (Imp p q) = disj (zlfm (NOT p)) (zlfm q)"
  1593   "zlfm (Iff p q) = disj (conj (zlfm p) (zlfm q)) (conj (zlfm (NOT p)) (zlfm (NOT q)))"
  1594   "zlfm (Lt a) = (let (c,r) = zsplit0 a in 
  1595      if c=0 then Lt r else 
  1596      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))) 
  1597      else Or (Gt (CN 0 (-c) (Floor(Neg r)))) (And (Eq(CN 0 (-c) (Floor(Neg r)))) (Lt (Add (Floor (Neg r)) r))))"
  1598   "zlfm (Le a) = (let (c,r) = zsplit0 a in 
  1599      if c=0 then Le r else 
  1600      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))) 
  1601      else Or (Ge (CN 0 (-c) (Floor(Neg r)))) (And (Eq(CN 0 (-c) (Floor(Neg r)))) (Lt (Add (Floor (Neg r)) r))))"
  1602   "zlfm (Gt a) = (let (c,r) = zsplit0 a in 
  1603      if c=0 then Gt r else 
  1604      if c>0 then Or (Gt (CN 0 c (Floor r))) (And (Eq (CN 0 c (Floor r))) (Lt (Sub (Floor r) r))) 
  1605      else Or (Lt (CN 0 (-c) (Neg (Floor r)))) (And (Eq(CN 0 (-c) (Neg (Floor r)))) (Lt (Sub (Floor r) r))))"
  1606   "zlfm (Ge a) = (let (c,r) = zsplit0 a in 
  1607      if c=0 then Ge r else 
  1608      if c>0 then Or (Ge (CN 0 c (Floor r))) (And (Eq (CN 0 c (Floor r))) (Lt (Sub (Floor r) r))) 
  1609      else Or (Le (CN 0 (-c) (Neg (Floor r)))) (And (Eq(CN 0 (-c) (Neg (Floor r)))) (Lt (Sub (Floor r) r))))"
  1610   "zlfm (Eq a) = (let (c,r) = zsplit0 a in 
  1611               if c=0 then Eq r else 
  1612       if c>0 then (And (Eq (CN 0 c (Neg (Floor (Neg r))))) (Eq (Add (Floor (Neg r)) r)))
  1613       else (And (Eq (CN 0 (-c) (Floor (Neg r)))) (Eq (Add (Floor (Neg r)) r))))"
  1614   "zlfm (NEq a) = (let (c,r) = zsplit0 a in 
  1615               if c=0 then NEq r else 
  1616       if c>0 then (Or (NEq (CN 0 c (Neg (Floor (Neg r))))) (NEq (Add (Floor (Neg r)) r)))
  1617       else (Or (NEq (CN 0 (-c) (Floor (Neg r)))) (NEq (Add (Floor (Neg r)) r))))"
  1618   "zlfm (Dvd i a) = (if i=0 then zlfm (Eq a) 
  1619   else (let (c,r) = zsplit0 a in 
  1620               if c=0 then Dvd (abs i) r else 
  1621       if c>0 then And (Eq (Sub (Floor r) r)) (Dvd (abs i) (CN 0 c (Floor r))) 
  1622       else And (Eq (Sub (Floor r) r)) (Dvd (abs i) (CN 0 (-c) (Neg (Floor r))))))"
  1623   "zlfm (NDvd i a) = (if i=0 then zlfm (NEq a) 
  1624   else (let (c,r) = zsplit0 a in 
  1625               if c=0 then NDvd (abs i) r else 
  1626       if c>0 then Or (NEq (Sub (Floor r) r)) (NDvd (abs i) (CN 0 c (Floor r))) 
  1627       else Or (NEq (Sub (Floor r) r)) (NDvd (abs i) (CN 0 (-c) (Neg (Floor r))))))"
  1628   "zlfm (NOT (And p q)) = disj (zlfm (NOT p)) (zlfm (NOT q))"
  1629   "zlfm (NOT (Or p q)) = conj (zlfm (NOT p)) (zlfm (NOT q))"
  1630   "zlfm (NOT (Imp p q)) = conj (zlfm p) (zlfm (NOT q))"
  1631   "zlfm (NOT (Iff p q)) = disj (conj(zlfm p) (zlfm(NOT q))) (conj (zlfm(NOT p)) (zlfm q))"
  1632   "zlfm (NOT (NOT p)) = zlfm p"
  1633   "zlfm (NOT T) = F"
  1634   "zlfm (NOT F) = T"
  1635   "zlfm (NOT (Lt a)) = zlfm (Ge a)"
  1636   "zlfm (NOT (Le a)) = zlfm (Gt a)"
  1637   "zlfm (NOT (Gt a)) = zlfm (Le a)"
  1638   "zlfm (NOT (Ge a)) = zlfm (Lt a)"
  1639   "zlfm (NOT (Eq a)) = zlfm (NEq a)"
  1640   "zlfm (NOT (NEq a)) = zlfm (Eq a)"
  1641   "zlfm (NOT (Dvd i a)) = zlfm (NDvd i a)"
  1642   "zlfm (NOT (NDvd i a)) = zlfm (Dvd i a)"
  1643   "zlfm p = p" (hints simp add: fmsize_pos)
  1644 
  1645 lemma split_int_less_real: 
  1646   "(real (a::int) < b) = (a < floor b \<or> (a = floor b \<and> real (floor b) < b))"
  1647 proof( auto)
  1648   assume alb: "real a < b" and agb: "\<not> a < floor b"
  1649   from agb have "floor b \<le> a" by simp hence th: "b < real a + 1" by (simp only: floor_le_eq)
  1650   from floor_eq[OF alb th] show "a= floor b" by simp 
  1651 next
  1652   assume alb: "a < floor b"
  1653   hence "real a < real (floor b)" by simp
  1654   moreover have "real (floor b) \<le> b" by simp ultimately show  "real a < b" by arith 
  1655 qed
  1656 
  1657 lemma split_int_less_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 "(real a + b <0) = (real a < -b)" by arith
  1661   with split_int_less_real[where a="a" and b="-b"] show ?thesis by arith  
  1662 qed
  1663 
  1664 lemma split_int_gt_real': 
  1665   "(real (a::int) + b > 0) = (real a + real (floor b) > 0 \<or> (real a + real (floor b) = 0 \<and> real (floor b) - b < 0))"
  1666 proof- 
  1667   have th: "(real a + b >0) = (real (-a) + (-b)< 0)" by arith
  1668   show ?thesis using myless[of _ "real (floor b)"] 
  1669     by (simp only:th split_int_less_real'[where a="-a" and b="-b"]) 
  1670     (simp add: algebra_simps,arith)
  1671 qed
  1672 
  1673 lemma split_int_le_real: 
  1674   "(real (a::int) \<le> b) = (a \<le> floor b \<or> (a = floor b \<and> real (floor b) < b))"
  1675 proof( auto)
  1676   assume alb: "real a \<le> b" and agb: "\<not> a \<le> floor b"
  1677   from alb have "floor (real a) \<le> floor b " by (simp only: floor_mono) 
  1678   hence "a \<le> floor b" by simp with agb show "False" by simp
  1679 next
  1680   assume alb: "a \<le> floor b"
  1681   hence "real a \<le> real (floor b)" by (simp only: floor_mono)
  1682   also have "\<dots>\<le> b" by simp  finally show  "real a \<le> b" . 
  1683 qed
  1684 
  1685 lemma split_int_le_real': 
  1686   "(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))"
  1687 proof- 
  1688   have "(real a + b \<le>0) = (real a \<le> -b)" by arith
  1689   with split_int_le_real[where a="a" and b="-b"] show ?thesis by arith  
  1690 qed
  1691 
  1692 lemma split_int_ge_real': 
  1693   "(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))"
  1694 proof- 
  1695   have th: "(real a + b \<ge>0) = (real (-a) + (-b) \<le> 0)" by arith
  1696   show ?thesis by (simp only: th split_int_le_real'[where a="-a" and b="-b"])
  1697     (simp add: algebra_simps ,arith)
  1698 qed
  1699 
  1700 lemma split_int_eq_real: "(real (a::int) = b) = ( a = floor b \<and> b = real (floor b))" (is "?l = ?r")
  1701 by auto
  1702 
  1703 lemma split_int_eq_real': "(real (a::int) + b = 0) = ( a - floor (-b) = 0 \<and> real (floor (-b)) + b = 0)" (is "?l = ?r")
  1704 proof-
  1705   have "?l = (real a = -b)" by arith
  1706   with split_int_eq_real[where a="a" and b="-b"] show ?thesis by simp arith
  1707 qed
  1708 
  1709 lemma zlfm_I:
  1710   assumes qfp: "qfree p"
  1711   shows "(Ifm (real i #bs) (zlfm p) = Ifm (real i# bs) p) \<and> iszlfm (zlfm p) (real (i::int) #bs)"
  1712   (is "(?I (?l p) = ?I p) \<and> ?L (?l p)")
  1713 using qfp
  1714 proof(induct p rule: zlfm.induct)
  1715   case (5 a) 
  1716   let ?c = "fst (zsplit0 a)"
  1717   let ?r = "snd (zsplit0 a)"
  1718   have spl: "zsplit0 a = (?c,?r)" by simp
  1719   from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1720   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto 
  1721   let ?N = "\<lambda> t. Inum (real i#bs) t"
  1722   have "?c = 0 \<or> (?c >0 \<and> ?c\<noteq>0) \<or> (?c<0 \<and> ?c\<noteq>0)" by arith
  1723   moreover
  1724   {assume "?c=0" hence ?case using zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1725       by (cases "?r", simp_all add: Let_def split_def,rename_tac nat a b,case_tac "nat", simp_all)}
  1726   moreover
  1727   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Lt a))" 
  1728       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1729     have "?I (Lt a) = (real (?c * i) + (?N ?r) < 0)" using Ia by (simp add: Let_def split_def)
  1730     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)
  1731     finally have ?case using l by simp}
  1732   moreover
  1733   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Lt a))" 
  1734       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1735     have "?I (Lt a) = (real (?c * i) + (?N ?r) < 0)" using Ia by (simp add: Let_def split_def)
  1736     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 ac_simps, arith)
  1737     finally have ?case using l by simp}
  1738   ultimately show ?case by blast
  1739 next
  1740   case (6 a)
  1741   let ?c = "fst (zsplit0 a)"
  1742   let ?r = "snd (zsplit0 a)"
  1743   have spl: "zsplit0 a = (?c,?r)" by simp
  1744   from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1745   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto 
  1746   let ?N = "\<lambda> t. Inum (real i#bs) t"
  1747   have "?c = 0 \<or> (?c >0 \<and> ?c\<noteq>0) \<or> (?c<0 \<and> ?c\<noteq>0)" by arith
  1748   moreover
  1749   {assume "?c=0" hence ?case using zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1750       by (cases "?r", simp_all add: Let_def split_def, rename_tac nat a b, case_tac "nat",simp_all)}
  1751   moreover
  1752   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Le a))" 
  1753       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1754     have "?I (Le a) = (real (?c * i) + (?N ?r) \<le> 0)" using Ia by (simp add: Let_def split_def)
  1755     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)
  1756     finally have ?case using l by simp}
  1757   moreover
  1758   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Le a))" 
  1759       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1760     have "?I (Le a) = (real (?c * i) + (?N ?r) \<le> 0)" using Ia by (simp add: Let_def split_def)
  1761     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 ac_simps, arith)
  1762     finally have ?case using l by simp}
  1763   ultimately show ?case by blast
  1764 next
  1765   case (7 a) 
  1766   let ?c = "fst (zsplit0 a)"
  1767   let ?r = "snd (zsplit0 a)"
  1768   have spl: "zsplit0 a = (?c,?r)" by simp
  1769   from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1770   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto 
  1771   let ?N = "\<lambda> t. Inum (real i#bs) t"
  1772   have "?c = 0 \<or> (?c >0 \<and> ?c\<noteq>0) \<or> (?c<0 \<and> ?c\<noteq>0)" by arith
  1773   moreover
  1774   {assume "?c=0" hence ?case using zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1775       by (cases "?r", simp_all add: Let_def split_def, rename_tac nat a b, case_tac "nat", simp_all)}
  1776   moreover
  1777   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Gt a))" 
  1778       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1779     have "?I (Gt a) = (real (?c * i) + (?N ?r) > 0)" using Ia by (simp add: Let_def split_def)
  1780     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)
  1781     finally have ?case using l by simp}
  1782   moreover
  1783   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Gt a))" 
  1784       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1785     have "?I (Gt a) = (real (?c * i) + (?N ?r) > 0)" using Ia by (simp add: Let_def split_def)
  1786     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 ac_simps, arith)
  1787     finally have ?case using l by simp}
  1788   ultimately show ?case by blast
  1789 next
  1790   case (8 a)
  1791    let ?c = "fst (zsplit0 a)"
  1792   let ?r = "snd (zsplit0 a)"
  1793   have spl: "zsplit0 a = (?c,?r)" by simp
  1794   from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1795   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto 
  1796   let ?N = "\<lambda> t. Inum (real i#bs) t"
  1797   have "?c = 0 \<or> (?c >0 \<and> ?c\<noteq>0) \<or> (?c<0 \<and> ?c\<noteq>0)" by arith
  1798   moreover
  1799   {assume "?c=0" hence ?case using zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1800       by (cases "?r", simp_all add: Let_def split_def, rename_tac nat a b, case_tac "nat", simp_all)}
  1801   moreover
  1802   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Ge a))" 
  1803       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1804     have "?I (Ge a) = (real (?c * i) + (?N ?r) \<ge> 0)" using Ia by (simp add: Let_def split_def)
  1805     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)
  1806     finally have ?case using l by simp}
  1807   moreover
  1808   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Ge a))" 
  1809       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1810     have "?I (Ge a) = (real (?c * i) + (?N ?r) \<ge> 0)" using Ia by (simp add: Let_def split_def)
  1811     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 ac_simps, arith)
  1812     finally have ?case using l by simp}
  1813   ultimately show ?case by blast
  1814 next
  1815   case (9 a)
  1816   let ?c = "fst (zsplit0 a)"
  1817   let ?r = "snd (zsplit0 a)"
  1818   have spl: "zsplit0 a = (?c,?r)" by simp
  1819   from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1820   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto 
  1821   let ?N = "\<lambda> t. Inum (real i#bs) t"
  1822   have "?c = 0 \<or> (?c >0 \<and> ?c\<noteq>0) \<or> (?c<0 \<and> ?c\<noteq>0)" by arith
  1823   moreover
  1824   {assume "?c=0" hence ?case using zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1825       by (cases "?r", simp_all add: Let_def split_def, rename_tac nat a b, case_tac "nat", simp_all)}
  1826   moreover
  1827   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Eq a))" 
  1828       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1829     have "?I (Eq a) = (real (?c * i) + (?N ?r) = 0)" using Ia by (simp add: Let_def split_def)
  1830     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)
  1831     finally have ?case using l by simp}
  1832   moreover
  1833   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (Eq a))" 
  1834       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1835     have "?I (Eq a) = (real (?c * i) + (?N ?r) = 0)" using Ia by (simp add: Let_def split_def)
  1836     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)
  1837     finally have ?case using l by simp}
  1838   ultimately show ?case by blast
  1839 next
  1840   case (10 a)
  1841   let ?c = "fst (zsplit0 a)"
  1842   let ?r = "snd (zsplit0 a)"
  1843   have spl: "zsplit0 a = (?c,?r)" by simp
  1844   from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1845   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto 
  1846   let ?N = "\<lambda> t. Inum (real i#bs) t"
  1847   have "?c = 0 \<or> (?c >0 \<and> ?c\<noteq>0) \<or> (?c<0 \<and> ?c\<noteq>0)" by arith
  1848   moreover
  1849   {assume "?c=0" hence ?case using zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1850       by (cases "?r", simp_all add: Let_def split_def, rename_tac nat a b, case_tac "nat", simp_all)}
  1851   moreover
  1852   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (NEq a))" 
  1853       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1854     have "?I (NEq a) = (real (?c * i) + (?N ?r) \<noteq> 0)" using Ia by (simp add: Let_def split_def)
  1855     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)
  1856     finally have ?case using l by simp}
  1857   moreover
  1858   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" hence l: "?L (?l (NEq a))" 
  1859       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1860     have "?I (NEq a) = (real (?c * i) + (?N ?r) \<noteq> 0)" using Ia by (simp add: Let_def split_def)
  1861     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)
  1862     finally have ?case using l by simp}
  1863   ultimately show ?case by blast
  1864 next
  1865   case (11 j a)
  1866   let ?c = "fst (zsplit0 a)"
  1867   let ?r = "snd (zsplit0 a)"
  1868   have spl: "zsplit0 a = (?c,?r)" by simp
  1869   from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1870   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto 
  1871   let ?N = "\<lambda> t. Inum (real i#bs) t"
  1872   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
  1873   moreover
  1874   { assume j: "j=0" hence z: "zlfm (Dvd j a) = (zlfm (Eq a))" by (simp add: Let_def) 
  1875     hence ?case using 11 j by (simp del: zlfm.simps add: rdvd_left_0_eq)}
  1876   moreover
  1877   {assume "?c=0" and "j\<noteq>0" hence ?case 
  1878       using zsplit0_I[OF spl, where x="i" and bs="bs"] rdvd_abs1[where d="j"]
  1879       by (cases "?r", simp_all add: Let_def split_def, rename_tac nat a b, case_tac "nat", simp_all)}
  1880   moreover
  1881   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" and jnz: "j\<noteq>0" hence l: "?L (?l (Dvd j a))" 
  1882       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1883     have "?I (Dvd j a) = (real j rdvd (real (?c * i) + (?N ?r)))" 
  1884       using Ia by (simp add: Let_def split_def)
  1885     also have "\<dots> = (real (abs j) rdvd real (?c*i) + (?N ?r))" 
  1886       by (simp only: rdvd_abs1[where d="j" and t="real (?c*i) + ?N ?r", symmetric]) simp
  1887     also have "\<dots> = ((abs j) dvd (floor ((?N ?r) + real (?c*i))) \<and> 
  1888        (real (floor ((?N ?r) + real (?c*i))) = (real (?c*i) + (?N ?r))))" 
  1889       by(simp only: int_rdvd_real[where i="abs j" and x="real (?c*i) + (?N ?r)"]) (simp only: ac_simps)
  1890     also have "\<dots> = (?I (?l (Dvd j a)))" using cp cnz jnz  
  1891       by (simp add: Let_def split_def int_rdvd_iff[symmetric]  
  1892         del: real_of_int_mult) (auto simp add: ac_simps)
  1893     finally have ?case using l jnz  by simp }
  1894   moreover
  1895   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" and jnz: "j\<noteq>0" hence l: "?L (?l (Dvd j a))" 
  1896       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1897     have "?I (Dvd j a) = (real j rdvd (real (?c * i) + (?N ?r)))" 
  1898       using Ia by (simp add: Let_def split_def)
  1899     also have "\<dots> = (real (abs j) rdvd real (?c*i) + (?N ?r))" 
  1900       by (simp only: rdvd_abs1[where d="j" and t="real (?c*i) + ?N ?r", symmetric]) simp
  1901     also have "\<dots> = ((abs j) dvd (floor ((?N ?r) + real (?c*i))) \<and> 
  1902        (real (floor ((?N ?r) + real (?c*i))) = (real (?c*i) + (?N ?r))))" 
  1903       by(simp only: int_rdvd_real[where i="abs j" and x="real (?c*i) + (?N ?r)"]) (simp only: ac_simps)
  1904     also have "\<dots> = (?I (?l (Dvd j a)))" using cn cnz jnz
  1905       using rdvd_minus [where d="abs j" and t="real (?c*i + floor (?N ?r))", simplified, symmetric]
  1906       by (simp add: Let_def split_def int_rdvd_iff[symmetric]  
  1907         del: real_of_int_mult) (auto simp add: ac_simps)
  1908     finally have ?case using l jnz by blast }
  1909   ultimately show ?case by blast
  1910 next
  1911   case (12 j a)
  1912   let ?c = "fst (zsplit0 a)"
  1913   let ?r = "snd (zsplit0 a)"
  1914   have spl: "zsplit0 a = (?c,?r)" by simp
  1915   from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  1916   have Ia:"Inum (real i # bs) a = Inum (real i #bs) (CN 0 ?c ?r)" and nb: "numbound0 ?r" by auto 
  1917   let ?N = "\<lambda> t. Inum (real i#bs) t"
  1918   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
  1919   moreover
  1920   {assume j: "j=0" hence z: "zlfm (NDvd j a) = (zlfm (NEq a))" by (simp add: Let_def) 
  1921     hence ?case using 12 j by (simp del: zlfm.simps add: rdvd_left_0_eq)}
  1922   moreover
  1923   {assume "?c=0" and "j\<noteq>0" hence ?case 
  1924       using zsplit0_I[OF spl, where x="i" and bs="bs"] rdvd_abs1[where d="j"]
  1925       by (cases "?r", simp_all add: Let_def split_def, rename_tac nat a b, case_tac "nat", simp_all)}
  1926   moreover
  1927   {assume cp: "?c > 0" and cnz: "?c\<noteq>0" and jnz: "j\<noteq>0" hence l: "?L (?l (NDvd j a))" 
  1928       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1929     have "?I (NDvd j a) = (\<not> (real j rdvd (real (?c * i) + (?N ?r))))" 
  1930       using Ia by (simp add: Let_def split_def)
  1931     also have "\<dots> = (\<not> (real (abs j) rdvd real (?c*i) + (?N ?r)))" 
  1932       by (simp only: rdvd_abs1[where d="j" and t="real (?c*i) + ?N ?r", symmetric]) simp
  1933     also have "\<dots> = (\<not> ((abs j) dvd (floor ((?N ?r) + real (?c*i))) \<and> 
  1934        (real (floor ((?N ?r) + real (?c*i))) = (real (?c*i) + (?N ?r)))))" 
  1935       by(simp only: int_rdvd_real[where i="abs j" and x="real (?c*i) + (?N ?r)"]) (simp only: ac_simps)
  1936     also have "\<dots> = (?I (?l (NDvd j a)))" using cp cnz jnz  
  1937       by (simp add: Let_def split_def int_rdvd_iff[symmetric]  
  1938         del: real_of_int_mult) (auto simp add: ac_simps)
  1939     finally have ?case using l jnz  by simp }
  1940   moreover
  1941   {assume cn: "?c < 0" and cnz: "?c\<noteq>0" and jnz: "j\<noteq>0" hence l: "?L (?l (NDvd j a))" 
  1942       by (simp add: nb Let_def split_def isint_Floor isint_neg)
  1943     have "?I (NDvd j a) = (\<not> (real j rdvd (real (?c * i) + (?N ?r))))" 
  1944       using Ia by (simp add: Let_def split_def)
  1945     also have "\<dots> = (\<not> (real (abs j) rdvd real (?c*i) + (?N ?r)))" 
  1946       by (simp only: rdvd_abs1[where d="j" and t="real (?c*i) + ?N ?r", symmetric]) simp
  1947     also have "\<dots> = (\<not> ((abs j) dvd (floor ((?N ?r) + real (?c*i))) \<and> 
  1948        (real (floor ((?N ?r) + real (?c*i))) = (real (?c*i) + (?N ?r)))))" 
  1949       by(simp only: int_rdvd_real[where i="abs j" and x="real (?c*i) + (?N ?r)"]) (simp only: ac_simps)
  1950     also have "\<dots> = (?I (?l (NDvd j a)))" using cn cnz jnz
  1951       using rdvd_minus [where d="abs j" and t="real (?c*i + floor (?N ?r))", simplified, symmetric]
  1952       by (simp add: Let_def split_def int_rdvd_iff[symmetric]  
  1953         del: real_of_int_mult) (auto simp add: ac_simps)
  1954     finally have ?case using l jnz by blast }
  1955   ultimately show ?case by blast
  1956 qed auto
  1957 
  1958 text{* plusinf : Virtual substitution of @{text "+\<infinity>"}
  1959        minusinf: Virtual substitution of @{text "-\<infinity>"}
  1960        @{text "\<delta>"} Compute lcm @{text "d| Dvd d  c*x+t \<in> p"}
  1961        @{text "d_\<delta>"} checks if a given l divides all the ds above*}
  1962 
  1963 fun minusinf:: "fm \<Rightarrow> fm" where
  1964   "minusinf (And p q) = conj (minusinf p) (minusinf q)" 
  1965 | "minusinf (Or p q) = disj (minusinf p) (minusinf q)" 
  1966 | "minusinf (Eq  (CN 0 c e)) = F"
  1967 | "minusinf (NEq (CN 0 c e)) = T"
  1968 | "minusinf (Lt  (CN 0 c e)) = T"
  1969 | "minusinf (Le  (CN 0 c e)) = T"
  1970 | "minusinf (Gt  (CN 0 c e)) = F"
  1971 | "minusinf (Ge  (CN 0 c e)) = F"
  1972 | "minusinf p = p"
  1973 
  1974 lemma minusinf_qfree: "qfree p \<Longrightarrow> qfree (minusinf p)"
  1975   by (induct p rule: minusinf.induct, auto)
  1976 
  1977 fun plusinf:: "fm \<Rightarrow> fm" where
  1978   "plusinf (And p q) = conj (plusinf p) (plusinf q)" 
  1979 | "plusinf (Or p q) = disj (plusinf p) (plusinf q)" 
  1980 | "plusinf (Eq  (CN 0 c e)) = F"
  1981 | "plusinf (NEq (CN 0 c e)) = T"
  1982 | "plusinf (Lt  (CN 0 c e)) = F"
  1983 | "plusinf (Le  (CN 0 c e)) = F"
  1984 | "plusinf (Gt  (CN 0 c e)) = T"
  1985 | "plusinf (Ge  (CN 0 c e)) = T"
  1986 | "plusinf p = p"
  1987 
  1988 fun \<delta> :: "fm \<Rightarrow> int" where
  1989   "\<delta> (And p q) = lcm (\<delta> p) (\<delta> q)" 
  1990 | "\<delta> (Or p q) = lcm (\<delta> p) (\<delta> q)" 
  1991 | "\<delta> (Dvd i (CN 0 c e)) = i"
  1992 | "\<delta> (NDvd i (CN 0 c e)) = i"
  1993 | "\<delta> p = 1"
  1994 
  1995 fun d_\<delta> :: "fm \<Rightarrow> int \<Rightarrow> bool" where
  1996   "d_\<delta> (And p q) = (\<lambda> d. d_\<delta> p d \<and> d_\<delta> q d)" 
  1997 | "d_\<delta> (Or p q) = (\<lambda> d. d_\<delta> p d \<and> d_\<delta> q d)" 
  1998 | "d_\<delta> (Dvd i (CN 0 c e)) = (\<lambda> d. i dvd d)"
  1999 | "d_\<delta> (NDvd i (CN 0 c e)) = (\<lambda> d. i dvd d)"
  2000 | "d_\<delta> p = (\<lambda> d. True)"
  2001 
  2002 lemma delta_mono: 
  2003   assumes lin: "iszlfm p bs"
  2004   and d: "d dvd d'"
  2005   and ad: "d_\<delta> p d"
  2006   shows "d_\<delta> p d'"
  2007   using lin ad d
  2008 proof(induct p rule: iszlfm.induct)
  2009   case (9 i c e)  thus ?case using d
  2010     by (simp add: dvd_trans[of "i" "d" "d'"])
  2011 next
  2012   case (10 i c e) thus ?case using d
  2013     by (simp add: dvd_trans[of "i" "d" "d'"])
  2014 qed simp_all
  2015 
  2016 lemma \<delta> : assumes lin:"iszlfm p bs"
  2017   shows "d_\<delta> p (\<delta> p) \<and> \<delta> p >0"
  2018 using lin
  2019 proof (induct p rule: iszlfm.induct)
  2020   case (1 p q) 
  2021   let ?d = "\<delta> (And p q)"
  2022   from 1 lcm_pos_int have dp: "?d >0" by simp
  2023   have d1: "\<delta> p dvd \<delta> (And p q)" using 1 by simp 
  2024   hence th: "d_\<delta> p ?d" 
  2025     using delta_mono 1 by (simp only: iszlfm.simps) blast
  2026   have "\<delta> q dvd \<delta> (And p q)" using 1 by simp 
  2027   hence th': "d_\<delta> q ?d" using delta_mono 1 by (simp only: iszlfm.simps) blast
  2028   from th th' dp show ?case by simp 
  2029 next
  2030   case (2 p q)  
  2031   let ?d = "\<delta> (And p q)"
  2032   from 2 lcm_pos_int have dp: "?d >0" by simp
  2033   have "\<delta> p dvd \<delta> (And p q)" using 2 by simp
  2034   hence th: "d_\<delta> p ?d" using delta_mono 2 by (simp only: iszlfm.simps) blast
  2035   have "\<delta> q dvd \<delta> (And p q)" using 2 by simp
  2036   hence th': "d_\<delta> q ?d" using delta_mono 2 by (simp only: iszlfm.simps) blast
  2037   from th th' dp show ?case by simp
  2038 qed simp_all
  2039 
  2040 
  2041 lemma minusinf_inf:
  2042   assumes linp: "iszlfm p (a # bs)"
  2043   shows "\<exists> (z::int). \<forall> x < z. Ifm ((real x)#bs) (minusinf p) = Ifm ((real x)#bs) p"
  2044   (is "?P p" is "\<exists> (z::int). \<forall> x < z. ?I x (?M p) = ?I x p")
  2045 using linp
  2046 proof (induct p rule: minusinf.induct)
  2047   case (1 f g)
  2048   then 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   with 1 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 (And f g)) = ?I x (And f g)" by simp
  2054   thus ?case by blast
  2055 next
  2056   case (2 f g)
  2057   then have "?P f" by simp
  2058   then obtain z1 where z1_def: "\<forall> x < z1. ?I x (?M f) = ?I x f" by blast
  2059   with 2 have "?P g" by simp
  2060   then obtain z2 where z2_def: "\<forall> x < z2. ?I x (?M g) = ?I x g" by blast
  2061   let ?z = "min z1 z2"
  2062   from z1_def z2_def have "\<forall> x < ?z. ?I x (?M (Or f g)) = ?I x (Or f g)" by simp
  2063   thus ?case by blast
  2064 next
  2065   case (3 c e) 
  2066   then have "c > 0" by simp
  2067   hence rcpos: "real c > 0" by simp
  2068   from 3 have nbe: "numbound0 e" by simp
  2069   fix y
  2070   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))"
  2071   proof (simp add: less_floor_eq , rule allI, rule impI) 
  2072     fix x :: int
  2073     assume A: "real x + 1 \<le> - (Inum (y # bs) e / real c)"
  2074     hence th1:"real x < - (Inum (y # bs) e / real c)" by simp
  2075     with rcpos  have "(real c)*(real  x) < (real c)*(- (Inum (y # bs) e / real c))"
  2076       by (simp only: mult_strict_left_mono [OF th1 rcpos])
  2077     hence "real c * real x + Inum (y # bs) e \<noteq> 0"using rcpos  by simp
  2078     thus "real c * real x + Inum (real x # bs) e \<noteq> 0" 
  2079       using numbound0_I[OF nbe, where b="y" and bs="bs" and b'="real x"]  by simp
  2080   qed
  2081   thus ?case by blast
  2082 next
  2083   case (4 c e) 
  2084   then have "c > 0" by simp hence rcpos: "real c > 0" by simp
  2085   from 4 have nbe: "numbound0 e" by simp
  2086   fix y
  2087   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))"
  2088   proof (simp add: less_floor_eq , rule allI, rule impI) 
  2089     fix x :: int
  2090     assume A: "real x + 1 \<le> - (Inum (y # bs) e / real c)"
  2091     hence th1:"real x < - (Inum (y # bs) e / real c)" by simp
  2092     with rcpos  have "(real c)*(real  x) < (real c)*(- (Inum (y # bs) e / real c))"
  2093       by (simp only: mult_strict_left_mono [OF th1 rcpos])
  2094     hence "real c * real x + Inum (y # bs) e \<noteq> 0"using rcpos  by simp
  2095     thus "real c * real x + Inum (real x # bs) e \<noteq> 0" 
  2096       using numbound0_I[OF nbe, where b="y" and bs="bs" and b'="real x"]  by simp
  2097   qed
  2098   thus ?case by blast
  2099 next
  2100   case (5 c e) 
  2101   then have "c > 0" by simp hence rcpos: "real c > 0" by simp
  2102   from 5 have nbe: "numbound0 e" by simp
  2103   fix y
  2104   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))"
  2105   proof (simp add: less_floor_eq , rule allI, rule impI) 
  2106     fix x :: int
  2107     assume A: "real x + 1 \<le> - (Inum (y # bs) e / real c)"
  2108     hence th1:"real x < - (Inum (y # bs) e / real c)" by simp
  2109     with rcpos  have "(real c)*(real  x) < (real c)*(- (Inum (y # bs) e / real c))"
  2110       by (simp only: mult_strict_left_mono [OF th1 rcpos])
  2111     thus "real c * real x + Inum (real x # bs) e < 0" 
  2112       using numbound0_I[OF nbe, where b="y" and bs="bs" and b'="real x"] rcpos by simp
  2113   qed
  2114   thus ?case by blast
  2115 next
  2116   case (6 c e) 
  2117   then have "c > 0" by simp hence rcpos: "real c > 0" by simp
  2118   from 6 have nbe: "numbound0 e" by simp
  2119   fix y
  2120   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))"
  2121   proof (simp add: less_floor_eq , rule allI, rule impI) 
  2122     fix x :: int
  2123     assume A: "real x + 1 \<le> - (Inum (y # bs) e / real c)"
  2124     hence th1:"real x < - (Inum (y # bs) e / real c)" by simp
  2125     with rcpos  have "(real c)*(real  x) < (real c)*(- (Inum (y # bs) e / real c))"
  2126       by (simp only: mult_strict_left_mono [OF th1 rcpos])
  2127     thus "real c * real x + Inum (real x # bs) e \<le> 0" 
  2128       using numbound0_I[OF nbe, where b="y" and bs="bs" and b'="real x"] rcpos by simp
  2129   qed
  2130   thus ?case by blast
  2131 next
  2132   case (7 c e) 
  2133   then have "c > 0" by simp hence rcpos: "real c > 0" by simp
  2134   from 7 have nbe: "numbound0 e" by simp
  2135   fix y
  2136   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))"
  2137   proof (simp add: less_floor_eq , rule allI, rule impI) 
  2138     fix x :: int
  2139     assume A: "real x + 1 \<le> - (Inum (y # bs) e / real c)"
  2140     hence th1:"real x < - (Inum (y # bs) e / real c)" by simp
  2141     with rcpos  have "(real c)*(real  x) < (real c)*(- (Inum (y # bs) e / real c))"
  2142       by (simp only: mult_strict_left_mono [OF th1 rcpos])
  2143     thus "\<not> (real c * real x + Inum (real x # bs) e>0)" 
  2144       using numbound0_I[OF nbe, where b="y" and bs="bs" and b'="real x"] rcpos by simp
  2145   qed
  2146   thus ?case by blast
  2147 next
  2148   case (8 c e) 
  2149   then have "c > 0" by simp hence rcpos: "real c > 0" by simp
  2150   from 8 have nbe: "numbound0 e" by simp
  2151   fix y
  2152   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))"
  2153   proof (simp add: less_floor_eq , rule allI, rule impI) 
  2154     fix x :: int
  2155     assume A: "real x + 1 \<le> - (Inum (y # bs) e / real c)"
  2156     hence th1:"real x < - (Inum (y # bs) e / real c)" by simp
  2157     with rcpos  have "(real c)*(real  x) < (real c)*(- (Inum (y # bs) e / real c))"
  2158       by (simp only: mult_strict_left_mono [OF th1 rcpos])
  2159     thus "\<not> real c * real x + Inum (real x # bs) e \<ge> 0" 
  2160       using numbound0_I[OF nbe, where b="y" and bs="bs" and b'="real x"] rcpos by simp
  2161   qed
  2162   thus ?case by blast
  2163 qed simp_all
  2164 
  2165 lemma minusinf_repeats:
  2166   assumes d: "d_\<delta> p d" and linp: "iszlfm p (a # bs)"
  2167   shows "Ifm ((real(x - k*d))#bs) (minusinf p) = Ifm (real x #bs) (minusinf p)"
  2168 using linp d
  2169 proof(induct p rule: iszlfm.induct) 
  2170   case (9 i c e) hence nbe: "numbound0 e"  and id: "i dvd d" by simp+
  2171     hence "\<exists> k. d=i*k" by (simp add: dvd_def)
  2172     then obtain "di" where di_def: "d=i*di" by blast
  2173     show ?case 
  2174     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)
  2175       assume 
  2176         "real i rdvd real c * real x - real c * (real k * real d) + Inum (real x # bs) e"
  2177       (is "?ri rdvd ?rc*?rx - ?rc*(?rk*?rd) + ?I x e" is "?ri rdvd ?rt")
  2178       hence "\<exists> (l::int). ?rt = ?ri * (real l)" by (simp add: rdvd_def)
  2179       hence "\<exists> (l::int). ?rc*?rx+ ?I x e = ?ri*(real l)+?rc*(?rk * (real i) * (real di))" 
  2180         by (simp add: algebra_simps di_def)
  2181       hence "\<exists> (l::int). ?rc*?rx+ ?I x e = ?ri*(real (l + c*k*di))"
  2182         by (simp add: algebra_simps)
  2183       hence "\<exists> (l::int). ?rc*?rx+ ?I x e = ?ri* (real l)" by blast
  2184       thus "real i rdvd real c * real x + Inum (real x # bs) e" using rdvd_def by simp
  2185     next
  2186       assume 
  2187         "real i rdvd real c * real x + Inum (real x # bs) e" (is "?ri rdvd ?rc*?rx+?e")
  2188       hence "\<exists> (l::int). ?rc*?rx+?e = ?ri * (real l)" by (simp add: rdvd_def)
  2189       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real l) - real c * (real k * real d)" by simp
  2190       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)
  2191       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real (l - c*k*di))" by (simp add: algebra_simps)
  2192       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real l)"
  2193         by blast
  2194       thus "real i rdvd real c * real x - real c * (real k * real d) + Inum (real x # bs) e" using rdvd_def by simp
  2195     qed
  2196 next
  2197   case (10 i c e) hence nbe: "numbound0 e"  and id: "i dvd d" by simp+
  2198     hence "\<exists> k. d=i*k" by (simp add: dvd_def)
  2199     then obtain "di" where di_def: "d=i*di" by blast
  2200     show ?case 
  2201     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)
  2202       assume 
  2203         "real i rdvd real c * real x - real c * (real k * real d) + Inum (real x # bs) e"
  2204       (is "?ri rdvd ?rc*?rx - ?rc*(?rk*?rd) + ?I x e" is "?ri rdvd ?rt")
  2205       hence "\<exists> (l::int). ?rt = ?ri * (real l)" by (simp add: rdvd_def)
  2206       hence "\<exists> (l::int). ?rc*?rx+ ?I x e = ?ri*(real l)+?rc*(?rk * (real i) * (real di))" 
  2207         by (simp add: algebra_simps di_def)
  2208       hence "\<exists> (l::int). ?rc*?rx+ ?I x e = ?ri*(real (l + c*k*di))"
  2209         by (simp add: algebra_simps)
  2210       hence "\<exists> (l::int). ?rc*?rx+ ?I x e = ?ri* (real l)" by blast
  2211       thus "real i rdvd real c * real x + Inum (real x # bs) e" using rdvd_def by simp
  2212     next
  2213       assume 
  2214         "real i rdvd real c * real x + Inum (real x # bs) e" (is "?ri rdvd ?rc*?rx+?e")
  2215       hence "\<exists> (l::int). ?rc*?rx+?e = ?ri * (real l)"
  2216         by (simp add: rdvd_def)
  2217       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real l) - real c * (real k * real d)"
  2218         by simp
  2219       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real l) - real c * (real k * real i * real di)"
  2220         by (simp add: di_def)
  2221       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real (l - c*k*di))"
  2222         by (simp add: algebra_simps)
  2223       hence "\<exists> (l::int). ?rc*?rx - real c * (real k * real d) +?e = ?ri * (real l)"
  2224         by blast
  2225       thus "real i rdvd real c * real x - real c * (real k * real d) + Inum (real x # bs) e"
  2226         using rdvd_def by simp
  2227     qed
  2228 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)
  2229 
  2230 lemma minusinf_ex:
  2231   assumes lin: "iszlfm p (real (a::int) #bs)"
  2232   and exmi: "\<exists> (x::int). Ifm (real x#bs) (minusinf p)" (is "\<exists> x. ?P1 x")
  2233   shows "\<exists> (x::int). Ifm (real x#bs) p" (is "\<exists> x. ?P x")
  2234 proof-
  2235   let ?d = "\<delta> p"
  2236   from \<delta> [OF lin] have dpos: "?d >0" by simp
  2237   from \<delta> [OF lin] have alld: "d_\<delta> p ?d" by simp
  2238   from minusinf_repeats[OF alld lin] have th1:"\<forall> x k. ?P1 x = ?P1 (x - (k * ?d))" by simp
  2239   from minusinf_inf[OF lin] have th2:"\<exists> z. \<forall> x. x<z \<longrightarrow> (?P x = ?P1 x)" by blast
  2240   from minusinfinity [OF dpos th1 th2] exmi show ?thesis by blast
  2241 qed
  2242 
  2243 lemma minusinf_bex:
  2244   assumes lin: "iszlfm p (real (a::int) #bs)"
  2245   shows "(\<exists> (x::int). Ifm (real x#bs) (minusinf p)) = 
  2246          (\<exists> (x::int)\<in> {1..\<delta> p}. Ifm (real x#bs) (minusinf p))"
  2247   (is "(\<exists> x. ?P x) = _")
  2248 proof-
  2249   let ?d = "\<delta> p"
  2250   from \<delta> [OF lin] have dpos: "?d >0" by simp
  2251   from \<delta> [OF lin] have alld: "d_\<delta> p ?d" by simp
  2252   from minusinf_repeats[OF alld lin] have th1:"\<forall> x k. ?P x = ?P (x - (k * ?d))" by simp
  2253   from periodic_finite_ex[OF dpos th1] show ?thesis by blast
  2254 qed
  2255 
  2256 lemma dvd1_eq1: "x >0 \<Longrightarrow> (x::int) dvd 1 = (x = 1)" by auto
  2257 
  2258 consts 
  2259   a_\<beta> :: "fm \<Rightarrow> int \<Rightarrow> fm" (* adjusts the coeffitients of a formula *)
  2260   d_\<beta> :: "fm \<Rightarrow> int \<Rightarrow> bool" (* tests if all coeffs c of c divide a given l*)
  2261   \<zeta>  :: "fm \<Rightarrow> int" (* computes the lcm of all coefficients of x*)
  2262   \<beta> :: "fm \<Rightarrow> num list"
  2263   \<alpha> :: "fm \<Rightarrow> num list"
  2264 
  2265 recdef a_\<beta> "measure size"
  2266   "a_\<beta> (And p q) = (\<lambda> k. And (a_\<beta> p k) (a_\<beta> q k))" 
  2267   "a_\<beta> (Or p q) = (\<lambda> k. Or (a_\<beta> p k) (a_\<beta> q k))" 
  2268   "a_\<beta> (Eq  (CN 0 c e)) = (\<lambda> k. Eq (CN 0 1 (Mul (k div c) e)))"
  2269   "a_\<beta> (NEq (CN 0 c e)) = (\<lambda> k. NEq (CN 0 1 (Mul (k div c) e)))"
  2270   "a_\<beta> (Lt  (CN 0 c e)) = (\<lambda> k. Lt (CN 0 1 (Mul (k div c) e)))"
  2271   "a_\<beta> (Le  (CN 0 c e)) = (\<lambda> k. Le (CN 0 1 (Mul (k div c) e)))"
  2272   "a_\<beta> (Gt  (CN 0 c e)) = (\<lambda> k. Gt (CN 0 1 (Mul (k div c) e)))"
  2273   "a_\<beta> (Ge  (CN 0 c e)) = (\<lambda> k. Ge (CN 0 1 (Mul (k div c) e)))"
  2274   "a_\<beta> (Dvd i (CN 0 c e)) =(\<lambda> k. Dvd ((k div c)*i) (CN 0 1 (Mul (k div c) e)))"
  2275   "a_\<beta> (NDvd i (CN 0 c e))=(\<lambda> k. NDvd ((k div c)*i) (CN 0 1 (Mul (k div c) e)))"
  2276   "a_\<beta> p = (\<lambda> k. p)"
  2277 
  2278 recdef d_\<beta> "measure size"
  2279   "d_\<beta> (And p q) = (\<lambda> k. (d_\<beta> p k) \<and> (d_\<beta> q k))" 
  2280   "d_\<beta> (Or p q) = (\<lambda> k. (d_\<beta> p k) \<and> (d_\<beta> q k))" 
  2281   "d_\<beta> (Eq  (CN 0 c e)) = (\<lambda> k. c dvd k)"
  2282   "d_\<beta> (NEq (CN 0 c e)) = (\<lambda> k. c dvd k)"
  2283   "d_\<beta> (Lt  (CN 0 c e)) = (\<lambda> k. c dvd k)"
  2284   "d_\<beta> (Le  (CN 0 c e)) = (\<lambda> k. c dvd k)"
  2285   "d_\<beta> (Gt  (CN 0 c e)) = (\<lambda> k. c dvd k)"
  2286   "d_\<beta> (Ge  (CN 0 c e)) = (\<lambda> k. c dvd k)"
  2287   "d_\<beta> (Dvd i (CN 0 c e)) =(\<lambda> k. c dvd k)"
  2288   "d_\<beta> (NDvd i (CN 0 c e))=(\<lambda> k. c dvd k)"
  2289   "d_\<beta> p = (\<lambda> k. True)"
  2290 
  2291 recdef \<zeta> "measure size"
  2292   "\<zeta> (And p q) = lcm (\<zeta> p) (\<zeta> q)" 
  2293   "\<zeta> (Or p q) = lcm (\<zeta> p) (\<zeta> q)" 
  2294   "\<zeta> (Eq  (CN 0 c e)) = c"
  2295   "\<zeta> (NEq (CN 0 c e)) = c"
  2296   "\<zeta> (Lt  (CN 0 c e)) = c"
  2297   "\<zeta> (Le  (CN 0 c e)) = c"
  2298   "\<zeta> (Gt  (CN 0 c e)) = c"
  2299   "\<zeta> (Ge  (CN 0 c e)) = c"
  2300   "\<zeta> (Dvd i (CN 0 c e)) = c"
  2301   "\<zeta> (NDvd i (CN 0 c e))= c"
  2302   "\<zeta> p = 1"
  2303 
  2304 recdef \<beta> "measure size"
  2305   "\<beta> (And p q) = (\<beta> p @ \<beta> q)" 
  2306   "\<beta> (Or p q) = (\<beta> p @ \<beta> q)" 
  2307   "\<beta> (Eq  (CN 0 c e)) = [Sub (C -1) e]"
  2308   "\<beta> (NEq (CN 0 c e)) = [Neg e]"
  2309   "\<beta> (Lt  (CN 0 c e)) = []"
  2310   "\<beta> (Le  (CN 0 c e)) = []"
  2311   "\<beta> (Gt  (CN 0 c e)) = [Neg e]"
  2312   "\<beta> (Ge  (CN 0 c e)) = [Sub (C -1) e]"
  2313   "\<beta> p = []"
  2314 
  2315 recdef \<alpha> "measure size"
  2316   "\<alpha> (And p q) = (\<alpha> p @ \<alpha> q)" 
  2317   "\<alpha> (Or p q) = (\<alpha> p @ \<alpha> q)" 
  2318   "\<alpha> (Eq  (CN 0 c e)) = [Add (C -1) e]"
  2319   "\<alpha> (NEq (CN 0 c e)) = [e]"
  2320   "\<alpha> (Lt  (CN 0 c e)) = [e]"
  2321   "\<alpha> (Le  (CN 0 c e)) = [Add (C -1) e]"
  2322   "\<alpha> (Gt  (CN 0 c e)) = []"
  2323   "\<alpha> (Ge  (CN 0 c e)) = []"
  2324   "\<alpha> p = []"
  2325 consts mirror :: "fm \<Rightarrow> fm"
  2326 recdef mirror "measure size"
  2327   "mirror (And p q) = And (mirror p) (mirror q)" 
  2328   "mirror (Or p q) = Or (mirror p) (mirror q)" 
  2329   "mirror (Eq  (CN 0 c e)) = Eq (CN 0 c (Neg e))"
  2330   "mirror (NEq (CN 0 c e)) = NEq (CN 0 c (Neg e))"
  2331   "mirror (Lt  (CN 0 c e)) = Gt (CN 0 c (Neg e))"
  2332   "mirror (Le  (CN 0 c e)) = Ge (CN 0 c (Neg e))"
  2333   "mirror (Gt  (CN 0 c e)) = Lt (CN 0 c (Neg e))"
  2334   "mirror (Ge  (CN 0 c e)) = Le (CN 0 c (Neg e))"
  2335   "mirror (Dvd i (CN 0 c e)) = Dvd i (CN 0 c (Neg e))"
  2336   "mirror (NDvd i (CN 0 c e)) = NDvd i (CN 0 c (Neg e))"
  2337   "mirror p = p"
  2338 
  2339 lemma mirror_\<alpha>_\<beta>:
  2340   assumes lp: "iszlfm p (a#bs)"
  2341   shows "(Inum (real (i::int)#bs)) ` set (\<alpha> p) = (Inum (real i#bs)) ` set (\<beta> (mirror p))"
  2342   using lp by (induct p rule: mirror.induct) auto
  2343 
  2344 lemma mirror: 
  2345   assumes lp: "iszlfm p (a#bs)"
  2346   shows "Ifm (real (x::int)#bs) (mirror p) = Ifm (real (- x)#bs) p" 
  2347   using lp
  2348 proof(induct p rule: iszlfm.induct)
  2349   case (9 j c e)
  2350   have th: "(real j rdvd real c * real x - Inum (real x # bs) e) =
  2351        (real j rdvd - (real c * real x - Inum (real x # bs) e))"
  2352     by (simp only: rdvd_minus[symmetric])
  2353   from 9 th show ?case
  2354     by (simp add: algebra_simps
  2355       numbound0_I[where bs="bs" and b'="real x" and b="- real x"])
  2356 next
  2357   case (10 j c e)
  2358   have th: "(real j rdvd real c * real x - Inum (real x # bs) e) =
  2359        (real j rdvd - (real c * real x - Inum (real x # bs) e))"
  2360     by (simp only: rdvd_minus[symmetric])
  2361   from 10 th show  ?case
  2362     by (simp add: algebra_simps
  2363       numbound0_I[where bs="bs" and b'="real x" and b="- real x"])
  2364 qed (auto simp add: numbound0_I[where bs="bs" and b="real x" and b'="- real x"])
  2365 
  2366 lemma mirror_l: "iszlfm p (a#bs) \<Longrightarrow> iszlfm (mirror p) (a#bs)"
  2367   by (induct p rule: mirror.induct) (auto simp add: isint_neg)
  2368 
  2369 lemma mirror_d_\<beta>: "iszlfm p (a#bs) \<and> d_\<beta> p 1 
  2370   \<Longrightarrow> iszlfm (mirror p) (a#bs) \<and> d_\<beta> (mirror p) 1"
  2371   by (induct p rule: mirror.induct) (auto simp add: isint_neg)
  2372 
  2373 lemma mirror_\<delta>: "iszlfm p (a#bs) \<Longrightarrow> \<delta> (mirror p) = \<delta> p"
  2374   by (induct p rule: mirror.induct) auto
  2375 
  2376 
  2377 lemma mirror_ex: 
  2378   assumes lp: "iszlfm p (real (i::int)#bs)"
  2379   shows "(\<exists> (x::int). Ifm (real x#bs) (mirror p)) = (\<exists> (x::int). Ifm (real x#bs) p)"
  2380   (is "(\<exists> x. ?I x ?mp) = (\<exists> x. ?I x p)")
  2381 proof(auto)
  2382   fix x assume "?I x ?mp" hence "?I (- x) p" using mirror[OF lp] by blast
  2383   thus "\<exists> x. ?I x p" by blast
  2384 next
  2385   fix x assume "?I x p" hence "?I (- x) ?mp" 
  2386     using mirror[OF lp, where x="- x", symmetric] by auto
  2387   thus "\<exists> x. ?I x ?mp" by blast
  2388 qed
  2389 
  2390 lemma \<beta>_numbound0: assumes lp: "iszlfm p bs"
  2391   shows "\<forall> b\<in> set (\<beta> p). numbound0 b"
  2392   using lp by (induct p rule: \<beta>.induct,auto)
  2393 
  2394 lemma d_\<beta>_mono: 
  2395   assumes linp: "iszlfm p (a #bs)"
  2396   and dr: "d_\<beta> p l"
  2397   and d: "l dvd l'"
  2398   shows "d_\<beta> p l'"
  2399 using dr linp dvd_trans[of _ "l" "l'", simplified d]
  2400 by (induct p rule: iszlfm.induct) simp_all
  2401 
  2402 lemma \<alpha>_l: assumes lp: "iszlfm p (a#bs)"
  2403   shows "\<forall> b\<in> set (\<alpha> p). numbound0 b \<and> isint b (a#bs)"
  2404 using lp
  2405 by(induct p rule: \<alpha>.induct, auto simp add: isint_add isint_c)
  2406 
  2407 lemma \<zeta>: 
  2408   assumes linp: "iszlfm p (a #bs)"
  2409   shows "\<zeta> p > 0 \<and> d_\<beta> p (\<zeta> p)"
  2410 using linp
  2411 proof(induct p rule: iszlfm.induct)
  2412   case (1 p q)
  2413   then  have dl1: "\<zeta> p dvd lcm (\<zeta> p) (\<zeta> q)" by simp
  2414   from 1 have dl2: "\<zeta> q dvd lcm (\<zeta> p) (\<zeta> q)" by simp
  2415   from 1 d_\<beta>_mono[where p = "p" and l="\<zeta> p" and l'="lcm (\<zeta> p) (\<zeta> q)"] 
  2416     d_\<beta>_mono[where p = "q" and l="\<zeta> q" and l'="lcm (\<zeta> p) (\<zeta> q)"] 
  2417     dl1 dl2 show ?case by (auto simp add: lcm_pos_int)
  2418 next
  2419   case (2 p q)
  2420   then have dl1: "\<zeta> p dvd lcm (\<zeta> p) (\<zeta> q)" by simp
  2421   from 2 have dl2: "\<zeta> q dvd lcm (\<zeta> p) (\<zeta> q)" by simp
  2422   from 2 d_\<beta>_mono[where p = "p" and l="\<zeta> p" and l'="lcm (\<zeta> p) (\<zeta> q)"] 
  2423     d_\<beta>_mono[where p = "q" and l="\<zeta> q" and l'="lcm (\<zeta> p) (\<zeta> q)"] 
  2424     dl1 dl2 show ?case by (auto simp add: lcm_pos_int)
  2425 qed (auto simp add: lcm_pos_int)
  2426 
  2427 lemma a_\<beta>: assumes linp: "iszlfm p (a #bs)" and d: "d_\<beta> p l" and lp: "l > 0"
  2428   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)"
  2429 using linp d
  2430 proof (induct p rule: iszlfm.induct)
  2431   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+
  2432     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2433     from cp have cnz: "c \<noteq> 0" by simp
  2434     have "c div c\<le> l div c"
  2435       by (simp add: zdiv_mono1[OF clel cp])
  2436     then have ldcp:"0 < l div c" 
  2437       by (simp add: div_self[OF cnz])
  2438     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
  2439     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2440       by simp
  2441     hence "(real l * real x + real (l div c) * Inum (real x # bs) e < (0\<Colon>real)) =
  2442           (real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e < 0)"
  2443       by simp
  2444     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)
  2445     also have "\<dots> = (real c * real x + Inum (real x # bs) e < 0)"
  2446     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
  2447   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
  2448 next
  2449   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+
  2450     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2451     from cp have cnz: "c \<noteq> 0" by simp
  2452     have "c div c\<le> l div c"
  2453       by (simp add: zdiv_mono1[OF clel cp])
  2454     then have ldcp:"0 < l div c" 
  2455       by (simp add: div_self[OF cnz])
  2456     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
  2457     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2458       by simp
  2459     hence "(real l * real x + real (l div c) * Inum (real x # bs) e \<le> (0\<Colon>real)) =
  2460           (real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e \<le> 0)"
  2461       by simp
  2462     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)
  2463     also have "\<dots> = (real c * real x + Inum (real x # bs) e \<le> 0)"
  2464     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
  2465   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
  2466 next
  2467   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+
  2468     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2469     from cp have cnz: "c \<noteq> 0" by simp
  2470     have "c div c\<le> l div c"
  2471       by (simp add: zdiv_mono1[OF clel cp])
  2472     then have ldcp:"0 < l div c" 
  2473       by (simp add: div_self[OF cnz])
  2474     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
  2475     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2476       by simp
  2477     hence "(real l * real x + real (l div c) * Inum (real x # bs) e > (0\<Colon>real)) =
  2478           (real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e > 0)"
  2479       by simp
  2480     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)
  2481     also have "\<dots> = (real c * real x + Inum (real x # bs) e > 0)"
  2482     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
  2483   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
  2484 next
  2485   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+
  2486     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2487     from cp have cnz: "c \<noteq> 0" by simp
  2488     have "c div c\<le> l div c"
  2489       by (simp add: zdiv_mono1[OF clel cp])
  2490     then have ldcp:"0 < l div c" 
  2491       by (simp add: div_self[OF cnz])
  2492     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
  2493     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2494       by simp
  2495     hence "(real l * real x + real (l div c) * Inum (real x # bs) e \<ge> (0\<Colon>real)) =
  2496           (real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e \<ge> 0)"
  2497       by simp
  2498     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)
  2499     also have "\<dots> = (real c * real x + Inum (real x # bs) e \<ge> 0)"
  2500     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
  2501   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
  2502 next
  2503   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+
  2504     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2505     from cp have cnz: "c \<noteq> 0" by simp
  2506     have "c div c\<le> l div c"
  2507       by (simp add: zdiv_mono1[OF clel cp])
  2508     then have ldcp:"0 < l div c" 
  2509       by (simp add: div_self[OF cnz])
  2510     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
  2511     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2512       by simp
  2513     hence "(real l * real x + real (l div c) * Inum (real x # bs) e = (0\<Colon>real)) =
  2514           (real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e = 0)"
  2515       by simp
  2516     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)
  2517     also have "\<dots> = (real c * real x + Inum (real x # bs) e = 0)"
  2518     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
  2519   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
  2520 next
  2521   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+
  2522     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2523     from cp have cnz: "c \<noteq> 0" by simp
  2524     have "c div c\<le> l div c"
  2525       by (simp add: zdiv_mono1[OF clel cp])
  2526     then have ldcp:"0 < l div c" 
  2527       by (simp add: div_self[OF cnz])
  2528     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
  2529     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2530       by simp
  2531     hence "(real l * real x + real (l div c) * Inum (real x # bs) e \<noteq> (0\<Colon>real)) =
  2532           (real (c * (l div c)) * real x + real (l div c) * Inum (real x # bs) e \<noteq> 0)"
  2533       by simp
  2534     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)
  2535     also have "\<dots> = (real c * real x + Inum (real x # bs) e \<noteq> 0)"
  2536     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
  2537   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
  2538 next
  2539   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+
  2540     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2541     from cp have cnz: "c \<noteq> 0" by simp
  2542     have "c div c\<le> l div c"
  2543       by (simp add: zdiv_mono1[OF clel cp])
  2544     then have ldcp:"0 < l div c" 
  2545       by (simp add: div_self[OF cnz])
  2546     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
  2547     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2548       by simp
  2549     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
  2550     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)
  2551     also fix k have "\<dots> = (\<exists> (k::int). real c * real x + Inum (real x # bs) e - real j * real k = 0)"
  2552     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
  2553   also have "\<dots> = (\<exists> (k::int). real c * real x + Inum (real x # bs) e = real j * real k)" by simp
  2554   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 
  2555 next
  2556   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+
  2557     from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2558     from cp have cnz: "c \<noteq> 0" by simp
  2559     have "c div c\<le> l div c"
  2560       by (simp add: zdiv_mono1[OF clel cp])
  2561     then have ldcp:"0 < l div c" 
  2562       by (simp add: div_self[OF cnz])
  2563     have "c * (l div c) = c* (l div c) + l mod c" using d' dvd_eq_mod_eq_0[of "c" "l"] by simp
  2564     hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2565       by simp
  2566     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
  2567     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)
  2568     also fix k have "\<dots> = (\<exists> (k::int). real c * real x + Inum (real x # bs) e - real j * real k = 0)"
  2569     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
  2570   also have "\<dots> = (\<exists> (k::int). real c * real x + Inum (real x # bs) e = real j * real k)" by simp
  2571   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
  2572 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)
  2573 
  2574 lemma a_\<beta>_ex: assumes linp: "iszlfm p (a#bs)" and d: "d_\<beta> p l" and lp: "l>0"
  2575   shows "(\<exists> x. l dvd x \<and> Ifm (real x #bs) (a_\<beta> p l)) = (\<exists> (x::int). Ifm (real x#bs) p)"
  2576   (is "(\<exists> x. l dvd x \<and> ?P x) = (\<exists> x. ?P' x)")
  2577 proof-
  2578   have "(\<exists> x. l dvd x \<and> ?P x) = (\<exists> (x::int). ?P (l*x))"
  2579     using unity_coeff_ex[where l="l" and P="?P", simplified] by simp
  2580   also have "\<dots> = (\<exists> (x::int). ?P' x)" using a_\<beta>[OF linp d lp] by simp
  2581   finally show ?thesis  . 
  2582 qed
  2583 
  2584 lemma \<beta>:
  2585   assumes lp: "iszlfm p (a#bs)"
  2586   and u: "d_\<beta> p 1"
  2587   and d: "d_\<delta> p d"
  2588   and dp: "d > 0"
  2589   and nob: "\<not>(\<exists>(j::int) \<in> {1 .. d}. \<exists> b\<in> (Inum (a#bs)) ` set(\<beta> p). real x = b + real j)"
  2590   and p: "Ifm (real x#bs) p" (is "?P x")
  2591   shows "?P (x - d)"
  2592 using lp u d dp nob p
  2593 proof(induct p rule: iszlfm.induct)
  2594   case (5 c e) hence c1: "c=1" and  bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp_all
  2595   with dp p c1 numbound0_I[OF bn,where b="real (x-d)" and b'="real x" and bs="bs"] 5
  2596   show ?case by (simp del: real_of_int_minus)
  2597 next
  2598   case (6 c e)  hence c1: "c=1" and  bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp_all
  2599   with dp p c1 numbound0_I[OF bn,where b="real (x-d)" and b'="real x" and bs="bs"] 6
  2600   show ?case by (simp del: real_of_int_minus)
  2601 next
  2602   case (7 c e) hence p: "Ifm (real x #bs) (Gt (CN 0 c e))" and c1: "c=1"
  2603     and bn:"numbound0 e" and ie1:"isint e (a#bs)" using dvd1_eq1[where x="c"] by simp_all
  2604   let ?e = "Inum (real x # bs) e"
  2605   from ie1 have ie: "real (floor ?e) = ?e" using isint_iff[where n="e" and bs="a#bs"]
  2606       numbound0_I[OF bn,where b="a" and b'="real x" and bs="bs"]
  2607     by (simp add: isint_iff)
  2608     {assume "real (x-d) +?e > 0" hence ?case using c1 
  2609       numbound0_I[OF bn,where b="real (x-d)" and b'="real x" and bs="bs"]
  2610         by (simp del: real_of_int_minus)}
  2611     moreover
  2612     {assume H: "\<not> real (x-d) + ?e > 0" 
  2613       let ?v="Neg e"
  2614       have vb: "?v \<in> set (\<beta> (Gt (CN 0 c e)))" by simp
  2615       from 7(5)[simplified simp_thms Inum.simps \<beta>.simps list.set bex_simps numbound0_I[OF bn,where b="a" and b'="real x" and bs="bs"]] 
  2616       have nob: "\<not> (\<exists> j\<in> {1 ..d}. real x =  - ?e + real j)" by auto 
  2617       from H p have "real x + ?e > 0 \<and> real x + ?e \<le> real d" by (simp add: c1)
  2618       hence "real (x + floor ?e) > real (0::int) \<and> real (x + floor ?e) \<le> real d"
  2619         using ie by simp
  2620       hence "x + floor ?e \<ge> 1 \<and> x + floor ?e \<le> d"  by simp
  2621       hence "\<exists> (j::int) \<in> {1 .. d}. j = x + floor ?e" by simp
  2622       hence "\<exists> (j::int) \<in> {1 .. d}. real x = real (- floor ?e + j)" 
  2623         by (simp only: real_of_int_inject) (simp add: algebra_simps)
  2624       hence "\<exists> (j::int) \<in> {1 .. d}. real x = - ?e + real j" 
  2625         by (simp add: ie[simplified isint_iff])
  2626       with nob have ?case by auto}
  2627     ultimately show ?case by blast
  2628 next
  2629   case (8 c e) hence p: "Ifm (real x #bs) (Ge (CN 0 c e))" and c1: "c=1" and bn:"numbound0 e" 
  2630     and ie1:"isint e (a #bs)" using dvd1_eq1[where x="c"] by simp+
  2631     let ?e = "Inum (real x # bs) e"
  2632     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"]
  2633       by (simp add: isint_iff)
  2634     {assume "real (x-d) +?e \<ge> 0" hence ?case using  c1 
  2635       numbound0_I[OF bn,where b="real (x-d)" and b'="real x" and bs="bs"]
  2636         by (simp del: real_of_int_minus)}
  2637     moreover
  2638     {assume H: "\<not> real (x-d) + ?e \<ge> 0" 
  2639       let ?v="Sub (C -1) e"
  2640       have vb: "?v \<in> set (\<beta> (Ge (CN 0 c e)))" by simp
  2641       from 8(5)[simplified simp_thms Inum.simps \<beta>.simps list.set bex_simps numbound0_I[OF bn,where b="a" and b'="real x" and bs="bs"]] 
  2642       have nob: "\<not> (\<exists> j\<in> {1 ..d}. real x =  - ?e - 1 + real j)" by auto 
  2643       from H p have "real x + ?e \<ge> 0 \<and> real x + ?e < real d" by (simp add: c1)
  2644       hence "real (x + floor ?e) \<ge> real (0::int) \<and> real (x + floor ?e) < real d"
  2645         using ie by simp
  2646       hence "x + floor ?e +1 \<ge> 1 \<and> x + floor ?e + 1 \<le> d"  by simp
  2647       hence "\<exists> (j::int) \<in> {1 .. d}. j = x + floor ?e + 1" by simp
  2648       hence "\<exists> (j::int) \<in> {1 .. d}. x= - floor ?e - 1 + j" by (simp add: algebra_simps)
  2649       hence "\<exists> (j::int) \<in> {1 .. d}. real x= real (- floor ?e - 1 + j)" 
  2650         by (simp only: real_of_int_inject)
  2651       hence "\<exists> (j::int) \<in> {1 .. d}. real x= - ?e - 1 + real j" 
  2652         by (simp add: ie[simplified isint_iff])
  2653       with nob have ?case by simp }
  2654     ultimately show ?case by blast
  2655 next
  2656   case (3 c e) hence p: "Ifm (real x #bs) (Eq (CN 0 c e))" (is "?p x") and c1: "c=1" 
  2657     and bn:"numbound0 e" and ie1: "isint e (a #bs)" using dvd1_eq1[where x="c"] by simp+
  2658     let ?e = "Inum (real x # bs) e"
  2659     let ?v="(Sub (C -1) e)"
  2660     have vb: "?v \<in> set (\<beta> (Eq (CN 0 c e)))" by simp
  2661     from p have "real x= - ?e" by (simp add: c1) with 3(5) show ?case using dp
  2662       by simp (erule ballE[where x="1"],
  2663         simp_all add:algebra_simps numbound0_I[OF bn,where b="real x"and b'="a"and bs="bs"])
  2664 next
  2665   case (4 c e)hence p: "Ifm (real x #bs) (NEq (CN 0 c e))" (is "?p x") and c1: "c=1" 
  2666     and bn:"numbound0 e" and ie1: "isint e (a #bs)" using dvd1_eq1[where x="c"] by simp+
  2667     let ?e = "Inum (real x # bs) e"
  2668     let ?v="Neg e"
  2669     have vb: "?v \<in> set (\<beta> (NEq (CN 0 c e)))" by simp
  2670     {assume "real x - real d + Inum ((real (x -d)) # bs) e \<noteq> 0" 
  2671       hence ?case by (simp add: c1)}
  2672     moreover
  2673     {assume H: "real x - real d + Inum ((real (x -d)) # bs) e = 0"
  2674       hence "real x = - Inum ((real (x -d)) # bs) e + real d" by simp
  2675       hence "real x = - Inum (a # bs) e + real d"
  2676         by (simp add: numbound0_I[OF bn,where b="real x - real d"and b'="a"and bs="bs"])
  2677        with 4(5) have ?case using dp by simp}
  2678   ultimately show ?case by blast
  2679 next 
  2680   case (9 j c e) hence p: "Ifm (real x #bs) (Dvd j (CN 0 c e))" (is "?p x") and c1: "c=1" 
  2681     and bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp+
  2682   let ?e = "Inum (real x # bs) e"
  2683   from 9 have "isint e (a #bs)"  by simp 
  2684   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"]
  2685     by (simp add: isint_iff)
  2686   from 9 have id: "j dvd d" by simp
  2687   from c1 ie[symmetric] have "?p x = (real j rdvd real (x+ floor ?e))" by simp
  2688   also have "\<dots> = (j dvd x + floor ?e)" 
  2689     using int_rdvd_real[where i="j" and x="real (x+ floor ?e)"] by simp
  2690   also have "\<dots> = (j dvd x - d + floor ?e)" 
  2691     using dvd_period[OF id, where x="x" and c="-1" and t="floor ?e"] by simp
  2692   also have "\<dots> = (real j rdvd real (x - d + floor ?e))" 
  2693     using int_rdvd_real[where i="j" and x="real (x-d + floor ?e)",symmetric, simplified]
  2694       ie by simp
  2695   also have "\<dots> = (real j rdvd real x - real d + ?e)" 
  2696     using ie by simp
  2697   finally show ?case 
  2698     using numbound0_I[OF bn,where b="real (x-d)" and b'="real x" and bs="bs"] c1 p by simp
  2699 next
  2700   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+
  2701   let ?e = "Inum (real x # bs) e"
  2702   from 10 have "isint e (a#bs)"  by simp 
  2703   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"]
  2704     by (simp add: isint_iff)
  2705   from 10 have id: "j dvd d" by simp
  2706   from c1 ie[symmetric] have "?p x = (\<not> real j rdvd real (x+ floor ?e))" by simp
  2707   also have "\<dots> = (\<not> j dvd x + floor ?e)" 
  2708     using int_rdvd_real[where i="j" and x="real (x+ floor ?e)"] by simp
  2709   also have "\<dots> = (\<not> j dvd x - d + floor ?e)" 
  2710     using dvd_period[OF id, where x="x" and c="-1" and t="floor ?e"] by simp
  2711   also have "\<dots> = (\<not> real j rdvd real (x - d + floor ?e))" 
  2712     using int_rdvd_real[where i="j" and x="real (x-d + floor ?e)",symmetric, simplified]
  2713       ie by simp
  2714   also have "\<dots> = (\<not> real j rdvd real x - real d + ?e)" 
  2715     using ie by simp
  2716   finally show ?case
  2717     using numbound0_I[OF bn,where b="real (x-d)" and b'="real x" and bs="bs"] c1 p by simp
  2718 qed (auto simp add: numbound0_I[where bs="bs" and b="real (x - d)" and b'="real x"]
  2719   simp del: real_of_int_diff)
  2720 
  2721 lemma \<beta>':   
  2722   assumes lp: "iszlfm p (a #bs)"
  2723   and u: "d_\<beta> p 1"
  2724   and d: "d_\<delta> p d"
  2725   and dp: "d > 0"
  2726   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)")
  2727 proof(clarify)
  2728   fix x 
  2729   assume nb:"?b" and px: "?P x" 
  2730   hence nb2: "\<not>(\<exists>(j::int) \<in> {1 .. d}. \<exists> b\<in> (Inum (a#bs)) ` set(\<beta> p). real x = b + real j)"
  2731     by auto
  2732   from  \<beta>[OF lp u d dp nb2 px] show "?P (x -d )" .
  2733 qed
  2734 
  2735 lemma \<beta>_int: assumes lp: "iszlfm p bs"
  2736   shows "\<forall> b\<in> set (\<beta> p). isint b bs"
  2737 using lp by (induct p rule: iszlfm.induct) (auto simp add: isint_neg isint_sub)
  2738 
  2739 lemma cpmi_eq: "0 < D \<Longrightarrow> (EX z::int. ALL x. x < z --> (P x = P1 x))
  2740 ==> ALL x.~(EX (j::int) : {1..D}. EX (b::int) : B. P(b+j)) --> P (x) --> P (x - D) 
  2741 ==> (ALL (x::int). ALL (k::int). ((P1 x)= (P1 (x-k*D))))
  2742 ==> (EX (x::int). P(x)) = ((EX (j::int) : {1..D} . (P1(j))) | (EX (j::int) : {1..D}. EX (b::int) : B. P (b+j)))"
  2743 apply(rule iffI)
  2744 prefer 2
  2745 apply(drule minusinfinity)
  2746 apply assumption+
  2747 apply(fastforce)
  2748 apply clarsimp
  2749 apply(subgoal_tac "!!k. 0<=k \<Longrightarrow> !x. P x \<longrightarrow> P (x - k*D)")
  2750 apply(frule_tac x = x and z=z in decr_lemma)
  2751 apply(subgoal_tac "P1(x - (\<bar>x - z\<bar> + 1) * D)")
  2752 prefer 2
  2753 apply(subgoal_tac "0 <= (\<bar>x - z\<bar> + 1)")
  2754 prefer 2 apply arith
  2755  apply fastforce
  2756 apply(drule (1)  periodic_finite_ex)
  2757 apply blast
  2758 apply(blast dest:decr_mult_lemma)
  2759 done
  2760 
  2761 
  2762 theorem cp_thm:
  2763   assumes lp: "iszlfm p (a #bs)"
  2764   and u: "d_\<beta> p 1"
  2765   and d: "d_\<delta> p d"
  2766   and dp: "d > 0"
  2767   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))"
  2768   (is "(\<exists> (x::int). ?P (real x)) = (\<exists> j\<in> ?D. ?M j \<or> (\<exists> b\<in> ?B. ?P (?I b + real j)))")
  2769 proof-
  2770   from minusinf_inf[OF lp] 
  2771   have th: "\<exists>(z::int). \<forall>x<z. ?P (real x) = ?M x" by blast
  2772   let ?B' = "{floor (?I b) | b. b\<in> ?B}"
  2773   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
  2774   from B[rule_format] 
  2775   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))" 
  2776     by simp
  2777   also have "\<dots> = (\<exists>j\<in>?D. \<exists>b\<in> ?B. ?P (real (floor (?I b) + j)))" by simp
  2778   also have"\<dots> = (\<exists> j \<in> ?D. \<exists> b \<in> ?B'. ?P (real (b + j)))"  by blast
  2779   finally have BB': 
  2780     "(\<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)))" 
  2781     by blast 
  2782   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
  2783   from minusinf_repeats[OF d lp]
  2784   have th3: "\<forall> x k. ?M x = ?M (x-k*d)" by simp
  2785   from cpmi_eq[OF dp th th2 th3] BB' show ?thesis by blast
  2786 qed
  2787 
  2788     (* Reddy and Loveland *)
  2789 
  2790 
  2791 consts 
  2792   \<rho> :: "fm \<Rightarrow> (num \<times> int) list" (* Compute the Reddy and Loveland Bset*)
  2793   \<sigma>_\<rho>:: "fm \<Rightarrow> num \<times> int \<Rightarrow> fm" (* Performs the modified substitution of Reddy and Loveland*)
  2794   \<alpha>_\<rho> :: "fm \<Rightarrow> (num\<times>int) list"
  2795   a_\<rho> :: "fm \<Rightarrow> int \<Rightarrow> fm"
  2796 recdef \<rho> "measure size"
  2797   "\<rho> (And p q) = (\<rho> p @ \<rho> q)" 
  2798   "\<rho> (Or p q) = (\<rho> p @ \<rho> q)" 
  2799   "\<rho> (Eq  (CN 0 c e)) = [(Sub (C -1) e,c)]"
  2800   "\<rho> (NEq (CN 0 c e)) = [(Neg e,c)]"
  2801   "\<rho> (Lt  (CN 0 c e)) = []"
  2802   "\<rho> (Le  (CN 0 c e)) = []"
  2803   "\<rho> (Gt  (CN 0 c e)) = [(Neg e, c)]"
  2804   "\<rho> (Ge  (CN 0 c e)) = [(Sub (C (-1)) e, c)]"
  2805   "\<rho> p = []"
  2806 
  2807 recdef \<sigma>_\<rho> "measure size"
  2808   "\<sigma>_\<rho> (And p q) = (\<lambda> (t,k). And (\<sigma>_\<rho> p (t,k)) (\<sigma>_\<rho> q (t,k)))" 
  2809   "\<sigma>_\<rho> (Or p q) = (\<lambda> (t,k). Or (\<sigma>_\<rho> p (t,k)) (\<sigma>_\<rho> q (t,k)))" 
  2810   "\<sigma>_\<rho> (Eq  (CN 0 c e)) = (\<lambda> (t,k). if k dvd c then (Eq (Add (Mul (c div k) t) e)) 
  2811                                             else (Eq (Add (Mul c t) (Mul k e))))"
  2812   "\<sigma>_\<rho> (NEq (CN 0 c e)) = (\<lambda> (t,k). if k dvd c then (NEq (Add (Mul (c div k) t) e)) 
  2813                                             else (NEq (Add (Mul c t) (Mul k e))))"
  2814   "\<sigma>_\<rho> (Lt  (CN 0 c e)) = (\<lambda> (t,k). if k dvd c then (Lt (Add (Mul (c div k) t) e)) 
  2815                                             else (Lt (Add (Mul c t) (Mul k e))))"
  2816   "\<sigma>_\<rho> (Le  (CN 0 c e)) = (\<lambda> (t,k). if k dvd c then (Le (Add (Mul (c div k) t) e)) 
  2817                                             else (Le (Add (Mul c t) (Mul k e))))"
  2818   "\<sigma>_\<rho> (Gt  (CN 0 c e)) = (\<lambda> (t,k). if k dvd c then (Gt (Add (Mul (c div k) t) e)) 
  2819                                             else (Gt (Add (Mul c t) (Mul k e))))"
  2820   "\<sigma>_\<rho> (Ge  (CN 0 c e)) = (\<lambda> (t,k). if k dvd c then (Ge (Add (Mul (c div k) t) e)) 
  2821                                             else (Ge (Add (Mul c t) (Mul k e))))"
  2822   "\<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)) 
  2823                                             else (Dvd (i*k) (Add (Mul c t) (Mul k e))))"
  2824   "\<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)) 
  2825                                             else (NDvd (i*k) (Add (Mul c t) (Mul k e))))"
  2826   "\<sigma>_\<rho> p = (\<lambda> (t,k). p)"
  2827 
  2828 recdef \<alpha>_\<rho> "measure size"
  2829   "\<alpha>_\<rho> (And p q) = (\<alpha>_\<rho> p @ \<alpha>_\<rho> q)" 
  2830   "\<alpha>_\<rho> (Or p q) = (\<alpha>_\<rho> p @ \<alpha>_\<rho> q)" 
  2831   "\<alpha>_\<rho> (Eq  (CN 0 c e)) = [(Add (C -1) e,c)]"
  2832   "\<alpha>_\<rho> (NEq (CN 0 c e)) = [(e,c)]"
  2833   "\<alpha>_\<rho> (Lt  (CN 0 c e)) = [(e,c)]"
  2834   "\<alpha>_\<rho> (Le  (CN 0 c e)) = [(Add (C -1) e,c)]"
  2835   "\<alpha>_\<rho> p = []"
  2836 
  2837     (* Simulates normal substituion by modifying the formula see correctness theorem *)
  2838 
  2839 definition \<sigma> :: "fm \<Rightarrow> int \<Rightarrow> num \<Rightarrow> fm" where
  2840   "\<sigma> p k t \<equiv> And (Dvd k t) (\<sigma>_\<rho> p (t,k))"
  2841 
  2842 lemma \<sigma>_\<rho>:
  2843   assumes linp: "iszlfm p (real (x::int)#bs)"
  2844   and kpos: "real k > 0"
  2845   and tnb: "numbound0 t"
  2846   and tint: "isint t (real x#bs)"
  2847   and kdt: "k dvd floor (Inum (b'#bs) t)"
  2848   shows "Ifm (real x#bs) (\<sigma>_\<rho> p (t,k)) = 
  2849   (Ifm ((real ((floor (Inum (b'#bs) t)) div k))#bs) p)" 
  2850   (is "?I (real x) (?s p) = (?I (real ((floor (?N b' t)) div k)) p)" is "_ = (?I ?tk p)")
  2851 using linp kpos tnb
  2852 proof(induct p rule: \<sigma>_\<rho>.induct)
  2853   case (3 c e) 
  2854   from 3 have cp: "c > 0" and nb: "numbound0 e" by auto
  2855   { assume kdc: "k dvd c" 
  2856     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  2857     from kdc have ?case using real_of_int_div[OF kdc] real_of_int_div[OF kdt]
  2858       numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2859       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) } 
  2860   moreover 
  2861   { assume *: "\<not> k dvd c"
  2862     from kpos have knz': "real k \<noteq> 0" by simp
  2863     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t"
  2864       using isint_def by simp
  2865     from assms * 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)"
  2866       using real_of_int_div[OF kdt]
  2867         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2868         numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
  2869       by (simp add: ti algebra_simps)
  2870       also have "\<dots> = (?I ?tk (Eq (CN 0 c e)))"
  2871         using nonzero_eq_divide_eq[OF knz',
  2872             where a="real c * (?N (real x) t / real k) + ?N (real x) e" and b="0", symmetric]
  2873           real_of_int_div[OF kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2874           numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
  2875         by (simp add: ti)
  2876       finally have ?case . }
  2877     ultimately show ?case by blast 
  2878 next
  2879   case (4 c e)  
  2880   then have cp: "c > 0" and nb: "numbound0 e" by auto
  2881   { assume kdc: "k dvd c" 
  2882     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  2883     from kdc have  ?case using real_of_int_div[OF kdc] real_of_int_div[OF kdt]
  2884       numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2885       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) } 
  2886   moreover 
  2887   { assume *: "\<not> k dvd c"
  2888     from kpos have knz': "real k \<noteq> 0" by simp
  2889     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  2890     from assms * 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)"
  2891       using real_of_int_div[OF kdt]
  2892         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2893         numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
  2894       by (simp add: ti algebra_simps)
  2895     also have "\<dots> = (?I ?tk (NEq (CN 0 c e)))"
  2896       using nonzero_eq_divide_eq[OF knz',
  2897           where a="real c * (?N (real x) t / real k) + ?N (real x) e" and b="0", symmetric]
  2898         real_of_int_div[OF kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2899         numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
  2900       by (simp add: ti)
  2901     finally have ?case . }
  2902   ultimately show ?case by blast 
  2903 next
  2904   case (5 c e) 
  2905   then have cp: "c > 0" and nb: "numbound0 e" by auto
  2906   { assume kdc: "k dvd c" 
  2907     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  2908     from kdc have  ?case using real_of_int_div[OF kdc] real_of_int_div[OF kdt]
  2909       numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2910       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) } 
  2911   moreover 
  2912   { assume *: "\<not> k dvd c"
  2913     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  2914     from assms * 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)"
  2915       using real_of_int_div[OF 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"]
  2918       by (simp add: ti algebra_simps)
  2919     also have "\<dots> = (?I ?tk (Lt (CN 0 c e)))"
  2920       using pos_less_divide_eq[OF kpos,
  2921           where a="real c * (?N (real x) t / real k) + ?N (real x) e" and b="0", symmetric]
  2922         real_of_int_div[OF kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2923         numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
  2924       by (simp add: ti)
  2925     finally have ?case . }
  2926   ultimately show ?case by blast 
  2927 next
  2928   case (6 c e)
  2929   then have cp: "c > 0" and nb: "numbound0 e" by auto
  2930   { assume kdc: "k dvd c" 
  2931     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  2932     from kdc have  ?case using real_of_int_div[OF kdc] real_of_int_div[OF kdt]
  2933       numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2934       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) } 
  2935   moreover 
  2936   { assume *: "\<not> k dvd c"
  2937     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  2938     from assms * 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)"
  2939       using real_of_int_div[OF kdt]
  2940         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"]
  2942       by (simp add: ti algebra_simps)
  2943     also have "\<dots> = (?I ?tk (Le (CN 0 c e)))"
  2944       using pos_le_divide_eq[OF kpos,
  2945           where a="real c * (?N (real x) t / real k) + ?N (real x) e" and b="0", symmetric]
  2946         real_of_int_div[OF kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2947         numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
  2948       by (simp add: ti)
  2949     finally have ?case . }
  2950   ultimately show ?case by blast 
  2951 next
  2952   case (7 c e) 
  2953   then have cp: "c > 0" and nb: "numbound0 e" by auto
  2954   { assume kdc: "k dvd c" 
  2955     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  2956     from kdc have  ?case using real_of_int_div[OF kdc] real_of_int_div[OF kdt]
  2957       numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2958       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) } 
  2959   moreover 
  2960   { assume *: "\<not> k dvd c"
  2961     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  2962     from assms * 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)"
  2963       using real_of_int_div[OF kdt]
  2964         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2965         numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
  2966       by (simp add: ti algebra_simps)
  2967     also have "\<dots> = (?I ?tk (Gt (CN 0 c e)))"
  2968       using pos_divide_less_eq[OF kpos,
  2969           where a="real c * (?N (real x) t / real k) + ?N (real x) e" and b="0", symmetric]
  2970         real_of_int_div[OF kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2971         numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
  2972       by (simp add: ti)
  2973     finally have ?case . }
  2974   ultimately show ?case by blast 
  2975 next
  2976   case (8 c e)  
  2977   then have cp: "c > 0" and nb: "numbound0 e" by auto
  2978   { assume kdc: "k dvd c" 
  2979     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  2980     from kdc have  ?case using real_of_int_div[OF kdc] real_of_int_div[OF 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) } 
  2983   moreover 
  2984   { assume *: "\<not> k dvd c"
  2985     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  2986     from assms * 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)"
  2987       using real_of_int_div[OF kdt]
  2988         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  2989         numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
  2990       by (simp add: ti algebra_simps)
  2991     also have "\<dots> = (?I ?tk (Ge (CN 0 c e)))"
  2992       using pos_divide_le_eq[OF kpos,
  2993           where a="real c * (?N (real x) t / real k) + ?N (real x) e" and b="0", symmetric]
  2994         real_of_int_div[OF kdt] 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"]
  2996       by (simp add: ti)
  2997     finally have ?case . }
  2998   ultimately show ?case by blast 
  2999 next
  3000   case (9 i c e)
  3001   then have cp: "c > 0" and nb: "numbound0 e" by auto
  3002   { assume kdc: "k dvd c" 
  3003     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  3004     from kdc have ?case using real_of_int_div[OF kdc] real_of_int_div[OF kdt]
  3005       numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  3006       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) } 
  3007   moreover 
  3008   { assume *: "\<not> k dvd c"
  3009     from kpos have knz: "k\<noteq>0" by simp hence knz': "real k \<noteq> 0" by simp
  3010     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  3011     from assms * 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)"
  3012       using real_of_int_div[OF kdt]
  3013         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  3014         numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
  3015       by (simp add: ti algebra_simps)
  3016     also have "\<dots> = (?I ?tk (Dvd i (CN 0 c e)))"
  3017       using rdvd_mult[OF knz, where n="i"]
  3018         real_of_int_div[OF kdt] numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  3019         numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
  3020       by (simp add: ti)
  3021     finally have ?case . }
  3022   ultimately show ?case by blast 
  3023 next
  3024   case (10 i c e)
  3025   then have cp: "c > 0" and nb: "numbound0 e" by auto
  3026   { assume kdc: "k dvd c" 
  3027     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  3028     from kdc have  ?case using real_of_int_div[OF kdc] real_of_int_div[OF kdt]
  3029       numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  3030       numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"] by (simp add: ti) } 
  3031   moreover 
  3032   { assume *: "\<not> k dvd c"
  3033     from kpos have knz: "k\<noteq>0" by simp hence knz': "real k \<noteq> 0" by simp
  3034     from tint have ti: "real (floor (?N (real x) t)) = ?N (real x) t" using isint_def by simp
  3035     from assms * 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))"
  3036       using real_of_int_div[OF kdt]
  3037         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  3038         numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
  3039       by (simp add: ti algebra_simps)
  3040     also have "\<dots> = (?I ?tk (NDvd i (CN 0 c e)))"
  3041       using rdvd_mult[OF knz, where n="i"] real_of_int_div[OF kdt]
  3042         numbound0_I[OF tnb, where bs="bs" and b="b'" and b'="real x"]
  3043         numbound0_I[OF nb, where bs="bs" and b="?tk" and b'="real x"]
  3044       by (simp add: ti)
  3045     finally have ?case . }
  3046   ultimately show ?case by blast 
  3047 qed (simp_all add: bound0_I[where bs="bs" and b="real ((floor (?N b' t)) div k)" and b'="real x"]
  3048   numbound0_I[where bs="bs" and b="real ((floor (?N b' t)) div k)" and b'="real x"])
  3049 
  3050 
  3051 lemma \<sigma>_\<rho>_nb: assumes lp:"iszlfm p (a#bs)" and nb: "numbound0 t"
  3052   shows "bound0 (\<sigma>_\<rho> p (t,k))"
  3053   using lp
  3054   by (induct p rule: iszlfm.induct, auto simp add: nb)
  3055 
  3056 lemma \<rho>_l:
  3057   assumes lp: "iszlfm p (real (i::int)#bs)"
  3058   shows "\<forall> (b,k) \<in> set (\<rho> p). k >0 \<and> numbound0 b \<and> isint b (real i#bs)"
  3059 using lp by (induct p rule: \<rho>.induct, auto simp add: isint_sub isint_neg)
  3060 
  3061 lemma \<alpha>_\<rho>_l:
  3062   assumes lp: "iszlfm p (real (i::int)#bs)"
  3063   shows "\<forall> (b,k) \<in> set (\<alpha>_\<rho> p). k >0 \<and> numbound0 b \<and> isint b (real i#bs)"
  3064 using lp isint_add [OF isint_c[where j="- 1"],where bs="real i#bs"]
  3065  by (induct p rule: \<alpha>_\<rho>.induct, auto)
  3066 
  3067 lemma \<rho>: assumes lp: "iszlfm p (real (i::int) #bs)"
  3068   and pi: "Ifm (real i#bs) p"
  3069   and d: "d_\<delta> p d"
  3070   and dp: "d > 0"
  3071   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"
  3072   (is "\<forall>(e,c) \<in> set (\<rho> p). \<forall> j\<in> {1 .. c*d}. _ \<noteq> ?N i e + _")
  3073   shows "Ifm (real(i - d)#bs) p"
  3074   using lp pi d nob
  3075 proof(induct p rule: iszlfm.induct)
  3076   case (3 c e) hence cp: "c >0" and nb: "numbound0 e" and ei: "isint e (real i#bs)"
  3077     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"
  3078     by simp+
  3079   from mult_strict_left_mono[OF dp cp]  have one:"1 \<in> {1 .. c*d}" by auto
  3080   from nob[rule_format, where j="1", OF one] pi show ?case by simp
  3081 next
  3082   case (4 c e)  
  3083   hence cp: "c >0" and nb: "numbound0 e" and ei: "isint e (real i#bs)"
  3084     and nob: "\<forall> j\<in> {1 .. c*d}. real (c*i) \<noteq> - ?N i e + real j"
  3085     by simp+
  3086   {assume "real (c*i) \<noteq> - ?N i e + real (c*d)"
  3087     with numbound0_I[OF nb, where bs="bs" and b="real i - real d" and b'="real i"]
  3088     have ?case by (simp add: algebra_simps)}
  3089   moreover
  3090   {assume pi: "real (c*i) = - ?N i e + real (c*d)"
  3091     from mult_strict_left_mono[OF dp cp] have d: "(c*d) \<in> {1 .. c*d}" by simp
  3092     from nob[rule_format, where j="c*d", OF d] pi have ?case by simp }
  3093   ultimately show ?case by blast
  3094 next
  3095   case (5 c e) hence cp: "c > 0" by simp
  3096   from 5 mult_strict_left_mono[OF dp cp, simplified real_of_int_less_iff[symmetric] 
  3097     real_of_int_mult]
  3098   show ?case using 5 dp 
  3099     by (simp add: numbound0_I[where bs="bs" and b="real i - real d" and b'="real i"] 
  3100       algebra_simps del: mult_pos_pos)
  3101 next
  3102   case (6 c e) hence cp: "c > 0" by simp
  3103   from 6 mult_strict_left_mono[OF dp cp, simplified real_of_int_less_iff[symmetric] 
  3104     real_of_int_mult]
  3105   show ?case using 6 dp 
  3106     by (simp add: numbound0_I[where bs="bs" and b="real i - real d" and b'="real i"] 
  3107       algebra_simps del: mult_pos_pos)
  3108 next
  3109   case (7 c e) hence cp: "c >0" and nb: "numbound0 e" and ei: "isint e (real i#bs)"
  3110     and nob: "\<forall> j\<in> {1 .. c*d}. real (c*i) \<noteq> - ?N i e + real j"
  3111     and pi: "real (c*i) + ?N i e > 0" and cp': "real c >0"
  3112     by simp+
  3113   let ?fe = "floor (?N i e)"
  3114   from pi cp have th:"(real i +?N i e / real c)*real c > 0" by (simp add: algebra_simps)
  3115   from pi ei[simplified isint_iff] have "real (c*i + ?fe) > real (0::int)" by simp
  3116   hence pi': "c*i + ?fe > 0" by (simp only: real_of_int_less_iff[symmetric])
  3117   have "real (c*i) + ?N i e > real (c*d) \<or> real (c*i) + ?N i e \<le> real (c*d)" by auto
  3118   moreover
  3119   {assume "real (c*i) + ?N i e > real (c*d)" hence ?case
  3120       by (simp add: algebra_simps 
  3121         numbound0_I[OF nb,where bs="bs" and b="real i - real d" and b'="real i"])} 
  3122   moreover 
  3123   {assume H:"real (c*i) + ?N i e \<le> real (c*d)"
  3124     with ei[simplified isint_iff] have "real (c*i + ?fe) \<le> real (c*d)" by simp
  3125     hence pid: "c*i + ?fe \<le> c*d" by (simp only: real_of_int_le_iff)
  3126     with pi' have "\<exists> j1\<in> {1 .. c*d}. c*i + ?fe = j1" by auto
  3127     hence "\<exists> j1\<in> {1 .. c*d}. real (c*i) = - ?N i e + real j1" 
  3128       by (simp only: real_of_int_mult real_of_int_add real_of_int_inject[symmetric] ei[simplified isint_iff])
  3129         (simp add: algebra_simps)
  3130     with nob  have ?case by blast }
  3131   ultimately show ?case by blast
  3132 next
  3133   case (8 c e)  hence cp: "c >0" and nb: "numbound0 e" and ei: "isint e (real i#bs)"
  3134     and nob: "\<forall> j\<in> {1 .. c*d}. real (c*i) \<noteq> - 1 - ?N i e + real j"
  3135     and pi: "real (c*i) + ?N i e \<ge> 0" and cp': "real c >0"
  3136     by simp+
  3137   let ?fe = "floor (?N i e)"
  3138   from pi cp have th:"(real i +?N i e / real c)*real c \<ge> 0" by (simp add: algebra_simps)
  3139   from pi ei[simplified isint_iff] have "real (c*i + ?fe) \<ge> real (0::int)" by simp
  3140   hence pi': "c*i + 1 + ?fe \<ge> 1" by (simp only: real_of_int_le_iff[symmetric])
  3141   have "real (c*i) + ?N i e \<ge> real (c*d) \<or> real (c*i) + ?N i e < real (c*d)" by auto
  3142   moreover
  3143   {assume "real (c*i) + ?N i e \<ge> real (c*d)" hence ?case
  3144       by (simp add: algebra_simps 
  3145         numbound0_I[OF nb,where bs="bs" and b="real i - real d" and b'="real i"])} 
  3146   moreover 
  3147   {assume H:"real (c*i) + ?N i e < real (c*d)"
  3148     with ei[simplified isint_iff] have "real (c*i + ?fe) < real (c*d)" by simp
  3149     hence pid: "c*i + 1 + ?fe \<le> c*d" by (simp only: real_of_int_le_iff)
  3150     with pi' have "\<exists> j1\<in> {1 .. c*d}. c*i + 1+ ?fe = j1" by auto
  3151     hence "\<exists> j1\<in> {1 .. c*d}. real (c*i) + 1= - ?N i e + real j1"
  3152       by (simp only: real_of_int_mult real_of_int_add real_of_int_inject[symmetric] ei[simplified isint_iff] real_of_one) 
  3153         (simp add: algebra_simps)
  3154     hence "\<exists> j1\<in> {1 .. c*d}. real (c*i) = (- ?N i e + real j1) - 1"
  3155       by (simp only: algebra_simps)
  3156         hence "\<exists> j1\<in> {1 .. c*d}. real (c*i) = - 1 - ?N i e + real j1"
  3157           by (simp add: algebra_simps)
  3158     with nob  have ?case by blast }
  3159   ultimately show ?case by blast
  3160 next
  3161   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+
  3162   let ?e = "Inum (real i # bs) e"
  3163   from 9 have "isint e (real i #bs)"  by simp 
  3164   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"]
  3165     by (simp add: isint_iff)
  3166   from 9 have id: "j dvd d" by simp
  3167   from ie[symmetric] have "?p i = (real j rdvd real (c*i+ floor ?e))" by simp
  3168   also have "\<dots> = (j dvd c*i + floor ?e)" 
  3169     using int_rdvd_iff [where i="j" and t="c*i+ floor ?e"] by simp
  3170   also have "\<dots> = (j dvd c*i - c*d + floor ?e)" 
  3171     using dvd_period[OF id, where x="c*i" and c="-c" and t="floor ?e"] by simp
  3172   also have "\<dots> = (real j rdvd real (c*i - c*d + floor ?e))" 
  3173     using int_rdvd_iff[where i="j" and t="(c*i - c*d + floor ?e)",symmetric, simplified]
  3174       ie by simp
  3175   also have "\<dots> = (real j rdvd real (c*(i - d)) + ?e)" 
  3176     using ie by (simp add:algebra_simps)
  3177   finally show ?case 
  3178     using numbound0_I[OF bn,where b="real i - real d" and b'="real i" and bs="bs"] p 
  3179     by (simp add: algebra_simps)
  3180 next
  3181   case (10 j c e)
  3182   hence p: "\<not> (real j rdvd real (c*i) + ?N i e)" (is "?p x") and cp: "c > 0" and bn:"numbound0 e"
  3183     by simp+
  3184   let ?e = "Inum (real i # bs) e"
  3185   from 10 have "isint e (real i #bs)"  by simp 
  3186   hence ie: "real (floor ?e) = ?e"
  3187     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"]
  3188     by (simp add: isint_iff)
  3189   from 10 have id: "j dvd d" by simp
  3190   from ie[symmetric] have "?p i = (\<not> (real j rdvd real (c*i+ floor ?e)))" by simp
  3191   also have "\<dots> = Not (j dvd c*i + floor ?e)" 
  3192     using int_rdvd_iff [where i="j" and t="c*i+ floor ?e"] by simp
  3193   also have "\<dots> = Not (j dvd c*i - c*d + floor ?e)" 
  3194     using dvd_period[OF id, where x="c*i" and c="-c" and t="floor ?e"] by simp
  3195   also have "\<dots> = Not (real j rdvd real (c*i - c*d + floor ?e))" 
  3196     using int_rdvd_iff[where i="j" and t="(c*i - c*d + floor ?e)",symmetric, simplified]
  3197       ie by simp
  3198   also have "\<dots> = Not (real j rdvd real (c*(i - d)) + ?e)" 
  3199     using ie by (simp add:algebra_simps)
  3200   finally show ?case 
  3201     using numbound0_I[OF bn,where b="real i - real d" and b'="real i" and bs="bs"] p 
  3202     by (simp add: algebra_simps)
  3203 qed (auto simp add: numbound0_I[where bs="bs" and b="real i - real d" and b'="real i"])
  3204 
  3205 lemma \<sigma>_nb: assumes lp: "iszlfm p (a#bs)" and nb: "numbound0 t"
  3206   shows "bound0 (\<sigma> p k t)"
  3207   using \<sigma>_\<rho>_nb[OF lp nb] nb by (simp add: \<sigma>_def)
  3208   
  3209 lemma \<rho>':   assumes lp: "iszlfm p (a #bs)"
  3210   and d: "d_\<delta> p d"
  3211   and dp: "d > 0"
  3212   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)")
  3213 proof(clarify)
  3214   fix x 
  3215   assume nob1:"?b x" and px: "?P x" 
  3216   from iszlfm_gen[OF lp, rule_format, where y="real x"] have lp': "iszlfm p (real x#bs)".
  3217   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" 
  3218   proof(clarify)
  3219     fix e c j assume ecR: "(e,c) \<in> set (\<rho> p)" and jD: "j\<in> {1 .. c*d}"
  3220       and cx: "real (c*x) = Inum (real x#bs) e + real j"
  3221     let ?e = "Inum (real x#bs) e"
  3222     let ?fe = "floor ?e"
  3223     from \<rho>_l[OF lp'] ecR have ei:"isint e (real x#bs)" and cp:"c>0" and nb:"numbound0 e"
  3224       by auto
  3225     from numbound0_gen [OF nb ei, rule_format,where y="a"] have "isint e (a#bs)" .
  3226     from cx ei[simplified isint_iff] have "real (c*x) = real (?fe + j)" by simp
  3227     hence cx: "c*x = ?fe + j" by (simp only: real_of_int_inject)
  3228     hence cdej:"c dvd ?fe + j" by (simp add: dvd_def) (rule_tac x="x" in exI, simp)
  3229     hence "real c rdvd real (?fe + j)" by (simp only: int_rdvd_iff)
  3230     hence rcdej: "real c rdvd ?e + real j" by (simp add: ei[simplified isint_iff])
  3231     from cx have "(c*x) div c = (?fe + j) div c" by simp
  3232     with cp have "x = (?fe + j) div c" by simp
  3233     with px have th: "?P ((?fe + j) div c)" by auto
  3234     from cp have cp': "real c > 0" by simp
  3235     from cdej have cdej': "c dvd floor (Inum (real x#bs) (Add e (C j)))" by simp
  3236     from nb have nb': "numbound0 (Add e (C j))" by simp
  3237     have ji: "isint (C j) (real x#bs)" by (simp add: isint_def)
  3238     from isint_add[OF ei ji] have ei':"isint (Add e (C j)) (real x#bs)" .
  3239     from th \<sigma>_\<rho>[where b'="real x", OF lp' cp' nb' ei' cdej',symmetric]
  3240     have "Ifm (real x#bs) (\<sigma>_\<rho> p (Add e (C j), c))" by simp
  3241     with rcdej have th: "Ifm (real x#bs) (\<sigma> p c (Add e (C j)))" by (simp add: \<sigma>_def)
  3242     from th bound0_I[OF \<sigma>_nb[OF lp nb', where k="c"],where bs="bs" and b="real x" and b'="a"]
  3243     have "Ifm (a#bs) (\<sigma> p c (Add e (C j)))" by blast
  3244       with ecR jD nob1    show "False" by blast
  3245   qed
  3246   from \<rho>[OF lp' px d dp nob] show "?P (x -d )" . 
  3247 qed
  3248 
  3249 
  3250 lemma rl_thm: 
  3251   assumes lp: "iszlfm p (real (i::int)#bs)"
  3252   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)))))"
  3253   (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))" 
  3254     is "?lhs = (?MD \<or> ?RD)"  is "?lhs = ?rhs")
  3255 proof-
  3256   let ?d= "\<delta> p"
  3257   from \<delta>[OF lp] have d:"d_\<delta> p ?d" and dp: "?d > 0" by auto
  3258   { assume H:"?MD" hence th:"\<exists> (x::int). ?MP x" by blast
  3259     from H minusinf_ex[OF lp th] have ?thesis  by blast}
  3260   moreover
  3261   { fix e c j assume exR:"(e,c) \<in> ?R" and jD:"j\<in> {1 .. c*?d}" and spx:"?SP c e j"
  3262     from exR \<rho>_l[OF lp] have nb: "numbound0 e" and ei:"isint e (real i#bs)" and cp: "c > 0"
  3263       by auto
  3264     have "isint (C j) (real i#bs)" by (simp add: isint_iff)
  3265     with isint_add[OF numbound0_gen[OF nb ei,rule_format, where y="real i"]]
  3266     have eji:"isint (Add e (C j)) (real i#bs)" by simp
  3267     from nb have nb': "numbound0 (Add e (C j))" by simp
  3268     from spx bound0_I[OF \<sigma>_nb[OF lp nb', where k="c"], where bs="bs" and b="a" and b'="real i"]
  3269     have spx': "Ifm (real i # bs) (\<sigma> p c (Add e (C j)))" by blast
  3270     from spx' have rcdej:"real c rdvd (Inum (real i#bs) (Add e (C j)))" 
  3271       and sr:"Ifm (real i#bs) (\<sigma>_\<rho> p (Add e (C j),c))" by (simp add: \<sigma>_def)+
  3272     from rcdej eji[simplified isint_iff] 
  3273     have "real c rdvd real (floor (Inum (real i#bs) (Add e (C j))))" by simp
  3274     hence cdej:"c dvd floor (Inum (real i#bs) (Add e (C j)))" by (simp only: int_rdvd_iff)
  3275     from cp have cp': "real c > 0" by simp
  3276     from \<sigma>_\<rho>[OF lp cp' nb' eji cdej] spx' have "?P (\<lfloor>Inum (real i # bs) (Add e (C j))\<rfloor> div c)"
  3277       by (simp add: \<sigma>_def)
  3278     hence ?lhs by blast
  3279     with exR jD spx have ?thesis by blast}
  3280   moreover
  3281   { fix x assume px: "?P x" and nob: "\<not> ?RD"
  3282     from iszlfm_gen [OF lp,rule_format, where y="a"] have lp':"iszlfm p (a#bs)" .
  3283     from \<rho>'[OF lp' d dp, rule_format, OF nob] have th:"\<forall> x. ?P x \<longrightarrow> ?P (x - ?d)" by blast
  3284     from minusinf_inf[OF lp] obtain z where z:"\<forall> x<z. ?MP x = ?P x" by blast
  3285     have zp: "abs (x - z) + 1 \<ge> 0" by arith
  3286     from decr_lemma[OF dp,where x="x" and z="z"] 
  3287       decr_mult_lemma[OF dp th zp, rule_format, OF px] z have th:"\<exists> x. ?MP x" by auto
  3288     with minusinf_bex[OF lp] px nob have ?thesis by blast}
  3289   ultimately show ?thesis by blast
  3290 qed
  3291 
  3292 lemma mirror_\<alpha>_\<rho>:   assumes lp: "iszlfm p (a#bs)"
  3293   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))"
  3294   using lp
  3295   by (induct p rule: mirror.induct) (simp_all add: split_def image_Un)
  3296   
  3297 text {* The @{text "\<real>"} part*}
  3298 
  3299 text{* Linearity for fm where Bound 0 ranges over @{text "\<real>"}*}
  3300 consts
  3301   isrlfm :: "fm \<Rightarrow> bool"   (* Linearity test for fm *)
  3302 recdef isrlfm "measure size"
  3303   "isrlfm (And p q) = (isrlfm p \<and> isrlfm q)" 
  3304   "isrlfm (Or p q) = (isrlfm p \<and> isrlfm q)" 
  3305   "isrlfm (Eq  (CN 0 c e)) = (c>0 \<and> numbound0 e)"
  3306   "isrlfm (NEq (CN 0 c e)) = (c>0 \<and> numbound0 e)"
  3307   "isrlfm (Lt  (CN 0 c e)) = (c>0 \<and> numbound0 e)"
  3308   "isrlfm (Le  (CN 0 c e)) = (c>0 \<and> numbound0 e)"
  3309   "isrlfm (Gt  (CN 0 c e)) = (c>0 \<and> numbound0 e)"
  3310   "isrlfm (Ge  (CN 0 c e)) = (c>0 \<and> numbound0 e)"
  3311   "isrlfm p = (isatom p \<and> (bound0 p))"
  3312 
  3313 definition fp :: "fm \<Rightarrow> int \<Rightarrow> num \<Rightarrow> int \<Rightarrow> fm" where
  3314   "fp p n s j \<equiv> (if n > 0 then 
  3315             (And p (And (Ge (CN 0 n (Sub s (Add (Floor s) (C j)))))
  3316                         (Lt (CN 0 n (Sub s (Add (Floor s) (C (j+1))))))))
  3317             else 
  3318             (And p (And (Le (CN 0 (-n) (Add (Neg s) (Add (Floor s) (C j))))) 
  3319                         (Gt (CN 0 (-n) (Add (Neg s) (Add (Floor s) (C (j + 1)))))))))"
  3320 
  3321   (* splits the bounded from the unbounded part*)
  3322 function (sequential) rsplit0 :: "num \<Rightarrow> (fm \<times> int \<times> num) list" where
  3323   "rsplit0 (Bound 0) = [(T,1,C 0)]"
  3324 | "rsplit0 (Add a b) = (let acs = rsplit0 a ; bcs = rsplit0 b 
  3325               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])"
  3326 | "rsplit0 (Sub a b) = rsplit0 (Add a (Neg b))"
  3327 | "rsplit0 (Neg a) = map (\<lambda> (p,n,s). (p,-n,Neg s)) (rsplit0 a)"
  3328 | "rsplit0 (Floor a) = concat (map 
  3329       (\<lambda> (p,n,s). if n=0 then [(p,0,Floor s)]
  3330           else (map (\<lambda> j. (fp p n s j, 0, Add (Floor s) (C j))) (if n > 0 then [0 .. n] else [n .. 0])))
  3331        (rsplit0 a))"
  3332 | "rsplit0 (CN 0 c a) = map (\<lambda> (p,n,s). (p,n+c,s)) (rsplit0 a)"
  3333 | "rsplit0 (CN m c a) = map (\<lambda> (p,n,s). (p,n,CN m c s)) (rsplit0 a)"
  3334 | "rsplit0 (CF c t s) = rsplit0 (Add (Mul c (Floor t)) s)"
  3335 | "rsplit0 (Mul c a) = map (\<lambda> (p,n,s). (p,c*n,Mul c s)) (rsplit0 a)"
  3336 | "rsplit0 t = [(T,0,t)]"
  3337 by pat_completeness auto
  3338 termination by (relation "measure num_size") auto
  3339 
  3340 lemma conj_rl[simp]: "isrlfm p \<Longrightarrow> isrlfm q \<Longrightarrow> isrlfm (conj p q)"
  3341   using conj_def by (cases p, auto)
  3342 lemma disj_rl[simp]: "isrlfm p \<Longrightarrow> isrlfm q \<Longrightarrow> isrlfm (disj p q)"
  3343   using disj_def by (cases p, auto)
  3344 
  3345 
  3346 lemma rsplit0_cs:
  3347   shows "\<forall> (p,n,s) \<in> set (rsplit0 t). 
  3348   (Ifm (x#bs) p \<longrightarrow>  (Inum (x#bs) t = Inum (x#bs) (CN 0 n s))) \<and> numbound0 s \<and> isrlfm p" 
  3349   (is "\<forall> (p,n,s) \<in> ?SS t. (?I p \<longrightarrow> ?N t = ?N (CN 0 n s)) \<and> _ \<and> _ ")
  3350 proof(induct t rule: rsplit0.induct)
  3351   case (5 a) 
  3352   let ?p = "\<lambda> (p,n,s) j. fp p n s j"
  3353   let ?f = "(\<lambda> (p,n,s) j. (?p (p,n,s) j, (0::int),Add (Floor s) (C j)))"
  3354   let ?J = "\<lambda> n. if n>0 then [0..n] else [n..0]"
  3355   let ?ff=" (\<lambda> (p,n,s). if n= 0 then [(p,0,Floor s)] else map (?f (p,n,s)) (?J n))"
  3356   have int_cases: "\<forall> (i::int). i= 0 \<or> i < 0 \<or> i > 0" by arith
  3357   have U1: "(UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) = 
  3358     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set [(p,0,Floor s)]))" by auto
  3359   have U2': "\<forall> (p,n,s) \<in> {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0}. 
  3360     ?ff (p,n,s) = map (?f(p,n,s)) [0..n]" by auto
  3361   hence U2: "(UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) = 
  3362     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). 
  3363     set (map (?f(p,n,s)) [0..n])))"
  3364   proof-
  3365     fix M :: "('a\<times>'b\<times>'c) set" and f :: "('a\<times>'b\<times>'c) \<Rightarrow> 'd list" and g
  3366     assume "\<forall> (a,b,c) \<in> M. f (a,b,c) = g a b c"
  3367     thus "(UNION M (\<lambda> (a,b,c). set (f (a,b,c)))) = (UNION M (\<lambda> (a,b,c). set (g a b c)))"
  3368       by (auto simp add: split_def)
  3369   qed
  3370   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]"
  3371     by auto
  3372   hence U3: "(UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) = 
  3373     (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])))"
  3374       proof-
  3375     fix M :: "('a\<times>'b\<times>'c) set" and f :: "('a\<times>'b\<times>'c) \<Rightarrow> 'd list" and g
  3376     assume "\<forall> (a,b,c) \<in> M. f (a,b,c) = g a b c"
  3377     thus "(UNION M (\<lambda> (a,b,c). set (f (a,b,c)))) = (UNION M (\<lambda> (a,b,c). set (g a b c)))"
  3378       by (auto simp add: split_def)
  3379   qed
  3380   have "?SS (Floor a) = UNION (?SS a) (\<lambda>x. set (?ff x))"
  3381     by auto
  3382   also have "\<dots> = UNION (?SS a) (\<lambda> (p,n,s). set (?ff (p,n,s)))" by blast
  3383   also have "\<dots> = 
  3384     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) Un 
  3385     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) Un 
  3386     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). set (?ff (p,n,s)))))" 
  3387     using int_cases[rule_format] by blast
  3388   also have "\<dots> =  
  3389     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set [(p,0,Floor s)])) Un 
  3390    (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 
  3391    (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). 
  3392     set (map (?f(p,n,s)) [n..0]))))" by (simp only: U1 U2 U3)
  3393   also have "\<dots> =  
  3394     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). {(p,0,Floor s)})) Un 
  3395     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). (?f(p,n,s)) ` {0 .. n})) Un 
  3396     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). (?f(p,n,s)) ` {n .. 0})))"
  3397     by (simp only: set_map set_upto list.set)
  3398   also have "\<dots> =   
  3399     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). {(p,0,Floor s)})) Un 
  3400     (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 
  3401     (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
  3402   finally 
  3403   have FS: "?SS (Floor a) =   
  3404     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). {(p,0,Floor s)})) Un 
  3405     (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 
  3406     (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
  3407   show ?case
  3408   proof(simp only: FS, clarsimp simp del: Ifm.simps Inum.simps, -)
  3409     fix p n s
  3410     let ?ths = "(?I p \<longrightarrow> (?N (Floor a) = ?N (CN 0 n s))) \<and> numbound0 s \<and> isrlfm p"
  3411     assume "(\<exists>ba. (p, 0, ba) \<in> set (rsplit0 a) \<and> n = 0 \<and> s = Floor ba) \<or>
  3412        (\<exists>ab ac ba.
  3413            (ab, ac, ba) \<in> set (rsplit0 a) \<and>
  3414            0 < ac \<and>
  3415            (\<exists>j. p = fp ab ac ba j \<and>
  3416                 n = 0 \<and> s = Add (Floor ba) (C j) \<and> 0 \<le> j \<and> j \<le> ac)) \<or>
  3417        (\<exists>ab ac ba.
  3418            (ab, ac, ba) \<in> set (rsplit0 a) \<and>
  3419            ac < 0 \<and>
  3420            (\<exists>j. p = fp ab ac ba j \<and>
  3421                 n = 0 \<and> s = Add (Floor ba) (C j) \<and> ac \<le> j \<and> j \<le> 0))"
  3422     moreover 
  3423     { fix s'
  3424       assume "(p, 0, s') \<in> ?SS a" and "n = 0" and "s = Floor s'"
  3425       hence ?ths using 5(1) by auto }
  3426     moreover
  3427     { fix p' n' s' j
  3428       assume pns: "(p', n', s') \<in> ?SS a" 
  3429         and np: "0 < n'" 
  3430         and p_def: "p = ?p (p',n',s') j" 
  3431         and n0: "n = 0" 
  3432         and s_def: "s = (Add (Floor s') (C j))" 
  3433         and jp: "0 \<le> j" and jn: "j \<le> n'"
  3434       from 5 pns have H:"(Ifm ((x\<Colon>real) # (bs\<Colon>real list)) p' \<longrightarrow>
  3435           Inum (x # bs) a = Inum (x # bs) (CN 0 n' s')) \<and>
  3436           numbound0 s' \<and> isrlfm p'" by blast
  3437       hence nb: "numbound0 s'" by simp
  3438       from H have nf: "isrlfm (?p (p',n',s') j)" using fp_def np by simp
  3439       let ?nxs = "CN 0 n' s'"
  3440       let ?l = "floor (?N s') + j"
  3441       from H 
  3442       have "?I (?p (p',n',s') j) \<longrightarrow> 
  3443           (((?N ?nxs \<ge> real ?l) \<and> (?N ?nxs < real (?l + 1))) \<and> (?N a = ?N ?nxs ))" 
  3444         by (simp add: fp_def np algebra_simps)
  3445       also have "\<dots> \<longrightarrow> ((floor (?N ?nxs) = ?l) \<and> (?N a = ?N ?nxs ))"
  3446         using floor_int_eq[where x="?N ?nxs" and n="?l"] by simp
  3447       moreover
  3448       have "\<dots> \<longrightarrow> (?N (Floor a) = ?N ((Add (Floor s') (C j))))" by simp
  3449       ultimately have "?I (?p (p',n',s') j) \<longrightarrow> (?N (Floor a) = ?N ((Add (Floor s') (C j))))"
  3450         by blast
  3451       with s_def n0 p_def nb nf have ?ths by auto}
  3452     moreover
  3453     { fix p' n' s' j
  3454       assume pns: "(p', n', s') \<in> ?SS a" 
  3455         and np: "n' < 0" 
  3456         and p_def: "p = ?p (p',n',s') j" 
  3457         and n0: "n = 0" 
  3458         and s_def: "s = (Add (Floor s') (C j))" 
  3459         and jp: "n' \<le> j" and jn: "j \<le> 0"
  3460       from 5 pns have H:"(Ifm ((x\<Colon>real) # (bs\<Colon>real list)) p' \<longrightarrow>
  3461           Inum (x # bs) a = Inum (x # bs) (CN 0 n' s')) \<and>
  3462           numbound0 s' \<and> isrlfm p'" by blast
  3463       hence nb: "numbound0 s'" by simp
  3464       from H have nf: "isrlfm (?p (p',n',s') j)" using fp_def np by simp
  3465       let ?nxs = "CN 0 n' s'"
  3466       let ?l = "floor (?N s') + j"
  3467       from H 
  3468       have "?I (?p (p',n',s') j) \<longrightarrow> 
  3469           (((?N ?nxs \<ge> real ?l) \<and> (?N ?nxs < real (?l + 1))) \<and> (?N a = ?N ?nxs ))" 
  3470         by (simp add: np fp_def algebra_simps)
  3471       also have "\<dots> \<longrightarrow> ((floor (?N ?nxs) = ?l) \<and> (?N a = ?N ?nxs ))"
  3472         using floor_int_eq[where x="?N ?nxs" and n="?l"] by simp
  3473       moreover
  3474       have "\<dots> \<longrightarrow> (?N (Floor a) = ?N ((Add (Floor s') (C j))))"  by simp
  3475       ultimately have "?I (?p (p',n',s') j) \<longrightarrow> (?N (Floor a) = ?N ((Add (Floor s') (C j))))"
  3476         by blast
  3477       with s_def n0 p_def nb nf have ?ths by auto}
  3478     ultimately show ?ths by auto
  3479   qed
  3480 next
  3481   case (3 a b) then show ?case
  3482     by auto
  3483 qed (auto simp add: Let_def split_def algebra_simps)
  3484 
  3485 lemma real_in_int_intervals: 
  3486   assumes xb: "real m \<le> x \<and> x < real ((n::int) + 1)"
  3487   shows "\<exists> j\<in> {m.. n}. real j \<le> x \<and> x < real (j+1)" (is "\<exists> j\<in> ?N. ?P j")
  3488 by (rule bexI[where P="?P" and x="floor x" and A="?N"]) 
  3489 (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"]])
  3490 
  3491 lemma rsplit0_complete:
  3492   assumes xp:"0 \<le> x" and x1:"x < 1"
  3493   shows "\<exists> (p,n,s) \<in> set (rsplit0 t). Ifm (x#bs) p" (is "\<exists> (p,n,s) \<in> ?SS t. ?I p")
  3494 proof(induct t rule: rsplit0.induct)
  3495   case (2 a b) 
  3496   then have "\<exists> (pa,na,sa) \<in> ?SS a. ?I pa" by auto
  3497   then obtain "pa" "na" "sa" where pa: "(pa,na,sa)\<in> ?SS a \<and> ?I pa" by blast
  3498   with 2 have "\<exists> (pb,nb,sb) \<in> ?SS b. ?I pb" by blast
  3499   then obtain "pb" "nb" "sb" where pb: "(pb,nb,sb)\<in> ?SS b \<and> ?I pb" by blast
  3500   from pa pb have th: "((pa,na,sa),(pb,nb,sb)) \<in> set[(x,y). x\<leftarrow>rsplit0 a, y\<leftarrow>rsplit0 b]"
  3501     by (auto)
  3502   let ?f="(\<lambda> ((p,n,t),(q,m,s)). (And p q, n+m, Add t s))"
  3503   from imageI[OF th, where f="?f"] have "?f ((pa,na,sa),(pb,nb,sb)) \<in> ?SS (Add a b)"
  3504     by (simp add: Let_def)
  3505   hence "(And pa pb, na +nb, Add sa sb) \<in> ?SS (Add a b)" by simp
  3506   moreover from pa pb have "?I (And pa pb)" by simp
  3507   ultimately show ?case by blast
  3508 next
  3509   case (5 a) 
  3510   let ?p = "\<lambda> (p,n,s) j. fp p n s j"
  3511   let ?f = "(\<lambda> (p,n,s) j. (?p (p,n,s) j, (0::int),(Add (Floor s) (C j))))"
  3512   let ?J = "\<lambda> n. if n>0 then [0..n] else [n..0]"
  3513   let ?ff=" (\<lambda> (p,n,s). if n= 0 then [(p,0,Floor s)] else map (?f (p,n,s)) (?J n))"
  3514   have int_cases: "\<forall> (i::int). i= 0 \<or> i < 0 \<or> i > 0" by arith
  3515   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
  3516   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]"
  3517     by auto
  3518   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])))"
  3519   proof-
  3520     fix M :: "('a\<times>'b\<times>'c) set" and f :: "('a\<times>'b\<times>'c) \<Rightarrow> 'd list" and g
  3521     assume "\<forall> (a,b,c) \<in> M. f (a,b,c) = g a b c"
  3522     thus "(UNION M (\<lambda> (a,b,c). set (f (a,b,c)))) = (UNION M (\<lambda> (a,b,c). set (g a b c)))"
  3523       by (auto simp add: split_def)
  3524   qed
  3525   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]"
  3526     by auto
  3527   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])))"
  3528   proof-
  3529     fix M :: "('a\<times>'b\<times>'c) set" and f :: "('a\<times>'b\<times>'c) \<Rightarrow> 'd list" and g
  3530     assume "\<forall> (a,b,c) \<in> M. f (a,b,c) = g a b c"
  3531     thus "(UNION M (\<lambda> (a,b,c). set (f (a,b,c)))) = (UNION M (\<lambda> (a,b,c). set (g a b c)))"
  3532       by (auto simp add: split_def)
  3533   qed
  3534 
  3535   have "?SS (Floor a) = UNION (?SS a) (\<lambda>x. set (?ff x))" by auto
  3536   also have "\<dots> = UNION (?SS a) (\<lambda> (p,n,s). set (?ff (p,n,s)))" by blast
  3537   also have "\<dots> = 
  3538     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) Un 
  3539     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). set (?ff (p,n,s)))) Un 
  3540     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). set (?ff (p,n,s)))))" 
  3541     using int_cases[rule_format] by blast
  3542   also have "\<dots> =  
  3543     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). set [(p,0,Floor s)])) Un 
  3544     (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 
  3545     (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]))))"
  3546     by (simp only: U1 U2 U3)
  3547   also have "\<dots> =  
  3548     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). {(p,0,Floor s)})) Un 
  3549     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n>0} (\<lambda> (p,n,s). (?f(p,n,s)) ` {0 .. n})) Un 
  3550     (UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n<0} (\<lambda> (p,n,s). (?f(p,n,s)) ` {n .. 0})))"
  3551     by (simp only: set_map set_upto list.set)
  3552   also have "\<dots> =   
  3553     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). {(p,0,Floor s)})) Un 
  3554     (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 
  3555     (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}})))"
  3556     by blast
  3557   finally 
  3558   have FS: "?SS (Floor a) =   
  3559     ((UNION {(p,n,s). (p,n,s) \<in> ?SS a \<and> n=0} (\<lambda> (p,n,s). {(p,0,Floor s)})) Un 
  3560     (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 
  3561     (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}})))"
  3562     by blast
  3563   from 5 have "\<exists> (p,n,s) \<in> ?SS a. ?I p" by auto
  3564   then obtain "p" "n" "s" where pns: "(p,n,s) \<in> ?SS a \<and> ?I p" by blast
  3565   let ?N = "\<lambda> t. Inum (x#bs) t"
  3566   from rsplit0_cs[rule_format] pns have ans:"(?N a = ?N (CN 0 n s)) \<and> numbound0 s \<and> isrlfm p"
  3567     by auto
  3568   
  3569   have "n=0 \<or> n >0 \<or> n <0" by arith
  3570   moreover {assume "n=0" hence ?case using pns by (simp only: FS) auto }
  3571   moreover
  3572   {
  3573     assume np: "n > 0"
  3574     from real_of_int_floor_le[where r="?N s"] have "?N (Floor s) \<le> ?N s" by simp
  3575     also from mult_left_mono[OF xp] np have "?N s \<le> real n * x + ?N s" by simp
  3576     finally have "?N (Floor s) \<le> real n * x + ?N s" .
  3577     moreover
  3578     {from x1 np have "real n *x + ?N s < real n + ?N s" by simp
  3579       also from real_of_int_floor_add_one_gt[where r="?N s"] 
  3580       have "\<dots> < real n + ?N (Floor s) + 1" by simp
  3581       finally have "real n *x + ?N s < ?N (Floor s) + real (n+1)" by simp}
  3582     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
  3583     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
  3584     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
  3585     
  3586     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"
  3587       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)"]) 
  3588     hence "\<exists> j\<in> {0.. n}. ?I (?p (p,n,s) j)"
  3589       using pns by (simp add: fp_def np algebra_simps)
  3590     then obtain "j" where j_def: "j\<in> {0 .. n} \<and> ?I (?p (p,n,s) j)" by blast
  3591     hence "\<exists>x \<in> {?p (p,n,s) j |j. 0\<le> j \<and> j \<le> n }. ?I x" by auto
  3592     hence ?case using pns 
  3593       by (simp only: FS,simp add: bex_Un) 
  3594     (rule disjI2, rule disjI1,rule exI [where x="p"],
  3595       rule exI [where x="n"],rule exI [where x="s"],simp_all add: np)
  3596   }
  3597   moreover
  3598   { assume nn: "n < 0" hence np: "-n >0" by simp
  3599     from real_of_int_floor_le[where r="?N s"] have "?N (Floor s) + 1 > ?N s" by simp
  3600     moreover from mult_left_mono_neg[OF xp] nn have "?N s \<ge> real n * x + ?N s" by simp
  3601     ultimately have "?N (Floor s) + 1 > real n * x + ?N s" by arith 
  3602     moreover
  3603     {from x1 nn have "real n *x + ?N s \<ge> real n + ?N s" by simp
  3604       moreover from real_of_int_floor_le[where r="?N s"]  have "real n + ?N s \<ge> real n + ?N (Floor s)" by simp
  3605       ultimately have "real n *x + ?N s \<ge> ?N (Floor s) + real n" 
  3606         by (simp only: algebra_simps)}
  3607     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
  3608     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
  3609     have th1: "\<forall> (a::real). (- a > 0) = (a < 0)" by auto
  3610     have th2: "\<forall> (a::real). (0 \<ge> - a) = (a \<ge> 0)" by auto
  3611     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
  3612     
  3613     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"
  3614       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)"]) 
  3615     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])
  3616     hence "\<exists> j\<in> {n.. 0}. ?I (?p (p,n,s) j)"
  3617       using pns by (simp add: fp_def nn algebra_simps
  3618         del: diff_less_0_iff_less diff_le_0_iff_le) 
  3619     then obtain "j" where j_def: "j\<in> {n .. 0} \<and> ?I (?p (p,n,s) j)" by blast
  3620     hence "\<exists>x \<in> {?p (p,n,s) j |j. n\<le> j \<and> j \<le> 0 }. ?I x" by auto
  3621     hence ?case using pns 
  3622       by (simp only: FS,simp add: bex_Un)
  3623     (rule disjI2, rule disjI2,rule exI [where x="p"],
  3624       rule exI [where x="n"],rule exI [where x="s"],simp_all add: nn)
  3625   }
  3626   ultimately show ?case by blast
  3627 qed (auto simp add: Let_def split_def)
  3628 
  3629     (* Linearize a formula where Bound 0 ranges over [0,1) *)
  3630 
  3631 definition rsplit :: "(int \<Rightarrow> num \<Rightarrow> fm) \<Rightarrow> num \<Rightarrow> fm" where
  3632   "rsplit f a \<equiv> foldr disj (map (\<lambda> (\<phi>, n, s). conj \<phi> (f n s)) (rsplit0 a)) F"
  3633 
  3634 lemma foldr_disj_map: "Ifm bs (foldr disj (map f xs) F) = (\<exists> x \<in> set xs. Ifm bs (f x))"
  3635 by(induct xs, simp_all)
  3636 
  3637 lemma foldr_conj_map: "Ifm bs (foldr conj (map f xs) T) = (\<forall> x \<in> set xs. Ifm bs (f x))"
  3638 by(induct xs, simp_all)
  3639 
  3640 lemma foldr_disj_map_rlfm: 
  3641   assumes lf: "\<forall> n s. numbound0 s \<longrightarrow> isrlfm (f n s)"
  3642   and \<phi>: "\<forall> (\<phi>,n,s) \<in> set xs. numbound0 s \<and> isrlfm \<phi>"
  3643   shows "isrlfm (foldr disj (map (\<lambda> (\<phi>, n, s). conj \<phi> (f n s)) xs) F)"
  3644 using lf \<phi> by (induct xs, auto)
  3645 
  3646 lemma rsplit_ex: "Ifm bs (rsplit f a) = (\<exists> (\<phi>,n,s) \<in> set (rsplit0 a). Ifm bs (conj \<phi> (f n s)))"
  3647 using foldr_disj_map[where xs="rsplit0 a"] rsplit_def by (simp add: split_def)
  3648 
  3649 lemma rsplit_l: assumes lf: "\<forall> n s. numbound0 s \<longrightarrow> isrlfm (f n s)"
  3650   shows "isrlfm (rsplit f a)"
  3651 proof-
  3652   from rsplit0_cs[where t="a"] have th: "\<forall> (\<phi>,n,s) \<in> set (rsplit0 a). numbound0 s \<and> isrlfm \<phi>" by blast
  3653   from foldr_disj_map_rlfm[OF lf th] rsplit_def show ?thesis by simp
  3654 qed
  3655 
  3656 lemma rsplit: 
  3657   assumes xp: "x \<ge> 0" and x1: "x < 1"
  3658   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))"
  3659   shows "Ifm (x#bs) (rsplit f a) = Ifm (x#bs) (g a)"
  3660 proof(auto)
  3661   let ?I = "\<lambda>x p. Ifm (x#bs) p"
  3662   let ?N = "\<lambda> x t. Inum (x#bs) t"
  3663   assume "?I x (rsplit f a)"
  3664   hence "\<exists> (\<phi>,n,s) \<in> set (rsplit0 a). ?I x (And \<phi> (f n s))" using rsplit_ex by simp
  3665   then obtain "\<phi>" "n" "s" where fnsS:"(\<phi>,n,s) \<in> set (rsplit0 a)" and "?I x (And \<phi> (f n s))" by blast
  3666   hence \<phi>: "?I x \<phi>" and fns: "?I x (f n s)" by auto
  3667   from rsplit0_cs[where t="a" and bs="bs" and x="x", rule_format, OF fnsS] \<phi> 
  3668   have th: "(?N x a = ?N x (CN 0 n s)) \<and> numbound0 s" by auto
  3669   from f[rule_format, OF th] fns show "?I x (g a)" by simp
  3670 next
  3671   let ?I = "\<lambda>x p. Ifm (x#bs) p"
  3672   let ?N = "\<lambda> x t. Inum (x#bs) t"
  3673   assume ga: "?I x (g a)"
  3674   from rsplit0_complete[OF xp x1, where bs="bs" and t="a"] 
  3675   obtain "\<phi>" "n" "s" where fnsS:"(\<phi>,n,s) \<in> set (rsplit0 a)" and fx: "?I x \<phi>" by blast
  3676   from rsplit0_cs[where t="a" and x="x" and bs="bs"] fnsS fx
  3677   have ans: "?N x a = ?N x (CN 0 n s)" and nb: "numbound0 s" by auto
  3678   with ga f have "?I x (f n s)" by auto
  3679   with rsplit_ex fnsS fx show "?I x (rsplit f a)" by auto
  3680 qed
  3681 
  3682 definition lt :: "int \<Rightarrow> num \<Rightarrow> fm" where
  3683   lt_def: "lt c t = (if c = 0 then (Lt t) else if c > 0 then (Lt (CN 0 c t)) 
  3684                         else (Gt (CN 0 (-c) (Neg t))))"
  3685 
  3686 definition  le :: "int \<Rightarrow> num \<Rightarrow> fm" where
  3687   le_def: "le c t = (if c = 0 then (Le t) else if c > 0 then (Le (CN 0 c t)) 
  3688                         else (Ge (CN 0 (-c) (Neg t))))"
  3689 
  3690 definition  gt :: "int \<Rightarrow> num \<Rightarrow> fm" where
  3691   gt_def: "gt c t = (if c = 0 then (Gt t) else if c > 0 then (Gt (CN 0 c t)) 
  3692                         else (Lt (CN 0 (-c) (Neg t))))"
  3693 
  3694 definition  ge :: "int \<Rightarrow> num \<Rightarrow> fm" where
  3695   ge_def: "ge c t = (if c = 0 then (Ge t) else if c > 0 then (Ge (CN 0 c t)) 
  3696                         else (Le (CN 0 (-c) (Neg t))))"
  3697 
  3698 definition  eq :: "int \<Rightarrow> num \<Rightarrow> fm" where
  3699   eq_def: "eq c t = (if c = 0 then (Eq t) else if c > 0 then (Eq (CN 0 c t)) 
  3700                         else (Eq (CN 0 (-c) (Neg t))))"
  3701 
  3702 definition neq :: "int \<Rightarrow> num \<Rightarrow> fm" where
  3703   neq_def: "neq c t = (if c = 0 then (NEq t) else if c > 0 then (NEq (CN 0 c t)) 
  3704                         else (NEq (CN 0 (-c) (Neg t))))"
  3705 
  3706 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)"
  3707   (is "\<forall> a n s . ?N a = ?N (CN 0 n s) \<and> _\<longrightarrow> ?I (lt n s) = ?I (Lt a)")
  3708 proof(clarify)
  3709   fix a n s
  3710   assume H: "?N a = ?N (CN 0 n s)"
  3711   show "?I (lt n s) = ?I (Lt a)" using H by (cases "n=0", (simp add: lt_def))
  3712   (cases "n > 0", simp_all add: lt_def algebra_simps myless[of _ "0"])
  3713 qed
  3714 
  3715 lemma lt_l: "isrlfm (rsplit lt a)"
  3716   by (rule rsplit_l[where f="lt" and a="a"], auto simp add: lt_def,
  3717     case_tac s, simp_all, rename_tac nat a b, case_tac "nat", simp_all)
  3718 
  3719 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)")
  3720 proof(clarify)
  3721   fix a n s
  3722   assume H: "?N a = ?N (CN 0 n s)"
  3723   show "?I (le n s) = ?I (Le a)" using H by (cases "n=0", (simp add: le_def))
  3724   (cases "n > 0", simp_all add: le_def algebra_simps myle[of _ "0"])
  3725 qed
  3726 
  3727 lemma le_l: "isrlfm (rsplit le a)"
  3728   by (rule rsplit_l[where f="le" and a="a"], auto simp add: le_def) 
  3729 (case_tac s, simp_all, rename_tac nat a b, case_tac "nat",simp_all)
  3730 
  3731 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)")
  3732 proof(clarify)
  3733   fix a n s
  3734   assume H: "?N a = ?N (CN 0 n s)"
  3735   show "?I (gt n s) = ?I (Gt a)" using H by (cases "n=0", (simp add: gt_def))
  3736   (cases "n > 0", simp_all add: gt_def algebra_simps myless[of _ "0"])
  3737 qed
  3738 lemma gt_l: "isrlfm (rsplit gt a)"
  3739   by (rule rsplit_l[where f="gt" and a="a"], auto simp add: gt_def) 
  3740 (case_tac s, simp_all, rename_tac nat a b, case_tac "nat", simp_all)
  3741 
  3742 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)")
  3743 proof(clarify)
  3744   fix a n s 
  3745   assume H: "?N a = ?N (CN 0 n s)"
  3746   show "?I (ge n s) = ?I (Ge a)" using H by (cases "n=0", (simp add: ge_def))
  3747   (cases "n > 0", simp_all add: ge_def algebra_simps myle[of _ "0"])
  3748 qed
  3749 lemma ge_l: "isrlfm (rsplit ge a)"
  3750   by (rule rsplit_l[where f="ge" and a="a"], auto simp add: ge_def) 
  3751 (case_tac s, simp_all, rename_tac nat a b, case_tac "nat", simp_all)
  3752 
  3753 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)")
  3754 proof(clarify)
  3755   fix a n s 
  3756   assume H: "?N a = ?N (CN 0 n s)"
  3757   show "?I (eq n s) = ?I (Eq a)" using H by (auto simp add: eq_def algebra_simps)
  3758 qed
  3759 lemma eq_l: "isrlfm (rsplit eq a)"
  3760   by (rule rsplit_l[where f="eq" and a="a"], auto simp add: eq_def) 
  3761 (case_tac s, simp_all, rename_tac nat a b, case_tac"nat", simp_all)
  3762 
  3763 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)")
  3764 proof(clarify)
  3765   fix a n s bs
  3766   assume H: "?N a = ?N (CN 0 n s)"
  3767   show "?I (neq n s) = ?I (NEq a)" using H by (auto simp add: neq_def algebra_simps)
  3768 qed
  3769 
  3770 lemma neq_l: "isrlfm (rsplit neq a)"
  3771   by (rule rsplit_l[where f="neq" and a="a"], auto simp add: neq_def) 
  3772 (case_tac s, simp_all, rename_tac nat a b, case_tac"nat", simp_all)
  3773 
  3774 lemma small_le: 
  3775   assumes u0:"0 \<le> u" and u1: "u < 1"
  3776   shows "(-u \<le> real (n::int)) = (0 \<le> n)"
  3777 using u0 u1  by auto
  3778 
  3779 lemma small_lt: 
  3780   assumes u0:"0 \<le> u" and u1: "u < 1"
  3781   shows "(real (n::int) < real (m::int) - u) = (n < m)"
  3782 using u0 u1  by auto
  3783 
  3784 lemma rdvd01_cs: 
  3785   assumes up: "u \<ge> 0" and u1: "u<1" and np: "real n > 0"
  3786   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")
  3787 proof-
  3788   let ?ss = "s - real (floor s)"
  3789   from real_of_int_floor_add_one_gt[where r="s", simplified myless[of "s"]] 
  3790     real_of_int_floor_le[where r="s"]  have ss0:"?ss \<ge> 0" and ss1:"?ss < 1" 
  3791     by (auto simp add: myle[of _ "s", symmetric] myless[of "?ss"])
  3792   from np have n0: "real n \<ge> 0" by simp
  3793   from mult_left_mono[OF up n0] mult_strict_left_mono[OF u1 np] 
  3794   have nu0:"real n * u - s \<ge> -s" and nun:"real n * u -s < real n - s" by auto  
  3795   from int_rdvd_real[where i="i" and x="real (n::int) * u - s"] 
  3796   have "real i rdvd real n * u - s = 
  3797     (i dvd floor (real n * u -s) \<and> (real (floor (real n * u - s)) = real n * u - s ))" 
  3798     (is "_ = (?DE)" is "_ = (?D \<and> ?E)") by simp
  3799   also have "\<dots> = (?DE \<and> real(floor (real n * u - s) + floor s)\<ge> -?ss 
  3800     \<and> real(floor (real n * u - s) + floor s)< real n - ?ss)" (is "_=(?DE \<and>real ?a \<ge> _ \<and> real ?a < _)")
  3801     using nu0 nun  by auto
  3802   also have "\<dots> = (?DE \<and> ?a \<ge> 0 \<and> ?a < n)" by(simp only: small_le[OF ss0 ss1] small_lt[OF ss0 ss1])
  3803   also have "\<dots> = (?DE \<and> (\<exists> j\<in> {0 .. (n - 1)}. ?a = j))" by simp
  3804   also have "\<dots> = (?DE \<and> (\<exists> j\<in> {0 .. (n - 1)}. real (\<lfloor>real n * u - s\<rfloor>) = real j - real \<lfloor>s\<rfloor> ))"
  3805     by (simp only: algebra_simps real_of_int_diff[symmetric] real_of_int_inject)
  3806   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>"]
  3807     by (auto cong: conj_cong)
  3808   also have "\<dots> = ?rhs" by(simp cong: conj_cong) (simp add: algebra_simps )
  3809   finally show ?thesis .
  3810 qed
  3811 
  3812 definition
  3813   DVDJ:: "int \<Rightarrow> int \<Rightarrow> num \<Rightarrow> fm"
  3814 where
  3815   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)"
  3816 
  3817 definition
  3818   NDVDJ:: "int \<Rightarrow> int \<Rightarrow> num \<Rightarrow> fm"
  3819 where
  3820   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)"
  3821 
  3822 lemma DVDJ_DVD: 
  3823   assumes xp:"x\<ge> 0" and x1: "x < 1" and np:"real n > 0"
  3824   shows "Ifm (x#bs) (DVDJ i n s) = Ifm (x#bs) (Dvd i (CN 0 n s))"
  3825 proof-
  3826   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))))"
  3827   let ?s= "Inum (x#bs) s"
  3828   from foldr_disj_map[where xs="[0..n - 1]" and bs="x#bs" and f="?f"]
  3829   have "Ifm (x#bs) (DVDJ i n s) = (\<exists> j\<in> {0 .. (n - 1)}. Ifm (x#bs) (?f j))" 
  3830     by (simp add: np DVDJ_def)
  3831   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)))"
  3832     by (simp add: algebra_simps)
  3833   also from rdvd01_cs[OF xp x1 np, where i="i" and s="-?s"] 
  3834   have "\<dots> = (real i rdvd real n * x - (-?s))" by simp
  3835   finally show ?thesis by simp
  3836 qed
  3837 
  3838 lemma NDVDJ_NDVD: 
  3839   assumes xp:"x\<ge> 0" and x1: "x < 1" and np:"real n > 0"
  3840   shows "Ifm (x#bs) (NDVDJ i n s) = Ifm (x#bs) (NDvd i (CN 0 n s))"
  3841 proof-
  3842   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))))"
  3843   let ?s= "Inum (x#bs) s"
  3844   from foldr_conj_map[where xs="[0..n - 1]" and bs="x#bs" and f="?f"]
  3845   have "Ifm (x#bs) (NDVDJ i n s) = (\<forall> j\<in> {0 .. (n - 1)}. Ifm (x#bs) (?f j))" 
  3846     by (simp add: np NDVDJ_def)
  3847   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))))"
  3848     by (simp add: algebra_simps)
  3849   also from rdvd01_cs[OF xp x1 np, where i="i" and s="-?s"] 
  3850   have "\<dots> = (\<not> (real i rdvd real n * x - (-?s)))" by simp
  3851   finally show ?thesis by simp
  3852 qed  
  3853 
  3854 lemma foldr_disj_map_rlfm2: 
  3855   assumes lf: "\<forall> n . isrlfm (f n)"
  3856   shows "isrlfm (foldr disj (map f xs) F)"
  3857 using lf by (induct xs, auto)
  3858 lemma foldr_And_map_rlfm2: 
  3859   assumes lf: "\<forall> n . isrlfm (f n)"
  3860   shows "isrlfm (foldr conj (map f xs) T)"
  3861 using lf by (induct xs, auto)
  3862 
  3863 lemma DVDJ_l: assumes ip: "i >0" and np: "n>0" and nb: "numbound0 s"
  3864   shows "isrlfm (DVDJ i n s)"
  3865 proof-
  3866   let ?f="\<lambda>j. conj (Eq (CN 0 n (Add s (Sub (Floor (Neg s)) (C j)))))
  3867                          (Dvd i (Sub (C j) (Floor (Neg s))))"
  3868   have th: "\<forall> j. isrlfm (?f j)" using nb np by auto
  3869   from DVDJ_def foldr_disj_map_rlfm2[OF th] show ?thesis by simp 
  3870 qed
  3871 
  3872 lemma NDVDJ_l: assumes ip: "i >0" and np: "n>0" and nb: "numbound0 s"
  3873   shows "isrlfm (NDVDJ i n s)"
  3874 proof-
  3875   let ?f="\<lambda>j. disj (NEq (CN 0 n (Add s (Sub (Floor (Neg s)) (C j)))))
  3876                       (NDvd i (Sub (C j) (Floor (Neg s))))"
  3877   have th: "\<forall> j. isrlfm (?f j)" using nb np by auto
  3878   from NDVDJ_def foldr_And_map_rlfm2[OF th] show ?thesis by auto
  3879 qed
  3880 
  3881 definition DVD :: "int \<Rightarrow> int \<Rightarrow> num \<Rightarrow> fm" where
  3882   DVD_def: "DVD i c t =
  3883   (if i=0 then eq c t else 
  3884   if c = 0 then (Dvd i t) else if c >0 then DVDJ (abs i) c t else DVDJ (abs i) (-c) (Neg t))"
  3885 
  3886 definition  NDVD :: "int \<Rightarrow> int \<Rightarrow> num \<Rightarrow> fm" where
  3887   "NDVD i c t =
  3888   (if i=0 then neq c t else 
  3889   if c = 0 then (NDvd i t) else if c >0 then NDVDJ (abs i) c t else NDVDJ (abs i) (-c) (Neg t))"
  3890 
  3891 lemma DVD_mono: 
  3892   assumes xp: "0\<le> x" and x1: "x < 1" 
  3893   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)"
  3894   (is "\<forall> a n s. ?N a = ?N (CN 0 n s) \<and> _ \<longrightarrow> ?I (DVD i n s) = ?I (Dvd i a)")
  3895 proof(clarify)
  3896   fix a n s 
  3897   assume H: "?N a = ?N (CN 0 n s)" and nb: "numbound0 s"
  3898   let ?th = "?I (DVD i n s) = ?I (Dvd i a)"
  3899   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
  3900   moreover {assume iz: "i=0" hence ?th using eq_mono[rule_format, OF conjI[OF H nb]] 
  3901       by (simp add: DVD_def rdvd_left_0_eq)}
  3902   moreover {assume inz: "i\<noteq>0" and "n=0" hence ?th by (simp add: H DVD_def) } 
  3903   moreover {assume inz: "i\<noteq>0" and "n<0" hence ?th 
  3904       by (simp add: DVD_def H DVDJ_DVD[OF xp x1] rdvd_abs1 
  3905         rdvd_minus[where d="i" and t="real n * x + Inum (x # bs) s"]) } 
  3906   moreover {assume inz: "i\<noteq>0" and "n>0" hence ?th by (simp add:DVD_def H DVDJ_DVD[OF xp x1] rdvd_abs1)}
  3907   ultimately show ?th by blast
  3908 qed
  3909 
  3910 lemma NDVD_mono:   assumes xp: "0\<le> x" and x1: "x < 1" 
  3911   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)"
  3912   (is "\<forall> a n s. ?N a = ?N (CN 0 n s) \<and> _ \<longrightarrow> ?I (NDVD i n s) = ?I (NDvd i a)")
  3913 proof(clarify)
  3914   fix a n s 
  3915   assume H: "?N a = ?N (CN 0 n s)" and nb: "numbound0 s"
  3916   let ?th = "?I (NDVD i n s) = ?I (NDvd i a)"
  3917   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
  3918   moreover {assume iz: "i=0" hence ?th using neq_mono[rule_format, OF conjI[OF H nb]] 
  3919       by (simp add: NDVD_def rdvd_left_0_eq)}
  3920   moreover {assume inz: "i\<noteq>0" and "n=0" hence ?th by (simp add: H NDVD_def) } 
  3921   moreover {assume inz: "i\<noteq>0" and "n<0" hence ?th 
  3922       by (simp add: NDVD_def H NDVDJ_NDVD[OF xp x1] rdvd_abs1 
  3923         rdvd_minus[where d="i" and t="real n * x + Inum (x # bs) s"]) } 
  3924   moreover {assume inz: "i\<noteq>0" and "n>0" hence ?th 
  3925       by (simp add:NDVD_def H NDVDJ_NDVD[OF xp x1] rdvd_abs1)}
  3926   ultimately show ?th by blast
  3927 qed
  3928 
  3929 lemma DVD_l: "isrlfm (rsplit (DVD i) a)"
  3930   by (rule rsplit_l[where f="DVD i" and a="a"], auto simp add: DVD_def eq_def DVDJ_l) 
  3931 (case_tac s, simp_all, rename_tac nat a b, case_tac "nat", simp_all)
  3932 
  3933 lemma NDVD_l: "isrlfm (rsplit (NDVD i) a)"
  3934   by (rule rsplit_l[where f="NDVD i" and a="a"], auto simp add: NDVD_def neq_def NDVDJ_l) 
  3935 (case_tac s, simp_all, rename_tac nat a b, case_tac "nat", simp_all)
  3936 
  3937 consts rlfm :: "fm \<Rightarrow> fm"
  3938 recdef rlfm "measure fmsize"
  3939   "rlfm (And p q) = conj (rlfm p) (rlfm q)"
  3940   "rlfm (Or p q) = disj (rlfm p) (rlfm q)"
  3941   "rlfm (Imp p q) = disj (rlfm (NOT p)) (rlfm q)"
  3942   "rlfm (Iff p q) = disj (conj(rlfm p) (rlfm q)) (conj(rlfm (NOT p)) (rlfm (NOT q)))"
  3943   "rlfm (Lt a) = rsplit lt a"
  3944   "rlfm (Le a) = rsplit le a"
  3945   "rlfm (Gt a) = rsplit gt a"
  3946   "rlfm (Ge a) = rsplit ge a"
  3947   "rlfm (Eq a) = rsplit eq a"
  3948   "rlfm (NEq a) = rsplit neq a"
  3949   "rlfm (Dvd i a) = rsplit (\<lambda> t. DVD i t) a"
  3950   "rlfm (NDvd i a) = rsplit (\<lambda> t. NDVD i t) a"
  3951   "rlfm (NOT (And p q)) = disj (rlfm (NOT p)) (rlfm (NOT q))"
  3952   "rlfm (NOT (Or p q)) = conj (rlfm (NOT p)) (rlfm (NOT q))"
  3953   "rlfm (NOT (Imp p q)) = conj (rlfm p) (rlfm (NOT q))"
  3954   "rlfm (NOT (Iff p q)) = disj (conj(rlfm p) (rlfm(NOT q))) (conj(rlfm(NOT p)) (rlfm q))"
  3955   "rlfm (NOT (NOT p)) = rlfm p"
  3956   "rlfm (NOT T) = F"
  3957   "rlfm (NOT F) = T"
  3958   "rlfm (NOT (Lt a)) = simpfm (rlfm (Ge a))"
  3959   "rlfm (NOT (Le a)) = simpfm (rlfm (Gt a))"
  3960   "rlfm (NOT (Gt a)) = simpfm (rlfm (Le a))"
  3961   "rlfm (NOT (Ge a)) = simpfm (rlfm (Lt a))"
  3962   "rlfm (NOT (Eq a)) = simpfm (rlfm (NEq a))"
  3963   "rlfm (NOT (NEq a)) = simpfm (rlfm (Eq a))"
  3964   "rlfm (NOT (Dvd i a)) = simpfm (rlfm (NDvd i a))"
  3965   "rlfm (NOT (NDvd i a)) = simpfm (rlfm (Dvd i a))"
  3966   "rlfm p = p" (hints simp add: fmsize_pos)
  3967 
  3968 lemma bound0at_l : "\<lbrakk>isatom p ; bound0 p\<rbrakk> \<Longrightarrow> isrlfm p"
  3969   by (induct p rule: isrlfm.induct, auto)
  3970 
  3971 lemma simpfm_rl: "isrlfm p \<Longrightarrow> isrlfm (simpfm p)"
  3972 proof (induct p)
  3973   case (Lt a) 
  3974   hence "bound0 (Lt a) \<or> (\<exists> c e. a = CN 0 c e \<and> c > 0 \<and> numbound0 e)"
  3975     by (cases a,simp_all, rename_tac nat a b, case_tac "nat", simp_all)
  3976   moreover
  3977   {assume "bound0 (Lt a)" hence bn:"bound0 (simpfm (Lt a))"  
  3978       using simpfm_bound0 by blast
  3979     have "isatom (simpfm (Lt a))" by (cases "simpnum a", auto simp add: Let_def)
  3980     with bn bound0at_l have ?case by blast}
  3981   moreover 
  3982   { fix c e assume a: "a = CN 0 c e" and "c>0" and "numbound0 e"
  3983     { assume cn1:"numgcd (CN 0 c (simpnum e)) \<noteq> 1" and cnz:"numgcd (CN 0 c (simpnum e)) \<noteq> 0"
  3984       with numgcd_pos[where t="CN 0 c (simpnum e)"]
  3985       have th1:"numgcd (CN 0 c (simpnum e)) > 0" by simp
  3986       from `c > 0` have th:"numgcd (CN 0 c (simpnum e)) \<le> c" 
  3987         by (simp add: numgcd_def)
  3988       from `c > 0` have th': "c\<noteq>0" by auto
  3989       from `c > 0` have cp: "c \<ge> 0" by simp
  3990       from zdiv_mono2[OF cp th1 th, simplified div_self[OF th']]
  3991       have "0 < c div numgcd (CN 0 c (simpnum e))" by simp
  3992     }
  3993     with Lt a have ?case
  3994       by (simp add: Let_def reducecoeff_def reducecoeffh_numbound0)}
  3995   ultimately show ?case by blast
  3996 next
  3997   case (Le a)   
  3998   hence "bound0 (Le a) \<or> (\<exists> c e. a = CN 0 c e \<and> c > 0 \<and> numbound0 e)"
  3999     by (cases a,simp_all, rename_tac nat a b, case_tac "nat", simp_all)
  4000   moreover
  4001   { assume "bound0 (Le a)" hence bn:"bound0 (simpfm (Le a))"  
  4002       using simpfm_bound0 by blast
  4003     have "isatom (simpfm (Le a))" by (cases "simpnum a", auto simp add: Let_def)
  4004     with bn bound0at_l have ?case by blast}
  4005   moreover 
  4006   { fix c e assume a: "a = CN 0 c e" and "c>0" and "numbound0 e"
  4007     { assume cn1:"numgcd (CN 0 c (simpnum e)) \<noteq> 1" and cnz:"numgcd (CN 0 c (simpnum e)) \<noteq> 0"
  4008       with numgcd_pos[where t="CN 0 c (simpnum e)"]
  4009       have th1:"numgcd (CN 0 c (simpnum e)) > 0" by simp
  4010       from `c > 0` have th:"numgcd (CN 0 c (simpnum e)) \<le> c" 
  4011         by (simp add: numgcd_def)
  4012       from `c > 0` have th': "c\<noteq>0" by auto
  4013       from `c > 0` have cp: "c \<ge> 0" by simp
  4014       from zdiv_mono2[OF cp th1 th, simplified div_self[OF th']]
  4015       have "0 < c div numgcd (CN 0 c (simpnum e))" by simp
  4016     }
  4017     with Le a have ?case
  4018       by (simp add: Let_def reducecoeff_def reducecoeffh_numbound0)}
  4019   ultimately show ?case by blast
  4020 next
  4021   case (Gt a)   
  4022   hence "bound0 (Gt a) \<or> (\<exists> c e. a = CN 0 c e \<and> c > 0 \<and> numbound0 e)"
  4023     by (cases a, simp_all, rename_tac nat a b,case_tac "nat", simp_all)
  4024   moreover
  4025   {assume "bound0 (Gt a)" hence bn:"bound0 (simpfm (Gt a))"  
  4026       using simpfm_bound0 by blast
  4027     have "isatom (simpfm (Gt a))" by (cases "simpnum a", auto simp add: Let_def)
  4028     with bn bound0at_l have ?case by blast}
  4029   moreover 
  4030   { fix c e assume a: "a = CN 0 c e" and "c>0" and "numbound0 e"
  4031     { assume cn1: "numgcd (CN 0 c (simpnum e)) \<noteq> 1" and cnz:"numgcd (CN 0 c (simpnum e)) \<noteq> 0"
  4032       with numgcd_pos[where t="CN 0 c (simpnum e)"]
  4033       have th1:"numgcd (CN 0 c (simpnum e)) > 0" by simp
  4034       from `c > 0` have th:"numgcd (CN 0 c (simpnum e)) \<le> c" 
  4035         by (simp add: numgcd_def)
  4036       from `c > 0` have th': "c\<noteq>0" by auto
  4037       from `c > 0` have cp: "c \<ge> 0" by simp
  4038       from zdiv_mono2[OF cp th1 th, simplified div_self[OF th']]
  4039       have "0 < c div numgcd (CN 0 c (simpnum e))" by simp
  4040     }
  4041     with Gt a have ?case
  4042       by (simp add: Let_def reducecoeff_def reducecoeffh_numbound0)}
  4043   ultimately show ?case by blast
  4044 next
  4045   case (Ge a)   
  4046   hence "bound0 (Ge a) \<or> (\<exists> c e. a = CN 0 c e \<and> c > 0 \<and> numbound0 e)"
  4047     by (cases a,simp_all, rename_tac nat a b, case_tac "nat", simp_all)
  4048   moreover
  4049   { assume "bound0 (Ge a)" hence bn:"bound0 (simpfm (Ge a))"  
  4050       using simpfm_bound0 by blast
  4051     have "isatom (simpfm (Ge a))" by (cases "simpnum a", auto simp add: Let_def)
  4052     with bn bound0at_l have ?case by blast}
  4053   moreover 
  4054   { fix c e assume a: "a = CN 0 c e" and "c>0" and "numbound0 e"
  4055     { assume cn1:"numgcd (CN 0 c (simpnum e)) \<noteq> 1" and cnz:"numgcd (CN 0 c (simpnum e)) \<noteq> 0"
  4056       with numgcd_pos[where t="CN 0 c (simpnum e)"]
  4057       have th1:"numgcd (CN 0 c (simpnum e)) > 0" by simp
  4058       from `c > 0` have th:"numgcd (CN 0 c (simpnum e)) \<le> c" 
  4059         by (simp add: numgcd_def)
  4060       from `c > 0` have th': "c\<noteq>0" by auto
  4061       from `c > 0` have cp: "c \<ge> 0" by simp
  4062       from zdiv_mono2[OF cp th1 th, simplified div_self[OF th']]
  4063       have "0 < c div numgcd (CN 0 c (simpnum e))" by simp
  4064     }
  4065     with Ge a have ?case
  4066       by (simp add: Let_def reducecoeff_def reducecoeffh_numbound0)}
  4067   ultimately show ?case by blast
  4068 next
  4069   case (Eq a)   
  4070   hence "bound0 (Eq a) \<or> (\<exists> c e. a = CN 0 c e \<and> c > 0 \<and> numbound0 e)"
  4071     by (cases a,simp_all, rename_tac nat a b, case_tac "nat", simp_all)
  4072   moreover
  4073   { assume "bound0 (Eq a)" hence bn:"bound0 (simpfm (Eq a))"  
  4074       using simpfm_bound0 by blast
  4075     have "isatom (simpfm (Eq a))" by (cases "simpnum a", auto simp add: Let_def)
  4076     with bn bound0at_l have ?case by blast}
  4077   moreover 
  4078   { fix c e assume a: "a = CN 0 c e" and "c>0" and "numbound0 e"
  4079     { assume cn1:"numgcd (CN 0 c (simpnum e)) \<noteq> 1" and cnz:"numgcd (CN 0 c (simpnum e)) \<noteq> 0"
  4080       with numgcd_pos[where t="CN 0 c (simpnum e)"]
  4081       have th1:"numgcd (CN 0 c (simpnum e)) > 0" by simp
  4082       from `c > 0` have th:"numgcd (CN 0 c (simpnum e)) \<le> c" 
  4083         by (simp add: numgcd_def)
  4084       from `c > 0` have th': "c\<noteq>0" by auto
  4085       from `c > 0` have cp: "c \<ge> 0" by simp
  4086       from zdiv_mono2[OF cp th1 th, simplified div_self[OF th']]
  4087       have "0 < c div numgcd (CN 0 c (simpnum e))" by simp
  4088     }
  4089     with Eq a have ?case
  4090       by (simp add: Let_def reducecoeff_def reducecoeffh_numbound0)}
  4091   ultimately show ?case by blast
  4092 next
  4093   case (NEq a)  
  4094   hence "bound0 (NEq a) \<or> (\<exists> c e. a = CN 0 c e \<and> c > 0 \<and> numbound0 e)"
  4095     by (cases a,simp_all, rename_tac nat a b, case_tac "nat", simp_all)
  4096   moreover
  4097   {assume "bound0 (NEq a)" hence bn:"bound0 (simpfm (NEq a))"  
  4098       using simpfm_bound0 by blast
  4099     have "isatom (simpfm (NEq a))" by (cases "simpnum a", auto simp add: Let_def)
  4100     with bn bound0at_l have ?case by blast}
  4101   moreover 
  4102   { fix c e assume a: "a = CN 0 c e" and "c>0" and "numbound0 e"
  4103     { assume cn1:"numgcd (CN 0 c (simpnum e)) \<noteq> 1" and cnz:"numgcd (CN 0 c (simpnum e)) \<noteq> 0"
  4104       with numgcd_pos[where t="CN 0 c (simpnum e)"]
  4105       have th1:"numgcd (CN 0 c (simpnum e)) > 0" by simp
  4106       from `c > 0` have th:"numgcd (CN 0 c (simpnum e)) \<le> c" 
  4107         by (simp add: numgcd_def)
  4108       from `c > 0` have th': "c\<noteq>0" by auto
  4109       from `c > 0` have cp: "c \<ge> 0" by simp
  4110       from zdiv_mono2[OF cp th1 th, simplified div_self[OF th']]
  4111       have "0 < c div numgcd (CN 0 c (simpnum e))" by simp
  4112     }
  4113     with NEq a have ?case
  4114       by (simp add: Let_def reducecoeff_def reducecoeffh_numbound0)}
  4115   ultimately show ?case by blast
  4116 next
  4117   case (Dvd i a) hence "bound0 (Dvd i a)" by auto hence bn:"bound0 (simpfm (Dvd i a))"  
  4118     using simpfm_bound0 by blast
  4119   have "isatom (simpfm (Dvd i a))" by (cases "simpnum a", auto simp add: Let_def split_def)
  4120   with bn bound0at_l show ?case by blast
  4121 next
  4122   case (NDvd i a)  hence "bound0 (NDvd i a)" by auto hence bn:"bound0 (simpfm (NDvd i a))"  
  4123     using simpfm_bound0 by blast
  4124   have "isatom (simpfm (NDvd i a))" by (cases "simpnum a", auto simp add: Let_def split_def)
  4125   with bn bound0at_l show ?case by blast
  4126 qed(auto simp add: conj_def imp_def disj_def iff_def Let_def)
  4127 
  4128 lemma rlfm_I:
  4129   assumes qfp: "qfree p"
  4130   and xp: "0 \<le> x" and x1: "x < 1"
  4131   shows "(Ifm (x#bs) (rlfm p) = Ifm (x# bs) p) \<and> isrlfm (rlfm p)"
  4132   using qfp 
  4133 by (induct p rule: rlfm.induct) 
  4134 (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
  4135                rsplit[OF xp x1 ge_mono] ge_l rsplit[OF xp x1 eq_mono] eq_l rsplit[OF xp x1 neq_mono] neq_l
  4136                rsplit[OF xp x1 DVD_mono[OF xp x1]] DVD_l rsplit[OF xp x1 NDVD_mono[OF xp x1]] NDVD_l simpfm_rl)
  4137 lemma rlfm_l:
  4138   assumes qfp: "qfree p"
  4139   shows "isrlfm (rlfm p)"
  4140   using qfp lt_l gt_l ge_l le_l eq_l neq_l DVD_l NDVD_l 
  4141 by (induct p rule: rlfm.induct) (auto simp add: simpfm_rl)
  4142 
  4143     (* Operations needed for Ferrante and Rackoff *)
  4144 lemma rminusinf_inf:
  4145   assumes lp: "isrlfm p"
  4146   shows "\<exists> z. \<forall> x < z. Ifm (x#bs) (minusinf p) = Ifm (x#bs) p" (is "\<exists> z. \<forall> x. ?P z x p")
  4147 using lp
  4148 proof (induct p rule: minusinf.induct)
  4149   case (1 p q) thus ?case by (auto,rule_tac x= "min z za" in exI) auto
  4150 next
  4151   case (2 p q) thus ?case by (auto,rule_tac x= "min z za" in exI) auto
  4152 next
  4153   case (3 c e) 
  4154   from 3 have nb: "numbound0 e" by simp
  4155   from 3 have cp: "real c > 0" by simp
  4156   fix a
  4157   let ?e="Inum (a#bs) e"
  4158   let ?z = "(- ?e) / real c"
  4159   {fix x
  4160     assume xz: "x < ?z"
  4161     hence "(real c * x < - ?e)" 
  4162       by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="- ?e"] ac_simps) 
  4163     hence "real c * x + ?e < 0" by arith
  4164     hence "real c * x + ?e \<noteq> 0" by simp
  4165     with xz have "?P ?z x (Eq (CN 0 c e))"
  4166       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp  }
  4167   hence "\<forall> x < ?z. ?P ?z x (Eq (CN 0 c e))" by simp
  4168   thus ?case by blast
  4169 next
  4170   case (4 c e)   
  4171   from 4 have nb: "numbound0 e" by simp
  4172   from 4 have cp: "real c > 0" by simp
  4173   fix a
  4174   let ?e="Inum (a#bs) e"
  4175   let ?z = "(- ?e) / real c"
  4176   {fix x
  4177     assume xz: "x < ?z"
  4178     hence "(real c * x < - ?e)" 
  4179       by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="- ?e"] ac_simps) 
  4180     hence "real c * x + ?e < 0" by arith
  4181     hence "real c * x + ?e \<noteq> 0" by simp
  4182     with xz have "?P ?z x (NEq (CN 0 c e))"
  4183       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
  4184   hence "\<forall> x < ?z. ?P ?z x (NEq (CN 0 c e))" by simp
  4185   thus ?case by blast
  4186 next
  4187   case (5 c e) 
  4188   from 5 have nb: "numbound0 e" by simp
  4189   from 5 have cp: "real c > 0" by simp
  4190   fix a
  4191   let ?e="Inum (a#bs) e"
  4192   let ?z = "(- ?e) / real c"
  4193   {fix x
  4194     assume xz: "x < ?z"
  4195     hence "(real c * x < - ?e)" 
  4196       by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="- ?e"] ac_simps) 
  4197     hence "real c * x + ?e < 0" by arith
  4198     with xz have "?P ?z x (Lt (CN 0 c e))"
  4199       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"]  by simp }
  4200   hence "\<forall> x < ?z. ?P ?z x (Lt (CN 0 c e))" by simp
  4201   thus ?case by blast
  4202 next
  4203   case (6 c e)  
  4204   from 6 have nb: "numbound0 e" by simp
  4205   from 6 have cp: "real c > 0" by simp
  4206   fix a
  4207   let ?e="Inum (a#bs) e"
  4208   let ?z = "(- ?e) / real c"
  4209   {fix x
  4210     assume xz: "x < ?z"
  4211     hence "(real c * x < - ?e)" 
  4212       by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="- ?e"] ac_simps) 
  4213     hence "real c * x + ?e < 0" by arith
  4214     with xz have "?P ?z x (Le (CN 0 c e))"
  4215       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
  4216   hence "\<forall> x < ?z. ?P ?z x (Le (CN 0 c e))" by simp
  4217   thus ?case by blast
  4218 next
  4219   case (7 c e)  
  4220   from 7 have nb: "numbound0 e" by simp
  4221   from 7 have cp: "real c > 0" by simp
  4222   fix a
  4223   let ?e="Inum (a#bs) e"
  4224   let ?z = "(- ?e) / real c"
  4225   {fix x
  4226     assume xz: "x < ?z"
  4227     hence "(real c * x < - ?e)" 
  4228       by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="- ?e"] ac_simps) 
  4229     hence "real c * x + ?e < 0" by arith
  4230     with xz have "?P ?z x (Gt (CN 0 c e))"
  4231       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
  4232   hence "\<forall> x < ?z. ?P ?z x (Gt (CN 0 c e))" by simp
  4233   thus ?case by blast
  4234 next
  4235   case (8 c e)  
  4236   from 8 have nb: "numbound0 e" by simp
  4237   from 8 have cp: "real c > 0" by simp
  4238   fix a
  4239   let ?e="Inum (a#bs) e"
  4240   let ?z = "(- ?e) / real c"
  4241   {fix x
  4242     assume xz: "x < ?z"
  4243     hence "(real c * x < - ?e)" 
  4244       by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="- ?e"] ac_simps) 
  4245     hence "real c * x + ?e < 0" by arith
  4246     with xz have "?P ?z x (Ge (CN 0 c e))"
  4247       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
  4248   hence "\<forall> x < ?z. ?P ?z x (Ge (CN 0 c e))" by simp
  4249   thus ?case by blast
  4250 qed simp_all
  4251 
  4252 lemma rplusinf_inf:
  4253   assumes lp: "isrlfm p"
  4254   shows "\<exists> z. \<forall> x > z. Ifm (x#bs) (plusinf p) = Ifm (x#bs) p" (is "\<exists> z. \<forall> x. ?P z x p")
  4255 using lp
  4256 proof (induct p rule: isrlfm.induct)
  4257   case (1 p q) thus ?case by (auto,rule_tac x= "max z za" in exI) auto
  4258 next
  4259   case (2 p q) thus ?case by (auto,rule_tac x= "max z za" in exI) auto
  4260 next
  4261   case (3 c e) 
  4262   from 3 have nb: "numbound0 e" by simp
  4263   from 3 have cp: "real c > 0" by simp
  4264   fix a
  4265   let ?e="Inum (a#bs) e"
  4266   let ?z = "(- ?e) / real c"
  4267   {fix x
  4268     assume xz: "x > ?z"
  4269     with mult_strict_right_mono [OF xz cp] cp
  4270     have "(real c * x > - ?e)" by (simp add: ac_simps)
  4271     hence "real c * x + ?e > 0" by arith
  4272     hence "real c * x + ?e \<noteq> 0" by simp
  4273     with xz have "?P ?z x (Eq (CN 0 c e))"
  4274       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
  4275   hence "\<forall> x > ?z. ?P ?z x (Eq (CN 0 c e))" by simp
  4276   thus ?case by blast
  4277 next
  4278   case (4 c e) 
  4279   from 4 have nb: "numbound0 e" by simp
  4280   from 4 have cp: "real c > 0" by simp
  4281   fix a
  4282   let ?e="Inum (a#bs) e"
  4283   let ?z = "(- ?e) / real c"
  4284   {fix x
  4285     assume xz: "x > ?z"
  4286     with mult_strict_right_mono [OF xz cp] cp
  4287     have "(real c * x > - ?e)" by (simp add: ac_simps)
  4288     hence "real c * x + ?e > 0" by arith
  4289     hence "real c * x + ?e \<noteq> 0" by simp
  4290     with xz have "?P ?z x (NEq (CN 0 c e))"
  4291       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
  4292   hence "\<forall> x > ?z. ?P ?z x (NEq (CN 0 c e))" by simp
  4293   thus ?case by blast
  4294 next
  4295   case (5 c e) 
  4296   from 5 have nb: "numbound0 e" by simp
  4297   from 5 have cp: "real c > 0" by simp
  4298   fix a
  4299   let ?e="Inum (a#bs) e"
  4300   let ?z = "(- ?e) / real c"
  4301   {fix x
  4302     assume xz: "x > ?z"
  4303     with mult_strict_right_mono [OF xz cp] cp
  4304     have "(real c * x > - ?e)" by (simp add: ac_simps)
  4305     hence "real c * x + ?e > 0" by arith
  4306     with xz have "?P ?z x (Lt (CN 0 c e))"
  4307       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
  4308   hence "\<forall> x > ?z. ?P ?z x (Lt (CN 0 c e))" by simp
  4309   thus ?case by blast
  4310 next
  4311   case (6 c e) 
  4312   from 6 have nb: "numbound0 e" by simp
  4313   from 6 have cp: "real c > 0" by simp
  4314   fix a
  4315   let ?e="Inum (a#bs) e"
  4316   let ?z = "(- ?e) / real c"
  4317   {fix x
  4318     assume xz: "x > ?z"
  4319     with mult_strict_right_mono [OF xz cp] cp
  4320     have "(real c * x > - ?e)" by (simp add: ac_simps)
  4321     hence "real c * x + ?e > 0" by arith
  4322     with xz have "?P ?z x (Le (CN 0 c e))"
  4323       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
  4324   hence "\<forall> x > ?z. ?P ?z x (Le (CN 0 c e))" by simp
  4325   thus ?case by blast
  4326 next
  4327   case (7 c e) 
  4328   from 7 have nb: "numbound0 e" by simp
  4329   from 7 have cp: "real c > 0" by simp
  4330   fix a
  4331   let ?e="Inum (a#bs) e"
  4332   let ?z = "(- ?e) / real c"
  4333   {fix x
  4334     assume xz: "x > ?z"
  4335     with mult_strict_right_mono [OF xz cp] cp
  4336     have "(real c * x > - ?e)" by (simp add: ac_simps)
  4337     hence "real c * x + ?e > 0" by arith
  4338     with xz have "?P ?z x (Gt (CN 0 c e))"
  4339       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"] by simp }
  4340   hence "\<forall> x > ?z. ?P ?z x (Gt (CN 0 c e))" by simp
  4341   thus ?case by blast
  4342 next
  4343   case (8 c e) 
  4344   from 8 have nb: "numbound0 e" by simp
  4345   from 8 have cp: "real c > 0" by simp
  4346   fix a
  4347   let ?e="Inum (a#bs) e"
  4348   let ?z = "(- ?e) / real c"
  4349   {fix x
  4350     assume xz: "x > ?z"
  4351     with mult_strict_right_mono [OF xz cp] cp
  4352     have "(real c * x > - ?e)" by (simp add: ac_simps)
  4353     hence "real c * x + ?e > 0" by arith
  4354     with xz have "?P ?z x (Ge (CN 0 c e))"
  4355       using numbound0_I[OF nb, where b="x" and bs="bs" and b'="a"]   by simp }
  4356   hence "\<forall> x > ?z. ?P ?z x (Ge (CN 0 c e))" by simp
  4357   thus ?case by blast
  4358 qed simp_all
  4359 
  4360 lemma rminusinf_bound0:
  4361   assumes lp: "isrlfm p"
  4362   shows "bound0 (minusinf p)"
  4363   using lp
  4364   by (induct p rule: minusinf.induct) simp_all
  4365 
  4366 lemma rplusinf_bound0:
  4367   assumes lp: "isrlfm p"
  4368   shows "bound0 (plusinf p)"
  4369   using lp
  4370   by (induct p rule: plusinf.induct) simp_all
  4371 
  4372 lemma rminusinf_ex:
  4373   assumes lp: "isrlfm p"
  4374   and ex: "Ifm (a#bs) (minusinf p)"
  4375   shows "\<exists> x. Ifm (x#bs) p"
  4376 proof-
  4377   from bound0_I [OF rminusinf_bound0[OF lp], where b="a" and bs ="bs"] ex
  4378   have th: "\<forall> x. Ifm (x#bs) (minusinf p)" by auto
  4379   from rminusinf_inf[OF lp, where bs="bs"] 
  4380   obtain z where z_def: "\<forall>x<z. Ifm (x # bs) (minusinf p) = Ifm (x # bs) p" by blast
  4381   from th have "Ifm ((z - 1)#bs) (minusinf p)" by simp
  4382   moreover have "z - 1 < z" by simp
  4383   ultimately show ?thesis using z_def by auto
  4384 qed
  4385 
  4386 lemma rplusinf_ex:
  4387   assumes lp: "isrlfm p"
  4388   and ex: "Ifm (a#bs) (plusinf p)"
  4389   shows "\<exists> x. Ifm (x#bs) p"
  4390 proof-
  4391   from bound0_I [OF rplusinf_bound0[OF lp], where b="a" and bs ="bs"] ex
  4392   have th: "\<forall> x. Ifm (x#bs) (plusinf p)" by auto
  4393   from rplusinf_inf[OF lp, where bs="bs"] 
  4394   obtain z where z_def: "\<forall>x>z. Ifm (x # bs) (plusinf p) = Ifm (x # bs) p" by blast
  4395   from th have "Ifm ((z + 1)#bs) (plusinf p)" by simp
  4396   moreover have "z + 1 > z" by simp
  4397   ultimately show ?thesis using z_def by auto
  4398 qed
  4399 
  4400 consts 
  4401   \<Upsilon>:: "fm \<Rightarrow> (num \<times> int) list"
  4402   \<upsilon> :: "fm \<Rightarrow> (num \<times> int) \<Rightarrow> fm "
  4403 recdef \<Upsilon> "measure size"
  4404   "\<Upsilon> (And p q) = (\<Upsilon> p @ \<Upsilon> q)" 
  4405   "\<Upsilon> (Or p q) = (\<Upsilon> p @ \<Upsilon> q)" 
  4406   "\<Upsilon> (Eq  (CN 0 c e)) = [(Neg e,c)]"
  4407   "\<Upsilon> (NEq (CN 0 c e)) = [(Neg e,c)]"
  4408   "\<Upsilon> (Lt  (CN 0 c e)) = [(Neg e,c)]"
  4409   "\<Upsilon> (Le  (CN 0 c e)) = [(Neg e,c)]"
  4410   "\<Upsilon> (Gt  (CN 0 c e)) = [(Neg e,c)]"
  4411   "\<Upsilon> (Ge  (CN 0 c e)) = [(Neg e,c)]"
  4412   "\<Upsilon> p = []"
  4413 
  4414 recdef \<upsilon> "measure size"
  4415   "\<upsilon> (And p q) = (\<lambda> (t,n). And (\<upsilon> p (t,n)) (\<upsilon> q (t,n)))"
  4416   "\<upsilon> (Or p q) = (\<lambda> (t,n). Or (\<upsilon> p (t,n)) (\<upsilon> q (t,n)))"
  4417   "\<upsilon> (Eq (CN 0 c e)) = (\<lambda> (t,n). Eq (Add (Mul c t) (Mul n e)))"
  4418   "\<upsilon> (NEq (CN 0 c e)) = (\<lambda> (t,n). NEq (Add (Mul c t) (Mul n e)))"
  4419   "\<upsilon> (Lt (CN 0 c e)) = (\<lambda> (t,n). Lt (Add (Mul c t) (Mul n e)))"
  4420   "\<upsilon> (Le (CN 0 c e)) = (\<lambda> (t,n). Le (Add (Mul c t) (Mul n e)))"
  4421   "\<upsilon> (Gt (CN 0 c e)) = (\<lambda> (t,n). Gt (Add (Mul c t) (Mul n e)))"
  4422   "\<upsilon> (Ge (CN 0 c e)) = (\<lambda> (t,n). Ge (Add (Mul c t) (Mul n e)))"
  4423   "\<upsilon> p = (\<lambda> (t,n). p)"
  4424 
  4425 lemma \<upsilon>_I: assumes lp: "isrlfm p"
  4426   and np: "real n > 0" and nbt: "numbound0 t"
  4427   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> _")
  4428   using lp
  4429 proof(induct p rule: \<upsilon>.induct)
  4430   case (5 c e)
  4431   from 5 have cp: "c >0" and nb: "numbound0 e" by simp_all
  4432   have "?I ?u (Lt (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: pos_less_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 (6 c e)
  4442   from 6 have cp: "c >0" and nb: "numbound0 e" by simp_all
  4443   have "?I ?u (Le (CN 0 c e)) = (real c *(?t/?n) + (?N x e) \<le> 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) \<le> 0)"
  4446     by (simp only: pos_le_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) \<le> 0)"
  4449     using np by simp 
  4450   finally show ?case using nbt nb by (simp add: algebra_simps)
  4451 next
  4452   case (7 c e)
  4453   from 7 have cp: "c >0" and nb: "numbound0 e" by simp_all
  4454   have "?I ?u (Gt (CN 0 c e)) = (real c *(?t/?n) + (?N x e) > 0)"
  4455     using numbound0_I[OF nb, where bs="bs" and b="?u" and b'="x"] by simp
  4456   also have "\<dots> = (?n*(real c *(?t/?n)) + ?n*(?N x e) > 0)"
  4457     by (simp only: pos_divide_less_eq[OF np, where a="real c *(?t/?n) + (?N x e)" 
  4458       and b="0", simplified divide_zero_left]) (simp only: algebra_simps)
  4459   also have "\<dots> = (real c *?t + ?n* (?N x e) > 0)"
  4460     using np by simp 
  4461   finally show ?case using nbt nb by (simp add: algebra_simps)
  4462 next
  4463   case (8 c e)
  4464   from 8 have cp: "c >0" and nb: "numbound0 e" by simp_all
  4465   have "?I ?u (Ge (CN 0 c e)) = (real c *(?t/?n) + (?N x e) \<ge> 0)"
  4466     using numbound0_I[OF nb, where bs="bs" and b="?u" and b'="x"] by simp
  4467   also have "\<dots> = (?n*(real c *(?t/?n)) + ?n*(?N x e) \<ge> 0)"
  4468     by (simp only: pos_divide_le_eq[OF np, where a="real c *(?t/?n) + (?N x e)" 
  4469       and b="0", simplified divide_zero_left]) (simp only: algebra_simps)
  4470   also have "\<dots> = (real c *?t + ?n* (?N x e) \<ge> 0)"
  4471     using np by simp 
  4472   finally show ?case using nbt nb by (simp add: algebra_simps)
  4473 next
  4474   case (3 c e)
  4475   from 3 have cp: "c >0" and nb: "numbound0 e" by simp_all
  4476   from np have np: "real n \<noteq> 0" by simp
  4477   have "?I ?u (Eq (CN 0 c e)) = (real c *(?t/?n) + (?N x e) = 0)"
  4478     using numbound0_I[OF nb, where bs="bs" and b="?u" and b'="x"] by simp
  4479   also have "\<dots> = (?n*(real c *(?t/?n)) + ?n*(?N x e) = 0)"
  4480     by (simp only: nonzero_eq_divide_eq[OF np, where a="real c *(?t/?n) + (?N x e)" 
  4481       and b="0", simplified divide_zero_left]) (simp only: algebra_simps)
  4482   also have "\<dots> = (real c *?t + ?n* (?N x e) = 0)"
  4483     using np by simp 
  4484   finally show ?case using nbt nb by (simp add: algebra_simps)
  4485 next
  4486   case (4 c e)
  4487   from 4 have cp: "c >0" and nb: "numbound0 e" by simp_all
  4488   from np have np: "real n \<noteq> 0" by simp
  4489   have "?I ?u (NEq (CN 0 c e)) = (real c *(?t/?n) + (?N x e) \<noteq> 0)"
  4490     using numbound0_I[OF nb, where bs="bs" and b="?u" and b'="x"] by simp
  4491   also have "\<dots> = (?n*(real c *(?t/?n)) + ?n*(?N x e) \<noteq> 0)"
  4492     by (simp only: nonzero_eq_divide_eq[OF np, where a="real c *(?t/?n) + (?N x e)" 
  4493       and b="0", simplified divide_zero_left]) (simp only: algebra_simps)
  4494   also have "\<dots> = (real c *?t + ?n* (?N x e) \<noteq> 0)"
  4495     using np by simp 
  4496   finally show ?case using nbt nb by (simp add: algebra_simps)
  4497 qed(simp_all add: nbt numbound0_I[where bs ="bs" and b="(Inum (x#bs) t)/ real n" and b'="x"])
  4498 
  4499 lemma \<Upsilon>_l:
  4500   assumes lp: "isrlfm p"
  4501   shows "\<forall> (t,k) \<in> set (\<Upsilon> p). numbound0 t \<and> k >0"
  4502 using lp
  4503 by(induct p rule: \<Upsilon>.induct)  auto
  4504 
  4505 lemma rminusinf_\<Upsilon>:
  4506   assumes lp: "isrlfm p"
  4507   and nmi: "\<not> (Ifm (a#bs) (minusinf p))" (is "\<not> (Ifm (a#bs) (?M p))")
  4508   and ex: "Ifm (x#bs) p" (is "?I x p")
  4509   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")
  4510 proof-
  4511   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")
  4512     using lp nmi ex
  4513     by (induct p rule: minusinf.induct, auto simp add:numbound0_I[where bs="bs" and b="a" and b'="x"])
  4514   then obtain s m where smU: "(s,m) \<in> set (\<Upsilon> p)" and mx: "real m * x \<ge> ?N a s" by blast
  4515   from \<Upsilon>_l[OF lp] smU have mp: "real m > 0" by auto
  4516   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" 
  4517     by (auto simp add: mult.commute)
  4518   thus ?thesis using smU by auto
  4519 qed
  4520 
  4521 lemma rplusinf_\<Upsilon>:
  4522   assumes lp: "isrlfm p"
  4523   and nmi: "\<not> (Ifm (a#bs) (plusinf p))" (is "\<not> (Ifm (a#bs) (?M p))")
  4524   and ex: "Ifm (x#bs) p" (is "?I x p")
  4525   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")
  4526 proof-
  4527   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")
  4528     using lp nmi ex
  4529     by (induct p rule: minusinf.induct, auto simp add:numbound0_I[where bs="bs" and b="a" and b'="x"])
  4530   then obtain s m where smU: "(s,m) \<in> set (\<Upsilon> p)" and mx: "real m * x \<le> ?N a s" by blast
  4531   from \<Upsilon>_l[OF lp] smU have mp: "real m > 0" by auto
  4532   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" 
  4533     by (auto simp add: mult.commute)
  4534   thus ?thesis using smU by auto
  4535 qed
  4536 
  4537 lemma lin_dense: 
  4538   assumes lp: "isrlfm p"
  4539   and noS: "\<forall> t. l < t \<and> t< u \<longrightarrow> t \<notin> (\<lambda> (t,n). Inum (x#bs) t / real n) ` set (\<Upsilon> p)" 
  4540   (is "\<forall> t. _ \<and> _ \<longrightarrow> t \<notin> (\<lambda> (t,n). ?N x t / real n ) ` (?U p)")
  4541   and lx: "l < x" and xu:"x < u" and px:" Ifm (x#bs) p"
  4542   and ly: "l < y" and yu: "y < u"
  4543   shows "Ifm (y#bs) p"
  4544 using lp px noS
  4545 proof (induct p rule: isrlfm.induct)
  4546   case (5 c e) hence cp: "real c > 0" and nb: "numbound0 e" by simp_all
  4547   from 5 have "x * real c + ?N x e < 0" by (simp add: algebra_simps)
  4548   hence pxc: "x < (- ?N x e) / real c" 
  4549     by (simp only: pos_less_divide_eq[OF cp, where a="x" and b="-?N x e"])
  4550   from 5 have noSc:"\<forall> t. l < t \<and> t < u \<longrightarrow> t \<noteq> (- ?N x e) / real c" by auto
  4551   with ly yu have yne: "y \<noteq> - ?N x e / real c" by auto
  4552   hence "y < (- ?N x e) / real c \<or> y > (-?N x e) / real c" by auto
  4553   moreover {assume y: "y < (-?N x e)/ real c"
  4554     hence "y * real c < - ?N x e"
  4555       by (simp add: pos_less_divide_eq[OF cp, where a="y" and b="-?N x e", symmetric])
  4556     hence "real c * y + ?N x e < 0" by (simp add: algebra_simps)
  4557     hence ?case using numbound0_I[OF nb, where bs="bs" and b="x" and b'="y"] by simp}
  4558   moreover {assume y: "y > (- ?N x e) / real c" 
  4559     with yu have eu: "u > (- ?N x e) / real c" by auto
  4560     with noSc ly yu have "(- ?N x e) / real c \<le> l" by (cases "(- ?N x e) / real c > l", auto)
  4561     with lx pxc have "False" by auto
  4562     hence ?case by simp }
  4563   ultimately show ?case by blast
  4564 next
  4565   case (6 c e) hence cp: "real c > 0" and nb: "numbound0 e" by simp_all
  4566   from 6 have "x * real c + ?N x e \<le> 0" by (simp add: algebra_simps)
  4567   hence pxc: "x \<le> (- ?N x e) / real c" 
  4568     by (simp only: pos_le_divide_eq[OF cp, where a="x" and b="-?N x e"])
  4569   from 6 have noSc:"\<forall> t. l < t \<and> t < u \<longrightarrow> t \<noteq> (- ?N x e) / real c" by auto
  4570   with ly yu have yne: "y \<noteq> - ?N x e / real c" by auto
  4571   hence "y < (- ?N x e) / real c \<or> y > (-?N x e) / real c" by auto
  4572   moreover {assume y: "y < (-?N x e)/ real c"
  4573     hence "y * real c < - ?N x e"
  4574       by (simp add: pos_less_divide_eq[OF cp, where a="y" and b="-?N x e", symmetric])
  4575     hence "real c * y + ?N x e < 0" by (simp add: algebra_simps)
  4576     hence ?case using numbound0_I[OF nb, where bs="bs" and b="x" and b'="y"] by simp}
  4577   moreover {assume y: "y > (- ?N x e) / real c" 
  4578     with yu have eu: "u > (- ?N x e) / real c" by auto
  4579     with noSc ly yu have "(- ?N x e) / real c \<le> l" by (cases "(- ?N x e) / real c > l", auto)
  4580     with lx pxc have "False" by auto
  4581     hence ?case by simp }
  4582   ultimately show ?case by blast
  4583 next
  4584   case (7 c e) hence cp: "real c > 0" and nb: "numbound0 e" by simp_all
  4585   from 7 have "x * real c + ?N x e > 0" by (simp add: algebra_simps)
  4586   hence pxc: "x > (- ?N x e) / real c" 
  4587     by (simp only: pos_divide_less_eq[OF cp, where a="x" and b="-?N x e"])
  4588   from 7 have noSc:"\<forall> t. l < t \<and> t < u \<longrightarrow> t \<noteq> (- ?N x e) / real c" by auto
  4589   with ly yu have yne: "y \<noteq> - ?N x e / real c" by auto
  4590   hence "y < (- ?N x e) / real c \<or> y > (-?N x e) / real c" by auto
  4591   moreover {assume y: "y > (-?N x e)/ real c"
  4592     hence "y * real c > - ?N x e"
  4593       by (simp add: pos_divide_less_eq[OF cp, where a="y" and b="-?N x e", symmetric])
  4594     hence "real c * y + ?N x e > 0" by (simp add: algebra_simps)
  4595     hence ?case using numbound0_I[OF nb, where bs="bs" and b="x" and b'="y"] by simp}
  4596   moreover {assume y: "y < (- ?N x e) / real c" 
  4597     with ly have eu: "l < (- ?N x e) / real c" by auto
  4598     with noSc ly yu have "(- ?N x e) / real c \<ge> u" by (cases "(- ?N x e) / real c > l", auto)
  4599     with xu pxc have "False" by auto
  4600     hence ?case by simp }
  4601   ultimately show ?case by blast
  4602 next
  4603   case (8 c e) hence cp: "real c > 0" and nb: "numbound0 e" by simp_all
  4604   from 8 have "x * real c + ?N x e \<ge> 0" by (simp add: algebra_simps)
  4605   hence pxc: "x \<ge> (- ?N x e) / real c" 
  4606     by (simp only: pos_divide_le_eq[OF cp, where a="x" and b="-?N x e"])
  4607   from 8 have noSc:"\<forall> t. l < t \<and> t < u \<longrightarrow> t \<noteq> (- ?N x e) / real c" by auto
  4608   with ly yu have yne: "y \<noteq> - ?N x e / real c" by auto
  4609   hence "y < (- ?N x e) / real c \<or> y > (-?N x e) / real c" by auto
  4610   moreover {assume y: "y > (-?N x e)/ real c"
  4611     hence "y * real c > - ?N x e"
  4612       by (simp add: pos_divide_less_eq[OF cp, where a="y" and b="-?N x e", symmetric])
  4613     hence "real c * y + ?N x e > 0" by (simp add: algebra_simps)
  4614     hence ?case using numbound0_I[OF nb, where bs="bs" and b="x" and b'="y"] by simp}
  4615   moreover {assume y: "y < (- ?N x e) / real c" 
  4616     with ly have eu: "l < (- ?N x e) / real c" by auto
  4617     with noSc ly yu have "(- ?N x e) / real c \<ge> u" by (cases "(- ?N x e) / real c > l", auto)
  4618     with xu pxc have "False" by auto
  4619     hence ?case by simp }
  4620   ultimately show ?case by blast
  4621 next
  4622   case (3 c e) hence cp: "real c > 0" and nb: "numbound0 e" by simp_all
  4623   from cp have cnz: "real c \<noteq> 0" by simp
  4624   from 3 have "x * real c + ?N x e = 0" by (simp add: algebra_simps)
  4625   hence pxc: "x = (- ?N x e) / real c" 
  4626     by (simp only: nonzero_eq_divide_eq[OF cnz, where a="x" and b="-?N x e"])
  4627   from 3 have noSc:"\<forall> t. l < t \<and> t < u \<longrightarrow> t \<noteq> (- ?N x e) / real c" by auto
  4628   with lx xu have yne: "x \<noteq> - ?N x e / real c" by auto
  4629   with pxc show ?case by simp
  4630 next
  4631   case (4 c e) hence cp: "real c > 0" and nb: "numbound0 e" by simp_all
  4632   from cp have cnz: "real c \<noteq> 0" by simp
  4633   from 4 have noSc:"\<forall> t. l < t \<and> t < u \<longrightarrow> t \<noteq> (- ?N x e) / real c" by auto
  4634   with ly yu have yne: "y \<noteq> - ?N x e / real c" by auto
  4635   hence "y* real c \<noteq> -?N x e"      
  4636     by (simp only: nonzero_eq_divide_eq[OF cnz, where a="y" and b="-?N x e"]) simp
  4637   hence "y* real c + ?N x e \<noteq> 0" by (simp add: algebra_simps)
  4638   thus ?case using numbound0_I[OF nb, where bs="bs" and b="x" and b'="y"] 
  4639     by (simp add: algebra_simps)
  4640 qed (auto simp add: numbound0_I[where bs="bs" and b="y" and b'="x"])
  4641 
  4642 lemma rinf_\<Upsilon>:
  4643   assumes lp: "isrlfm p"
  4644   and nmi: "\<not> (Ifm (x#bs) (minusinf p))" (is "\<not> (Ifm (x#bs) (?M p))")
  4645   and npi: "\<not> (Ifm (x#bs) (plusinf p))" (is "\<not> (Ifm (x#bs) (?P p))")
  4646   and ex: "\<exists> x.  Ifm (x#bs) p" (is "\<exists> x. ?I x p")
  4647   shows "\<exists> (l,n) \<in> set (\<Upsilon> p). \<exists> (s,m) \<in> set (\<Upsilon> p).
  4648     ?I ((Inum (x#bs) l / real n + Inum (x#bs) s / real m) / 2) p" 
  4649 proof-
  4650   let ?N = "\<lambda> x t. Inum (x#bs) t"
  4651   let ?U = "set (\<Upsilon> p)"
  4652   from ex obtain a where pa: "?I a p" by blast
  4653   from bound0_I[OF rminusinf_bound0[OF lp], where bs="bs" and b="x" and b'="a"] nmi
  4654   have nmi': "\<not> (?I a (?M p))" by simp
  4655   from bound0_I[OF rplusinf_bound0[OF lp], where bs="bs" and b="x" and b'="a"] npi
  4656   have npi': "\<not> (?I a (?P p))" by simp
  4657   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"
  4658   proof-
  4659     let ?M = "(\<lambda> (t,c). ?N a t / real c) ` ?U"
  4660     have fM: "finite ?M" by auto
  4661     from rminusinf_\<Upsilon>[OF lp nmi pa] rplusinf_\<Upsilon>[OF lp npi pa] 
  4662     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
  4663     then obtain "t" "n" "s" "m" where 
  4664       tnU: "(t,n) \<in> ?U" and smU: "(s,m) \<in> ?U" 
  4665       and xs1: "a \<le> ?N x s / real m" and tx1: "a \<ge> ?N x t / real n" by blast
  4666     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
  4667     from tnU have Mne: "?M \<noteq> {}" by auto
  4668     hence Une: "?U \<noteq> {}" by simp
  4669     let ?l = "Min ?M"
  4670     let ?u = "Max ?M"
  4671     have linM: "?l \<in> ?M" using fM Mne by simp
  4672     have uinM: "?u \<in> ?M" using fM Mne by simp
  4673     have tnM: "?N a t / real n \<in> ?M" using tnU by auto
  4674     have smM: "?N a s / real m \<in> ?M" using smU by auto 
  4675     have lM: "\<forall> t\<in> ?M. ?l \<le> t" using Mne fM by auto
  4676     have Mu: "\<forall> t\<in> ?M. t \<le> ?u" using Mne fM by auto
  4677     have "?l \<le> ?N a t / real n" using tnM Mne by simp hence lx: "?l \<le> a" using tx by simp
  4678     have "?N a s / real m \<le> ?u" using smM Mne by simp hence xu: "a \<le> ?u" using xs by simp
  4679     from finite_set_intervals2[where P="\<lambda> x. ?I x p",OF pa lx xu linM uinM fM lM Mu]
  4680     have "(\<exists> s\<in> ?M. ?I s p) \<or> 
  4681       (\<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)" .
  4682     moreover { fix u assume um: "u\<in> ?M" and pu: "?I u p"
  4683       hence "\<exists> (tu,nu) \<in> ?U. u = ?N a tu / real nu" by auto
  4684       then obtain "tu" "nu" where tuU: "(tu,nu) \<in> ?U" and tuu:"u= ?N a tu / real nu" by blast
  4685       have "(u + u) / 2 = u" by auto with pu tuu 
  4686       have "?I (((?N a tu / real nu) + (?N a tu / real nu)) / 2) p" by simp
  4687       with tuU have ?thesis by blast}
  4688     moreover{
  4689       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"
  4690       then obtain t1 and t2 where t1M: "t1 \<in> ?M" and t2M: "t2\<in> ?M" 
  4691         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"
  4692         by blast
  4693       from t1M have "\<exists> (t1u,t1n) \<in> ?U. t1 = ?N a t1u / real t1n" by auto
  4694       then obtain "t1u" "t1n" where t1uU: "(t1u,t1n) \<in> ?U" and t1u: "t1 = ?N a t1u / real t1n" by blast
  4695       from t2M have "\<exists> (t2u,t2n) \<in> ?U. t2 = ?N a t2u / real t2n" by auto
  4696       then obtain "t2u" "t2n" where t2uU: "(t2u,t2n) \<in> ?U" and t2u: "t2 = ?N a t2u / real t2n" by blast
  4697       from t1x xt2 have t1t2: "t1 < t2" by simp
  4698       let ?u = "(t1 + t2) / 2"
  4699       from less_half_sum[OF t1t2] gt_half_sum[OF t1t2] have t1lu: "t1 < ?u" and ut2: "?u < t2" by auto
  4700       from lin_dense[OF lp noM t1x xt2 px t1lu ut2] have "?I ?u p" .
  4701       with t1uU t2uU t1u t2u have ?thesis by blast}
  4702     ultimately show ?thesis by blast
  4703   qed
  4704   then obtain "l" "n" "s"  "m" where lnU: "(l,n) \<in> ?U" and smU:"(s,m) \<in> ?U" 
  4705     and pu: "?I ((?N a l / real n + ?N a s / real m) / 2) p" by blast
  4706   from lnU smU \<Upsilon>_l[OF lp] have nbl: "numbound0 l" and nbs: "numbound0 s" by auto
  4707   from numbound0_I[OF nbl, where bs="bs" and b="a" and b'="x"] 
  4708     numbound0_I[OF nbs, where bs="bs" and b="a" and b'="x"] pu
  4709   have "?I ((?N x l / real n + ?N x s / real m) / 2) p" by simp
  4710   with lnU smU
  4711   show ?thesis by auto
  4712 qed
  4713     (* The Ferrante - Rackoff Theorem *)
  4714 
  4715 theorem fr_eq: 
  4716   assumes lp: "isrlfm p"
  4717   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))"
  4718   (is "(\<exists> x. ?I x p) = (?M \<or> ?P \<or> ?F)" is "?E = ?D")
  4719 proof
  4720   assume px: "\<exists> x. ?I x p"
  4721   have "?M \<or> ?P \<or> (\<not> ?M \<and> \<not> ?P)" by blast
  4722   moreover {assume "?M \<or> ?P" hence "?D" by blast}
  4723   moreover {assume nmi: "\<not> ?M" and npi: "\<not> ?P"
  4724     from rinf_\<Upsilon>[OF lp nmi npi] have "?F" using px by blast hence "?D" by blast}
  4725   ultimately show "?D" by blast
  4726 next
  4727   assume "?D" 
  4728   moreover {assume m:"?M" from rminusinf_ex[OF lp m] have "?E" .}
  4729   moreover {assume p: "?P" from rplusinf_ex[OF lp p] have "?E" . }
  4730   moreover {assume f:"?F" hence "?E" by blast}
  4731   ultimately show "?E" by blast
  4732 qed
  4733 
  4734 
  4735 lemma fr_eq_\<upsilon>: 
  4736   assumes lp: "isrlfm p"
  4737   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))))"
  4738   (is "(\<exists> x. ?I x p) = (?M \<or> ?P \<or> ?F)" is "?E = ?D")
  4739 proof
  4740   assume px: "\<exists> x. ?I x p"
  4741   have "?M \<or> ?P \<or> (\<not> ?M \<and> \<not> ?P)" by blast
  4742   moreover {assume "?M \<or> ?P" hence "?D" by blast}
  4743   moreover {assume nmi: "\<not> ?M" and npi: "\<not> ?P"
  4744     let ?f ="\<lambda> (t,n). Inum (x#bs) t / real n"
  4745     let ?N = "\<lambda> t. Inum (x#bs) t"
  4746     {fix t n s m assume "(t,n)\<in> set (\<Upsilon> p)" and "(s,m) \<in> set (\<Upsilon> p)"
  4747       with \<Upsilon>_l[OF lp] have tnb: "numbound0 t" and np:"real n > 0" and snb: "numbound0 s" and mp:"real m > 0"
  4748         by auto
  4749       let ?st = "Add (Mul m t) (Mul n s)"
  4750       from np mp have mnp: "real (2*n*m) > 0" by (simp add: mult.commute)
  4751       from tnb snb have st_nb: "numbound0 ?st" by simp
  4752       have st: "(?N t / real n + ?N s / real m)/2 = ?N ?st / real (2*n*m)"
  4753         using mnp mp np by (simp add: algebra_simps add_divide_distrib)
  4754       from \<upsilon>_I[OF lp mnp st_nb, where x="x" and bs="bs"] 
  4755       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])}
  4756     with rinf_\<Upsilon>[OF lp nmi npi px] have "?F" by blast hence "?D" by blast}
  4757   ultimately show "?D" by blast
  4758 next
  4759   assume "?D" 
  4760   moreover {assume m:"?M" from rminusinf_ex[OF lp m] have "?E" .}
  4761   moreover {assume p: "?P" from rplusinf_ex[OF lp p] have "?E" . }
  4762   moreover {fix t k s l assume "(t,k) \<in> set (\<Upsilon> p)" and "(s,l) \<in> set (\<Upsilon> p)" 
  4763     and px:"?I x (\<upsilon> p (Add (Mul l t) (Mul k s), 2*k*l))"
  4764     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
  4765     let ?st = "Add (Mul l t) (Mul k s)"
  4766     from np mp have mnp: "real (2*k*l) > 0" by (simp add: mult.commute)
  4767     from tnb snb have st_nb: "numbound0 ?st" by simp
  4768     from \<upsilon>_I[OF lp mnp st_nb, where bs="bs"] px have "?E" by auto}
  4769   ultimately show "?E" by blast
  4770 qed
  4771 
  4772 text{* The overall Part *}
  4773 
  4774 lemma real_ex_int_real01:
  4775   shows "(\<exists> (x::real). P x) = (\<exists> (i::int) (u::real). 0\<le> u \<and> u< 1 \<and> P (real i + u))"
  4776 proof(auto)
  4777   fix x
  4778   assume Px: "P x"
  4779   let ?i = "floor x"
  4780   let ?u = "x - real ?i"
  4781   have "x = real ?i + ?u" by simp
  4782   hence "P (real ?i + ?u)" using Px by simp
  4783   moreover have "real ?i \<le> x" using real_of_int_floor_le by simp hence "0 \<le> ?u" by arith
  4784   moreover have "?u < 1" using real_of_int_floor_add_one_gt[where r="x"] by arith 
  4785   ultimately show "(\<exists> (i::int) (u::real). 0\<le> u \<and> u< 1 \<and> P (real i + u))" by blast
  4786 qed
  4787 
  4788 fun exsplitnum :: "num \<Rightarrow> num" where
  4789   "exsplitnum (C c) = (C c)"
  4790 | "exsplitnum (Bound 0) = Add (Bound 0) (Bound 1)"
  4791 | "exsplitnum (Bound n) = Bound (n+1)"
  4792 | "exsplitnum (Neg a) = Neg (exsplitnum a)"
  4793 | "exsplitnum (Add a b) = Add (exsplitnum a) (exsplitnum b) "
  4794 | "exsplitnum (Sub a b) = Sub (exsplitnum a) (exsplitnum b) "
  4795 | "exsplitnum (Mul c a) = Mul c (exsplitnum a)"
  4796 | "exsplitnum (Floor a) = Floor (exsplitnum a)"
  4797 | "exsplitnum (CN 0 c a) = CN 0 c (Add (Mul c (Bound 1)) (exsplitnum a))"
  4798 | "exsplitnum (CN n c a) = CN (n+1) c (exsplitnum a)"
  4799 | "exsplitnum (CF c s t) = CF c (exsplitnum s) (exsplitnum t)"
  4800 
  4801 fun exsplit :: "fm \<Rightarrow> fm" where
  4802   "exsplit (Lt a) = Lt (exsplitnum a)"
  4803 | "exsplit (Le a) = Le (exsplitnum a)"
  4804 | "exsplit (Gt a) = Gt (exsplitnum a)"
  4805 | "exsplit (Ge a) = Ge (exsplitnum a)"
  4806 | "exsplit (Eq a) = Eq (exsplitnum a)"
  4807 | "exsplit (NEq a) = NEq (exsplitnum a)"
  4808 | "exsplit (Dvd i a) = Dvd i (exsplitnum a)"
  4809 | "exsplit (NDvd i a) = NDvd i (exsplitnum a)"
  4810 | "exsplit (And p q) = And (exsplit p) (exsplit q)"
  4811 | "exsplit (Or p q) = Or (exsplit p) (exsplit q)"
  4812 | "exsplit (Imp p q) = Imp (exsplit p) (exsplit q)"
  4813 | "exsplit (Iff p q) = Iff (exsplit p) (exsplit q)"
  4814 | "exsplit (NOT p) = NOT (exsplit p)"
  4815 | "exsplit p = p"
  4816 
  4817 lemma exsplitnum: 
  4818   "Inum (x#y#bs) (exsplitnum t) = Inum ((x+y) #bs) t"
  4819   by(induct t rule: exsplitnum.induct) (simp_all add: algebra_simps)
  4820 
  4821 lemma exsplit: 
  4822   assumes qfp: "qfree p"
  4823   shows "Ifm (x#y#bs) (exsplit p) = Ifm ((x+y)#bs) p"
  4824 using qfp exsplitnum[where x="x" and y="y" and bs="bs"]
  4825 by(induct p rule: exsplit.induct) simp_all
  4826 
  4827 lemma splitex:
  4828   assumes qf: "qfree p"
  4829   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")
  4830 proof-
  4831   have "?rhs = (\<exists> (i::int). \<exists> x. 0\<le> x \<and> x < 1 \<and> Ifm (x#(real i)#bs) (exsplit p))"
  4832     by (simp add: myless[of _ "1"] myless[of _ "0"] ac_simps)
  4833   also have "\<dots> = (\<exists> (i::int). \<exists> x. 0\<le> x \<and> x < 1 \<and> Ifm ((real i + x) #bs) p)"
  4834     by (simp only: exsplit[OF qf] ac_simps)
  4835   also have "\<dots> = (\<exists> x. Ifm (x#bs) p)" 
  4836     by (simp only: real_ex_int_real01[where P="\<lambda> x. Ifm (x#bs) p"])
  4837   finally show ?thesis by simp
  4838 qed
  4839 
  4840     (* Implement the right hand sides of Cooper's theorem and Ferrante and Rackoff. *)
  4841 
  4842 definition ferrack01 :: "fm \<Rightarrow> fm" where
  4843   "ferrack01 p \<equiv> (let p' = rlfm(And (And (Ge(CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) p);
  4844                     U = remdups(map simp_num_pair 
  4845                      (map (\<lambda> ((t,n),(s,m)). (Add (Mul m t) (Mul n s) , 2*n*m))
  4846                            (alluopairs (\<Upsilon> p')))) 
  4847   in decr (evaldjf (\<upsilon> p') U ))"
  4848 
  4849 lemma fr_eq_01: 
  4850   assumes qf: "qfree p"
  4851   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)))"
  4852   (is "(\<exists> x. ?I x ?q) = ?F")
  4853 proof-
  4854   let ?rq = "rlfm ?q"
  4855   let ?M = "?I x (minusinf ?rq)"
  4856   let ?P = "?I x (plusinf ?rq)"
  4857   have MF: "?M = False"
  4858     apply (simp add: Let_def reducecoeff_def numgcd_def rsplit_def ge_def lt_def conj_def disj_def)
  4859     by (cases "rlfm p = And (Ge (CN 0 1 (C 0))) (Lt (CN 0 1 (C -1)))", simp_all)
  4860   have PF: "?P = False" apply (simp add: Let_def reducecoeff_def numgcd_def rsplit_def ge_def lt_def conj_def disj_def)
  4861     by (cases "rlfm p = And (Ge (CN 0 1 (C 0))) (Lt (CN 0 1 (C -1)))", simp_all)
  4862   have "(\<exists> x. ?I x ?q ) = 
  4863     ((?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))))"
  4864     (is "(\<exists> x. ?I x ?q) = (?M \<or> ?P \<or> ?F)" is "?E = ?D")
  4865   proof
  4866     assume "\<exists> x. ?I x ?q"  
  4867     then obtain x where qx: "?I x ?q" by blast
  4868     hence xp: "0\<le> x" and x1: "x< 1" and px: "?I x p" 
  4869       by (auto simp add: rsplit_def lt_def ge_def rlfm_I[OF qf])
  4870     from qx have "?I x ?rq " 
  4871       by (simp add: rsplit_def lt_def ge_def rlfm_I[OF qf xp x1])
  4872     hence lqx: "?I x ?rq " using simpfm[where p="?rq" and bs="x#bs"] by auto
  4873     from qf have qfq:"isrlfm ?rq"  
  4874       by (auto simp add: rsplit_def lt_def ge_def rlfm_I[OF qf xp x1])
  4875     with lqx fr_eq_\<upsilon>[OF qfq] show "?M \<or> ?P \<or> ?F" by blast
  4876   next
  4877     assume D: "?D"
  4878     let ?U = "set (\<Upsilon> ?rq )"
  4879     from MF PF D have "?F" by auto
  4880     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
  4881     from qf have lrq:"isrlfm ?rq"using rlfm_l[OF qf] 
  4882       by (auto simp add: rsplit_def lt_def ge_def)
  4883     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)
  4884     let ?st = "Add (Mul m t) (Mul n s)"
  4885     from tnb snb have stnb: "numbound0 ?st" by simp
  4886     from np mp have mnp: "real (2*n*m) > 0" by (simp add: mult.commute)
  4887     from conjunct1[OF \<upsilon>_I[OF lrq mnp stnb, where bs="bs" and x="x"], symmetric] rqx
  4888     have "\<exists> x. ?I x ?rq" by auto
  4889     thus "?E" 
  4890       using rlfm_I[OF qf] by (auto simp add: rsplit_def lt_def ge_def)
  4891   qed
  4892   with MF PF show ?thesis by blast
  4893 qed
  4894 
  4895 lemma \<Upsilon>_cong_aux:
  4896   assumes Ul: "\<forall> (t,n) \<in> set U. numbound0 t \<and> n >0"
  4897   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))"
  4898   (is "?lhs = ?rhs")
  4899 proof(auto)
  4900   fix t n s m
  4901   assume "((t,n),(s,m)) \<in> set (alluopairs U)"
  4902   hence th: "((t,n),(s,m)) \<in> (set U \<times> set U)"
  4903     using alluopairs_set1[where xs="U"] by blast
  4904   let ?N = "\<lambda> t. Inum (x#bs) t"
  4905   let ?st= "Add (Mul m t) (Mul n s)"
  4906   from Ul th have mnz: "m \<noteq> 0" by auto
  4907   from Ul th have  nnz: "n \<noteq> 0" by auto  
  4908   have st: "(?N t / real n + ?N s / real m)/2 = ?N ?st / real (2*n*m)"
  4909    using mnz nnz by (simp add: algebra_simps add_divide_distrib)
  4910  
  4911   thus "(real m *  Inum (x # bs) t + real n * Inum (x # bs) s) /
  4912        (2 * real n * real m)
  4913        \<in> (\<lambda>((t, n), s, m).
  4914              (Inum (x # bs) t / real n + Inum (x # bs) s / real m) / 2) `
  4915          (set U \<times> set U)"using mnz nnz th  
  4916     apply (auto simp add: th add_divide_distrib algebra_simps split_def image_def)
  4917     by (rule_tac x="(s,m)" in bexI,simp_all) 
  4918   (rule_tac x="(t,n)" in bexI,simp_all add: mult.commute)
  4919 next
  4920   fix t n s m
  4921   assume tnU: "(t,n) \<in> set U" and smU:"(s,m) \<in> set U" 
  4922   let ?N = "\<lambda> t. Inum (x#bs) t"
  4923   let ?st= "Add (Mul m t) (Mul n s)"
  4924   from Ul smU have mnz: "m \<noteq> 0" by auto
  4925   from Ul tnU have  nnz: "n \<noteq> 0" by auto  
  4926   have st: "(?N t / real n + ?N s / real m)/2 = ?N ?st / real (2*n*m)"
  4927    using mnz nnz by (simp add: algebra_simps add_divide_distrib)
  4928  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"
  4929  have Pc:"\<forall> a b. ?P a b = ?P b a"
  4930    by auto
  4931  from Ul alluopairs_set1 have Up:"\<forall> ((t,n),(s,m)) \<in> set (alluopairs U). n \<noteq> 0 \<and> m \<noteq> 0" by blast
  4932  from alluopairs_ex[OF Pc, where xs="U"] tnU smU
  4933  have th':"\<exists> ((t',n'),(s',m')) \<in> set (alluopairs U). ?P (t',n') (s',m')"
  4934    by blast
  4935  then obtain t' n' s' m' where ts'_U: "((t',n'),(s',m')) \<in> set (alluopairs U)" 
  4936    and Pts': "?P (t',n') (s',m')" by blast
  4937  from ts'_U Up have mnz': "m' \<noteq> 0" and nnz': "n'\<noteq> 0" by auto
  4938  let ?st' = "Add (Mul m' t') (Mul n' s')"
  4939    have st': "(?N t' / real n' + ?N s' / real m')/2 = ?N ?st' / real (2*n'*m')"
  4940    using mnz' nnz' by (simp add: algebra_simps add_divide_distrib)
  4941  from Pts' have 
  4942    "(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
  4943  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')
  4944  finally show "(Inum (x # bs) t / real n + Inum (x # bs) s / real m) / 2
  4945           \<in> (\<lambda>(t, n). Inum (x # bs) t / real n) `
  4946             (\<lambda>((t, n), s, m). (Add (Mul m t) (Mul n s), 2 * n * m)) `
  4947             set (alluopairs U)"
  4948    using ts'_U by blast
  4949 qed
  4950 
  4951 lemma \<Upsilon>_cong:
  4952   assumes lp: "isrlfm p"
  4953   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)")
  4954   and U: "\<forall> (t,n) \<in> U. numbound0 t \<and> n > 0"
  4955   and U': "\<forall> (t,n) \<in> U'. numbound0 t \<and> n > 0"
  4956   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)))"
  4957   (is "?lhs = ?rhs")
  4958 proof
  4959   assume ?lhs
  4960   then obtain t n s m where tnU: "(t,n) \<in> U" and smU:"(s,m) \<in> U" and 
  4961     Pst: "Ifm (x#bs) (\<upsilon> p (Add (Mul m t) (Mul n s),2*n*m))" by blast
  4962   let ?N = "\<lambda> t. Inum (x#bs) t"
  4963   from tnU smU U have tnb: "numbound0 t" and np: "n > 0" 
  4964     and snb: "numbound0 s" and mp:"m > 0"  by auto
  4965   let ?st= "Add (Mul m t) (Mul n s)"
  4966   from np mp have mnp: "real (2*n*m) > 0" 
  4967       by (simp add: mult.commute real_of_int_mult[symmetric] del: real_of_int_mult)
  4968     from tnb snb have stnb: "numbound0 ?st" by simp
  4969   have st: "(?N t / real n + ?N s / real m)/2 = ?N ?st / real (2*n*m)"
  4970    using mp np by (simp add: algebra_simps add_divide_distrib)
  4971   from tnU smU UU' have "?g ((t,n),(s,m)) \<in> ?f ` U'" by blast
  4972   hence "\<exists> (t',n') \<in> U'. ?g ((t,n),(s,m)) = ?f (t',n')"
  4973     by auto (rule_tac x="(a,b)" in bexI, auto)
  4974   then obtain t' n' where tnU': "(t',n') \<in> U'" and th: "?g ((t,n),(s,m)) = ?f (t',n')" by blast
  4975   from U' tnU' have tnb': "numbound0 t'" and np': "real n' > 0" by auto
  4976   from \<upsilon>_I[OF lp mnp stnb, where bs="bs" and x="x"] Pst 
  4977   have Pst2: "Ifm (Inum (x # bs) (Add (Mul m t) (Mul n s)) / real (2 * n * m) # bs) p" by simp
  4978   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]]
  4979   have "Ifm (x # bs) (\<upsilon> p (t', n')) " by (simp only: st) 
  4980   then show ?rhs using tnU' by auto 
  4981 next
  4982   assume ?rhs
  4983   then obtain t' n' where tnU': "(t',n') \<in> U'" and Pt': "Ifm (x # bs) (\<upsilon> p (t', n'))" 
  4984     by blast
  4985   from tnU' UU' have "?f (t',n') \<in> ?g ` (U\<times>U)" by blast
  4986   hence "\<exists> ((t,n),(s,m)) \<in> (U\<times>U). ?f (t',n') = ?g ((t,n),(s,m))" 
  4987     by auto (rule_tac x="(a,b)" in bexI, auto)
  4988   then obtain t n s m where tnU: "(t,n) \<in> U" and smU:"(s,m) \<in> U" and 
  4989     th: "?f (t',n') = ?g((t,n),(s,m)) "by blast
  4990     let ?N = "\<lambda> t. Inum (x#bs) t"
  4991   from tnU smU U have tnb: "numbound0 t" and np: "n > 0" 
  4992     and snb: "numbound0 s" and mp:"m > 0"  by auto
  4993   let ?st= "Add (Mul m t) (Mul n s)"
  4994   from np mp have mnp: "real (2*n*m) > 0" 
  4995       by (simp add: mult.commute real_of_int_mult[symmetric] del: real_of_int_mult)
  4996     from tnb snb have stnb: "numbound0 ?st" by simp
  4997   have st: "(?N t / real n + ?N s / real m)/2 = ?N ?st / real (2*n*m)"
  4998    using mp np by (simp add: algebra_simps add_divide_distrib)
  4999   from U' tnU' have tnb': "numbound0 t'" and np': "real n' > 0" by auto
  5000   from \<upsilon>_I[OF lp np' tnb', where bs="bs" and x="x",simplified th[simplified split_def fst_conv snd_conv] st] Pt'
  5001   have Pst2: "Ifm (Inum (x # bs) (Add (Mul m t) (Mul n s)) / real (2 * n * m) # bs) p" by simp
  5002   with \<upsilon>_I[OF lp mnp stnb, where x="x" and bs="bs"] tnU smU show ?lhs by blast
  5003 qed
  5004   
  5005 lemma ferrack01: 
  5006   assumes qf: "qfree p"
  5007   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> _")
  5008 proof-
  5009   let ?I = "\<lambda> x p. Ifm (x#bs) p"
  5010   fix x
  5011   let ?N = "\<lambda> t. Inum (x#bs) t"
  5012   let ?q = "rlfm (And (And (Ge(CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) p)"
  5013   let ?U = "\<Upsilon> ?q"
  5014   let ?Up = "alluopairs ?U"
  5015   let ?g = "\<lambda> ((t,n),(s,m)). (Add (Mul m t) (Mul n s) , 2*n*m)"
  5016   let ?S = "map ?g ?Up"
  5017   let ?SS = "map simp_num_pair ?S"
  5018   let ?Y = "remdups ?SS"
  5019   let ?f= "(\<lambda> (t,n). ?N t / real n)"
  5020   let ?h = "\<lambda> ((t,n),(s,m)). (?N t/real n + ?N s/ real m) /2"
  5021   let ?F = "\<lambda> p. \<exists> a \<in> set (\<Upsilon> p). \<exists> b \<in> set (\<Upsilon> p). ?I x (\<upsilon> p (?g(a,b)))"
  5022   let ?ep = "evaldjf (\<upsilon> ?q) ?Y"
  5023   from rlfm_l[OF qf] have lq: "isrlfm ?q" 
  5024     by (simp add: rsplit_def lt_def ge_def conj_def disj_def Let_def reducecoeff_def numgcd_def)
  5025   from alluopairs_set1[where xs="?U"] have UpU: "set ?Up \<le> (set ?U \<times> set ?U)" by simp
  5026   from \<Upsilon>_l[OF lq] have U_l: "\<forall> (t,n) \<in> set ?U. numbound0 t \<and> n > 0" .
  5027   from U_l UpU 
  5028   have "\<forall> ((t,n),(s,m)) \<in> set ?Up. numbound0 t \<and> n> 0 \<and> numbound0 s \<and> m > 0" by auto
  5029   hence Snb: "\<forall> (t,n) \<in> set ?S. numbound0 t \<and> n > 0 "
  5030     by (auto)
  5031   have Y_l: "\<forall> (t,n) \<in> set ?Y. numbound0 t \<and> n > 0" 
  5032   proof-
  5033     { fix t n assume tnY: "(t,n) \<in> set ?Y" 
  5034       hence "(t,n) \<in> set ?SS" by simp
  5035       hence "\<exists> (t',n') \<in> set ?S. simp_num_pair (t',n') = (t,n)"
  5036         by (auto simp add: split_def simp del: map_map)
  5037            (rule_tac x="((aa,ba),(ab,bb))" in bexI, simp_all)
  5038       then obtain t' n' where tn'S: "(t',n') \<in> set ?S" and tns: "simp_num_pair (t',n') = (t,n)" by blast
  5039       from tn'S Snb have tnb: "numbound0 t'" and np: "n' > 0" by auto
  5040       from simp_num_pair_l[OF tnb np tns]
  5041       have "numbound0 t \<and> n > 0" . }
  5042     thus ?thesis by blast
  5043   qed
  5044 
  5045   have YU: "(?f ` set ?Y) = (?h ` (set ?U \<times> set ?U))"
  5046   proof-
  5047      from simp_num_pair_ci[where bs="x#bs"] have 
  5048     "\<forall>x. (?f o simp_num_pair) x = ?f x" by auto
  5049      hence th: "?f o simp_num_pair = ?f" using ext by blast
  5050     have "(?f ` set ?Y) = ((?f o simp_num_pair) ` set ?S)" by (simp add: image_comp comp_assoc)
  5051     also have "\<dots> = (?f ` set ?S)" by (simp add: th)
  5052     also have "\<dots> = ((?f o ?g) ` set ?Up)" 
  5053       by (simp only: set_map o_def image_comp)
  5054     also have "\<dots> = (?h ` (set ?U \<times> set ?U))"
  5055       using \<Upsilon>_cong_aux[OF U_l, where x="x" and bs="bs", simplified set_map image_comp] by blast
  5056     finally show ?thesis .
  5057   qed
  5058   have "\<forall> (t,n) \<in> set ?Y. bound0 (\<upsilon> ?q (t,n))"
  5059   proof-
  5060     { fix t n assume tnY: "(t,n) \<in> set ?Y"
  5061       with Y_l have tnb: "numbound0 t" and np: "real n > 0" by auto
  5062       from \<upsilon>_I[OF lq np tnb]
  5063     have "bound0 (\<upsilon> ?q (t,n))"  by simp}
  5064     thus ?thesis by blast
  5065   qed
  5066   hence ep_nb: "bound0 ?ep"  using evaldjf_bound0[where xs="?Y" and f="\<upsilon> ?q"]
  5067     by auto
  5068 
  5069   from fr_eq_01[OF qf, where bs="bs" and x="x"] have "?lhs = ?F ?q"
  5070     by (simp only: split_def fst_conv snd_conv)
  5071   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]
  5072     by (simp only: split_def fst_conv snd_conv) 
  5073   also have "\<dots> = (Ifm (x#bs) ?ep)" 
  5074     using evaldjf_ex[where ps="?Y" and bs = "x#bs" and f="\<upsilon> ?q",symmetric]
  5075     by (simp only: split_def pair_collapse)
  5076   also have "\<dots> = (Ifm bs (decr ?ep))" using decr[OF ep_nb] by blast
  5077   finally have lr: "?lhs = ?rhs" by (simp only: ferrack01_def Let_def)
  5078   from decr_qf[OF ep_nb] have "qfree (ferrack01 p)" by (simp only: Let_def ferrack01_def)
  5079   with lr show ?thesis by blast
  5080 qed
  5081 
  5082 lemma cp_thm': 
  5083   assumes lp: "iszlfm p (real (i::int)#bs)"
  5084   and up: "d_\<beta> p 1" and dd: "d_\<delta> p d" and dp: "d > 0"
  5085   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))"
  5086   using cp_thm[OF lp up dd dp] by auto
  5087 
  5088 definition unit :: "fm \<Rightarrow> fm \<times> num list \<times> int" where
  5089   "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;
  5090              B = remdups (map simpnum (\<beta> q)) ; a = remdups (map simpnum (\<alpha> q))
  5091              in if length B \<le> length a then (q,B,d) else (mirror q, a,d))"
  5092 
  5093 lemma unit: assumes qf: "qfree p"
  5094   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)"
  5095 proof-
  5096   fix q B d 
  5097   assume qBd: "unit p = (q,B,d)"
  5098   let ?thes = "((\<exists> (x::int). Ifm (real x#bs) p) = (\<exists> (x::int). Ifm (real x#bs) q)) \<and>
  5099     Inum (real i#bs) ` set B = Inum (real i#bs) ` set (\<beta> q) \<and>
  5100     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)"
  5101   let ?I = "\<lambda> (x::int) p. Ifm (real x#bs) p"
  5102   let ?p' = "zlfm p"
  5103   let ?l = "\<zeta> ?p'"
  5104   let ?q = "And (Dvd ?l (CN 0 1 (C 0))) (a_\<beta> ?p' ?l)"
  5105   let ?d = "\<delta> ?q"
  5106   let ?B = "set (\<beta> ?q)"
  5107   let ?B'= "remdups (map simpnum (\<beta> ?q))"
  5108   let ?A = "set (\<alpha> ?q)"
  5109   let ?A'= "remdups (map simpnum (\<alpha> ?q))"
  5110   from conjunct1[OF zlfm_I[OF qf, where bs="bs"]] 
  5111   have pp': "\<forall> i. ?I i ?p' = ?I i p" by auto
  5112   from iszlfm_gen[OF conjunct2[OF zlfm_I[OF qf, where bs="bs" and i="i"]]]
  5113   have lp': "\<forall> (i::int). iszlfm ?p' (real i#bs)" by simp 
  5114   hence lp'': "iszlfm ?p' (real (i::int)#bs)" by simp
  5115   from lp' \<zeta>[where p="?p'" and bs="bs"] have lp: "?l >0" and dl: "d_\<beta> ?p' ?l" by auto
  5116   from a_\<beta>_ex[where p="?p'" and l="?l" and bs="bs", OF lp'' dl lp] pp'
  5117   have pq_ex:"(\<exists> (x::int). ?I x p) = (\<exists> x. ?I x ?q)" by (simp add: int_rdvd_iff) 
  5118   from lp'' lp a_\<beta>[OF lp'' dl lp] have lq:"iszlfm ?q (real i#bs)" and uq: "d_\<beta> ?q 1" 
  5119     by (auto simp add: isint_def)
  5120   from \<delta>[OF lq] have dp:"?d >0" and dd: "d_\<delta> ?q ?d" by blast+
  5121   let ?N = "\<lambda> t. Inum (real (i::int)#bs) t"
  5122   have "?N ` set ?B' = ((?N o simpnum) ` ?B)" by (simp add:image_comp) 
  5123   also have "\<dots> = ?N ` ?B" using simpnum_ci[where bs="real i #bs"] by auto
  5124   finally have BB': "?N ` set ?B' = ?N ` ?B" .
  5125   have "?N ` set ?A' = ((?N o simpnum) ` ?A)" by (simp add:image_comp) 
  5126   also have "\<dots> = ?N ` ?A" using simpnum_ci[where bs="real i #bs"] by auto
  5127   finally have AA': "?N ` set ?A' = ?N ` ?A" .
  5128   from \<beta>_numbound0[OF lq] have B_nb:"\<forall> b\<in> set ?B'. numbound0 b"
  5129     by simp
  5130   from \<alpha>_l[OF lq] have A_nb: "\<forall> b\<in> set ?A'. numbound0 b"
  5131     by simp
  5132   { assume "length ?B' \<le> length ?A'"
  5133     hence q:"q=?q" and "B = ?B'" and d:"d = ?d"
  5134       using qBd by (auto simp add: Let_def unit_def)
  5135     with BB' B_nb have b: "?N ` (set B) = ?N ` set (\<beta> q)" 
  5136       and bn: "\<forall>b\<in> set B. numbound0 b" by simp+
  5137     with pq_ex dp uq dd lq q d have ?thes by simp }
  5138   moreover 
  5139   { assume "\<not> (length ?B' \<le> length ?A')"
  5140     hence q:"q=mirror ?q" and "B = ?A'" and d:"d = ?d"
  5141       using qBd by (auto simp add: Let_def unit_def)
  5142     with AA' mirror_\<alpha>_\<beta>[OF lq] A_nb have b:"?N ` (set B) = ?N ` set (\<beta> q)" 
  5143       and bn: "\<forall>b\<in> set B. numbound0 b" by simp+
  5144     from mirror_ex[OF lq] pq_ex q 
  5145     have pqm_eq:"(\<exists> (x::int). ?I x p) = (\<exists> (x::int). ?I x q)" by simp
  5146     from lq uq q mirror_d_\<beta> [where p="?q" and bs="bs" and a="real i"]
  5147     have lq': "iszlfm q (real i#bs)" and uq: "d_\<beta> q 1" by auto
  5148     from \<delta>[OF lq'] mirror_\<delta>[OF lq] q d have dq:"d_\<delta> q d " by auto
  5149     from pqm_eq b bn uq lq' dp dq q dp d have ?thes by simp
  5150   }
  5151   ultimately show ?thes by blast
  5152 qed
  5153     (* Cooper's Algorithm *)
  5154 
  5155 definition cooper :: "fm \<Rightarrow> fm" where
  5156   "cooper p \<equiv> 
  5157   (let (q,B,d) = unit p; js = [1..d];
  5158        mq = simpfm (minusinf q);
  5159        md = evaldjf (\<lambda> j. simpfm (subst0 (C j) mq)) js
  5160    in if md = T then T else
  5161     (let qd = evaldjf (\<lambda> t. simpfm (subst0 t q)) 
  5162                                (remdups (map (\<lambda> (b,j). simpnum (Add b (C j))) 
  5163                                             [(b,j). b\<leftarrow>B,j\<leftarrow>js]))
  5164      in decr (disj md qd)))"
  5165 lemma cooper: assumes qf: "qfree p"
  5166   shows "((\<exists> (x::int). Ifm (real x#bs) p) = (Ifm bs (cooper p))) \<and> qfree (cooper p)" 
  5167   (is "(?lhs = ?rhs) \<and> _")
  5168 proof-
  5169 
  5170   let ?I = "\<lambda> (x::int) p. Ifm (real x#bs) p"
  5171   let ?q = "fst (unit p)"
  5172   let ?B = "fst (snd(unit p))"
  5173   let ?d = "snd (snd (unit p))"
  5174   let ?js = "[1..?d]"
  5175   let ?mq = "minusinf ?q"
  5176   let ?smq = "simpfm ?mq"
  5177   let ?md = "evaldjf (\<lambda> j. simpfm (subst0 (C j) ?smq)) ?js"
  5178   fix i
  5179   let ?N = "\<lambda> t. Inum (real (i::int)#bs) t"
  5180   let ?bjs = "[(b,j). b\<leftarrow>?B,j\<leftarrow>?js]"
  5181   let ?sbjs = "map (\<lambda> (b,j). simpnum (Add b (C j))) ?bjs"
  5182   let ?qd = "evaldjf (\<lambda> t. simpfm (subst0 t ?q)) (remdups ?sbjs)"
  5183   have qbf:"unit p = (?q,?B,?d)" by simp
  5184   from unit[OF qf qbf] have pq_ex: "(\<exists>(x::int). ?I x p) = (\<exists> (x::int). ?I x ?q)" and 
  5185     B:"?N ` set ?B = ?N ` set (\<beta> ?q)" and 
  5186     uq:"d_\<beta> ?q 1" and dd: "d_\<delta> ?q ?d" and dp: "?d > 0" and 
  5187     lq: "iszlfm ?q (real i#bs)" and 
  5188     Bn: "\<forall> b\<in> set ?B. numbound0 b" by auto
  5189   from zlin_qfree[OF lq] have qfq: "qfree ?q" .
  5190   from simpfm_qf[OF minusinf_qfree[OF qfq]] have qfmq: "qfree ?smq".
  5191   have jsnb: "\<forall> j \<in> set ?js. numbound0 (C j)" by simp
  5192   hence "\<forall> j\<in> set ?js. bound0 (subst0 (C j) ?smq)" 
  5193     by (auto simp only: subst0_bound0[OF qfmq])
  5194   hence th: "\<forall> j\<in> set ?js. bound0 (simpfm (subst0 (C j) ?smq))"
  5195     by auto
  5196   from evaldjf_bound0[OF th] have mdb: "bound0 ?md" by simp 
  5197   from Bn jsnb have "\<forall> (b,j) \<in> set ?bjs. numbound0 (Add b (C j))"
  5198     by simp
  5199   hence "\<forall> (b,j) \<in> set ?bjs. numbound0 (simpnum (Add b (C j)))"
  5200     using simpnum_numbound0 by blast
  5201   hence "\<forall> t \<in> set ?sbjs. numbound0 t" by simp
  5202   hence "\<forall> t \<in> set (remdups ?sbjs). bound0 (subst0 t ?q)"
  5203     using subst0_bound0[OF qfq] by auto 
  5204   hence th': "\<forall> t \<in> set (remdups ?sbjs). bound0 (simpfm (subst0 t ?q))"
  5205     using simpfm_bound0 by blast
  5206   from evaldjf_bound0 [OF th'] have qdb: "bound0 ?qd" by simp
  5207   from mdb qdb 
  5208   have mdqdb: "bound0 (disj ?md ?qd)" by (simp only: disj_def, cases "?md=T \<or> ?qd=T", simp_all)
  5209   from trans [OF pq_ex cp_thm'[OF lq uq dd dp]] B
  5210   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
  5211   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
  5212   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
  5213   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)
  5214   also  have "\<dots>= ((\<exists> j\<in> set ?js. ?I j ?smq) \<or> (\<exists> t \<in> set ?sbjs. Ifm (?N t #bs) ?q))" 
  5215     by (auto simp add: split_def) 
  5216   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))"
  5217     by (simp only: simpfm subst0_I[OF qfq] Inum.simps subst0_I[OF qfmq] set_remdups)
  5218   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)
  5219   finally have mdqd: "?lhs = (?I i (disj ?md ?qd))" by simp
  5220   hence mdqd2: "?lhs = (Ifm bs (decr (disj ?md ?qd)))" using decr [OF mdqdb] by simp
  5221   {assume mdT: "?md = T"
  5222     hence cT:"cooper p = T" 
  5223       by (simp only: cooper_def unit_def split_def Let_def if_True) simp
  5224     from mdT mdqd have lhs:"?lhs" by auto
  5225     from mdT have "?rhs" by (simp add: cooper_def unit_def split_def)
  5226     with lhs cT have ?thesis by simp }
  5227   moreover
  5228   {assume mdT: "?md \<noteq> T" hence "cooper p = decr (disj ?md ?qd)" 
  5229       by (simp only: cooper_def unit_def split_def Let_def if_False) 
  5230     with mdqd2 decr_qf[OF mdqdb] have ?thesis by simp }
  5231   ultimately show ?thesis by blast
  5232 qed
  5233 
  5234 lemma DJcooper: 
  5235   assumes qf: "qfree p"
  5236   shows "((\<exists> (x::int). Ifm (real x#bs) p) = (Ifm bs (DJ cooper p))) \<and> qfree (DJ cooper p)"
  5237 proof-
  5238   from cooper have cqf: "\<forall> p. qfree p \<longrightarrow> qfree (cooper p)" by  blast
  5239   from DJ_qf[OF cqf] qf have thqf:"qfree (DJ cooper p)" by blast
  5240   have "Ifm bs (DJ cooper p) = (\<exists> q\<in> set (disjuncts p). Ifm bs (cooper q))" 
  5241      by (simp add: DJ_def evaldjf_ex)
  5242   also have "\<dots> = (\<exists> q \<in> set(disjuncts p). \<exists> (x::int). Ifm (real x#bs)  q)" 
  5243     using cooper disjuncts_qf[OF qf] by blast
  5244   also have "\<dots> = (\<exists> (x::int). Ifm (real x#bs) p)" by (induct p rule: disjuncts.induct, auto)
  5245   finally show ?thesis using thqf by blast
  5246 qed
  5247 
  5248     (* Redy and Loveland *)
  5249 
  5250 lemma \<sigma>_\<rho>_cong: assumes lp: "iszlfm p (a#bs)" and tt': "Inum (a#bs) t = Inum (a#bs) t'"
  5251   shows "Ifm (a#bs) (\<sigma>_\<rho> p (t,c)) = Ifm (a#bs) (\<sigma>_\<rho> p (t',c))"
  5252   using lp 
  5253   by (induct p rule: iszlfm.induct, auto simp add: tt')
  5254 
  5255 lemma \<sigma>_cong: assumes lp: "iszlfm p (a#bs)" and tt': "Inum (a#bs) t = Inum (a#bs) t'"
  5256   shows "Ifm (a#bs) (\<sigma> p c t) = Ifm (a#bs) (\<sigma> p c t')"
  5257   by (simp add: \<sigma>_def tt' \<sigma>_\<rho>_cong[OF lp tt'])
  5258 
  5259 lemma \<rho>_cong: assumes lp: "iszlfm p (a#bs)" 
  5260   and RR: "(\<lambda>(b,k). (Inum (a#bs) b,k)) ` R =  (\<lambda>(b,k). (Inum (a#bs) b,k)) ` set (\<rho> p)"
  5261   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))))"
  5262   (is "?lhs = ?rhs")
  5263 proof
  5264   let ?d = "\<delta> p"
  5265   assume ?lhs then obtain e c j where ecR: "(e,c) \<in> R" and jD:"j \<in> {1 .. c*?d}" 
  5266     and px: "Ifm (a#bs) (\<sigma> p c (Add e (C j)))" (is "?sp c e j") by blast
  5267   from ecR have "(Inum (a#bs) e,c) \<in> (\<lambda>(b,k). (Inum (a#bs) b,k)) ` R" by auto
  5268   hence "(Inum (a#bs) e,c) \<in> (\<lambda>(b,k). (Inum (a#bs) b,k)) ` set (\<rho> p)" using RR by simp
  5269   hence "\<exists> (e',c') \<in> set (\<rho> p). Inum (a#bs) e = Inum (a#bs) e' \<and> c = c'" by auto
  5270   then obtain e' c' where ecRo:"(e',c') \<in> set (\<rho> p)" and ee':"Inum (a#bs) e = Inum (a#bs) e'"
  5271     and cc':"c = c'" by blast
  5272   from ee' have tt': "Inum (a#bs) (Add e (C j)) = Inum (a#bs) (Add e' (C j))" by simp
  5273   
  5274   from \<sigma>_cong[OF lp tt', where c="c"] px have px':"?sp c e' j" by simp
  5275   from ecRo jD px' show ?rhs apply (auto simp: cc')
  5276     by (rule_tac x="(e', c')" in bexI,simp_all)
  5277   (rule_tac x="j" in bexI, simp_all add: cc'[symmetric])
  5278 next
  5279   let ?d = "\<delta> p"
  5280   assume ?rhs then obtain e c j where ecR: "(e,c) \<in> set (\<rho> p)" and jD:"j \<in> {1 .. c*?d}" 
  5281     and px: "Ifm (a#bs) (\<sigma> p c (Add e (C j)))" (is "?sp c e j") by blast
  5282   from ecR have "(Inum (a#bs) e,c) \<in> (\<lambda>(b,k). (Inum (a#bs) b,k)) ` set (\<rho> p)" by auto
  5283   hence "(Inum (a#bs) e,c) \<in> (\<lambda>(b,k). (Inum (a#bs) b,k)) ` R" using RR by simp
  5284   hence "\<exists> (e',c') \<in> R. Inum (a#bs) e = Inum (a#bs) e' \<and> c = c'" by auto
  5285   then obtain e' c' where ecRo:"(e',c') \<in> R" and ee':"Inum (a#bs) e = Inum (a#bs) e'"
  5286     and cc':"c = c'" by blast
  5287   from ee' have tt': "Inum (a#bs) (Add e (C j)) = Inum (a#bs) (Add e' (C j))" by simp
  5288   from \<sigma>_cong[OF lp tt', where c="c"] px have px':"?sp c e' j" by simp
  5289   from ecRo jD px' show ?lhs apply (auto simp: cc')
  5290     by (rule_tac x="(e', c')" in bexI,simp_all)
  5291   (rule_tac x="j" in bexI, simp_all add: cc'[symmetric])
  5292 qed
  5293 
  5294 lemma rl_thm': 
  5295   assumes lp: "iszlfm p (real (i::int)#bs)" 
  5296   and R: "(\<lambda>(b,k). (Inum (a#bs) b,k)) ` R =  (\<lambda>(b,k). (Inum (a#bs) b,k)) ` set (\<rho> p)"
  5297   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)))))"
  5298   using rl_thm[OF lp] \<rho>_cong[OF iszlfm_gen[OF lp, rule_format, where y="a"] R] by simp 
  5299 
  5300 definition chooset :: "fm \<Rightarrow> fm \<times> ((num\<times>int) list) \<times> int" where
  5301   "chooset p \<equiv> (let q = zlfm p ; d = \<delta> q;
  5302              B = remdups (map (\<lambda> (t,k). (simpnum t,k)) (\<rho> q)) ; 
  5303              a = remdups (map (\<lambda> (t,k). (simpnum t,k)) (\<alpha>_\<rho> q))
  5304              in if length B \<le> length a then (q,B,d) else (mirror q, a,d))"
  5305 
  5306 lemma chooset: assumes qf: "qfree p"
  5307   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)"
  5308 proof-
  5309   fix q B d 
  5310   assume qBd: "chooset p = (q,B,d)"
  5311   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)" 
  5312   let ?I = "\<lambda> (x::int) p. Ifm (real x#bs) p"
  5313   let ?q = "zlfm p"
  5314   let ?d = "\<delta> ?q"
  5315   let ?B = "set (\<rho> ?q)"
  5316   let ?f = "\<lambda> (t,k). (simpnum t,k)"
  5317   let ?B'= "remdups (map ?f (\<rho> ?q))"
  5318   let ?A = "set (\<alpha>_\<rho> ?q)"
  5319   let ?A'= "remdups (map ?f (\<alpha>_\<rho> ?q))"
  5320   from conjunct1[OF zlfm_I[OF qf, where bs="bs"]] 
  5321   have pp': "\<forall> i. ?I i ?q = ?I i p" by auto
  5322   hence pq_ex:"(\<exists> (x::int). ?I x p) = (\<exists> x. ?I x ?q)" by simp 
  5323   from iszlfm_gen[OF conjunct2[OF zlfm_I[OF qf, where bs="bs" and i="i"]], rule_format, where y="real i"]
  5324   have lq: "iszlfm ?q (real (i::int)#bs)" . 
  5325   from \<delta>[OF lq] have dp:"?d >0" by blast
  5326   let ?N = "\<lambda> (t,c). (Inum (real (i::int)#bs) t,c)"
  5327   have "?N ` set ?B' = ((?N o ?f) ` ?B)" by (simp add: split_def image_comp)
  5328   also have "\<dots> = ?N ` ?B"
  5329     by(simp add: split_def image_comp simpnum_ci[where bs="real i #bs"] image_def)
  5330   finally have BB': "?N ` set ?B' = ?N ` ?B" .
  5331   have "?N ` set ?A' = ((?N o ?f) ` ?A)" by (simp add: split_def image_comp) 
  5332   also have "\<dots> = ?N ` ?A" using simpnum_ci[where bs="real i #bs"]
  5333     by(simp add: split_def image_comp simpnum_ci[where bs="real i #bs"] image_def) 
  5334   finally have AA': "?N ` set ?A' = ?N ` ?A" .
  5335   from \<rho>_l[OF lq] have B_nb:"\<forall> (e,c)\<in> set ?B'. numbound0 e \<and> c > 0"
  5336     by (simp add: split_def)
  5337   from \<alpha>_\<rho>_l[OF lq] have A_nb: "\<forall> (e,c)\<in> set ?A'. numbound0 e \<and> c > 0"
  5338     by (simp add: split_def)
  5339     {assume "length ?B' \<le> length ?A'"
  5340     hence q:"q=?q" and "B = ?B'" and d:"d = ?d"
  5341       using qBd by (auto simp add: Let_def chooset_def)
  5342     with BB' B_nb have b: "?N ` (set B) = ?N ` set (\<rho> q)" 
  5343       and bn: "\<forall>(e,c)\<in> set B. numbound0 e \<and> c > 0" by auto
  5344   with pq_ex dp lq q d have ?thes by simp}
  5345   moreover 
  5346   {assume "\<not> (length ?B' \<le> length ?A')"
  5347     hence q:"q=mirror ?q" and "B = ?A'" and d:"d = ?d"
  5348       using qBd by (auto simp add: Let_def chooset_def)
  5349     with AA' mirror_\<alpha>_\<rho>[OF lq] A_nb have b:"?N ` (set B) = ?N ` set (\<rho> q)" 
  5350       and bn: "\<forall>(e,c)\<in> set B. numbound0 e \<and> c > 0" by auto 
  5351     from mirror_ex[OF lq] pq_ex q 
  5352     have pqm_eq:"(\<exists> (x::int). ?I x p) = (\<exists> (x::int). ?I x q)" by simp
  5353     from lq q mirror_l [where p="?q" and bs="bs" and a="real i"]
  5354     have lq': "iszlfm q (real i#bs)" by auto
  5355     from mirror_\<delta>[OF lq] pqm_eq b bn lq' dp q dp d have ?thes by simp
  5356   }
  5357   ultimately show ?thes by blast
  5358 qed
  5359 
  5360 definition stage :: "fm \<Rightarrow> int \<Rightarrow> (num \<times> int) \<Rightarrow> fm" where
  5361   "stage p d \<equiv> (\<lambda> (e,c). evaldjf (\<lambda> j. simpfm (\<sigma> p c (Add e (C j)))) [1..c*d])"
  5362 lemma stage:
  5363   shows "Ifm bs (stage p d (e,c)) = (\<exists> j\<in>{1 .. c*d}. Ifm bs (\<sigma> p c (Add e (C j))))"
  5364   by (unfold stage_def split_def ,simp only: evaldjf_ex simpfm) simp
  5365 
  5366 lemma stage_nb: assumes lp: "iszlfm p (a#bs)" and cp: "c >0" and nb:"numbound0 e"
  5367   shows "bound0 (stage p d (e,c))"
  5368 proof-
  5369   let ?f = "\<lambda> j. simpfm (\<sigma> p c (Add e (C j)))"
  5370   have th: "\<forall> j\<in> set [1..c*d]. bound0 (?f j)"
  5371   proof
  5372     fix j
  5373     from nb have nb':"numbound0 (Add e (C j))" by simp
  5374     from simpfm_bound0[OF \<sigma>_nb[OF lp nb', where k="c"]]
  5375     show "bound0 (simpfm (\<sigma> p c (Add e (C j))))" .
  5376   qed
  5377   from evaldjf_bound0[OF th] show ?thesis by (unfold stage_def split_def) simp
  5378 qed
  5379 
  5380 definition redlove :: "fm \<Rightarrow> fm" where
  5381   "redlove p \<equiv> 
  5382   (let (q,B,d) = chooset p;
  5383        mq = simpfm (minusinf q);
  5384        md = evaldjf (\<lambda> j. simpfm (subst0 (C j) mq)) [1..d]
  5385    in if md = T then T else
  5386     (let qd = evaldjf (stage q d) B
  5387      in decr (disj md qd)))"
  5388 
  5389 lemma redlove: assumes qf: "qfree p"
  5390   shows "((\<exists> (x::int). Ifm (real x#bs) p) = (Ifm bs (redlove p))) \<and> qfree (redlove p)" 
  5391   (is "(?lhs = ?rhs) \<and> _")
  5392 proof-
  5393 
  5394   let ?I = "\<lambda> (x::int) p. Ifm (real x#bs) p"
  5395   let ?q = "fst (chooset p)"
  5396   let ?B = "fst (snd(chooset p))"
  5397   let ?d = "snd (snd (chooset p))"
  5398   let ?js = "[1..?d]"
  5399   let ?mq = "minusinf ?q"
  5400   let ?smq = "simpfm ?mq"
  5401   let ?md = "evaldjf (\<lambda> j. simpfm (subst0 (C j) ?smq)) ?js"
  5402   fix i
  5403   let ?N = "\<lambda> (t,k). (Inum (real (i::int)#bs) t,k)"
  5404   let ?qd = "evaldjf (stage ?q ?d) ?B"
  5405   have qbf:"chooset p = (?q,?B,?d)" by simp
  5406   from chooset[OF qf qbf] have pq_ex: "(\<exists>(x::int). ?I x p) = (\<exists> (x::int). ?I x ?q)" and 
  5407     B:"?N ` set ?B = ?N ` set (\<rho> ?q)" and dd: "\<delta> ?q = ?d" and dp: "?d > 0" and 
  5408     lq: "iszlfm ?q (real i#bs)" and 
  5409     Bn: "\<forall> (e,c)\<in> set ?B. numbound0 e \<and> c > 0" by auto
  5410   from zlin_qfree[OF lq] have qfq: "qfree ?q" .
  5411   from simpfm_qf[OF minusinf_qfree[OF qfq]] have qfmq: "qfree ?smq".
  5412   have jsnb: "\<forall> j \<in> set ?js. numbound0 (C j)" by simp
  5413   hence "\<forall> j\<in> set ?js. bound0 (subst0 (C j) ?smq)" 
  5414     by (auto simp only: subst0_bound0[OF qfmq])
  5415   hence th: "\<forall> j\<in> set ?js. bound0 (simpfm (subst0 (C j) ?smq))"
  5416     by auto
  5417   from evaldjf_bound0[OF th] have mdb: "bound0 ?md" by simp 
  5418   from Bn stage_nb[OF lq] have th:"\<forall> x \<in> set ?B. bound0 (stage ?q ?d x)" by auto
  5419   from evaldjf_bound0[OF th]  have qdb: "bound0 ?qd" .
  5420   from mdb qdb 
  5421   have mdqdb: "bound0 (disj ?md ?qd)" by (simp only: disj_def, cases "?md=T \<or> ?qd=T", simp_all)
  5422   from trans [OF pq_ex rl_thm'[OF lq B]] dd
  5423   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
  5424   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) )))" 
  5425     by (simp add: stage split_def)
  5426   also have "\<dots> = ((\<exists> j\<in> {1 .. ?d}. ?I i (subst0 (C j) ?smq))  \<or> ?I i ?qd)"
  5427     by (simp add: evaldjf_ex subst0_I[OF qfmq])
  5428   finally have mdqd:"?lhs = (?I i ?md \<or> ?I i ?qd)" by (simp only: evaldjf_ex set_upto simpfm) 
  5429   also have "\<dots> = (?I i (disj ?md ?qd))" by simp
  5430   also have "\<dots> = (Ifm bs (decr (disj ?md ?qd)))" by (simp only: decr [OF mdqdb]) 
  5431   finally have mdqd2: "?lhs = (Ifm bs (decr (disj ?md ?qd)))" . 
  5432   {assume mdT: "?md = T"
  5433     hence cT:"redlove p = T" by (simp add: redlove_def Let_def chooset_def split_def)
  5434     from mdT have lhs:"?lhs" using mdqd by simp 
  5435     from mdT have "?rhs" by (simp add: redlove_def chooset_def split_def)
  5436     with lhs cT have ?thesis by simp }
  5437   moreover
  5438   {assume mdT: "?md \<noteq> T" hence "redlove p = decr (disj ?md ?qd)" 
  5439       by (simp add: redlove_def chooset_def split_def Let_def)
  5440     with mdqd2 decr_qf[OF mdqdb] have ?thesis by simp }
  5441   ultimately show ?thesis by blast
  5442 qed
  5443 
  5444 lemma DJredlove: 
  5445   assumes qf: "qfree p"
  5446   shows "((\<exists> (x::int). Ifm (real x#bs) p) = (Ifm bs (DJ redlove p))) \<and> qfree (DJ redlove p)"
  5447 proof-
  5448   from redlove have cqf: "\<forall> p. qfree p \<longrightarrow> qfree (redlove p)" by  blast
  5449   from DJ_qf[OF cqf] qf have thqf:"qfree (DJ redlove p)" by blast
  5450   have "Ifm bs (DJ redlove p) = (\<exists> q\<in> set (disjuncts p). Ifm bs (redlove q))" 
  5451      by (simp add: DJ_def evaldjf_ex)
  5452   also have "\<dots> = (\<exists> q \<in> set(disjuncts p). \<exists> (x::int). Ifm (real x#bs)  q)" 
  5453     using redlove disjuncts_qf[OF qf] by blast
  5454   also have "\<dots> = (\<exists> (x::int). Ifm (real x#bs) p)" by (induct p rule: disjuncts.induct, auto)
  5455   finally show ?thesis using thqf by blast
  5456 qed
  5457 
  5458 
  5459 lemma exsplit_qf: assumes qf: "qfree p"
  5460   shows "qfree (exsplit p)"
  5461 using qf by (induct p rule: exsplit.induct, auto)
  5462 
  5463 definition mircfr :: "fm \<Rightarrow> fm" where
  5464   "mircfr = DJ cooper o ferrack01 o simpfm o exsplit"
  5465 
  5466 definition mirlfr :: "fm \<Rightarrow> fm" where
  5467   "mirlfr = DJ redlove o ferrack01 o simpfm o exsplit"
  5468 
  5469 lemma mircfr: "\<forall> bs p. qfree p \<longrightarrow> qfree (mircfr p) \<and> Ifm bs (mircfr p) = Ifm bs (E p)"
  5470 proof(clarsimp simp del: Ifm.simps)
  5471   fix bs p
  5472   assume qf: "qfree p"
  5473   show "qfree (mircfr p)\<and>(Ifm bs (mircfr p) = Ifm bs (E p))" (is "_ \<and> (?lhs = ?rhs)")
  5474   proof-
  5475     let ?es = "(And (And (Ge (CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) (simpfm (exsplit p)))"
  5476     have "?rhs = (\<exists> (i::int). \<exists> x. Ifm (x#real i#bs) ?es)" 
  5477       using splitex[OF qf] by simp
  5478     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+
  5479     with DJcooper[OF qf'] show ?thesis by (simp add: mircfr_def)
  5480   qed
  5481 qed
  5482   
  5483 lemma mirlfr: "\<forall> bs p. qfree p \<longrightarrow> qfree(mirlfr p) \<and> Ifm bs (mirlfr p) = Ifm bs (E p)"
  5484 proof(clarsimp simp del: Ifm.simps)
  5485   fix bs p
  5486   assume qf: "qfree p"
  5487   show "qfree (mirlfr p)\<and>(Ifm bs (mirlfr p) = Ifm bs (E p))" (is "_ \<and> (?lhs = ?rhs)")
  5488   proof-
  5489     let ?es = "(And (And (Ge (CN 0 1 (C 0))) (Lt (CN 0 1 (C (- 1))))) (simpfm (exsplit p)))"
  5490     have "?rhs = (\<exists> (i::int). \<exists> x. Ifm (x#real i#bs) ?es)" 
  5491       using splitex[OF qf] by simp
  5492     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+
  5493     with DJredlove[OF qf'] show ?thesis by (simp add: mirlfr_def)
  5494   qed
  5495 qed
  5496   
  5497 definition mircfrqe:: "fm \<Rightarrow> fm" where
  5498   "mircfrqe p = qelim (prep p) mircfr"
  5499 
  5500 definition mirlfrqe:: "fm \<Rightarrow> fm" where
  5501   "mirlfrqe p = qelim (prep p) mirlfr"
  5502 
  5503 theorem mircfrqe: "(Ifm bs (mircfrqe p) = Ifm bs p) \<and> qfree (mircfrqe p)"
  5504   using qelim_ci[OF mircfr] prep by (auto simp add: mircfrqe_def)
  5505 
  5506 theorem mirlfrqe: "(Ifm bs (mirlfrqe p) = Ifm bs p) \<and> qfree (mirlfrqe p)"
  5507   using qelim_ci[OF mirlfr] prep by (auto simp add: mirlfrqe_def)
  5508 
  5509 definition
  5510   "problem1 = A (And (Le (Sub (Floor (Bound 0)) (Bound 0))) (Le (Add (Bound 0) (Floor (Neg (Bound 0))))))"
  5511 
  5512 definition
  5513   "problem2 = A (Iff (Eq (Add (Floor (Bound 0)) (Floor (Neg (Bound 0))))) (Eq (Sub (Floor (Bound 0)) (Bound 0))))"
  5514 
  5515 definition
  5516   "problem3 = A (And (Le (Sub (Floor (Bound 0)) (Bound 0))) (Le (Add (Bound 0) (Floor (Neg (Bound 0))))))"
  5517 
  5518 definition
  5519   "problem4 = E (And (Ge (Sub (Bound 1) (Bound 0))) (Eq (Add (Floor (Bound 1)) (Floor (Neg (Bound 0))))))"
  5520 
  5521 ML_val {* @{code mircfrqe} @{code problem1} *}
  5522 ML_val {* @{code mirlfrqe} @{code problem1} *}
  5523 ML_val {* @{code mircfrqe} @{code problem2} *}
  5524 ML_val {* @{code mirlfrqe} @{code problem2} *}
  5525 ML_val {* @{code mircfrqe} @{code problem3} *}
  5526 ML_val {* @{code mirlfrqe} @{code problem3} *}
  5527 ML_val {* @{code mircfrqe} @{code problem4} *}
  5528 ML_val {* @{code mirlfrqe} @{code problem4} *}
  5529 
  5530 
  5531 (*code_reflect Mir
  5532   functions mircfrqe mirlfrqe
  5533   file "mir.ML"*)
  5534 
  5535 oracle mirfr_oracle = {* fn (proofs, ct) =>
  5536 let
  5537 
  5538 val mk_C = @{code C} o @{code int_of_integer};
  5539 val mk_Dvd = @{code Dvd} o apfst @{code int_of_integer};
  5540 val mk_Bound = @{code Bound} o @{code nat_of_integer};
  5541 
  5542 fun num_of_term vs (t as Free (xn, xT)) = (case AList.lookup (op =) vs t
  5543      of NONE => error "Variable not found in the list!"
  5544       | SOME n => mk_Bound n)
  5545   | num_of_term vs @{term "real (0::int)"} = mk_C 0
  5546   | num_of_term vs @{term "real (1::int)"} = mk_C 1
  5547   | num_of_term vs @{term "0::real"} = mk_C 0
  5548   | num_of_term vs @{term "1::real"} = mk_C 1
  5549   | num_of_term vs @{term "- 1::real"} = mk_C (~ 1)
  5550   | num_of_term vs (Bound i) = mk_Bound i
  5551   | num_of_term vs (@{term "uminus :: real \<Rightarrow> real"} $ t') = @{code Neg} (num_of_term vs t')
  5552   | num_of_term vs (@{term "op + :: real \<Rightarrow> real \<Rightarrow> real"} $ t1 $ t2) =
  5553       @{code Add} (num_of_term vs t1, num_of_term vs t2)
  5554   | num_of_term vs (@{term "op - :: real \<Rightarrow> real \<Rightarrow> real"} $ t1 $ t2) =
  5555       @{code Sub} (num_of_term vs t1, num_of_term vs t2)
  5556   | num_of_term vs (@{term "op * :: real \<Rightarrow> real \<Rightarrow> real"} $ t1 $ t2) =
  5557       (case (num_of_term vs t1)
  5558        of @{code C} i => @{code Mul} (i, num_of_term vs t2)
  5559         | _ => error "num_of_term: unsupported Multiplication")
  5560   | num_of_term vs (@{term "real :: int \<Rightarrow> real"} $ (@{term "numeral :: _ \<Rightarrow> int"} $ t')) =
  5561       mk_C (HOLogic.dest_num t')
  5562   | num_of_term vs (@{term "real :: int \<Rightarrow> real"} $ (@{term "- numeral :: _ \<Rightarrow> int"} $ t')) =
  5563       mk_C (~ (HOLogic.dest_num t'))
  5564   | num_of_term vs (@{term "real :: int \<Rightarrow> real"} $ (@{term "floor :: real \<Rightarrow> int"} $ t')) =
  5565       @{code Floor} (num_of_term vs t')
  5566   | num_of_term vs (@{term "real :: int \<Rightarrow> real"} $ (@{term "ceiling :: real \<Rightarrow> int"} $ t')) =
  5567       @{code Neg} (@{code Floor} (@{code Neg} (num_of_term vs t')))
  5568   | num_of_term vs (@{term "numeral :: _ \<Rightarrow> real"} $ t') =
  5569       mk_C (HOLogic.dest_num t')