New Reflected Presburger added to HOL/ex
authorchaieb
Wed Jun 06 16:12:08 2007 +0200 (2007-06-06)
changeset 23274f997514ad8f4
parent 23273 c6d5ab154c7c
child 23275 339cdc29b0bc
New Reflected Presburger added to HOL/ex
src/HOL/IsaMakefile
src/HOL/ex/Reflected_Presburger.thy
src/HOL/ex/coopereif.ML
src/HOL/ex/coopertac.ML
     1.1 --- a/src/HOL/IsaMakefile	Tue Jun 05 22:47:49 2007 +0200
     1.2 +++ b/src/HOL/IsaMakefile	Wed Jun 06 16:12:08 2007 +0200
     1.3 @@ -651,8 +651,8 @@
     1.4    ex/NatSum.thy ex/PER.thy ex/PresburgerEx.thy ex/Primrec.thy \
     1.5    ex/Puzzle.thy ex/Qsort.thy ex/Quickcheck_Examples.thy \
     1.6    ex/Reflection.thy ex/ReflectionEx.thy ex/ROOT.ML ex/Recdefs.thy \
     1.7 -  ex/Records.thy ex/Reflected_Presburger.thy ex/Refute_Examples.thy \
     1.8 -  ex/SAT_Examples.thy ex/svc_oracle.ML ex/SVC_Oracle.thy \
     1.9 +  ex/Records.thy ex/Reflected_Presburger.thy ex/coopertac.ML ex/coopereif.ML \
    1.10 +  ex/Refute_Examples.thy ex/SAT_Examples.thy ex/svc_oracle.ML ex/SVC_Oracle.thy \
    1.11    ex/Sudoku.thy ex/Tarski.thy ex/Unification.thy ex/document/root.bib \
    1.12    ex/document/root.tex ex/mesontest2.ML ex/mesontest2.thy ex/reflection.ML \
    1.13    ex/set.thy ex/svc_funcs.ML ex/svc_test.thy Library/Parity.thy Library/GCD.thy
     2.1 --- a/src/HOL/ex/Reflected_Presburger.thy	Tue Jun 05 22:47:49 2007 +0200
     2.2 +++ b/src/HOL/ex/Reflected_Presburger.thy	Wed Jun 06 16:12:08 2007 +0200
     2.3 @@ -1,5717 +1,1999 @@
     2.4 -(*  Title:      HOL/ex/PresburgerEx.thy
     2.5 -    ID:         $Id$
     2.6 -    Author:     Amine Chaieb, TU Muenchen
     2.7 -
     2.8 -A formalization of quantifier elimination for Presburger arithmetic
     2.9 -based on a generic quantifier elimination algorithm and Cooper's
    2.10 -method to eliminate on \<exists>. *)
    2.11 -
    2.12 -header {* Quantifier elimination for Presburger arithmetic *}
    2.13 -
    2.14  theory Reflected_Presburger
    2.15 -imports Main GCD
    2.16 -begin
    2.17 -
    2.18 -(* Shadow syntax for integer terms *)
    2.19 -datatype intterm =
    2.20 -    Cst int
    2.21 -  | Var nat
    2.22 -  | Neg intterm
    2.23 -  | Add intterm intterm 
    2.24 -  | Sub intterm intterm
    2.25 -  | Mult intterm intterm
    2.26 -
    2.27 -(* interpretation of intterms, takes bound variables and free variables *)
    2.28 -consts I_intterm :: "int list \<Rightarrow> intterm \<Rightarrow> int"
    2.29 -primrec 
    2.30 -"I_intterm ats (Cst b) = b"
    2.31 -"I_intterm ats (Var n) = (ats!n)"
    2.32 -"I_intterm ats (Neg it) = -(I_intterm ats it)"
    2.33 -"I_intterm ats (Add it1 it2) = (I_intterm ats it1) + (I_intterm ats it2)" 
    2.34 -"I_intterm ats (Sub it1 it2) = (I_intterm ats it1) - (I_intterm ats it2)"
    2.35 -"I_intterm ats (Mult it1 it2) = (I_intterm ats it1) * (I_intterm ats it2)"
    2.36 -
    2.37 -(* Shadow syntax for Presburger formulae *)
    2.38 -datatype QF = 
    2.39 -   Lt intterm intterm
    2.40 -  |Gt intterm intterm
    2.41 -  |Le intterm intterm
    2.42 -  |Ge intterm intterm
    2.43 -  |Eq intterm intterm
    2.44 -  |Divides intterm intterm
    2.45 -  |T
    2.46 -  |F
    2.47 -  |NOT QF
    2.48 -  |And QF QF
    2.49 -  |Or QF QF
    2.50 -  |Imp QF QF
    2.51 -  |Equ QF QF
    2.52 -  |QAll QF
    2.53 -  |QEx QF
    2.54 -
    2.55 -(* Interpretation of Presburger formulae *)
    2.56 -consts qinterp :: "int list \<Rightarrow> QF \<Rightarrow> bool"
    2.57 -primrec
    2.58 -"qinterp ats (Lt it1 it2) = (I_intterm ats it1 < I_intterm ats it2)"
    2.59 -"qinterp ats (Gt it1 it2) = (I_intterm ats it1 > I_intterm ats it2)"
    2.60 -"qinterp ats (Le it1 it2) = (I_intterm ats it1 \<le> I_intterm ats it2)"
    2.61 -"qinterp ats (Ge it1 it2) = (I_intterm ats it1 \<ge> I_intterm ats it2)"
    2.62 -"qinterp ats (Divides it1 it2) = (I_intterm ats it1 dvd I_intterm ats it2)"
    2.63 -"qinterp ats (Eq it1 it2) = (I_intterm ats it1 = I_intterm ats it2)"
    2.64 -"qinterp ats T = True"
    2.65 -"qinterp ats F = False"
    2.66 -"qinterp ats (NOT p) = (\<not>(qinterp ats p))"
    2.67 -"qinterp ats (And p q) = (qinterp ats p \<and> qinterp ats q)"
    2.68 -"qinterp ats (Or p q) = (qinterp ats p \<or> qinterp ats q)"
    2.69 -"qinterp ats (Imp p q) = (qinterp ats p \<longrightarrow> qinterp ats q)"
    2.70 -"qinterp ats (Equ p q) = (qinterp ats p = qinterp ats q)"
    2.71 -"qinterp ats (QAll p) = (\<forall>x. qinterp (x#ats) p)"
    2.72 -"qinterp ats (QEx p) = (\<exists>x. qinterp (x#ats) p)"
    2.73 -
    2.74 -(* quantifier elimination based on qe, quantifier elimination for an
    2.75 -   existential formula, with quantifier free body 
    2.76 -   Since quantifier elimination for one formula is allowed to fail,
    2.77 -   the result is of type QF option *)
    2.78 -
    2.79 -consts lift_bin:: "('a \<Rightarrow> 'a \<Rightarrow> 'b) \<times> 'a option \<times> 'a option \<Rightarrow> 'b option"
    2.80 -recdef lift_bin "measure (\<lambda>(c,a,b). size a)"
    2.81 -"lift_bin (c,Some a,Some b) = Some (c a b)"
    2.82 -"lift_bin (c,x, y)  = None"
    2.83 -
    2.84 -lemma lift_bin_Some:
    2.85 -  assumes ls: "lift_bin (c,x,y) = Some t"
    2.86 -  shows "(\<exists>a. x = Some a) \<and> (\<exists>b. y = Some b)"
    2.87 -  using ls 
    2.88 -  by (cases "x", auto) (cases "y", auto)+
    2.89 -
    2.90 -consts lift_un:: "('a \<Rightarrow> 'b) \<Rightarrow> 'a option \<Rightarrow> 'b option"
    2.91 -primrec
    2.92 -"lift_un c None = None"
    2.93 -"lift_un c (Some p) = Some (c p)"
    2.94 -
    2.95 -consts lift_qe:: "('a \<Rightarrow> 'b option) \<Rightarrow> 'a option \<Rightarrow> 'b option"
    2.96 -primrec
    2.97 -"lift_qe qe None = None"
    2.98 -"lift_qe qe (Some p) = qe p"
    2.99 -
   2.100 -(* generic quantifier elimination *)
   2.101 -consts qelim :: "(QF \<Rightarrow> QF option) \<times> QF \<Rightarrow> QF option"
   2.102 -recdef qelim "measure (\<lambda>(qe,p). size p)"
   2.103 -"qelim (qe, (QAll p)) = lift_un NOT (lift_qe qe (lift_un NOT (qelim (qe ,p))))"
   2.104 -"qelim (qe, (QEx p)) = lift_qe qe (qelim (qe,p))"
   2.105 -"qelim (qe, (And p q)) = lift_bin (And, (qelim (qe, p)), (qelim (qe, q)))"
   2.106 -"qelim (qe, (Or p q)) = lift_bin (Or, (qelim (qe, p)), (qelim (qe, q)))"
   2.107 -"qelim (qe, (Imp p q)) = lift_bin (Imp, (qelim (qe, p)), (qelim (qe, q)))"
   2.108 -"qelim (qe, (Equ p q)) = lift_bin (Equ, (qelim (qe, p)), (qelim (qe, q)))"
   2.109 -"qelim (qe,NOT p) = lift_un NOT (qelim (qe,p))"
   2.110 -"qelim (qe, p) = Some p"
   2.111 -
   2.112 -(* quantifier free-ness *)
   2.113 -consts isqfree :: "QF \<Rightarrow> bool"
   2.114 -recdef isqfree "measure size"
   2.115 -"isqfree (QAll p) = False"
   2.116 -"isqfree (QEx p) = False"
   2.117 -"isqfree (And p q) = (isqfree p \<and> isqfree q)"
   2.118 -"isqfree (Or p q) = (isqfree p \<and> isqfree q)"
   2.119 -"isqfree (Imp p q) = (isqfree p \<and> isqfree q)"
   2.120 -"isqfree (Equ p q) = (isqfree p \<and> isqfree q)"
   2.121 -"isqfree (NOT p) = isqfree p"
   2.122 -"isqfree p = True"
   2.123 +  imports GCD Main EfficientNat
   2.124 +  uses ("coopereif.ML") ("coopertac.ML")
   2.125 +  begin
   2.126  
   2.127 -(* qelim lifts quantifierfreeness*)
   2.128 -lemma qelim_qfree: 
   2.129 -  assumes qeqf: "(\<And> q q'. \<lbrakk>isqfree q ; qe q = Some q'\<rbrakk> \<Longrightarrow>  isqfree q')"
   2.130 -  shows qff:"\<And> p'. qelim (qe, p) = Some p' \<Longrightarrow> isqfree p'"
   2.131 -  using qeqf
   2.132 -proof (induct p)
   2.133 -  case (Lt a b)
   2.134 -  have "qelim (qe, Lt a b) = Some (Lt a b)" by simp
   2.135 -  moreover have "qelim (qe,Lt a b) = Some p'" . 
   2.136 -  ultimately have "p' = Lt a b" by simp
   2.137 -  moreover have "isqfree (Lt a b)" by simp
   2.138 -  ultimately 
   2.139 -  show ?case  by simp
   2.140 -next  
   2.141 -  case (Gt a b)
   2.142 -  have "qelim (qe, Gt a b) = Some (Gt a b)" by simp
   2.143 -  moreover have "qelim (qe,Gt a b) = Some p'" . 
   2.144 -  ultimately have "p' = Gt a b" by simp
   2.145 -  moreover have "isqfree (Gt a b)" by simp
   2.146 -  ultimately 
   2.147 -  show ?case  by simp
   2.148 -next  
   2.149 -  case (Le a b)
   2.150 -  have "qelim (qe, Le a b) = Some (Le a b)" by simp
   2.151 -  moreover have "qelim (qe,Le a b) = Some p'" . 
   2.152 -  ultimately have "p' = Le a b" by simp
   2.153 -  moreover have "isqfree (Le a b)" by simp
   2.154 -  ultimately 
   2.155 -  show ?case  by simp
   2.156 -next  
   2.157 -  case (Ge a b)
   2.158 -  have "qelim (qe, Ge a b) = Some (Ge a b)" by simp
   2.159 -  moreover have "qelim (qe,Ge a b) = Some p'" . 
   2.160 -  ultimately have "p' = Ge a b" by simp
   2.161 -  moreover have "isqfree (Ge a b)" by simp
   2.162 -  ultimately 
   2.163 -  show ?case  by simp
   2.164 -next  
   2.165 -  case (Eq a b)
   2.166 -  have "qelim (qe, Eq a b) = Some (Eq a b)" by simp
   2.167 -  moreover have "qelim (qe,Eq a b) = Some p'" . 
   2.168 -  ultimately have "p' = Eq a b" by simp
   2.169 -  moreover have "isqfree (Eq a b)" by simp
   2.170 -  ultimately 
   2.171 -  show ?case  by simp
   2.172 -next  
   2.173 -  case (Divides a b)
   2.174 -  have "qelim (qe, Divides a b) = Some (Divides a b)" by simp
   2.175 -  moreover have "qelim (qe,Divides a b) = Some p'" . 
   2.176 -  ultimately have "p' = Divides a b" by simp
   2.177 -  moreover have "isqfree (Divides a b)" by simp
   2.178 -  ultimately 
   2.179 -  show ?case  by simp
   2.180 -next  
   2.181 -  case T 
   2.182 -  have "qelim(qe,T) = Some T" by simp
   2.183 -  moreover have "qelim(qe,T) = Some p'" .
   2.184 -  ultimately have "p' = T" by simp
   2.185 -  moreover have "isqfree T" by simp
   2.186 -  ultimately show ?case by simp
   2.187 -next  
   2.188 -  case F
   2.189 -  have "qelim(qe,F) = Some F" by simp
   2.190 -  moreover have "qelim(qe,F) = Some p'" .
   2.191 -  ultimately have "p' = F" by simp
   2.192 -  moreover have "isqfree F" by simp
   2.193 -  ultimately show ?case by simp
   2.194 -next  
   2.195 -  case (NOT p)
   2.196 -  from "NOT.prems" have "\<exists> p1. qelim(qe,p) = Some p1"
   2.197 -    by  (cases "qelim(qe,p)") simp_all
   2.198 -  then obtain "p1" where p1_def: "qelim(qe,p) = Some p1" by blast
   2.199 -  from "NOT.prems" have "\<And>q q'. \<lbrakk>isqfree q; qe q = Some q'\<rbrakk> \<Longrightarrow> isqfree q'" 
   2.200 -    by blast
   2.201 -  with "NOT.hyps" p1_def have p1qf: "isqfree p1" by blast
   2.202 -  then have "p' = NOT p1" using "NOT.prems" p1_def
   2.203 -    by (cases "qelim(qe,NOT p)") simp_all
   2.204 -  then show ?case using p1qf by simp
   2.205 -next  
   2.206 -  case (And p q) 
   2.207 -  from "And.prems" have p1q1: "(\<exists>p1. qelim(qe,p) = Some p1) \<and> 
   2.208 -    (\<exists>q1. qelim(qe,q) = Some q1)" using lift_bin_Some[where c="And"] by simp
   2.209 -  from p1q1 obtain "p1" and "q1" 
   2.210 -    where p1_def: "qelim(qe,p) = Some p1" 
   2.211 -    and q1_def: "qelim(qe,q) = Some q1" by blast
   2.212 -  from prems have qf1:"isqfree p1"
   2.213 -    using p1_def by blast
   2.214 -  from prems have qf2:"isqfree q1"
   2.215 -    using q1_def by blast
   2.216 -  from "And.prems" have "qelim(qe,And p q) = Some p'" by blast
   2.217 -  then have "p' = And p1 q1" using p1_def q1_def by simp
   2.218 -  then 
   2.219 -  show ?case using qf1 qf2 by simp
   2.220 -next  
   2.221 -  case (Or p q)
   2.222 -  from "Or.prems" have p1q1: "(\<exists>p1. qelim(qe,p) = Some p1) \<and> 
   2.223 -    (\<exists>q1. qelim(qe,q) = Some q1)" using lift_bin_Some[where c="Or"] by simp
   2.224 -  from p1q1 obtain "p1" and "q1" 
   2.225 -    where p1_def: "qelim(qe,p) = Some p1" 
   2.226 -    and q1_def: "qelim(qe,q) = Some q1" by blast
   2.227 -  from prems have qf1:"isqfree p1"
   2.228 -    using p1_def by blast
   2.229 -  from prems have qf2:"isqfree q1"
   2.230 -    using q1_def by blast
   2.231 -  from "Or.prems" have "qelim(qe,Or p q) = Some p'" by blast
   2.232 -  then have "p' = Or p1 q1" using p1_def q1_def by simp
   2.233 -  then 
   2.234 -  show ?case using qf1 qf2 by simp
   2.235 -next  
   2.236 -  case (Imp p q)
   2.237 -  from "Imp.prems" have p1q1: "(\<exists>p1. qelim(qe,p) = Some p1) \<and> 
   2.238 -    (\<exists>q1. qelim(qe,q) = Some q1)" using lift_bin_Some[where c="Imp"] by simp
   2.239 -  from p1q1 obtain "p1" and "q1" 
   2.240 -    where p1_def: "qelim(qe,p) = Some p1" 
   2.241 -    and q1_def: "qelim(qe,q) = Some q1" by blast
   2.242 -  from prems have qf1:"isqfree p1"
   2.243 -    using p1_def by blast
   2.244 -  from prems have qf2:"isqfree q1"
   2.245 -    using q1_def by blast
   2.246 -  from "Imp.prems" have "qelim(qe,Imp p q) = Some p'" by blast
   2.247 -  then have "p' = Imp p1 q1" using p1_def q1_def by simp
   2.248 -  then 
   2.249 -  show ?case using qf1 qf2 by simp
   2.250 -next  
   2.251 -  case (Equ p q)
   2.252 -  from "Equ.prems" have p1q1: "(\<exists>p1. qelim(qe,p) = Some p1) \<and> 
   2.253 -    (\<exists>q1. qelim(qe,q) = Some q1)" using lift_bin_Some[where c="Equ"] by simp
   2.254 -  from p1q1 obtain "p1" and "q1" 
   2.255 -    where p1_def: "qelim(qe,p) = Some p1" 
   2.256 -    and q1_def: "qelim(qe,q) = Some q1" by blast
   2.257 -  from prems have qf1:"isqfree p1"
   2.258 -    using p1_def by blast
   2.259 -  from prems have qf2:"isqfree q1"
   2.260 -    using q1_def by blast
   2.261 -  from "Equ.prems" have "qelim(qe,Equ p q) = Some p'" by blast
   2.262 -  then have "p' = Equ p1 q1" using p1_def q1_def by simp
   2.263 -  then 
   2.264 -  show ?case using qf1 qf2 by simp
   2.265 -next 
   2.266 -  case (QEx p)
   2.267 -  from "QEx.prems" have "\<exists> p1. qelim(qe,p) = Some p1"
   2.268 -    by  (cases "qelim(qe,p)") simp_all
   2.269 -  then obtain "p1" where p1_def: "qelim(qe,p) = Some p1" by blast
   2.270 -  from "QEx.prems" have "\<And>q q'. \<lbrakk>isqfree q; qe q = Some q'\<rbrakk> \<Longrightarrow> isqfree q'" 
   2.271 -    by blast
   2.272 -  with "QEx.hyps" p1_def have p1qf: "isqfree p1" by blast
   2.273 -  from "QEx.prems" have "qe p1 = Some p'" using p1_def by simp
   2.274 -  with "QEx.prems" show ?case  using p1qf 
   2.275 -    by simp
   2.276 -next 
   2.277 -  case (QAll p) 
   2.278 -  from "QAll.prems"
   2.279 -  have "\<exists> p1. lift_qe qe (lift_un NOT (qelim (qe ,p))) = Some p1" 
   2.280 -    by (cases "lift_qe qe (lift_un NOT (qelim (qe ,p)))") simp_all
   2.281 -  then obtain "p1" where 
   2.282 -    p1_def:"lift_qe qe (lift_un NOT (qelim (qe ,p))) = Some p1" by blast
   2.283 -  then have "\<exists> p2. lift_un NOT (qelim (qe ,p)) = Some p2"
   2.284 -    by (cases "qelim (qe ,p)") simp_all
   2.285 -  then obtain "p2" 
   2.286 -    where p2_def:"lift_un NOT (qelim (qe ,p)) = Some p2" by blast
   2.287 -  then have "\<exists> p3. qelim(qe,p) = Some p3" by (cases "qelim(qe,p)") simp_all
   2.288 -  then obtain "p3" where p3_def: "qelim(qe,p) = Some p3" by blast
   2.289 -  with prems have qf3: "isqfree p3" by blast
   2.290 -  have p2_def2: "p2 = NOT p3" using p2_def p3_def by simp
   2.291 -  then have qf2: "isqfree p2" using qf3 by simp
   2.292 -  have p1_edf2: "qe p2 = Some p1" using p1_def p2_def by simp
   2.293 -  with "QAll.prems" have qf1: "isqfree p1" using qf2 by blast
   2.294 -  from "QAll.prems" have "p' = NOT p1" using p1_def by simp
   2.295 -  with qf1 show ?case by simp
   2.296 -qed
   2.297 -
   2.298 -(* qelim lifts semantical equivalence *)
   2.299 -lemma qelim_corr: 
   2.300 -  assumes qecorr: "(\<And> q q' ats. \<lbrakk>isqfree q ; qe q = Some q'\<rbrakk> \<Longrightarrow>  (qinterp ats (QEx q)) = (qinterp ats q'))"
   2.301 -  and qeqf: "(\<And> q q'. \<lbrakk>isqfree q ; qe q = Some q'\<rbrakk> \<Longrightarrow>  isqfree q')"
   2.302 -  shows qff:"\<And> p' ats. qelim (qe, p) = Some p' \<Longrightarrow> (qinterp ats p = qinterp ats p')" (is "\<And> p' ats. ?Qe p p' \<Longrightarrow> (?F ats p = ?F ats p')")
   2.303 -  using qeqf qecorr
   2.304 -proof (induct p)
   2.305 -  case (NOT f)  
   2.306 -  from "NOT.prems" have "\<exists>f'. ?Qe f f' " by (cases "qelim(qe,f)") simp_all
   2.307 -  then obtain "f'" where df': "?Qe f f'" by blast
   2.308 -  with prems have feqf': "?F ats f = ?F ats f'" by blast
   2.309 -  from "NOT.prems" df' have "p' = NOT f'" by simp
   2.310 -  with feqf' show ?case by simp
   2.311 -
   2.312 -next
   2.313 -  case (And f g) 
   2.314 -  from "And.prems" have f1g1: "(\<exists>f1. qelim(qe,f) = Some f1) \<and> 
   2.315 -    (\<exists>g1. qelim(qe,g) = Some g1)" using lift_bin_Some[where c="And"] by simp
   2.316 -  from f1g1 obtain "f1" and "g1" 
   2.317 -    where f1_def: "qelim(qe, f) = Some f1" 
   2.318 -    and g1_def: "qelim(qe,g) = Some g1" by blast
   2.319 -  from prems f1_def have feqf1: "?F ats f = ?F ats f1" by blast
   2.320 -  from prems g1_def have geqg1: "?F ats g = ?F ats g1" by blast
   2.321 -  from "And.prems" f1_def g1_def have "p' = And f1 g1" by simp
   2.322 -  with feqf1 geqg1 show ?case by simp
   2.323 -
   2.324 -next
   2.325 -  case (Or f g) 
   2.326 -  from "Or.prems" have f1g1: "(\<exists>f1. qelim(qe,f) = Some f1) \<and> 
   2.327 -    (\<exists>g1. qelim(qe,g) = Some g1)" using lift_bin_Some[where c="Or"] by simp
   2.328 -  from f1g1 obtain "f1" and "g1" 
   2.329 -    where f1_def: "qelim(qe, f) = Some f1" 
   2.330 -    and g1_def: "qelim(qe,g) = Some g1" by blast
   2.331 -  from prems f1_def have feqf1: "?F ats f = ?F ats  f1" by blast
   2.332 -  from prems g1_def have geqg1: "?F ats g = ?F ats g1" by blast
   2.333 -  from "Or.prems" f1_def g1_def have "p' = Or f1 g1" by simp
   2.334 -  with feqf1 geqg1 show ?case by simp
   2.335 -next
   2.336 -  case (Imp f g)
   2.337 -  from "Imp.prems" have f1g1: "(\<exists>f1. qelim(qe,f) = Some f1) \<and> 
   2.338 -    (\<exists>g1. qelim(qe,g) = Some g1)" using lift_bin_Some[where c="Imp"] by simp
   2.339 -  from f1g1 obtain "f1" and "g1" 
   2.340 -    where f1_def: "qelim(qe, f) = Some f1" 
   2.341 -    and g1_def: "qelim(qe,g) = Some g1" by blast
   2.342 -  from prems f1_def have feqf1: "?F ats f = ?F ats f1" by blast
   2.343 -  from prems g1_def have geqg1: "?F ats g = ?F ats g1" by blast
   2.344 -  from "Imp.prems" f1_def g1_def have "p' = Imp f1 g1" by simp
   2.345 -  with feqf1 geqg1 show ?case by simp
   2.346 -next
   2.347 -  case (Equ f g)
   2.348 -  from "Equ.prems" have f1g1: "(\<exists>f1. qelim(qe,f) = Some f1) \<and> 
   2.349 -    (\<exists>g1. qelim(qe,g) = Some g1)" using lift_bin_Some[where c="Equ"] by simp
   2.350 -  from f1g1 obtain "f1" and "g1" 
   2.351 -    where f1_def: "qelim(qe, f) = Some f1" 
   2.352 -    and g1_def: "qelim(qe,g) = Some g1" by blast
   2.353 -  from prems f1_def have feqf1: "?F ats f = ?F ats f1" by blast
   2.354 -  from prems g1_def have geqg1: "?F ats g = ?F ats g1" by blast
   2.355 -  from "Equ.prems" f1_def g1_def have "p' = Equ f1 g1" by simp
   2.356 -  with feqf1 geqg1 show ?case by simp
   2.357 -next
   2.358 -  case (QEx f) 
   2.359 -    from "QEx.prems" have "\<exists> f1. ?Qe f f1"
   2.360 -    by  (cases "qelim(qe,f)") simp_all
   2.361 -  then obtain "f1" where f1_def: "qelim(qe,f) = Some f1" by blast
   2.362 -  from prems have qf1:"isqfree f1" using qelim_qfree by blast
   2.363 -  from prems have feqf1: "\<forall> ats. qinterp ats f = qinterp ats f1"
   2.364 -    using f1_def qf1 by blast
   2.365 -  then  have "?F ats (QEx f) = ?F ats (QEx f1)" 
   2.366 -    by simp 
   2.367 -  from prems have "qelim (qe,QEx f) = Some p'" by blast
   2.368 -  then  have "\<exists> f'. qe f1 = Some f'" using f1_def by simp
   2.369 -  then obtain "f'" where fdef': "qe f1 = Some f'" by blast
   2.370 -  with prems have exf1: "?F ats (QEx f1) = ?F ats f'" using qf1 by blast
   2.371 -  have fp: "?Qe (QEx f) f'" using f1_def fdef' by simp
   2.372 -  from prems have "?Qe (QEx f) p'" by blast 
   2.373 -  then have "p' = f'" using fp by simp
   2.374 -  then show ?case using feqf1 exf1 by simp
   2.375 -next
   2.376 -  case (QAll f)
   2.377 -  from "QAll.prems"
   2.378 -  have "\<exists> f0. lift_un NOT (lift_qe qe (lift_un NOT (qelim (qe ,f)))) = 
   2.379 -    Some f0"
   2.380 -    by (cases "lift_un NOT (lift_qe qe (lift_un NOT (qelim (qe ,f))))") 
   2.381 -      simp_all
   2.382 -  then obtain "f0" 
   2.383 -    where f0_def: "lift_un NOT (lift_qe qe (lift_un NOT (qelim (qe ,f)))) = 
   2.384 -    Some f0" by blast
   2.385 -  then have "\<exists> f1. lift_qe qe (lift_un NOT (qelim (qe ,f))) = Some f1" 
   2.386 -    by (cases "lift_qe qe (lift_un NOT (qelim (qe ,f)))") simp_all
   2.387 -  then obtain "f1" where 
   2.388 -    f1_def:"lift_qe qe (lift_un NOT (qelim (qe ,f))) = Some f1" by blast
   2.389 -  then have "\<exists> f2. lift_un NOT (qelim (qe ,f)) = Some f2"
   2.390 -    by (cases "qelim (qe ,f)") simp_all
   2.391 -  then obtain "f2" 
   2.392 -    where f2_def:"lift_un NOT (qelim (qe ,f)) = Some f2" by blast
   2.393 -  then have "\<exists> f3. qelim(qe,f) = Some f3" by (cases "qelim(qe,f)") simp_all
   2.394 -  then obtain "f3" where f3_def: "qelim(qe,f) = Some f3" by blast
   2.395 -  from prems have qf3:"isqfree f3" using qelim_qfree by blast
   2.396 -  from prems have feqf3: "\<forall> ats. qinterp ats f = qinterp ats f3"
   2.397 -    using f3_def qf3 by blast
   2.398 -  have f23:"f2 = NOT f3" using f2_def f3_def by simp
   2.399 -  then have feqf2: "\<forall> ats. qinterp ats f = qinterp ats (NOT f2)"
   2.400 -    using feqf3 by simp
   2.401 -  have qf2: "isqfree f2" using f23 qf3 by simp
   2.402 -  have "qe f2 = Some f1" using f1_def f2_def f23 by simp
   2.403 -  with prems have exf2eqf1: "?F ats (QEx f2) = ?F ats f1" using qf2 by blast
   2.404 -  have "f0 = NOT f1" using f0_def f1_def by simp
   2.405 -  then have f0eqf1: "?F ats f0 = ?F ats (NOT f1)" by simp
   2.406 -  from prems have "qelim (qe, QAll f) = Some p'" by blast
   2.407 -  then have f0eqp': "p' = f0" using f0_def by simp
   2.408 -  have "?F ats (QAll f) = (\<forall>x. ?F (x#ats) f)" by simp
   2.409 -  also have "\<dots> = (\<not> (\<exists> x. ?F (x#ats) (NOT f)))" by simp
   2.410 -  also have "\<dots> = (\<not> (\<exists> x. ?F (x#ats) (NOT (NOT f2))))" using feqf2
   2.411 -    by auto
   2.412 -  also have "\<dots> = (\<not> (\<exists> x. ?F (x#ats) f2))" by simp
   2.413 -  also have "\<dots> = (\<not> (?F ats f1))" using exf2eqf1 by simp
   2.414 -  finally show ?case using f0eqp' f0eqf1 by simp
   2.415 -qed simp_all
   2.416 -
   2.417 -(* Cooper's algorithm *)
   2.418 +lemma allpairs_set: "set (allpairs Pair xs ys) = {(x,y). x\<in> set xs \<and> y \<in> set ys}"
   2.419 +by (induct xs) auto
   2.420  
   2.421  
   2.422 -(* Transform an intform into NNF *)
   2.423 -consts lgth :: "QF \<Rightarrow> nat"
   2.424 -       nnf :: "QF \<Rightarrow> QF"    
   2.425 -primrec
   2.426 -"lgth (Lt it1 it2) = 1"
   2.427 -"lgth (Gt it1 it2) = 1"
   2.428 -"lgth (Le it1 it2) = 1"
   2.429 -"lgth (Ge it1 it2) = 1"
   2.430 -"lgth (Eq it1 it2) = 1"
   2.431 -"lgth (Divides it1 it2) = 1"
   2.432 -"lgth T = 1"
   2.433 -"lgth F = 1"
   2.434 -"lgth (NOT p) = 1 + lgth p"
   2.435 -"lgth (And p q) = 1 + lgth p + lgth q"
   2.436 -"lgth (Or p q) = 1 + lgth p + lgth q"
   2.437 -"lgth (Imp p q) = 1 + lgth p + lgth q"
   2.438 -"lgth (Equ p q) = 1 + lgth p + lgth q" 
   2.439 -"lgth (QAll p) = 1 + lgth p" 
   2.440 -"lgth (QEx p) = 1 + lgth p" 
   2.441 -
   2.442 -lemma [simp] :"0 < lgth q"
   2.443 -apply (induct_tac q)
   2.444 -apply(auto)
   2.445 -done
   2.446 -
   2.447 -(* NNF *)
   2.448 -recdef nnf "measure (\<lambda>p. lgth p)"
   2.449 -  "nnf (Lt it1 it2) = Le (Sub it1 it2) (Cst (- 1))"
   2.450 -  "nnf (Gt it1 it2) = Le (Sub it2 it1) (Cst (- 1))"
   2.451 -  "nnf (Le it1 it2) = Le it1 it2 "
   2.452 -  "nnf (Ge it1 it2) = Le it2 it1"
   2.453 -  "nnf (Eq it1 it2) = Eq it2 it1"
   2.454 -  "nnf (Divides d t) = Divides d t"
   2.455 -  "nnf T = T"
   2.456 -  "nnf F = F"
   2.457 -  "nnf (And p q) = And (nnf p) (nnf q)"
   2.458 -  "nnf (Or p q) = Or (nnf p) (nnf q)"
   2.459 -  "nnf (Imp p q) = Or (nnf (NOT p)) (nnf q)"
   2.460 -  "nnf (Equ p q) = Or (And (nnf p) (nnf q)) 
   2.461 -  (And (nnf (NOT p)) (nnf (NOT q)))"
   2.462 -  "nnf (NOT (Lt it1 it2)) = (Le it2 it1)"
   2.463 -  "nnf (NOT (Gt it1 it2))  = (Le it1 it2)"
   2.464 -  "nnf (NOT (Le it1 it2)) = (Le (Sub it2 it1) (Cst (- 1)))"
   2.465 -  "nnf (NOT (Ge it1 it2)) = (Le (Sub it1 it2) (Cst (- 1)))"
   2.466 -  "nnf (NOT (Eq it1 it2)) = (NOT (Eq it1 it2))"
   2.467 -  "nnf (NOT (Divides d t)) = (NOT (Divides d t))"
   2.468 -  "nnf (NOT T) = F"
   2.469 -  "nnf (NOT F) = T"
   2.470 -  "nnf (NOT (NOT p)) = (nnf p)"
   2.471 -  "nnf (NOT (And p q)) = (Or (nnf (NOT p)) (nnf (NOT q)))"
   2.472 -  "nnf (NOT (Or p q)) = (And (nnf (NOT p)) (nnf (NOT q)))"
   2.473 -  "nnf (NOT (Imp p q)) = (And (nnf p) (nnf (NOT q)))"
   2.474 -  "nnf (NOT (Equ p q)) = (Or (And (nnf p) (nnf (NOT q))) (And (nnf (NOT p)) (nnf q)))"
   2.475 -
   2.476 -consts isnnf :: "QF \<Rightarrow> bool"
   2.477 -recdef isnnf "measure (\<lambda>p. lgth p)"
   2.478 -  "isnnf (Le it1 it2) = True"
   2.479 -  "isnnf (Eq it1 it2) = True"
   2.480 -  "isnnf (Divides d t) = True"
   2.481 -  "isnnf T = True"
   2.482 -  "isnnf F = True"
   2.483 -  "isnnf (And p q) = (isnnf p \<and> isnnf q)"
   2.484 -  "isnnf (Or p q) = (isnnf p \<and> isnnf q)"
   2.485 -  "isnnf (NOT (Divides d t)) = True" 
   2.486 -  "isnnf (NOT (Eq it1 it2)) = True" 
   2.487 -  "isnnf p = False"
   2.488 -
   2.489 -(* nnf preserves semantics *)
   2.490 -lemma nnf_corr: "isqfree p \<Longrightarrow> qinterp ats p = qinterp ats (nnf p)"
   2.491 -by (induct p rule: nnf.induct,simp_all) 
   2.492 -(arith, arith, arith, arith, arith, arith, arith, arith, arith, blast)
   2.493 -
   2.494 +  (* generate a list from i to j*)
   2.495 +consts iupt :: "int \<times> int \<Rightarrow> int list"
   2.496 +recdef iupt "measure (\<lambda> (i,j). nat (j-i +1))" 
   2.497 +  "iupt (i,j) = (if j <i then [] else (i# iupt(i+1, j)))"
   2.498  
   2.499 -(* the result of nnf is in NNF *)
   2.500 -lemma nnf_isnnf : "isqfree p \<Longrightarrow> isnnf (nnf p)"
   2.501 -by (induct p rule: nnf.induct, auto)
   2.502 -
   2.503 -lemma nnf_isqfree: "isnnf p \<Longrightarrow> isqfree p"
   2.504 -by (induct p rule: isnnf.induct) auto
   2.505 -
   2.506 -(* nnf preserves quantifier freeness *)
   2.507 -lemma nnf_qfree: "isqfree p \<Longrightarrow> isqfree(nnf p)"
   2.508 -  using nnf_isqfree nnf_isnnf by simp
   2.509 -
   2.510 -(* Linearization and normalization of formulae *)
   2.511 -(* Definition of linearity of an intterm *)
   2.512 -
   2.513 -consts islinintterm :: "intterm \<Rightarrow> bool"
   2.514 -recdef islinintterm "measure size"
   2.515 -"islinintterm (Cst i) = True"
   2.516 -"islinintterm (Add (Mult (Cst i) (Var n)) (Cst i')) = (i \<noteq> 0)"
   2.517 -"islinintterm (Add (Mult (Cst i) (Var n)) (Add (Mult (Cst i') (Var n')) r)) = ( i \<noteq> 0 \<and> i' \<noteq> 0 \<and> n < n' \<and> islinintterm  (Add (Mult (Cst i') (Var n')) r))"
   2.518 -"islinintterm i = False"
   2.519 -
   2.520 -(* subterms of linear terms are linear *)
   2.521 -lemma islinintterm_subt:
   2.522 -  assumes lr: "islinintterm (Add (Mult (Cst i) (Var n)) r)"
   2.523 -  shows "islinintterm r"
   2.524 -using lr
   2.525 -by (induct r rule: islinintterm.induct) auto
   2.526 -
   2.527 -(* c \<noteq> 0 for linear term c.n + r*)
   2.528 -lemma islinintterm_cnz:
   2.529 -  assumes lr: "islinintterm (Add (Mult (Cst i) (Var n)) r)"
   2.530 -  shows "i \<noteq> 0"
   2.531 -using lr
   2.532 -by (induct r rule: islinintterm.induct) auto
   2.533 -
   2.534 -lemma islininttermc0r: "islinintterm (Add (Mult (Cst c) (Var n)) r) \<Longrightarrow> (c \<noteq> 0 \<and> islinintterm r)"
   2.535 -by (induct r rule: islinintterm.induct, simp_all)
   2.536 -
   2.537 -(* An alternative linearity definition *)
   2.538 -consts islintn :: "(nat \<times> intterm) \<Rightarrow> bool"
   2.539 -recdef islintn "measure (\<lambda> (n,t). (size t))"
   2.540 -"islintn (n0, Cst i) = True"
   2.541 -"islintn (n0, Add (Mult (Cst i) (Var n)) r) = (i \<noteq> 0 \<and> n0 \<le> n \<and> islintn (n+1,r))"
   2.542 -"islintn (n0, t) = False"
   2.543 -
   2.544 -definition
   2.545 -  islint :: "intterm \<Rightarrow> bool" where
   2.546 -  "islint t = islintn(0,t)"
   2.547 -
   2.548 -(* And the equivalence to the first definition *)
   2.549 -lemma islinintterm_eq_islint: "islinintterm t = islint t"
   2.550 -  using islint_def
   2.551 -by (induct t rule: islinintterm.induct) auto
   2.552 -
   2.553 -(* monotony *)
   2.554 -lemma islintn_mon:
   2.555 -  assumes lin: "islintn (n,t)"
   2.556 -  and mgen: "m \<le> n"
   2.557 -  shows "islintn(m,t)"
   2.558 -  using lin mgen 
   2.559 -by (induct t rule: islintn.induct) auto
   2.560 -
   2.561 -lemma islintn_subt:
   2.562 -  assumes lint: "islintn(n,Add (Mult (Cst i) (Var m)) r)"
   2.563 -  shows "islintn (m+1,r)"
   2.564 -using lint
   2.565 -by auto
   2.566 -
   2.567 -(* List indexin for n > 0 *)
   2.568 -lemma nth_pos: "0 < n \<longrightarrow> (x#xs) ! n = (y#xs) ! n"
   2.569 -using Nat.gr0_conv_Suc 
   2.570 -by clarsimp 
   2.571 +lemma iupt_set: "set (iupt(i,j)) = {i .. j}"
   2.572 +proof(induct rule: iupt.induct)
   2.573 +  case (1 a b)
   2.574 +  show ?case
   2.575 +    using prems by (simp add: simp_from_to)
   2.576 +qed
   2.577  
   2.578  lemma nth_pos2: "0 < n \<Longrightarrow> (x#xs) ! n = xs ! (n - 1)"
   2.579  using Nat.gr0_conv_Suc
   2.580  by clarsimp
   2.581  
   2.582 -lemma intterm_novar0: 
   2.583 -  assumes lin: "islinintterm (Add (Mult (Cst i) (Var n)) r)"
   2.584 -  shows "I_intterm (x#ats) r = I_intterm (y#ats) r"
   2.585 -using lin
   2.586 -by (induct r rule: islinintterm.induct) (simp_all add: nth_pos2)
   2.587 -(* a simple version of a general theorem: Interpretation does not depend 
   2.588 -   on the first variable if it does not occur in the term *)
   2.589 +
   2.590 +lemma myl: "\<forall> (a::'a::{pordered_ab_group_add}) (b::'a). (a \<le> b) = (0 \<le> b - a)" 
   2.591 +proof(clarify)
   2.592 +  fix x y ::"'a"
   2.593 +  have "(x \<le> y) = (x - y \<le> 0)" by (simp only: le_iff_diff_le_0[where a="x" and b="y"])
   2.594 +  also have "\<dots> = (- (y - x) \<le> 0)" by simp
   2.595 +  also have "\<dots> = (0 \<le> y - x)" by (simp only: neg_le_0_iff_le[where a="y-x"])
   2.596 +  finally show "(x \<le> y) = (0 \<le> y - x)" .
   2.597 +qed
   2.598  
   2.599 -lemma linterm_novar0:
   2.600 -  assumes lin: "islintn (n,t)"
   2.601 -  and npos: "0 < n"
   2.602 -  shows "I_intterm (x#ats) t = I_intterm (y#ats) t"
   2.603 -using lin npos
   2.604 -by (induct n t rule: islintn.induct) (simp_all add: nth_pos2)
   2.605 +lemma myless: "\<forall> (a::'a::{pordered_ab_group_add}) (b::'a). (a < b) = (0 < b - a)" 
   2.606 +proof(clarify)
   2.607 +  fix x y ::"'a"
   2.608 +  have "(x < y) = (x - y < 0)" by (simp only: less_iff_diff_less_0[where a="x" and b="y"])
   2.609 +  also have "\<dots> = (- (y - x) < 0)" by simp
   2.610 +  also have "\<dots> = (0 < y - x)" by (simp only: neg_less_0_iff_less[where a="y-x"])
   2.611 +  finally show "(x < y) = (0 < y - x)" .
   2.612 +qed
   2.613 +
   2.614 +lemma myeq: "\<forall> (a::'a::{pordered_ab_group_add}) (b::'a). (a = b) = (0 = b - a)"
   2.615 +  by auto
   2.616  
   2.617  (* Periodicity of dvd *)
   2.618  lemma dvd_period:
   2.619    assumes advdd: "(a::int) dvd d"
   2.620    shows "(a dvd (x + t)) = (a dvd ((x+ c*d) + t))"
   2.621 -using advdd  
   2.622 +  using advdd  
   2.623  proof-
   2.624 -  from advdd  have "\<forall>x.\<forall>k. (((a::int) dvd (x + t)) = (a dvd
   2.625 - (x+k*d + t)))" by (rule dvd_modd_pinf)
   2.626 +  from advdd  have "\<forall>x.\<forall>k. (((a::int) dvd (x + t)) = (a dvd (x+k*d + t)))" 
   2.627 +    by (rule dvd_modd_pinf)
   2.628    then show ?thesis by simp
   2.629  qed
   2.630  
   2.631 -(* lin_ad adds two linear terms*)
   2.632 -consts lin_add :: "intterm \<times> intterm \<Rightarrow> intterm"
   2.633 -recdef lin_add "measure (\<lambda>(x,y). ((size x) + (size y)))"
   2.634 -"lin_add (Add (Mult (Cst c1) (Var n1)) (r1),Add (Mult (Cst c2) (Var n2)) (r2)) =
   2.635 -  (if n1=n2 then 
   2.636 -  (let c = Cst (c1 + c2) 
   2.637 -   in (if c1+c2=0 then lin_add(r1,r2) else Add (Mult c (Var n1)) (lin_add (r1,r2))))
   2.638 -  else if n1 \<le> n2 then (Add (Mult (Cst c1) (Var n1)) (lin_add (r1,Add (Mult (Cst c2) (Var n2)) (r2)))) 
   2.639 -  else (Add (Mult (Cst c2) (Var n2)) (lin_add (Add (Mult (Cst c1) (Var n1)) r1,r2))))"
   2.640 -"lin_add (Add (Mult (Cst c1) (Var n1)) (r1),Cst b) = 
   2.641 -  (Add (Mult (Cst c1) (Var n1)) (lin_add (r1, Cst b)))"  
   2.642 -"lin_add (Cst x,Add (Mult (Cst c2) (Var n2)) (r2)) = 
   2.643 -  Add (Mult (Cst c2) (Var n2)) (lin_add (Cst x,r2))" 
   2.644 -"lin_add (Cst b1, Cst b2) = Cst (b1+b2)"
   2.645 +  (*********************************************************************************)
   2.646 +  (****                            SHADOW SYNTAX AND SEMANTICS                  ****)
   2.647 +  (*********************************************************************************)
   2.648 +
   2.649 +datatype num = C int | Bound nat | CX int num | Neg num | Add num num| Sub num num 
   2.650 +  | Mul int num
   2.651 +
   2.652 +  (* A size for num to make inductive proofs simpler*)
   2.653 +consts num_size :: "num \<Rightarrow> nat" 
   2.654 +primrec 
   2.655 +  "num_size (C c) = 1"
   2.656 +  "num_size (Bound n) = 1"
   2.657 +  "num_size (Neg a) = 1 + num_size a"
   2.658 +  "num_size (Add a b) = 1 + num_size a + num_size b"
   2.659 +  "num_size (Sub a b) = 3 + num_size a + num_size b"
   2.660 +  "num_size (CX c a) = 4 + num_size a"
   2.661 +  "num_size (Mul c a) = 1 + num_size a"
   2.662  
   2.663 -lemma lin_add_cst_corr: 
   2.664 -  assumes blin : "islintn(n0,b)"
   2.665 -  shows "I_intterm ats (lin_add (Cst a,b)) = (I_intterm ats (Add (Cst a) b))"
   2.666 -using blin
   2.667 -by (induct n0 b rule: islintn.induct) auto
   2.668 +consts Inum :: "int list \<Rightarrow> num \<Rightarrow> int"
   2.669 +primrec
   2.670 +  "Inum bs (C c) = c"
   2.671 +  "Inum bs (Bound n) = bs!n"
   2.672 +  "Inum bs (CX c a) = c * (bs!0) + (Inum bs a)"
   2.673 +  "Inum bs (Neg a) = -(Inum bs a)"
   2.674 +  "Inum bs (Add a b) = Inum bs a + Inum bs b"
   2.675 +  "Inum bs (Sub a b) = Inum bs a - Inum bs b"
   2.676 +  "Inum bs (Mul c a) = c* Inum bs a"
   2.677 +
   2.678 +datatype fm  = 
   2.679 +  T| F| Lt num| Le num| Gt num| Ge num| Eq num| NEq num| Dvd int num| NDvd int num|
   2.680 +  NOT fm| And fm fm|  Or fm fm| Imp fm fm| Iff fm fm| E fm| A fm 
   2.681 +  | Closed nat | NClosed nat
   2.682 +
   2.683 +
   2.684 +  (* A size for fm *)
   2.685 +consts fmsize :: "fm \<Rightarrow> nat"
   2.686 +recdef fmsize "measure size"
   2.687 +  "fmsize (NOT p) = 1 + fmsize p"
   2.688 +  "fmsize (And p q) = 1 + fmsize p + fmsize q"
   2.689 +  "fmsize (Or p q) = 1 + fmsize p + fmsize q"
   2.690 +  "fmsize (Imp p q) = 3 + fmsize p + fmsize q"
   2.691 +  "fmsize (Iff p q) = 3 + 2*(fmsize p + fmsize q)"
   2.692 +  "fmsize (E p) = 1 + fmsize p"
   2.693 +  "fmsize (A p) = 4+ fmsize p"
   2.694 +  "fmsize (Dvd i t) = 2"
   2.695 +  "fmsize (NDvd i t) = 2"
   2.696 +  "fmsize p = 1"
   2.697 +  (* several lemmas about fmsize *)
   2.698 +lemma fmsize_pos: "fmsize p > 0"	
   2.699 +by (induct p rule: fmsize.induct) simp_all
   2.700  
   2.701 -lemma lin_add_cst_corr2: 
   2.702 -  assumes blin : "islintn(n0,b)"
   2.703 -  shows "I_intterm ats (lin_add (b,Cst a)) = (I_intterm ats (Add b (Cst a)))"
   2.704 -using blin
   2.705 -by (induct n0 b rule: islintn.induct) auto
   2.706 +  (* Semantics of formulae (fm) *)
   2.707 +consts Ifm ::"bool list \<Rightarrow> int list \<Rightarrow> fm \<Rightarrow> bool"
   2.708 +primrec
   2.709 +  "Ifm bbs bs T = True"
   2.710 +  "Ifm bbs bs F = False"
   2.711 +  "Ifm bbs bs (Lt a) = (Inum bs a < 0)"
   2.712 +  "Ifm bbs bs (Gt a) = (Inum bs a > 0)"
   2.713 +  "Ifm bbs bs (Le a) = (Inum bs a \<le> 0)"
   2.714 +  "Ifm bbs bs (Ge a) = (Inum bs a \<ge> 0)"
   2.715 +  "Ifm bbs bs (Eq a) = (Inum bs a = 0)"
   2.716 +  "Ifm bbs bs (NEq a) = (Inum bs a \<noteq> 0)"
   2.717 +  "Ifm bbs bs (Dvd i b) = (i dvd Inum bs b)"
   2.718 +  "Ifm bbs bs (NDvd i b) = (\<not>(i dvd Inum bs b))"
   2.719 +  "Ifm bbs bs (NOT p) = (\<not> (Ifm bbs bs p))"
   2.720 +  "Ifm bbs bs (And p q) = (Ifm bbs bs p \<and> Ifm bbs bs q)"
   2.721 +  "Ifm bbs bs (Or p q) = (Ifm bbs bs p \<or> Ifm bbs bs q)"
   2.722 +  "Ifm bbs bs (Imp p q) = ((Ifm bbs bs p) \<longrightarrow> (Ifm bbs bs q))"
   2.723 +  "Ifm bbs bs (Iff p q) = (Ifm bbs bs p = Ifm bbs bs q)"
   2.724 +  "Ifm bbs bs (E p) = (\<exists> x. Ifm bbs (x#bs) p)"
   2.725 +  "Ifm bbs bs (A p) = (\<forall> x. Ifm bbs (x#bs) p)"
   2.726 +  "Ifm bbs bs (Closed n) = bbs!n"
   2.727 +  "Ifm bbs bs (NClosed n) = (\<not> bbs!n)"
   2.728 +
   2.729 +lemma "Ifm bbs [] (A(Imp (Gt (Sub (Bound 0) (C 8))) (E(E(Eq(Sub(Add (Mul 3 (Bound 0)) (Mul 5 (Bound 1))) (Bound 2))))))) = P"
   2.730 +apply simp
   2.731 +oops
   2.732  
   2.733 -lemma lin_add_corrh: "\<And> n01 n02. \<lbrakk> islintn (n01,a) ; islintn (n02,b)\<rbrakk> 
   2.734 -  \<Longrightarrow> I_intterm ats (lin_add(a,b)) = I_intterm ats (Add a b)"
   2.735 -proof(induct a b rule: lin_add.induct)
   2.736 -  case (58 i n r j m s) 
   2.737 -  have "(n = m \<and> i+j = 0) \<or> (n = m \<and> i+j \<noteq> 0) \<or> n < m \<or> m < n " by arith
   2.738 -  moreover
   2.739 -  {assume "n=m\<and>i+j=0" hence ?case using prems by (auto simp add: sym[OF zadd_zmult_distrib]) }
   2.740 -  moreover
   2.741 -  {assume "n=m\<and>i+j\<noteq>0" hence ?case using prems by (auto simp add: Let_def zadd_zmult_distrib)}
   2.742 -  moreover
   2.743 -  {assume "n < m" hence ?case using prems by auto }
   2.744 -  moreover
   2.745 -  {assume "n > m" hence ?case using prems by auto }
   2.746 -  ultimately show ?case by blast
   2.747 -qed (auto simp add: lin_add_cst_corr lin_add_cst_corr2 Let_def)
   2.748 +consts prep :: "fm \<Rightarrow> fm"
   2.749 +recdef prep "measure fmsize"
   2.750 +  "prep (E T) = T"
   2.751 +  "prep (E F) = F"
   2.752 +  "prep (E (Or p q)) = Or (prep (E p)) (prep (E q))"
   2.753 +  "prep (E (Imp p q)) = Or (prep (E (NOT p))) (prep (E q))"
   2.754 +  "prep (E (Iff p q)) = Or (prep (E (And p q))) (prep (E (And (NOT p) (NOT q))))" 
   2.755 +  "prep (E (NOT (And p q))) = Or (prep (E (NOT p))) (prep (E(NOT q)))"
   2.756 +  "prep (E (NOT (Imp p q))) = prep (E (And p (NOT q)))"
   2.757 +  "prep (E (NOT (Iff p q))) = Or (prep (E (And p (NOT q)))) (prep (E(And (NOT p) q)))"
   2.758 +  "prep (E p) = E (prep p)"
   2.759 +  "prep (A (And p q)) = And (prep (A p)) (prep (A q))"
   2.760 +  "prep (A p) = prep (NOT (E (NOT p)))"
   2.761 +  "prep (NOT (NOT p)) = prep p"
   2.762 +  "prep (NOT (And p q)) = Or (prep (NOT p)) (prep (NOT q))"
   2.763 +  "prep (NOT (A p)) = prep (E (NOT p))"
   2.764 +  "prep (NOT (Or p q)) = And (prep (NOT p)) (prep (NOT q))"
   2.765 +  "prep (NOT (Imp p q)) = And (prep p) (prep (NOT q))"
   2.766 +  "prep (NOT (Iff p q)) = Or (prep (And p (NOT q))) (prep (And (NOT p) q))"
   2.767 +  "prep (NOT p) = NOT (prep p)"
   2.768 +  "prep (Or p q) = Or (prep p) (prep q)"
   2.769 +  "prep (And p q) = And (prep p) (prep q)"
   2.770 +  "prep (Imp p q) = prep (Or (NOT p) q)"
   2.771 +  "prep (Iff p q) = Or (prep (And p q)) (prep (And (NOT p) (NOT q)))"
   2.772 +  "prep p = p"
   2.773 +(hints simp add: fmsize_pos)
   2.774 +lemma prep: "Ifm bbs bs (prep p) = Ifm bbs bs p"
   2.775 +by (induct p arbitrary: bs rule: prep.induct, auto)
   2.776 +
   2.777  
   2.778 -(* lin_add has the semantics of Add*)
   2.779 -lemma lin_add_corr:
   2.780 -  assumes lina: "islinintterm a"
   2.781 -  and linb: "islinintterm b"
   2.782 -  shows "I_intterm ats (lin_add (a,b)) = (I_intterm ats (Add a b))"
   2.783 -using lina linb islinintterm_eq_islint islint_def lin_add_corrh
   2.784 -by blast
   2.785 +  (* Quantifier freeness *)
   2.786 +consts qfree:: "fm \<Rightarrow> bool"
   2.787 +recdef qfree "measure size"
   2.788 +  "qfree (E p) = False"
   2.789 +  "qfree (A p) = False"
   2.790 +  "qfree (NOT p) = qfree p" 
   2.791 +  "qfree (And p q) = (qfree p \<and> qfree q)" 
   2.792 +  "qfree (Or  p q) = (qfree p \<and> qfree q)" 
   2.793 +  "qfree (Imp p q) = (qfree p \<and> qfree q)" 
   2.794 +  "qfree (Iff p q) = (qfree p \<and> qfree q)"
   2.795 +  "qfree p = True"
   2.796 +
   2.797 +  (* Boundedness and substitution *)
   2.798 +consts 
   2.799 +  numbound0:: "num \<Rightarrow> bool" (* a num is INDEPENDENT of Bound 0 *)
   2.800 +  bound0:: "fm \<Rightarrow> bool" (* A Formula is independent of Bound 0 *)
   2.801 +  numsubst0:: "num \<Rightarrow> num \<Rightarrow> num" (* substitute a num into a num for Bound 0 *)
   2.802 +  subst0:: "num \<Rightarrow> fm \<Rightarrow> fm" (* substitue a num into a formula for Bound 0 *)
   2.803 +primrec
   2.804 +  "numbound0 (C c) = True"
   2.805 +  "numbound0 (Bound n) = (n>0)"
   2.806 +  "numbound0 (CX i a) = False"
   2.807 +  "numbound0 (Neg a) = numbound0 a"
   2.808 +  "numbound0 (Add a b) = (numbound0 a \<and> numbound0 b)"
   2.809 +  "numbound0 (Sub a b) = (numbound0 a \<and> numbound0 b)" 
   2.810 +  "numbound0 (Mul i a) = numbound0 a"
   2.811 +
   2.812 +lemma numbound0_I:
   2.813 +  assumes nb: "numbound0 a"
   2.814 +  shows "Inum (b#bs) a = Inum (b'#bs) a"
   2.815 +using nb
   2.816 +by (induct a rule: numbound0.induct) (auto simp add: nth_pos2)
   2.817  
   2.818 -lemma lin_add_cst_lint:
   2.819 -  assumes lin: "islintn (n0,b)"
   2.820 -  shows "islintn (n0, lin_add (Cst i, b))"
   2.821 -using lin
   2.822 -by (induct n0 b rule: islintn.induct) auto
   2.823 +primrec
   2.824 +  "bound0 T = True"
   2.825 +  "bound0 F = True"
   2.826 +  "bound0 (Lt a) = numbound0 a"
   2.827 +  "bound0 (Le a) = numbound0 a"
   2.828 +  "bound0 (Gt a) = numbound0 a"
   2.829 +  "bound0 (Ge a) = numbound0 a"
   2.830 +  "bound0 (Eq a) = numbound0 a"
   2.831 +  "bound0 (NEq a) = numbound0 a"
   2.832 +  "bound0 (Dvd i a) = numbound0 a"
   2.833 +  "bound0 (NDvd i a) = numbound0 a"
   2.834 +  "bound0 (NOT p) = bound0 p"
   2.835 +  "bound0 (And p q) = (bound0 p \<and> bound0 q)"
   2.836 +  "bound0 (Or p q) = (bound0 p \<and> bound0 q)"
   2.837 +  "bound0 (Imp p q) = ((bound0 p) \<and> (bound0 q))"
   2.838 +  "bound0 (Iff p q) = (bound0 p \<and> bound0 q)"
   2.839 +  "bound0 (E p) = False"
   2.840 +  "bound0 (A p) = False"
   2.841 +  "bound0 (Closed P) = True"
   2.842 +  "bound0 (NClosed P) = True"
   2.843 +lemma bound0_I:
   2.844 +  assumes bp: "bound0 p"
   2.845 +  shows "Ifm bbs (b#bs) p = Ifm bbs (b'#bs) p"
   2.846 +using bp numbound0_I[where b="b" and bs="bs" and b'="b'"]
   2.847 +by (induct p rule: bound0.induct) (auto simp add: nth_pos2)
   2.848 +
   2.849 +primrec
   2.850 +  "numsubst0 t (C c) = (C c)"
   2.851 +  "numsubst0 t (Bound n) = (if n=0 then t else Bound n)"
   2.852 +  "numsubst0 t (CX i a) = Add (Mul i t) (numsubst0 t a)"
   2.853 +  "numsubst0 t (Neg a) = Neg (numsubst0 t a)"
   2.854 +  "numsubst0 t (Add a b) = Add (numsubst0 t a) (numsubst0 t b)"
   2.855 +  "numsubst0 t (Sub a b) = Sub (numsubst0 t a) (numsubst0 t b)" 
   2.856 +  "numsubst0 t (Mul i a) = Mul i (numsubst0 t a)"
   2.857 +
   2.858 +lemma numsubst0_I:
   2.859 +  shows "Inum (b#bs) (numsubst0 a t) = Inum ((Inum (b#bs) a)#bs) t"
   2.860 +  by (induct t) (simp_all add: nth_pos2)
   2.861  
   2.862 -lemma lin_add_cst_lint2:
   2.863 -  assumes lin: "islintn (n0,b)"
   2.864 -  shows "islintn (n0, lin_add (b,Cst i))"
   2.865 -using lin
   2.866 -by (induct n0 b rule: islintn.induct) auto
   2.867 +lemma numsubst0_I':
   2.868 +  assumes nb: "numbound0 a"
   2.869 +  shows "Inum (b#bs) (numsubst0 a t) = Inum ((Inum (b'#bs) a)#bs) t"
   2.870 +  by (induct t) (simp_all add: nth_pos2 numbound0_I[OF nb, where b="b" and b'="b'"])
   2.871 +
   2.872 +
   2.873 +primrec
   2.874 +  "subst0 t T = T"
   2.875 +  "subst0 t F = F"
   2.876 +  "subst0 t (Lt a) = Lt (numsubst0 t a)"
   2.877 +  "subst0 t (Le a) = Le (numsubst0 t a)"
   2.878 +  "subst0 t (Gt a) = Gt (numsubst0 t a)"
   2.879 +  "subst0 t (Ge a) = Ge (numsubst0 t a)"
   2.880 +  "subst0 t (Eq a) = Eq (numsubst0 t a)"
   2.881 +  "subst0 t (NEq a) = NEq (numsubst0 t a)"
   2.882 +  "subst0 t (Dvd i a) = Dvd i (numsubst0 t a)"
   2.883 +  "subst0 t (NDvd i a) = NDvd i (numsubst0 t a)"
   2.884 +  "subst0 t (NOT p) = NOT (subst0 t p)"
   2.885 +  "subst0 t (And p q) = And (subst0 t p) (subst0 t q)"
   2.886 +  "subst0 t (Or p q) = Or (subst0 t p) (subst0 t q)"
   2.887 +  "subst0 t (Imp p q) = Imp (subst0 t p) (subst0 t q)"
   2.888 +  "subst0 t (Iff p q) = Iff (subst0 t p) (subst0 t q)"
   2.889 +  "subst0 t (Closed P) = (Closed P)"
   2.890 +  "subst0 t (NClosed P) = (NClosed P)"
   2.891 +
   2.892 +lemma subst0_I: assumes qfp: "qfree p"
   2.893 +  shows "Ifm bbs (b#bs) (subst0 a p) = Ifm bbs ((Inum (b#bs) a)#bs) p"
   2.894 +  using qfp numsubst0_I[where b="b" and bs="bs" and a="a"]
   2.895 +  by (induct p) (simp_all add: nth_pos2 )
   2.896 +
   2.897 +
   2.898 +consts 
   2.899 +  decrnum:: "num \<Rightarrow> num" 
   2.900 +  decr :: "fm \<Rightarrow> fm"
   2.901 +
   2.902 +recdef decrnum "measure size"
   2.903 +  "decrnum (Bound n) = Bound (n - 1)"
   2.904 +  "decrnum (Neg a) = Neg (decrnum a)"
   2.905 +  "decrnum (Add a b) = Add (decrnum a) (decrnum b)"
   2.906 +  "decrnum (Sub a b) = Sub (decrnum a) (decrnum b)"
   2.907 +  "decrnum (Mul c a) = Mul c (decrnum a)"
   2.908 +  "decrnum a = a"
   2.909  
   2.910 -(* lin_add preserves linearity..*)
   2.911 -lemma lin_add_lint: "\<And> n0 n01 n02. \<lbrakk> islintn (n01,a) ; islintn (n02,b); n0 \<le>  min n01 n02 \<rbrakk> 
   2.912 -  \<Longrightarrow> islintn (n0, lin_add (a,b))"
   2.913 -proof (induct a b rule: lin_add.induct)
   2.914 -  case (58 i n r j m s)
   2.915 -  have "(n =m \<and> i + j = 0) \<or> (n = m \<and> i+j \<noteq> 0) \<or> n <m \<or> m < n" by arith
   2.916 -  moreover 
   2.917 -  { assume "n = m"
   2.918 -      and  "i+j = 0"
   2.919 -    hence ?case using "58" islintn_mon[where m = "n01" and n = "Suc m"]
   2.920 -      islintn_mon[where m = "n02" and n = "Suc m"] by auto }
   2.921 -  moreover 
   2.922 -  { assume  "n = m"
   2.923 -      and "i+j \<noteq> 0"
   2.924 -    hence ?case using "58" islintn_mon[where m = "n01" and n = "Suc m"]
   2.925 -      islintn_mon[where m = "n02" and n = "Suc m"] by (auto simp add: Let_def) }
   2.926 -  moreover
   2.927 -  { assume "n < m" hence ?case using 58 by force }
   2.928 -moreover
   2.929 -  { assume "m < n"
   2.930 -    hence ?case using 58 
   2.931 -      apply (auto simp add: Let_def) 
   2.932 -      apply (erule allE[where x = "Suc m" ] )
   2.933 -      by (erule allE[where x = "Suc m" ] ) simp }
   2.934 -  ultimately show ?case by blast
   2.935 -qed(simp_all add: Let_def lin_add_cst_lint lin_add_cst_lint2)
   2.936 +recdef decr "measure size"
   2.937 +  "decr (Lt a) = Lt (decrnum a)"
   2.938 +  "decr (Le a) = Le (decrnum a)"
   2.939 +  "decr (Gt a) = Gt (decrnum a)"
   2.940 +  "decr (Ge a) = Ge (decrnum a)"
   2.941 +  "decr (Eq a) = Eq (decrnum a)"
   2.942 +  "decr (NEq a) = NEq (decrnum a)"
   2.943 +  "decr (Dvd i a) = Dvd i (decrnum a)"
   2.944 +  "decr (NDvd i a) = NDvd i (decrnum a)"
   2.945 +  "decr (NOT p) = NOT (decr p)" 
   2.946 +  "decr (And p q) = And (decr p) (decr q)"
   2.947 +  "decr (Or p q) = Or (decr p) (decr q)"
   2.948 +  "decr (Imp p q) = Imp (decr p) (decr q)"
   2.949 +  "decr (Iff p q) = Iff (decr p) (decr q)"
   2.950 +  "decr p = p"
   2.951 +
   2.952 +lemma decrnum: assumes nb: "numbound0 t"
   2.953 +  shows "Inum (x#bs) t = Inum bs (decrnum t)"
   2.954 +  using nb by (induct t rule: decrnum.induct, simp_all add: nth_pos2)
   2.955 +
   2.956 +lemma decr: assumes nb: "bound0 p"
   2.957 +  shows "Ifm bbs (x#bs) p = Ifm bbs bs (decr p)"
   2.958 +  using nb 
   2.959 +  by (induct p rule: decr.induct, simp_all add: nth_pos2 decrnum)
   2.960 +
   2.961 +lemma decr_qf: "bound0 p \<Longrightarrow> qfree (decr p)"
   2.962 +by (induct p, simp_all)
   2.963 +
   2.964 +consts 
   2.965 +  isatom :: "fm \<Rightarrow> bool" (* test for atomicity *)
   2.966 +recdef isatom "measure size"
   2.967 +  "isatom T = True"
   2.968 +  "isatom F = True"
   2.969 +  "isatom (Lt a) = True"
   2.970 +  "isatom (Le a) = True"
   2.971 +  "isatom (Gt a) = True"
   2.972 +  "isatom (Ge a) = True"
   2.973 +  "isatom (Eq a) = True"
   2.974 +  "isatom (NEq a) = True"
   2.975 +  "isatom (Dvd i b) = True"
   2.976 +  "isatom (NDvd i b) = True"
   2.977 +  "isatom (Closed P) = True"
   2.978 +  "isatom (NClosed P) = True"
   2.979 +  "isatom p = False"
   2.980  
   2.981 -lemma lin_add_lin:
   2.982 -  assumes lina: "islinintterm a"
   2.983 -  and linb: "islinintterm b"
   2.984 -  shows "islinintterm (lin_add (a,b))"
   2.985 -using islinintterm_eq_islint islint_def lin_add_lint lina linb by auto
   2.986 +lemma numsubst0_numbound0: assumes nb: "numbound0 t"
   2.987 +  shows "numbound0 (numsubst0 t a)"
   2.988 +using nb by (induct a rule: numsubst0.induct, auto)
   2.989 +
   2.990 +lemma subst0_bound0: assumes qf: "qfree p" and nb: "numbound0 t"
   2.991 +  shows "bound0 (subst0 t p)"
   2.992 +using qf numsubst0_numbound0[OF nb] by (induct p  rule: subst0.induct, auto)
   2.993 +
   2.994 +lemma bound0_qf: "bound0 p \<Longrightarrow> qfree p"
   2.995 +by (induct p, simp_all)
   2.996 +
   2.997 +
   2.998 +constdefs djf:: "('a \<Rightarrow> fm) \<Rightarrow> 'a \<Rightarrow> fm \<Rightarrow> fm"
   2.999 +  "djf f p q \<equiv> (if q=T then T else if q=F then f p else 
  2.1000 +  (let fp = f p in case fp of T \<Rightarrow> T | F \<Rightarrow> q | _ \<Rightarrow> Or (f p) q))"
  2.1001 +constdefs evaldjf:: "('a \<Rightarrow> fm) \<Rightarrow> 'a list \<Rightarrow> fm"
  2.1002 +  "evaldjf f ps \<equiv> foldr (djf f) ps F"
  2.1003 +
  2.1004 +lemma djf_Or: "Ifm bbs bs (djf f p q) = Ifm bbs bs (Or (f p) q)"
  2.1005 +by (cases "q=T", simp add: djf_def,cases "q=F",simp add: djf_def) 
  2.1006 +(cases "f p", simp_all add: Let_def djf_def) 
  2.1007 +
  2.1008 +lemma evaldjf_ex: "Ifm bbs bs (evaldjf f ps) = (\<exists> p \<in> set ps. Ifm bbs bs (f p))"
  2.1009 +  by(induct ps, simp_all add: evaldjf_def djf_Or)
  2.1010  
  2.1011 -(* lin_mul multiplies a linear term by a constant *)
  2.1012 -consts lin_mul :: "int \<times> intterm \<Rightarrow> intterm"
  2.1013 -recdef lin_mul "measure (\<lambda>(c,t). size t)"
  2.1014 -"lin_mul (c,Cst i) = (Cst (c*i))"
  2.1015 -"lin_mul (c,Add (Mult (Cst c') (Var n)) r)  = 
  2.1016 -  (if c = 0 then (Cst 0) else
  2.1017 -  (Add (Mult (Cst (c*c')) (Var n)) (lin_mul (c,r))))"
  2.1018 +lemma evaldjf_bound0: 
  2.1019 +  assumes nb: "\<forall> x\<in> set xs. bound0 (f x)"
  2.1020 +  shows "bound0 (evaldjf f xs)"
  2.1021 +  using nb by (induct xs, auto simp add: evaldjf_def djf_def Let_def) (case_tac "f a", auto) 
  2.1022 +
  2.1023 +lemma evaldjf_qf: 
  2.1024 +  assumes nb: "\<forall> x\<in> set xs. qfree (f x)"
  2.1025 +  shows "qfree (evaldjf f xs)"
  2.1026 +  using nb by (induct xs, auto simp add: evaldjf_def djf_def Let_def) (case_tac "f a", auto) 
  2.1027  
  2.1028 -lemma zmult_zadd_distrib[simp]: "(a::int) * (b+c) = a*b + a*c"
  2.1029 +consts disjuncts :: "fm \<Rightarrow> fm list"
  2.1030 +recdef disjuncts "measure size"
  2.1031 +  "disjuncts (Or p q) = (disjuncts p) @ (disjuncts q)"
  2.1032 +  "disjuncts F = []"
  2.1033 +  "disjuncts p = [p]"
  2.1034 +
  2.1035 +lemma disjuncts: "(\<exists> q\<in> set (disjuncts p). Ifm bbs bs q) = Ifm bbs bs p"
  2.1036 +by(induct p rule: disjuncts.induct, auto)
  2.1037 +
  2.1038 +lemma disjuncts_nb: "bound0 p \<Longrightarrow> \<forall> q\<in> set (disjuncts p). bound0 q"
  2.1039  proof-
  2.1040 -  have "a*(b+c) = (b+c)*a" by simp
  2.1041 -  moreover have "(b+c)*a = b*a + c*a" by (simp add: zadd_zmult_distrib)
  2.1042 -  ultimately show ?thesis by simp
  2.1043 +  assume nb: "bound0 p"
  2.1044 +  hence "list_all bound0 (disjuncts p)" by (induct p rule:disjuncts.induct,auto)
  2.1045 +  thus ?thesis by (simp only: list_all_iff)
  2.1046  qed
  2.1047  
  2.1048 -(* lin_mul has the semantics of Mult *)
  2.1049 -lemma lin_mul_corr: 
  2.1050 -  assumes lint: "islinintterm  t"
  2.1051 -  shows "I_intterm ats (lin_mul (c,t)) = I_intterm ats (Mult (Cst c) t)"
  2.1052 -using lint
  2.1053 -proof (induct c t rule: lin_mul.induct)
  2.1054 -  case (21 c c' n r)
  2.1055 -  have "islinintterm (Add (Mult (Cst c') (Var n)) r)" .
  2.1056 -  then have "islinintterm r" 
  2.1057 -    by (rule islinintterm_subt[of "c'" "n" "r"])
  2.1058 -  then show ?case  using "21.hyps" "21.prems" by simp
  2.1059 -qed(auto)
  2.1060 -
  2.1061 -(* lin_mul preserves linearity *)
  2.1062 -lemma lin_mul_lin:
  2.1063 -  assumes lint: "islinintterm t"
  2.1064 -  shows "islinintterm (lin_mul(c,t))"
  2.1065 -using lint
  2.1066 -by (induct t rule: islinintterm.induct) auto
  2.1067 -
  2.1068 -lemma lin_mul0:
  2.1069 -  assumes lint: "islinintterm t"
  2.1070 -  shows "lin_mul(0,t) = Cst 0"
  2.1071 -  using lint
  2.1072 -  by (induct t rule: islinintterm.induct) auto
  2.1073 -
  2.1074 -lemma lin_mul_lintn:
  2.1075 -  "\<And> m. islintn(m,t) \<Longrightarrow> islintn(m,lin_mul(l,t))"
  2.1076 -  by (induct l t rule: lin_mul.induct) simp_all
  2.1077 -
  2.1078 -(* lin_neg neagtes a linear term *)
  2.1079 -definition
  2.1080 -  lin_neg :: "intterm \<Rightarrow> intterm" where
  2.1081 -  "lin_neg i = lin_mul ((-1::int),i)"
  2.1082 -
  2.1083 -(* lin_neg has the semantics of Neg *)
  2.1084 -lemma lin_neg_corr:
  2.1085 -  assumes lint: "islinintterm  t"
  2.1086 -  shows "I_intterm ats (lin_neg t) = I_intterm ats (Neg t)"
  2.1087 -  using lint lin_mul_corr
  2.1088 -  by (simp add: lin_neg_def lin_mul_corr)
  2.1089 -
  2.1090 -(* lin_neg preserves linearity *)
  2.1091 -lemma lin_neg_lin:
  2.1092 -  assumes lint: "islinintterm  t"
  2.1093 -  shows "islinintterm (lin_neg t)"
  2.1094 -using lint
  2.1095 -by (simp add: lin_mul_lin lin_neg_def)
  2.1096 -
  2.1097 -(* Some properties about lin_add and lin-neg should be moved above *)
  2.1098 +lemma disjuncts_qf: "qfree p \<Longrightarrow> \<forall> q\<in> set (disjuncts p). qfree q"
  2.1099 +proof-
  2.1100 +  assume qf: "qfree p"
  2.1101 +  hence "list_all qfree (disjuncts p)"
  2.1102 +    by (induct p rule: disjuncts.induct, auto)
  2.1103 +  thus ?thesis by (simp only: list_all_iff)
  2.1104 +qed
  2.1105  
  2.1106 -lemma lin_neg_idemp: 
  2.1107 -  assumes lini: "islinintterm i"
  2.1108 -  shows "lin_neg (lin_neg i) = i"
  2.1109 -using lini
  2.1110 -by (induct i rule: islinintterm.induct) (auto simp add: lin_neg_def)
  2.1111 -
  2.1112 -lemma lin_neg_lin_add_distrib:
  2.1113 -  assumes lina : "islinintterm a"
  2.1114 -  and linb :"islinintterm b"
  2.1115 -  shows "lin_neg (lin_add(a,b)) = lin_add (lin_neg a, lin_neg b)"
  2.1116 -using lina linb
  2.1117 -proof (induct a b rule: lin_add.induct)
  2.1118 -  case (58 c1 n1 r1 c2 n2 r2)
  2.1119 -  from prems have lincnr1:"islinintterm (Add (Mult (Cst c1) (Var n1)) r1)" by simp
  2.1120 -  have linr1: "islinintterm r1" by (rule islinintterm_subt[OF lincnr1])
  2.1121 -  from prems have lincnr2: "islinintterm (Add (Mult (Cst c2) (Var n2)) r2)" by simp
  2.1122 -  have linr2: "islinintterm r2" by (rule islinintterm_subt[OF lincnr2])
  2.1123 -  have "n1 = n2 \<or> n1 < n2 \<or> n1 > n2" by arith
  2.1124 -  show ?case using prems linr1 linr2 by (simp_all add: lin_neg_def Let_def)
  2.1125 -next
  2.1126 -  case (59 c n r b) 
  2.1127 -  from prems have lincnr: "islinintterm (Add (Mult (Cst c) (Var n)) r)" by simp
  2.1128 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.1129 -  show ?case using prems linr by (simp add: lin_neg_def Let_def)
  2.1130 -next
  2.1131 -  case (60 b c n r)
  2.1132 -  from prems have lincnr: "islinintterm (Add (Mult (Cst c) (Var n)) r)" by simp
  2.1133 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.1134 -  show ?case  using prems linr by (simp add: lin_neg_def Let_def)
  2.1135 -qed (simp_all add: lin_neg_def)
  2.1136 -
  2.1137 -(* linearize tries to linearize a term *)
  2.1138 -consts linearize :: "intterm \<Rightarrow> intterm option"
  2.1139 -recdef linearize "measure (\<lambda>t. size t)"
  2.1140 -"linearize (Cst b) = Some (Cst b)"
  2.1141 -"linearize (Var n) = Some (Add (Mult (Cst 1) (Var n)) (Cst 0))"
  2.1142 -"linearize (Neg i) = lift_un lin_neg (linearize i)"
  2.1143 - "linearize (Add i j) = lift_bin(\<lambda> x. \<lambda> y. lin_add(x,y), linearize i, linearize j)"
  2.1144 -"linearize (Sub i j) = 
  2.1145 -  lift_bin(\<lambda> x. \<lambda> y. lin_add(x,lin_neg y), linearize i, linearize j)"
  2.1146 -"linearize (Mult i j) = 
  2.1147 -  (case linearize i of
  2.1148 -  None \<Rightarrow> None
  2.1149 -  | Some li \<Rightarrow> (case li of 
  2.1150 -     Cst b \<Rightarrow> (case linearize j of
  2.1151 -      None \<Rightarrow> None
  2.1152 -     | (Some lj) \<Rightarrow> Some (lin_mul(b,lj)))
  2.1153 -  | _ \<Rightarrow> (case linearize j of
  2.1154 -      None \<Rightarrow> None
  2.1155 -    | (Some lj) \<Rightarrow> (case lj of 
  2.1156 -        Cst b \<Rightarrow> Some (lin_mul (b,li))
  2.1157 -      | _ \<Rightarrow> None))))"
  2.1158 +constdefs DJ :: "(fm \<Rightarrow> fm) \<Rightarrow> fm \<Rightarrow> fm"
  2.1159 +  "DJ f p \<equiv> evaldjf f (disjuncts p)"
  2.1160  
  2.1161 -lemma linearize_linear1:
  2.1162 -  assumes lin: "linearize t \<noteq> None"
  2.1163 -  shows "islinintterm (the (linearize t))"
  2.1164 -using lin
  2.1165 -proof (induct t rule: linearize.induct)
  2.1166 -  case (1 b) show ?case by simp  
  2.1167 -next 
  2.1168 -  case (2 n) show ?case by simp 
  2.1169 -next 
  2.1170 -  case (3 i) show ?case 
  2.1171 -    proof-
  2.1172 -    have "(linearize i = None) \<or> (\<exists>li. linearize i = Some li)" by auto
  2.1173 -    moreover 
  2.1174 -    { assume "linearize i = None" with prems have ?thesis by auto}
  2.1175 -    moreover 
  2.1176 -    { assume lini: "\<exists>li. linearize i = Some li"
  2.1177 -      from lini obtain "li" where  "linearize i = Some li" by blast
  2.1178 -      have linli: "islinintterm li" by (simp!)
  2.1179 -      moreover have "linearize (Neg i) = Some (lin_neg li)" using prems by simp
  2.1180 -      moreover from linli have "islinintterm(lin_neg li)" by (simp add: lin_neg_lin)
  2.1181 -      ultimately have ?thesis by simp
  2.1182 -    }
  2.1183 -    ultimately show ?thesis by blast
  2.1184 -  qed
  2.1185 -next 
  2.1186 -  case (4 i j) show ?case 
  2.1187 -    proof-
  2.1188 -    have "(linearize i = None) \<or> ((\<exists> li. linearize i = Some li) \<and> linearize j = None) \<or> ((\<exists> li. linearize i = Some li) \<and> (\<exists> lj. linearize j = Some lj))" by auto 
  2.1189 -    moreover 
  2.1190 -    {
  2.1191 -      assume nlini: "linearize i = None"
  2.1192 -      from nlini have "linearize (Add i j) = None" 
  2.1193 -	by simp then have ?thesis using prems by auto}
  2.1194 -    moreover 
  2.1195 -    { assume nlinj: "linearize j = None"
  2.1196 -	and lini: "\<exists> li. linearize i = Some li"
  2.1197 -      from nlinj lini have "linearize (Add i j) = None"
  2.1198 -	by auto with prems have ?thesis by auto}
  2.1199 -    moreover 
  2.1200 -    { assume lini: "\<exists>li. linearize i = Some li"
  2.1201 -	and linj: "\<exists>lj. linearize j = Some lj"
  2.1202 -      from lini obtain "li" where  "linearize i = Some li" by blast
  2.1203 -      have linli: "islinintterm li" by (simp!)
  2.1204 -      from linj obtain "lj" where  "linearize j = Some lj" by blast
  2.1205 -      have linlj: "islinintterm lj" by (simp!)
  2.1206 -      moreover from lini linj have "linearize (Add i j) = Some (lin_add (li,lj))" 
  2.1207 -	by (auto!)
  2.1208 -      moreover from linli linlj have "islinintterm(lin_add (li,lj))" by (simp add: lin_add_lin)
  2.1209 -      ultimately have ?thesis by simp  }
  2.1210 -    ultimately show ?thesis by blast
  2.1211 -  qed
  2.1212 -next 
  2.1213 -  case (5 i j)show ?case 
  2.1214 -    proof-
  2.1215 -    have "(linearize i = None) \<or> ((\<exists> li. linearize i = Some li) \<and> linearize j = None) \<or> ((\<exists> li. linearize i = Some li) \<and> (\<exists> lj. linearize j = Some lj))" by auto 
  2.1216 -    moreover 
  2.1217 -    {
  2.1218 -      assume nlini: "linearize i = None"
  2.1219 -      from nlini have "linearize (Sub i j) = None" by simp then have ?thesis by (auto!)
  2.1220 -    }
  2.1221 -    moreover 
  2.1222 -    {
  2.1223 -      assume lini: "\<exists> li. linearize i = Some li"
  2.1224 -	and nlinj: "linearize j = None"
  2.1225 -      from nlinj lini have "linearize (Sub i j) = None" 
  2.1226 -	by auto then have ?thesis by (auto!)
  2.1227 -    }
  2.1228 -    moreover 
  2.1229 -    {
  2.1230 -      assume lini: "\<exists>li. linearize i = Some li"
  2.1231 -	and linj: "\<exists>lj. linearize j = Some lj"
  2.1232 -      from lini obtain "li" where  "linearize i = Some li" by blast
  2.1233 -      have linli: "islinintterm li" by (simp!)
  2.1234 -      from linj obtain "lj" where  "linearize j = Some lj" by blast
  2.1235 -      have linlj: "islinintterm lj" by (simp!)
  2.1236 -      moreover from lini linj have "linearize (Sub i j) = Some (lin_add (li,lin_neg lj))" 
  2.1237 -	by (auto!)
  2.1238 -      moreover from linli linlj have "islinintterm(lin_add (li,lin_neg lj))" by (simp add: lin_add_lin lin_neg_lin)
  2.1239 -      ultimately have ?thesis by simp
  2.1240 -    }
  2.1241 -    ultimately show ?thesis by blast
  2.1242 -  qed
  2.1243 -next
  2.1244 -  case (6 i j)show ?case 
  2.1245 -    proof-
  2.1246 -      have cses: "(linearize i = None) \<or> 
  2.1247 -	((\<exists> li. linearize i = Some li) \<and> linearize j = None) \<or> 
  2.1248 -	((\<exists> li. linearize i = Some li) \<and> (\<exists> bj. linearize j = Some (Cst bj)))
  2.1249 -	\<or> ((\<exists> bi. linearize i = Some (Cst bi)) \<and> (\<exists> lj. linearize j = Some lj))
  2.1250 -	\<or> ((\<exists> li. linearize i = Some li \<and> \<not> (\<exists> bi. li = Cst bi)) \<and> (\<exists> lj. linearize j = Some lj \<and> \<not> (\<exists> bj. lj = Cst bj)))" by auto 
  2.1251 -    moreover 
  2.1252 -    {
  2.1253 -      assume nlini: "linearize i = None"
  2.1254 -      from nlini have "linearize (Mult i j) = None" by (simp)
  2.1255 -      with prems have ?thesis by auto }
  2.1256 -    moreover 
  2.1257 -    {  assume lini: "\<exists> li. linearize i = Some li"
  2.1258 -	and nlinj: "linearize j = None"
  2.1259 -      from lini obtain "li" where "linearize i = Some li" by blast 
  2.1260 -      moreover from nlinj lini have "linearize (Mult i j) = None"
  2.1261 -	using prems
  2.1262 -	by (cases li) (auto)
  2.1263 -      with prems have ?thesis by auto}
  2.1264 -    moreover 
  2.1265 -    { assume lini: "\<exists>li. linearize i = Some li"
  2.1266 -	and linj: "\<exists>bj. linearize j = Some (Cst bj)"
  2.1267 -      from lini obtain "li" where  li_def: "linearize i = Some li" by blast
  2.1268 -      from prems have linli: "islinintterm li" by simp
  2.1269 -      moreover 
  2.1270 -      from linj  obtain "bj" where  bj_def: "linearize j = Some (Cst bj)" by blast
  2.1271 -      have linlj: "islinintterm (Cst bj)" by simp 
  2.1272 -      moreover from lini linj prems 
  2.1273 -      have "linearize (Mult i j) = Some (lin_mul (bj,li))"
  2.1274 -	by (cases li) auto
  2.1275 -      moreover from linli linlj have "islinintterm(lin_mul (bj,li))" by (simp add: lin_mul_lin)
  2.1276 -      ultimately have ?thesis by simp  }
  2.1277 -    moreover 
  2.1278 -    { assume lini: "\<exists>bi. linearize i = Some (Cst bi)"
  2.1279 -	and linj: "\<exists>lj. linearize j = Some lj"
  2.1280 -      from lini obtain "bi" where  "linearize i = Some (Cst bi)" by blast
  2.1281 -      from prems have linli: "islinintterm (Cst bi)" by simp
  2.1282 -      moreover 
  2.1283 -      from linj  obtain "lj" where  "linearize j = Some lj" by blast
  2.1284 -      from prems have linlj: "islinintterm lj" by simp
  2.1285 -      moreover from lini linj prems have "linearize (Mult i j) = Some (lin_mul (bi,lj))" 
  2.1286 -	by simp 
  2.1287 -      moreover from linli linlj have "islinintterm(lin_mul (bi,lj))" by (simp add: lin_mul_lin)
  2.1288 -      ultimately have ?thesis by simp }
  2.1289 -    moreover 
  2.1290 -    { assume linc: "\<exists> li. linearize i = Some li \<and> \<not> (\<exists> bi. li = Cst bi)"
  2.1291 -	and ljnc: "\<exists> lj. linearize j = Some lj \<and> \<not> (\<exists> bj. lj = Cst bj)"
  2.1292 -      from linc obtain "li" where "linearize i = Some li \<and> \<not> (\<exists> bi. li = Cst bi)" by blast
  2.1293 -      moreover 
  2.1294 -      from ljnc obtain "lj" where "linearize j = Some lj \<and> \<not> (\<exists> bj. lj = Cst bj)" by blast
  2.1295 -      ultimately have "linearize (Mult i j) = None"
  2.1296 -	by (cases li, auto) (cases lj, auto)+
  2.1297 -      with prems have ?thesis by simp }
  2.1298 -    ultimately show ?thesis by blast
  2.1299 -  qed
  2.1300 -qed  
  2.1301 +lemma DJ: assumes fdj: "\<forall> p q. f (Or p q) = Or (f p) (f q)"
  2.1302 +  and fF: "f F = F"
  2.1303 +  shows "Ifm bbs bs (DJ f p) = Ifm bbs bs (f p)"
  2.1304 +proof-
  2.1305 +  have "Ifm bbs bs (DJ f p) = (\<exists> q \<in> set (disjuncts p). Ifm bbs bs (f q))"
  2.1306 +    by (simp add: DJ_def evaldjf_ex) 
  2.1307 +  also have "\<dots> = Ifm bbs bs (f p)" using fdj fF by (induct p rule: disjuncts.induct, auto)
  2.1308 +  finally show ?thesis .
  2.1309 +qed
  2.1310  
  2.1311 -(* the result of linearize, when successful, is a linear term*)
  2.1312 -lemma linearize_linear: "\<And> t'. linearize t = Some t' \<Longrightarrow> islinintterm t'"
  2.1313 -proof-
  2.1314 -  fix t'
  2.1315 -  assume lint: "linearize t = Some t'"
  2.1316 -  from lint have lt: "linearize t \<noteq> None" by auto
  2.1317 -  then have "islinintterm (the (linearize t))" by (rule_tac  linearize_linear1[OF lt])
  2.1318 -  with lint show "islinintterm t'" by simp
  2.1319 +lemma DJ_qf: assumes 
  2.1320 +  fqf: "\<forall> p. qfree p \<longrightarrow> qfree (f p)"
  2.1321 +  shows "\<forall>p. qfree p \<longrightarrow> qfree (DJ f p) "
  2.1322 +proof(clarify)
  2.1323 +  fix  p assume qf: "qfree p"
  2.1324 +  have th: "DJ f p = evaldjf f (disjuncts p)" by (simp add: DJ_def)
  2.1325 +  from disjuncts_qf[OF qf] have "\<forall> q\<in> set (disjuncts p). qfree q" .
  2.1326 +  with fqf have th':"\<forall> q\<in> set (disjuncts p). qfree (f q)" by blast
  2.1327 +  
  2.1328 +  from evaldjf_qf[OF th'] th show "qfree (DJ f p)" by simp
  2.1329  qed
  2.1330  
  2.1331 -lemma linearize_corr1: 
  2.1332 -  assumes lin: "linearize t \<noteq> None"
  2.1333 -  shows "I_intterm ats t = I_intterm ats (the (linearize t))"
  2.1334 -using lin
  2.1335 -proof (induct t rule: linearize.induct)
  2.1336 -  case (3 i) show ?case 
  2.1337 -    proof-
  2.1338 -    have "(linearize i = None) \<or> (\<exists>li. linearize i = Some li)" by auto
  2.1339 -    moreover 
  2.1340 -    {
  2.1341 -      assume "linearize i = None"
  2.1342 -      have ?thesis using prems by simp
  2.1343 -    }
  2.1344 -    moreover 
  2.1345 -    {
  2.1346 -      assume lini: "\<exists>li. linearize i = Some li"
  2.1347 -      from lini have lini2: "linearize i \<noteq> None" by auto
  2.1348 -      from lini obtain "li" where  "linearize i = Some li" by blast
  2.1349 -      from lini2 lini have "islinintterm (the (linearize i))"
  2.1350 -	by (simp add: linearize_linear1[OF lini2])
  2.1351 -      then have linli: "islinintterm li" using prems by simp
  2.1352 -      have ieqli: "I_intterm ats i = I_intterm ats li" using prems by simp
  2.1353 -      moreover have "linearize (Neg i) = Some (lin_neg li)" using prems by simp
  2.1354 -      moreover from ieqli linli have "I_intterm ats (Neg i) = I_intterm ats (lin_neg li)" by (simp add: lin_neg_corr[OF linli])
  2.1355 -      ultimately have ?thesis using prems by (simp add: lin_neg_corr)
  2.1356 -    }
  2.1357 -    ultimately show ?thesis by blast
  2.1358 -  qed
  2.1359 -next 
  2.1360 -  case (4 i j) show ?case 
  2.1361 -    proof-
  2.1362 -    have "(linearize i = None) \<or> ((\<exists> li. linearize i = Some li) \<and> linearize j = None) \<or> ((\<exists> li. linearize i = Some li) \<and> (\<exists> lj. linearize j = Some lj))" by auto 
  2.1363 -    moreover 
  2.1364 -    {
  2.1365 -      assume nlini: "linearize i = None"
  2.1366 -      from nlini have "linearize (Add i j) = None" by simp then have ?thesis using prems by auto
  2.1367 -    }
  2.1368 -    moreover 
  2.1369 -    {
  2.1370 -      assume nlinj: "linearize j = None"
  2.1371 -	and lini: "\<exists> li. linearize i = Some li"
  2.1372 -      from nlinj lini have "linearize (Add i j) = None"	by auto 
  2.1373 -      then have ?thesis using prems by auto
  2.1374 -    }
  2.1375 -    moreover 
  2.1376 -    {
  2.1377 -      assume lini: "\<exists>li. linearize i = Some li"
  2.1378 -	and linj: "\<exists>lj. linearize j = Some lj"
  2.1379 -      from lini have lini2: "linearize i \<noteq> None" by auto
  2.1380 -      from linj have linj2: "linearize j \<noteq> None" by auto
  2.1381 -      from lini obtain "li" where  "linearize i = Some li" by blast
  2.1382 -      from lini2 have "islinintterm (the (linearize i))" by (simp add: linearize_linear1)
  2.1383 -      then have linli: "islinintterm li" using prems by simp
  2.1384 -      from linj obtain "lj" where  "linearize j = Some lj" by blast
  2.1385 -      from linj2 have "islinintterm (the (linearize j))" by (simp add: linearize_linear1)
  2.1386 -      then have linlj: "islinintterm lj" using prems by simp
  2.1387 -      moreover from lini linj have "linearize (Add i j) = Some (lin_add (li,lj))"
  2.1388 -	using prems by simp
  2.1389 -      moreover from linli linlj have "I_intterm ats (lin_add (li,lj)) = I_intterm ats (Add li lj)" by (simp add: lin_add_corr)
  2.1390 -      ultimately have ?thesis using prems by simp
  2.1391 -    }
  2.1392 -    ultimately show ?thesis by blast
  2.1393 -  qed
  2.1394 -next 
  2.1395 -  case (5 i j)show ?case 
  2.1396 -    proof-
  2.1397 -    have "(linearize i = None) \<or> ((\<exists> li. linearize i = Some li) \<and> linearize j = None) \<or> ((\<exists> li. linearize i = Some li) \<and> (\<exists> lj. linearize j = Some lj))" by auto 
  2.1398 -    moreover 
  2.1399 -    {
  2.1400 -      assume nlini: "linearize i = None"
  2.1401 -      from nlini have "linearize (Sub i j) = None" by simp then have ?thesis using prems by auto
  2.1402 -    }
  2.1403 -    moreover 
  2.1404 -    {
  2.1405 -      assume lini: "\<exists> li. linearize i = Some li"
  2.1406 -	and nlinj: "linearize j = None"
  2.1407 -      from nlinj lini have "linearize (Sub i j) = None" 
  2.1408 -	by auto with prems have ?thesis by auto
  2.1409 -    }
  2.1410 -    moreover 
  2.1411 -    {
  2.1412 -      assume lini: "\<exists>li. linearize i = Some li"
  2.1413 -	and linj: "\<exists>lj. linearize j = Some lj"
  2.1414 -      from lini have lini2: "linearize i \<noteq> None" by auto
  2.1415 -      from linj have linj2: "linearize j \<noteq> None" by auto
  2.1416 -      from lini obtain "li" where  "linearize i = Some li" by blast
  2.1417 -      from lini2 have "islinintterm (the (linearize i))" by (simp add: linearize_linear1)
  2.1418 -      with prems have linli: "islinintterm li" by simp
  2.1419 -      from linj obtain "lj" where  "linearize j = Some lj" by blast
  2.1420 -      from linj2 have "islinintterm (the (linearize j))" by (simp add: linearize_linear1)
  2.1421 -      with prems have linlj: "islinintterm lj" by simp
  2.1422 -      moreover from prems have "linearize (Sub i j) = Some (lin_add (li,lin_neg lj))" 
  2.1423 -	by simp
  2.1424 -      moreover from linlj have linnlj:"islinintterm (lin_neg lj)" by (simp add: lin_neg_lin)
  2.1425 -      moreover from linli linnlj have "I_intterm ats (lin_add (li,lin_neg lj)) = I_intterm ats (Add li (lin_neg lj))" by (simp only: lin_add_corr[OF linli linnlj])
  2.1426 -      moreover from linli linlj linnlj have "I_intterm ats (Add li (lin_neg lj)) = I_intterm ats (Sub li lj)" 
  2.1427 -	by (simp add: lin_neg_corr)
  2.1428 -      ultimately have ?thesis using prems by simp    
  2.1429 -    }
  2.1430 -    ultimately show ?thesis by blast
  2.1431 -  qed
  2.1432 +lemma DJ_qe: assumes qe: "\<forall> bs p. qfree p \<longrightarrow> qfree (qe p) \<and> (Ifm bbs bs (qe p) = Ifm bbs bs (E p))"
  2.1433 +  shows "\<forall> bs p. qfree p \<longrightarrow> qfree (DJ qe p) \<and> (Ifm bbs bs ((DJ qe p)) = Ifm bbs bs (E p))"
  2.1434 +proof(clarify)
  2.1435 +  fix p::fm and bs
  2.1436 +  assume qf: "qfree p"
  2.1437 +  from qe have qth: "\<forall> p. qfree p \<longrightarrow> qfree (qe p)" by blast
  2.1438 +  from DJ_qf[OF qth] qf have qfth:"qfree (DJ qe p)" by auto
  2.1439 +  have "Ifm bbs bs (DJ qe p) = (\<exists> q\<in> set (disjuncts p). Ifm bbs bs (qe q))"
  2.1440 +    by (simp add: DJ_def evaldjf_ex)
  2.1441 +  also have "\<dots> = (\<exists> q \<in> set(disjuncts p). Ifm bbs bs (E q))" using qe disjuncts_qf[OF qf] by auto
  2.1442 +  also have "\<dots> = Ifm bbs bs (E p)" by (induct p rule: disjuncts.induct, auto)
  2.1443 +  finally show "qfree (DJ qe p) \<and> Ifm bbs bs (DJ qe p) = Ifm bbs bs (E p)" using qfth by blast
  2.1444 +qed
  2.1445 +  (* Simplification *)
  2.1446 +
  2.1447 +  (* Algebraic simplifications for nums *)
  2.1448 +consts bnds:: "num \<Rightarrow> nat list"
  2.1449 +  lex_ns:: "nat list \<times> nat list \<Rightarrow> bool"
  2.1450 +recdef bnds "measure size"
  2.1451 +  "bnds (Bound n) = [n]"
  2.1452 +  "bnds (CX c a) = 0#(bnds a)"
  2.1453 +  "bnds (Neg a) = bnds a"
  2.1454 +  "bnds (Add a b) = (bnds a)@(bnds b)"
  2.1455 +  "bnds (Sub a b) = (bnds a)@(bnds b)"
  2.1456 +  "bnds (Mul i a) = bnds a"
  2.1457 +  "bnds a = []"
  2.1458 +recdef lex_ns "measure (\<lambda> (xs,ys). length xs + length ys)"
  2.1459 +  "lex_ns ([], ms) = True"
  2.1460 +  "lex_ns (ns, []) = False"
  2.1461 +  "lex_ns (n#ns, m#ms) = (n<m \<or> ((n = m) \<and> lex_ns (ns,ms))) "
  2.1462 +constdefs lex_bnd :: "num \<Rightarrow> num \<Rightarrow> bool"
  2.1463 +  "lex_bnd t s \<equiv> lex_ns (bnds t, bnds s)"
  2.1464 +
  2.1465 +consts simpnum:: "num \<Rightarrow> num"
  2.1466 +  numadd:: "num \<times> num \<Rightarrow> num"
  2.1467 +  nummul:: "num \<Rightarrow> int \<Rightarrow> num"
  2.1468 +  numfloor:: "num \<Rightarrow> num"
  2.1469 +recdef numadd "measure (\<lambda> (t,s). size t + size s)"
  2.1470 +  "numadd (Add (Mul c1 (Bound n1)) r1,Add (Mul c2 (Bound n2)) r2) =
  2.1471 +  (if n1=n2 then 
  2.1472 +  (let c = c1 + c2
  2.1473 +  in (if c=0 then numadd(r1,r2) else Add (Mul c (Bound n1)) (numadd (r1,r2))))
  2.1474 +  else if n1 \<le> n2 then (Add (Mul c1 (Bound n1)) (numadd (r1,Add (Mul c2 (Bound n2)) r2))) 
  2.1475 +  else (Add (Mul c2 (Bound n2)) (numadd (Add (Mul c1 (Bound n1)) r1,r2))))"
  2.1476 +  "numadd (Add (Mul c1 (Bound n1)) r1,t) = Add (Mul c1 (Bound n1)) (numadd (r1, t))"  
  2.1477 +  "numadd (t,Add (Mul c2 (Bound n2)) r2) = Add (Mul c2 (Bound n2)) (numadd (t,r2))" 
  2.1478 +  "numadd (C b1, C b2) = C (b1+b2)"
  2.1479 +  "numadd (a,b) = Add a b"
  2.1480 +
  2.1481 +lemma numadd: "Inum bs (numadd (t,s)) = Inum bs (Add t s)"
  2.1482 +apply (induct t s rule: numadd.induct, simp_all add: Let_def)
  2.1483 +apply (case_tac "c1+c2 = 0",case_tac "n1 \<le> n2", simp_all)
  2.1484 +by (case_tac "n1 = n2", simp_all add: ring_eq_simps)
  2.1485 +(simp add: ring_eq_simps(1)[symmetric]) 
  2.1486 +
  2.1487 +lemma numadd_nb: "\<lbrakk> numbound0 t ; numbound0 s\<rbrakk> \<Longrightarrow> numbound0 (numadd (t,s))"
  2.1488 +by (induct t s rule: numadd.induct, auto simp add: Let_def)
  2.1489 +
  2.1490 +recdef nummul "measure size"
  2.1491 +  "nummul (C j) = (\<lambda> i. C (i*j))"
  2.1492 +  "nummul (Add a b) = (\<lambda> i. numadd (nummul a i, nummul b i))"
  2.1493 +  "nummul (Mul c t) = (\<lambda> i. nummul t (i*c))"
  2.1494 +  "nummul t = (\<lambda> i. Mul i t)"
  2.1495 +
  2.1496 +lemma nummul: "\<And> i. Inum bs (nummul t i) = Inum bs (Mul i t)"
  2.1497 +by (induct t rule: nummul.induct, auto simp add: ring_eq_simps numadd)
  2.1498 +
  2.1499 +lemma nummul_nb: "\<And> i. numbound0 t \<Longrightarrow> numbound0 (nummul t i)"
  2.1500 +by (induct t rule: nummul.induct, auto simp add: numadd_nb)
  2.1501 +
  2.1502 +constdefs numneg :: "num \<Rightarrow> num"
  2.1503 +  "numneg t \<equiv> nummul t (- 1)"
  2.1504 +
  2.1505 +constdefs numsub :: "num \<Rightarrow> num \<Rightarrow> num"
  2.1506 +  "numsub s t \<equiv> (if s = t then C 0 else numadd (s,numneg t))"
  2.1507 +
  2.1508 +lemma numneg: "Inum bs (numneg t) = Inum bs (Neg t)"
  2.1509 +using numneg_def nummul by simp
  2.1510 +
  2.1511 +lemma numneg_nb: "numbound0 t \<Longrightarrow> numbound0 (numneg t)"
  2.1512 +using numneg_def nummul_nb by simp
  2.1513 +
  2.1514 +lemma numsub: "Inum bs (numsub a b) = Inum bs (Sub a b)"
  2.1515 +using numneg numadd numsub_def by simp
  2.1516 +
  2.1517 +lemma numsub_nb: "\<lbrakk> numbound0 t ; numbound0 s\<rbrakk> \<Longrightarrow> numbound0 (numsub t s)"
  2.1518 +using numsub_def numadd_nb numneg_nb by simp
  2.1519 +
  2.1520 +recdef simpnum "measure size"
  2.1521 +  "simpnum (C j) = C j"
  2.1522 +  "simpnum (Bound n) = Add (Mul 1 (Bound n)) (C 0)"
  2.1523 +  "simpnum (Neg t) = numneg (simpnum t)"
  2.1524 +  "simpnum (Add t s) = numadd (simpnum t,simpnum s)"
  2.1525 +  "simpnum (Sub t s) = numsub (simpnum t) (simpnum s)"
  2.1526 +  "simpnum (Mul i t) = (if i = 0 then (C 0) else nummul (simpnum t) i)"
  2.1527 +  "simpnum t = t"
  2.1528 +
  2.1529 +lemma simpnum_ci: "Inum bs (simpnum t) = Inum bs t"
  2.1530 +by (induct t rule: simpnum.induct, auto simp add: numneg numadd numsub nummul)
  2.1531 +
  2.1532 +lemma simpnum_numbound0: 
  2.1533 +  "numbound0 t \<Longrightarrow> numbound0 (simpnum t)"
  2.1534 +by (induct t rule: simpnum.induct, auto simp add: numadd_nb numsub_nb nummul_nb numneg_nb)
  2.1535 +
  2.1536 +consts not:: "fm \<Rightarrow> fm"
  2.1537 +recdef not "measure size"
  2.1538 +  "not (NOT p) = p"
  2.1539 +  "not T = F"
  2.1540 +  "not F = T"
  2.1541 +  "not p = NOT p"
  2.1542 +lemma not: "Ifm bbs bs (not p) = Ifm bbs bs (NOT p)"
  2.1543 +by (cases p) auto
  2.1544 +lemma not_qf: "qfree p \<Longrightarrow> qfree (not p)"
  2.1545 +by (cases p, auto)
  2.1546 +lemma not_bn: "bound0 p \<Longrightarrow> bound0 (not p)"
  2.1547 +by (cases p, auto)
  2.1548 +
  2.1549 +constdefs conj :: "fm \<Rightarrow> fm \<Rightarrow> fm"
  2.1550 +  "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 And p q)"
  2.1551 +lemma conj: "Ifm bbs bs (conj p q) = Ifm bbs bs (And p q)"
  2.1552 +by (cases "p=F \<or> q=F",simp_all add: conj_def) (cases p,simp_all)
  2.1553 +
  2.1554 +lemma conj_qf: "\<lbrakk>qfree p ; qfree q\<rbrakk> \<Longrightarrow> qfree (conj p q)"
  2.1555 +using conj_def by auto 
  2.1556 +lemma conj_nb: "\<lbrakk>bound0 p ; bound0 q\<rbrakk> \<Longrightarrow> bound0 (conj p q)"
  2.1557 +using conj_def by auto 
  2.1558 +
  2.1559 +constdefs disj :: "fm \<Rightarrow> fm \<Rightarrow> fm"
  2.1560 +  "disj p q \<equiv> (if (p = T \<or> q=T) then T else if p=F then q else if q=F then p else Or p q)"
  2.1561 +
  2.1562 +lemma disj: "Ifm bbs bs (disj p q) = Ifm bbs bs (Or p q)"
  2.1563 +by (cases "p=T \<or> q=T",simp_all add: disj_def) (cases p,simp_all)
  2.1564 +lemma disj_qf: "\<lbrakk>qfree p ; qfree q\<rbrakk> \<Longrightarrow> qfree (disj p q)"
  2.1565 +using disj_def by auto 
  2.1566 +lemma disj_nb: "\<lbrakk>bound0 p ; bound0 q\<rbrakk> \<Longrightarrow> bound0 (disj p q)"
  2.1567 +using disj_def by auto 
  2.1568 +
  2.1569 +constdefs   imp :: "fm \<Rightarrow> fm \<Rightarrow> fm"
  2.1570 +  "imp p q \<equiv> (if (p = F \<or> q=T) then T else if p=T then q else if q=F then not p else Imp p q)"
  2.1571 +lemma imp: "Ifm bbs bs (imp p q) = Ifm bbs bs (Imp p q)"
  2.1572 +by (cases "p=F \<or> q=T",simp_all add: imp_def,cases p) (simp_all add: not)
  2.1573 +lemma imp_qf: "\<lbrakk>qfree p ; qfree q\<rbrakk> \<Longrightarrow> qfree (imp p q)"
  2.1574 +using imp_def by (cases "p=F \<or> q=T",simp_all add: imp_def,cases p) (simp_all add: not_qf) 
  2.1575 +lemma imp_nb: "\<lbrakk>bound0 p ; bound0 q\<rbrakk> \<Longrightarrow> bound0 (imp p q)"
  2.1576 +using imp_def by (cases "p=F \<or> q=T",simp_all add: imp_def,cases p) simp_all
  2.1577 +
  2.1578 +constdefs   iff :: "fm \<Rightarrow> fm \<Rightarrow> fm"
  2.1579 +  "iff p q \<equiv> (if (p = q) then T else if (p = not q \<or> not p = q) then F else 
  2.1580 +       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 
  2.1581 +  Iff p q)"
  2.1582 +lemma iff: "Ifm bbs bs (iff p q) = Ifm bbs bs (Iff p q)"
  2.1583 +  by (unfold iff_def,cases "p=q", simp,cases "p=not q", simp add:not) 
  2.1584 +(cases "not p= q", auto simp add:not)
  2.1585 +lemma iff_qf: "\<lbrakk>qfree p ; qfree q\<rbrakk> \<Longrightarrow> qfree (iff p q)"
  2.1586 +  by (unfold iff_def,cases "p=q", auto simp add: not_qf)
  2.1587 +lemma iff_nb: "\<lbrakk>bound0 p ; bound0 q\<rbrakk> \<Longrightarrow> bound0 (iff p q)"
  2.1588 +using iff_def by (unfold iff_def,cases "p=q", auto simp add: not_bn)
  2.1589 +
  2.1590 +consts simpfm :: "fm \<Rightarrow> fm"
  2.1591 +recdef simpfm "measure fmsize"
  2.1592 +  "simpfm (And p q) = conj (simpfm p) (simpfm q)"
  2.1593 +  "simpfm (Or p q) = disj (simpfm p) (simpfm q)"
  2.1594 +  "simpfm (Imp p q) = imp (simpfm p) (simpfm q)"
  2.1595 +  "simpfm (Iff p q) = iff (simpfm p) (simpfm q)"
  2.1596 +  "simpfm (NOT p) = not (simpfm p)"
  2.1597 +  "simpfm (Lt a) = (let a' = simpnum a in case a' of C v \<Rightarrow> if (v < 0) then T else F 
  2.1598 +  | _ \<Rightarrow> Lt a')"
  2.1599 +  "simpfm (Le a) = (let a' = simpnum a in case a' of C v \<Rightarrow> if (v \<le> 0)  then T else F | _ \<Rightarrow> Le a')"
  2.1600 +  "simpfm (Gt a) = (let a' = simpnum a in case a' of C v \<Rightarrow> if (v > 0)  then T else F | _ \<Rightarrow> Gt a')"
  2.1601 +  "simpfm (Ge a) = (let a' = simpnum a in case a' of C v \<Rightarrow> if (v \<ge> 0)  then T else F | _ \<Rightarrow> Ge a')"
  2.1602 +  "simpfm (Eq a) = (let a' = simpnum a in case a' of C v \<Rightarrow> if (v = 0)  then T else F | _ \<Rightarrow> Eq a')"
  2.1603 +  "simpfm (NEq a) = (let a' = simpnum a in case a' of C v \<Rightarrow> if (v \<noteq> 0)  then T else F | _ \<Rightarrow> NEq a')"
  2.1604 +  "simpfm (Dvd i a) = (if i=0 then simpfm (Eq a)
  2.1605 +             else if (abs i = 1) then T
  2.1606 +             else let a' = simpnum a in case a' of C v \<Rightarrow> if (i dvd v)  then T else F | _ \<Rightarrow> Dvd i a')"
  2.1607 +  "simpfm (NDvd i a) = (if i=0 then simpfm (NEq a) 
  2.1608 +             else if (abs i = 1) then F
  2.1609 +             else let a' = simpnum a in case a' of C v \<Rightarrow> if (\<not>(i dvd v)) then T else F | _ \<Rightarrow> NDvd i a')"
  2.1610 +  "simpfm p = p"
  2.1611 +lemma simpfm: "Ifm bbs bs (simpfm p) = Ifm bbs bs p"
  2.1612 +proof(induct p rule: simpfm.induct)
  2.1613 +  case (6 a) let ?sa = "simpnum a" from simpnum_ci have sa: "Inum bs ?sa = Inum bs a" by simp
  2.1614 +  {fix v assume "?sa = C v" hence ?case using sa by simp }
  2.1615 +  moreover {assume "\<not> (\<exists> v. ?sa = C v)" hence ?case using sa 
  2.1616 +      by (cases ?sa, simp_all add: Let_def)}
  2.1617 +  ultimately show ?case by blast
  2.1618  next
  2.1619 -  case (6 i j)show ?case 
  2.1620 -    proof-
  2.1621 -      have cses: "(linearize i = None) \<or> 
  2.1622 -	((\<exists> li. linearize i = Some li) \<and> linearize j = None) \<or> 
  2.1623 -	((\<exists> li. linearize i = Some li) \<and> (\<exists> bj. linearize j = Some (Cst bj)))
  2.1624 -	\<or> ((\<exists> bi. linearize i = Some (Cst bi)) \<and> (\<exists> lj. linearize j = Some lj))
  2.1625 -	\<or> ((\<exists> li. linearize i = Some li \<and> \<not> (\<exists> bi. li = Cst bi)) \<and> (\<exists> lj. linearize j = Some lj \<and> \<not> (\<exists> bj. lj = Cst bj)))" by auto 
  2.1626 -    moreover 
  2.1627 -    {
  2.1628 -      assume nlini: "linearize i = None"
  2.1629 -      from nlini have "linearize (Mult i j) = None" by simp with prems  have ?thesis by auto
  2.1630 -    }
  2.1631 -    moreover 
  2.1632 -    {
  2.1633 -      assume lini: "\<exists> li. linearize i = Some li"
  2.1634 -	and nlinj: "linearize j = None"
  2.1635 +  case (7 a)  let ?sa = "simpnum a" 
  2.1636 +  from simpnum_ci have sa: "Inum bs ?sa = Inum bs a" by simp
  2.1637 +  {fix v assume "?sa = C v" hence ?case using sa by simp }
  2.1638 +  moreover {assume "\<not> (\<exists> v. ?sa = C v)" hence ?case using sa 
  2.1639 +      by (cases ?sa, simp_all add: Let_def)}
  2.1640 +  ultimately show ?case by blast
  2.1641 +next
  2.1642 +  case (8 a)  let ?sa = "simpnum a" 
  2.1643 +  from simpnum_ci have sa: "Inum bs ?sa = Inum bs a" by simp
  2.1644 +  {fix v assume "?sa = C v" hence ?case using sa by simp }
  2.1645 +  moreover {assume "\<not> (\<exists> v. ?sa = C v)" hence ?case using sa 
  2.1646 +      by (cases ?sa, simp_all add: Let_def)}
  2.1647 +  ultimately show ?case by blast
  2.1648 +next
  2.1649 +  case (9 a)  let ?sa = "simpnum a" 
  2.1650 +  from simpnum_ci have sa: "Inum bs ?sa = Inum bs a" by simp
  2.1651 +  {fix v assume "?sa = C v" hence ?case using sa by simp }
  2.1652 +  moreover {assume "\<not> (\<exists> v. ?sa = C v)" hence ?case using sa 
  2.1653 +      by (cases ?sa, simp_all add: Let_def)}
  2.1654 +  ultimately show ?case by blast
  2.1655 +next
  2.1656 +  case (10 a)  let ?sa = "simpnum a" 
  2.1657 +  from simpnum_ci have sa: "Inum bs ?sa = Inum bs a" by simp
  2.1658 +  {fix v assume "?sa = C v" hence ?case using sa by simp }
  2.1659 +  moreover {assume "\<not> (\<exists> v. ?sa = C v)" hence ?case using sa 
  2.1660 +      by (cases ?sa, simp_all add: Let_def)}
  2.1661 +  ultimately show ?case by blast
  2.1662 +next
  2.1663 +  case (11 a)  let ?sa = "simpnum a" 
  2.1664 +  from simpnum_ci have sa: "Inum bs ?sa = Inum bs a" by simp
  2.1665 +  {fix v assume "?sa = C v" hence ?case using sa by simp }
  2.1666 +  moreover {assume "\<not> (\<exists> v. ?sa = C v)" hence ?case using sa 
  2.1667 +      by (cases ?sa, simp_all add: Let_def)}
  2.1668 +  ultimately show ?case by blast
  2.1669 +next
  2.1670 +  case (12 i a)  let ?sa = "simpnum a" from simpnum_ci 
  2.1671 +  have sa: "Inum bs ?sa = Inum bs a" by simp
  2.1672 +  have "i=0 \<or> abs i = 1 \<or> (i\<noteq>0 \<and> (abs i \<noteq> 1))" by auto
  2.1673 +  {assume "i=0" hence ?case using "12.hyps" by (simp add: dvd_def Let_def)}
  2.1674 +  moreover 
  2.1675 +  {assume i1: "abs i = 1"
  2.1676 +      from zdvd_1_left[where m = "Inum bs a"] uminus_dvd_conv[where d="1" and t="Inum bs a"]
  2.1677 +      have ?case using i1 by (cases "i=0", simp_all add: Let_def) arith}
  2.1678 +  moreover   
  2.1679 +  {assume inz: "i\<noteq>0" and cond: "abs i \<noteq> 1"
  2.1680 +    {fix v assume "?sa = C v" hence ?case using sa[symmetric] inz cond
  2.1681 +	by (cases "abs i = 1", auto) }
  2.1682 +    moreover {assume "\<not> (\<exists> v. ?sa = C v)" 
  2.1683 +      hence "simpfm (Dvd i a) = Dvd i ?sa" using inz cond 
  2.1684 +	by (cases ?sa, auto simp add: Let_def)
  2.1685 +      hence ?case using sa by simp}
  2.1686 +    ultimately have ?case by blast}
  2.1687 +  ultimately show ?case by blast
  2.1688 +next
  2.1689 +  case (13 i a)  let ?sa = "simpnum a" from simpnum_ci 
  2.1690 +  have sa: "Inum bs ?sa = Inum bs a" by simp
  2.1691 +  have "i=0 \<or> abs i = 1 \<or> (i\<noteq>0 \<and> (abs i \<noteq> 1))" by auto
  2.1692 +  {assume "i=0" hence ?case using "13.hyps" by (simp add: dvd_def Let_def)}
  2.1693 +  moreover 
  2.1694 +  {assume i1: "abs i = 1"
  2.1695 +      from zdvd_1_left[where m = "Inum bs a"] uminus_dvd_conv[where d="1" and t="Inum bs a"]
  2.1696 +      have ?case using i1 by (cases "i=0", simp_all add: Let_def) arith}
  2.1697 +  moreover   
  2.1698 +  {assume inz: "i\<noteq>0" and cond: "abs i \<noteq> 1"
  2.1699 +    {fix v assume "?sa = C v" hence ?case using sa[symmetric] inz cond
  2.1700 +	by (cases "abs i = 1", auto) }
  2.1701 +    moreover {assume "\<not> (\<exists> v. ?sa = C v)" 
  2.1702 +      hence "simpfm (NDvd i a) = NDvd i ?sa" using inz cond 
  2.1703 +	by (cases ?sa, auto simp add: Let_def)
  2.1704 +      hence ?case using sa by simp}
  2.1705 +    ultimately have ?case by blast}
  2.1706 +  ultimately show ?case by blast
  2.1707 +qed (induct p rule: simpfm.induct, simp_all add: conj disj imp iff not)
  2.1708  
  2.1709 -      from lini obtain "li" where "linearize i = Some li" by blast 
  2.1710 -      moreover from prems have "linearize (Mult i j) = None" 
  2.1711 -	by (cases li) simp_all
  2.1712 -      with prems have ?thesis by auto
  2.1713 -    }
  2.1714 -    moreover 
  2.1715 -    {
  2.1716 -      assume lini: "\<exists>li. linearize i = Some li"
  2.1717 -	and linj: "\<exists>bj. linearize j = Some (Cst bj)"
  2.1718 -      from lini have lini2: "linearize i \<noteq> None" by auto
  2.1719 -      from linj have linj2: "linearize j \<noteq> None" by auto
  2.1720 -      from lini obtain "li" where  "linearize i = Some li" by blast
  2.1721 -      from lini2 have "islinintterm (the (linearize i))" by (simp add: linearize_linear1)
  2.1722 -      with prems  have linli: "islinintterm li" by simp
  2.1723 -      moreover 
  2.1724 -      from linj  obtain "bj" where  "linearize j = Some (Cst bj)" by blast
  2.1725 -      have linlj: "islinintterm (Cst bj)" by simp
  2.1726 -      moreover from prems have "linearize (Mult i j) = Some (lin_mul (bj,li))"
  2.1727 - 	by (cases li) auto
  2.1728 -      then have lm1: "I_intterm ats (the(linearize (Mult i j))) = I_intterm ats (lin_mul (bj,li))" by simp
  2.1729 -      moreover from linli linlj have "I_intterm ats (lin_mul(bj,li)) = I_intterm ats (Mult li (Cst bj))" by (simp add: lin_mul_corr)
  2.1730 -      with prems 
  2.1731 -      have "I_intterm ats (lin_mul(bj,li)) = I_intterm ats (Mult li (the (linearize j)))" 
  2.1732 -	by auto
  2.1733 -      moreover have "I_intterm ats (Mult li (the (linearize j))) = I_intterm ats (Mult i (the (linearize j)))" using prems  by simp
  2.1734 -      moreover have "I_intterm ats i = I_intterm ats (the (linearize i))"  
  2.1735 -	using lini2 lini "6.hyps" by simp
  2.1736 -	moreover have "I_intterm ats j = I_intterm ats (the (linearize j))"
  2.1737 -	  using prems by (cases li) auto
  2.1738 -      ultimately have ?thesis by auto }
  2.1739 -    moreover 
  2.1740 -    { assume lini: "\<exists>bi. linearize i = Some (Cst bi)"
  2.1741 -	and linj: "\<exists>lj. linearize j = Some lj"
  2.1742 -      from lini have lini2 : "linearize i \<noteq> None" by auto
  2.1743 -      from linj have linj2 : "linearize j \<noteq> None" by auto      
  2.1744 -      from lini obtain "bi" where  "linearize i = Some (Cst bi)" by blast
  2.1745 -      have linli: "islinintterm (Cst bi)" using prems by simp
  2.1746 -      moreover 
  2.1747 -      from linj  obtain "lj" where  "linearize j = Some lj" by blast
  2.1748 -      from linj2 have "islinintterm (the (linearize j))" by (simp add: linearize_linear1) 
  2.1749 -      then have linlj: "islinintterm lj" by (simp!)
  2.1750 -      moreover from linli lini linj have "linearize (Mult i j) = Some (lin_mul (bi,lj))"
  2.1751 -	by (case_tac "li::intterm",auto!)
  2.1752 -      then have lm1: "I_intterm ats (the(linearize (Mult i j))) = I_intterm ats (lin_mul (bi,lj))" by simp
  2.1753 -      moreover from linli linlj have "I_intterm ats (lin_mul(bi,lj)) = I_intterm ats (Mult (Cst bi) lj)" by (simp add: lin_mul_corr)
  2.1754 -      then have "I_intterm ats (lin_mul(bi,lj)) = I_intterm ats (Mult (the (linearize i)) lj)" by (auto!)
  2.1755 -      moreover have "I_intterm ats (Mult (the (linearize i)) lj) = I_intterm ats (Mult (the (linearize i)) j)" using lini lini2  by (simp!)
  2.1756 -      moreover have "I_intterm ats i = I_intterm ats (the (linearize i))"  
  2.1757 -	using lini2 lini "6.hyps" by simp
  2.1758 -	moreover have "I_intterm ats j = I_intterm ats (the (linearize j))"
  2.1759 -	  using linj linj2 lini lini2 linli linlj "6.hyps" by (auto!)
  2.1760 +lemma simpfm_bound0: "bound0 p \<Longrightarrow> bound0 (simpfm p)"
  2.1761 +proof(induct p rule: simpfm.induct)
  2.1762 +  case (6 a) hence nb: "numbound0 a" by simp
  2.1763 +  hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  2.1764 +  thus ?case by (cases "simpnum a", auto simp add: Let_def)
  2.1765 +next
  2.1766 +  case (7 a) hence nb: "numbound0 a" by simp
  2.1767 +  hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  2.1768 +  thus ?case by (cases "simpnum a", auto simp add: Let_def)
  2.1769 +next
  2.1770 +  case (8 a) hence nb: "numbound0 a" by simp
  2.1771 +  hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  2.1772 +  thus ?case by (cases "simpnum a", auto simp add: Let_def)
  2.1773 +next
  2.1774 +  case (9 a) hence nb: "numbound0 a" by simp
  2.1775 +  hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  2.1776 +  thus ?case by (cases "simpnum a", auto simp add: Let_def)
  2.1777 +next
  2.1778 +  case (10 a) hence nb: "numbound0 a" by simp
  2.1779 +  hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  2.1780 +  thus ?case by (cases "simpnum a", auto simp add: Let_def)
  2.1781 +next
  2.1782 +  case (11 a) hence nb: "numbound0 a" by simp
  2.1783 +  hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  2.1784 +  thus ?case by (cases "simpnum a", auto simp add: Let_def)
  2.1785 +next
  2.1786 +  case (12 i a) hence nb: "numbound0 a" by simp
  2.1787 +  hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  2.1788 +  thus ?case by (cases "simpnum a", auto simp add: Let_def)
  2.1789 +next
  2.1790 +  case (13 i a) hence nb: "numbound0 a" by simp
  2.1791 +  hence "numbound0 (simpnum a)" by (simp only: simpnum_numbound0[OF nb])
  2.1792 +  thus ?case by (cases "simpnum a", auto simp add: Let_def)
  2.1793 +qed(auto simp add: disj_def imp_def iff_def conj_def not_bn)
  2.1794  
  2.1795 -      ultimately have ?thesis by auto }
  2.1796 -    moreover 
  2.1797 -    { assume linc: "\<exists> li. linearize i = Some li \<and> \<not> (\<exists> bi. li = Cst bi)"
  2.1798 -	and ljnc: "\<exists> lj. linearize j = Some lj \<and> \<not> (\<exists> bj. lj = Cst bj)"
  2.1799 -      from linc obtain "li" where "\<exists> li. linearize i = Some li \<and> \<not> (\<exists> bi. li = Cst bi)" by blast
  2.1800 -      moreover 
  2.1801 -      from ljnc obtain "lj" where "\<exists> lj. linearize j = Some lj \<and> \<not> (\<exists> bj. lj = Cst bj)" by blast
  2.1802 -      ultimately have "linearize (Mult i j) = None"
  2.1803 -	apply simp
  2.1804 -	apply (case_tac "linearize i", auto)
  2.1805 -	apply (case_tac a)
  2.1806 -	apply (auto!)
  2.1807 -	by (case_tac "lj",auto)+
  2.1808 -      then have ?thesis by (simp!) }
  2.1809 -    ultimately show ?thesis by blast
  2.1810 -  qed
  2.1811 -qed  simp_all
  2.1812 +lemma simpfm_qf: "qfree p \<Longrightarrow> qfree (simpfm p)"
  2.1813 +by (induct p rule: simpfm.induct, auto simp add: disj_qf imp_qf iff_qf conj_qf not_qf Let_def)
  2.1814 + (case_tac "simpnum a",auto)+
  2.1815 +
  2.1816 +  (* Generic quantifier elimination *)
  2.1817 +consts qelim :: "fm \<Rightarrow> (fm \<Rightarrow> fm) \<Rightarrow> fm"
  2.1818 +recdef qelim "measure fmsize"
  2.1819 +  "qelim (E p) = (\<lambda> qe. DJ qe (qelim p qe))"
  2.1820 +  "qelim (A p) = (\<lambda> qe. not (qe ((qelim (NOT p) qe))))"
  2.1821 +  "qelim (NOT p) = (\<lambda> qe. not (qelim p qe))"
  2.1822 +  "qelim (And p q) = (\<lambda> qe. conj (qelim p qe) (qelim q qe))" 
  2.1823 +  "qelim (Or  p q) = (\<lambda> qe. disj (qelim p qe) (qelim q qe))" 
  2.1824 +  "qelim (Imp p q) = (\<lambda> qe. imp (qelim p qe) (qelim q qe))"
  2.1825 +  "qelim (Iff p q) = (\<lambda> qe. iff (qelim p qe) (qelim q qe))"
  2.1826 +  "qelim p = (\<lambda> y. simpfm p)"
  2.1827 +
  2.1828 +lemma qelim_ci:
  2.1829 +  assumes qe_inv: "\<forall> bs p. qfree p \<longrightarrow> qfree (qe p) \<and> (Ifm bbs bs (qe p) = Ifm bbs bs (E p))"
  2.1830 +  shows "\<And> bs. qfree (qelim p qe) \<and> (Ifm bbs bs (qelim p qe) = Ifm bbs bs p)"
  2.1831 +using qe_inv DJ_qe[OF qe_inv] 
  2.1832 +by(induct p rule: qelim.induct) 
  2.1833 +(auto simp add: not disj conj iff imp not_qf disj_qf conj_qf imp_qf iff_qf 
  2.1834 +  simpfm simpfm_qf simp del: simpfm.simps)
  2.1835  
  2.1836  
  2.1837 -(* linearize, when successful, preserves semantics *)
  2.1838 -lemma linearize_corr: "\<And> t'. linearize t = Some t' \<Longrightarrow> I_intterm ats t = I_intterm ats t' "
  2.1839 -proof-
  2.1840 -  fix t'
  2.1841 -  assume lint: "linearize t = Some t'"
  2.1842 -  show  "I_intterm ats t = I_intterm ats t'"
  2.1843 -  proof-
  2.1844 -    from lint have lt: "linearize t \<noteq> None" by simp 
  2.1845 -    then have "I_intterm ats t = I_intterm ats (the (linearize t))" 
  2.1846 -      by (rule_tac linearize_corr1[OF lt])
  2.1847 -    with lint show ?thesis by simp
  2.1848 -  qed
  2.1849 +
  2.1850 +    (**********************************************************************************)
  2.1851 +    (*******                             THE \<int>-PART                                 ***)
  2.1852 +    (**********************************************************************************)
  2.1853 +  (* Linearity for fm where Bound 0 ranges over \<int> *)
  2.1854 +consts
  2.1855 +  zsplit0 :: "num \<Rightarrow> int \<times> num" (* splits the bounded from the unbounded part*)
  2.1856 +recdef zsplit0 "measure size"
  2.1857 +  "zsplit0 (C c) = (0,C c)"
  2.1858 +  "zsplit0 (Bound n) = (if n=0 then (1, C 0) else (0,Bound n))"
  2.1859 +  "zsplit0 (CX i a) = (let (i',a') =  zsplit0 a in (i+i', a'))"
  2.1860 +  "zsplit0 (Neg a) = (let (i',a') =  zsplit0 a in (-i', Neg a'))"
  2.1861 +  "zsplit0 (Add a b) = (let (ia,a') =  zsplit0 a ; 
  2.1862 +                            (ib,b') =  zsplit0 b 
  2.1863 +                            in (ia+ib, Add a' b'))"
  2.1864 +  "zsplit0 (Sub a b) = (let (ia,a') =  zsplit0 a ; 
  2.1865 +                            (ib,b') =  zsplit0 b 
  2.1866 +                            in (ia-ib, Sub a' b'))"
  2.1867 +  "zsplit0 (Mul i a) = (let (i',a') =  zsplit0 a in (i*i', Mul i a'))"
  2.1868 +(hints simp add: Let_def)
  2.1869 +
  2.1870 +lemma zsplit0_I:
  2.1871 +  shows "\<And> n a. zsplit0 t = (n,a) \<Longrightarrow> (Inum ((x::int) #bs) (CX n a) = Inum (x #bs) t) \<and> numbound0 a"
  2.1872 +  (is "\<And> n a. ?S t = (n,a) \<Longrightarrow> (?I x (CX n a) = ?I x t) \<and> ?N a")
  2.1873 +proof(induct t rule: zsplit0.induct)
  2.1874 +  case (1 c n a) thus ?case by auto 
  2.1875 +next
  2.1876 +  case (2 m n a) thus ?case by (cases "m=0") auto
  2.1877 +next
  2.1878 +  case (3 i a n a')
  2.1879 +  let ?j = "fst (zsplit0 a)"
  2.1880 +  let ?b = "snd (zsplit0 a)"
  2.1881 +  have abj: "zsplit0 a = (?j,?b)" by simp hence th: "a'=?b \<and> n=i+?j" using prems 
  2.1882 +    by (simp add: Let_def split_def)
  2.1883 +  from abj prems  have th2: "(?I x (CX ?j ?b) = ?I x a) \<and> ?N ?b" by blast
  2.1884 +  from th have "?I x (CX n a') = ?I x (CX (i+?j) ?b)" by simp
  2.1885 +  also from th2 have "\<dots> = ?I x (CX i (CX ?j ?b))" by (simp add: left_distrib)
  2.1886 +  finally have "?I x (CX n a') = ?I  x (CX i a)" using th2 by simp
  2.1887 +  with th2 th show ?case by blast
  2.1888 +next
  2.1889 +  case (4 t n a)
  2.1890 +  let ?nt = "fst (zsplit0 t)"
  2.1891 +  let ?at = "snd (zsplit0 t)"
  2.1892 +  have abj: "zsplit0 t = (?nt,?at)" by simp hence th: "a=Neg ?at \<and> n=-?nt" using prems 
  2.1893 +    by (simp add: Let_def split_def)
  2.1894 +  from abj prems  have th2: "(?I x (CX ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
  2.1895 +  from th2[simplified] th[simplified] show ?case by simp
  2.1896 +next
  2.1897 +  case (5 s t n a)
  2.1898 +  let ?ns = "fst (zsplit0 s)"
  2.1899 +  let ?as = "snd (zsplit0 s)"
  2.1900 +  let ?nt = "fst (zsplit0 t)"
  2.1901 +  let ?at = "snd (zsplit0 t)"
  2.1902 +  have abjs: "zsplit0 s = (?ns,?as)" by simp 
  2.1903 +  moreover have abjt:  "zsplit0 t = (?nt,?at)" by simp 
  2.1904 +  ultimately have th: "a=Add ?as ?at \<and> n=?ns + ?nt" using prems 
  2.1905 +    by (simp add: Let_def split_def)
  2.1906 +  from abjs[symmetric] have bluddy: "\<exists> x y. (x,y) = zsplit0 s" by blast
  2.1907 +  from prems have "(\<exists> x y. (x,y) = zsplit0 s) \<longrightarrow> (\<forall>xa xb. zsplit0 t = (xa, xb) \<longrightarrow> Inum (x # bs) (CX xa xb) = Inum (x # bs) t \<and> numbound0 xb)" by simp
  2.1908 +  with bluddy abjt have th3: "(?I x (CX ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
  2.1909 +  from abjs prems  have th2: "(?I x (CX ?ns ?as) = ?I x s) \<and> ?N ?as" by blast
  2.1910 +  from th3[simplified] th2[simplified] th[simplified] show ?case 
  2.1911 +    by (simp add: left_distrib)
  2.1912 +next
  2.1913 +  case (6 s t n a)
  2.1914 +  let ?ns = "fst (zsplit0 s)"
  2.1915 +  let ?as = "snd (zsplit0 s)"
  2.1916 +  let ?nt = "fst (zsplit0 t)"
  2.1917 +  let ?at = "snd (zsplit0 t)"
  2.1918 +  have abjs: "zsplit0 s = (?ns,?as)" by simp 
  2.1919 +  moreover have abjt:  "zsplit0 t = (?nt,?at)" by simp 
  2.1920 +  ultimately have th: "a=Sub ?as ?at \<and> n=?ns - ?nt" using prems 
  2.1921 +    by (simp add: Let_def split_def)
  2.1922 +  from abjs[symmetric] have bluddy: "\<exists> x y. (x,y) = zsplit0 s" by blast
  2.1923 +  from prems have "(\<exists> x y. (x,y) = zsplit0 s) \<longrightarrow> (\<forall>xa xb. zsplit0 t = (xa, xb) \<longrightarrow> Inum (x # bs) (CX xa xb) = Inum (x # bs) t \<and> numbound0 xb)" by simp
  2.1924 +  with bluddy abjt have th3: "(?I x (CX ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
  2.1925 +  from abjs prems  have th2: "(?I x (CX ?ns ?as) = ?I x s) \<and> ?N ?as" by blast
  2.1926 +  from th3[simplified] th2[simplified] th[simplified] show ?case 
  2.1927 +    by (simp add: left_diff_distrib)
  2.1928 +next
  2.1929 +  case (7 i t n a)
  2.1930 +  let ?nt = "fst (zsplit0 t)"
  2.1931 +  let ?at = "snd (zsplit0 t)"
  2.1932 +  have abj: "zsplit0 t = (?nt,?at)" by simp hence th: "a=Mul i ?at \<and> n=i*?nt" using prems 
  2.1933 +    by (simp add: Let_def split_def)
  2.1934 +  from abj prems  have th2: "(?I x (CX ?nt ?at) = ?I x t) \<and> ?N ?at" by blast
  2.1935 +  hence " ?I x (Mul i t) = i * ?I x (CX ?nt ?at)" by simp
  2.1936 +  also have "\<dots> = ?I x (CX (i*?nt) (Mul i ?at))" by (simp add: right_distrib)
  2.1937 +  finally show ?case using th th2 by simp
  2.1938  qed
  2.1939  
  2.1940 -(* tries to linearize a formula *)
  2.1941 -consts linform :: "QF \<Rightarrow> QF option"
  2.1942 -primrec
  2.1943 -"linform (Le it1 it2) =  
  2.1944 -  lift_bin(\<lambda>x. \<lambda>y. Le (lin_add(x,lin_neg y)) (Cst 0),linearize it1, linearize it2)"
  2.1945 -"linform (Eq it1 it2) =  
  2.1946 -  lift_bin(\<lambda>x. \<lambda>y. Eq (lin_add(x,lin_neg y)) (Cst 0),linearize it1, linearize it2)"
  2.1947 -"linform (Divides d t) =  
  2.1948 -  (case linearize d of
  2.1949 -    None \<Rightarrow> None
  2.1950 -   | Some ld \<Rightarrow> (case ld of
  2.1951 -          Cst b \<Rightarrow> 
  2.1952 -               (if (b=0) then None
  2.1953 -               else 
  2.1954 -                (case linearize t of 
  2.1955 -                 None \<Rightarrow> None
  2.1956 -               | Some lt \<Rightarrow> Some (Divides ld lt)))
  2.1957 -         | _ \<Rightarrow> None))"
  2.1958 -"linform  T = Some T"
  2.1959 -"linform  F = Some F"
  2.1960 -"linform (NOT p) = lift_un NOT (linform p)"
  2.1961 -"linform (And p q)= lift_bin(\<lambda>f. \<lambda>g. And f g, linform p, linform q)"
  2.1962 -"linform (Or p q) = lift_bin(\<lambda>f. \<lambda>g. Or f g, linform p, linform q)"
  2.1963 -
  2.1964 -(* linearity of formulae *)
  2.1965 -consts islinform :: "QF \<Rightarrow> bool"
  2.1966 -recdef islinform "measure size"
  2.1967 -"islinform (Le it (Cst i)) = (i=0 \<and> islinintterm it )"
  2.1968 -"islinform (Eq it (Cst i)) = (i=0 \<and> islinintterm it)"
  2.1969 -"islinform (Divides (Cst d) t) = (d \<noteq> 0 \<and> islinintterm t)"
  2.1970 -"islinform  T = True"
  2.1971 -"islinform  F = True"
  2.1972 -"islinform (NOT (Divides (Cst d) t)) = (d \<noteq> 0 \<and> islinintterm t)"
  2.1973 -"islinform (NOT (Eq it (Cst i))) = (i=0 \<and> islinintterm it)"
  2.1974 -"islinform (And p q)= ((islinform p) \<and> (islinform q))"
  2.1975 -"islinform (Or p q) = ((islinform p) \<and> (islinform q))"
  2.1976 -"islinform p = False"
  2.1977 +consts
  2.1978 +  iszlfm :: "fm \<Rightarrow> bool"   (* Linearity test for fm *)
  2.1979 +  zlfm :: "fm \<Rightarrow> fm"       (* Linearity transformation for fm *)
  2.1980 +recdef iszlfm "measure size"
  2.1981 +  "iszlfm (And p q) = (iszlfm p \<and> iszlfm q)" 
  2.1982 +  "iszlfm (Or p q) = (iszlfm p \<and> iszlfm q)" 
  2.1983 +  "iszlfm (Eq  (CX c e)) = (c>0 \<and> numbound0 e)"
  2.1984 +  "iszlfm (NEq (CX c e)) = (c>0 \<and> numbound0 e)"
  2.1985 +  "iszlfm (Lt  (CX c e)) = (c>0 \<and> numbound0 e)"
  2.1986 +  "iszlfm (Le  (CX c e)) = (c>0 \<and> numbound0 e)"
  2.1987 +  "iszlfm (Gt  (CX c e)) = (c>0 \<and> numbound0 e)"
  2.1988 +  "iszlfm (Ge  (CX c e)) = ( c>0 \<and> numbound0 e)"
  2.1989 +  "iszlfm (Dvd i (CX c e)) = 
  2.1990 +                 (c>0 \<and> i>0 \<and> numbound0 e)"
  2.1991 +  "iszlfm (NDvd i (CX c e))= 
  2.1992 +                 (c>0 \<and> i>0 \<and> numbound0 e)"
  2.1993 +  "iszlfm p = (isatom p \<and> (bound0 p))"
  2.1994  
  2.1995 -(* linform preserves nnf, if successful *)
  2.1996 -lemma linform_nnf: 
  2.1997 -  assumes nnfp: "isnnf p" 
  2.1998 -  shows "\<And> p'. \<lbrakk>linform p = Some p'\<rbrakk> \<Longrightarrow> isnnf p'"
  2.1999 -using nnfp
  2.2000 -proof (induct p rule: isnnf.induct, simp_all)
  2.2001 -  case (goal1 a b p')
  2.2002 -  show ?case 
  2.2003 -    using prems 
  2.2004 -    by (cases "linearize a", auto) (cases "linearize b", auto)
  2.2005 -next 
  2.2006 -  case (goal2 a b p')
  2.2007 -  show ?case 
  2.2008 -    using prems 
  2.2009 -    by (cases "linearize a", auto) (cases "linearize b", auto)
  2.2010 -next 
  2.2011 -  case (goal3 d t p')
  2.2012 -  show ?case 
  2.2013 -    using prems
  2.2014 -    apply (cases "linearize d", auto)
  2.2015 -    apply (case_tac "a",auto)
  2.2016 -    apply (case_tac "int=0",auto)
  2.2017 -    by (cases "linearize t",auto)
  2.2018 -next
  2.2019 -  case (goal4 f g p') show ?case 
  2.2020 -    using prems
  2.2021 -    by (cases "linform f", auto) (cases "linform g", auto)
  2.2022 -next
  2.2023 -  case (goal5 f g p') show ?case 
  2.2024 -    using prems
  2.2025 -    by (cases "linform f", auto) (cases "linform g", auto)
  2.2026 -next
  2.2027 -  case (goal6 d t p') show ?case 
  2.2028 -    using prems
  2.2029 -    apply (cases "linearize d", auto)
  2.2030 -    apply (case_tac "a", auto)
  2.2031 -    apply (case_tac "int = 0",auto)
  2.2032 -    by (cases "linearize t", auto)
  2.2033 -next 
  2.2034 -  case (goal7 a b p')
  2.2035 -  show ?case 
  2.2036 -    using prems 
  2.2037 -    by (cases "linearize a", auto) (cases "linearize b", auto)
  2.2038 -
  2.2039 -
  2.2040 -qed
  2.2041 +lemma zlin_qfree: "iszlfm p \<Longrightarrow> qfree p"
  2.2042 +  by (induct p rule: iszlfm.induct) auto
  2.2043  
  2.2044  
  2.2045 -lemma linform_corr: "\<And> lp. \<lbrakk> isnnf p ; linform p = Some lp \<rbrakk> \<Longrightarrow> 
  2.2046 -                     (qinterp ats p = qinterp ats lp)"
  2.2047 -proof (induct p rule: linform.induct)
  2.2048 -  case (Le x y)
  2.2049 -  show ?case
  2.2050 -    using "Le.prems"
  2.2051 -  proof-
  2.2052 -    have "(\<exists> lx ly. linearize x = Some lx \<and> linearize y = Some ly) \<or> 
  2.2053 -      (linearize x = None) \<or> (linearize y = None)"by auto
  2.2054 -    moreover 
  2.2055 -    {
  2.2056 -      assume linxy: "\<exists> lx ly. linearize x = Some lx \<and> linearize y = Some ly"
  2.2057 -      from linxy obtain "lx" "ly" 
  2.2058 -	where lxly:"linearize x = Some lx \<and> linearize y = Some ly" by blast
  2.2059 -      then 
  2.2060 -      have lxeqx: "I_intterm ats x = I_intterm ats lx" 
  2.2061 -	by (simp add: linearize_corr)
  2.2062 -      from lxly have lxlin: "islinintterm lx" 
  2.2063 -	by (auto simp add: linearize_linear)
  2.2064 -      from lxly have lyeqy: "I_intterm ats y = I_intterm ats ly"
  2.2065 -	by (simp add: linearize_corr)
  2.2066 -      from lxly have lylin: "islinintterm ly" 
  2.2067 -	by (auto simp add: linearize_linear)
  2.2068 -      from "prems"
  2.2069 -      have lpeqle: "lp =  (Le (lin_add(lx,lin_neg ly)) (Cst 0))"
  2.2070 -	by auto
  2.2071 -      moreover
  2.2072 -      have lin1: "islinintterm (Cst 1)" by simp
  2.2073 -      then
  2.2074 -      have ?thesis  
  2.2075 -	using lxlin lylin lin1 lin_add_lin lin_neg_lin "prems" lxly lpeqle
  2.2076 -	by (simp add: lin_add_corr lin_neg_corr lxeqx lyeqy)
  2.2077 -      
  2.2078 -    }
  2.2079 -    
  2.2080 -    moreover
  2.2081 -    {
  2.2082 -      assume "linearize x = None"
  2.2083 -      have ?thesis using "prems" by simp
  2.2084 -    }
  2.2085 -    
  2.2086 -    moreover
  2.2087 -    {
  2.2088 -      assume "linearize y = None"
  2.2089 -      then have ?thesis using "prems"
  2.2090 -	by (case_tac "linearize x", auto)
  2.2091 -    }
  2.2092 -    ultimately show ?thesis by blast
  2.2093 -  qed
  2.2094 -  
  2.2095 -next 
  2.2096 -  case (Eq x y)
  2.2097 -  show ?case
  2.2098 -    using "Eq.prems"
  2.2099 -  proof-
  2.2100 -    have "(\<exists> lx ly. linearize x = Some lx \<and> linearize y = Some ly) \<or> 
  2.2101 -      (linearize x = None) \<or> (linearize y = None)"by auto
  2.2102 -    moreover 
  2.2103 -    {
  2.2104 -      assume linxy: "\<exists> lx ly. linearize x = Some lx \<and> linearize y = Some ly"
  2.2105 -      from linxy obtain "lx" "ly" 
  2.2106 -	where lxly:"linearize x = Some lx \<and> linearize y = Some ly" by blast
  2.2107 -      then 
  2.2108 -      have lxeqx: "I_intterm ats x = I_intterm ats lx" 
  2.2109 -	by (simp add: linearize_corr)
  2.2110 -      from lxly have lxlin: "islinintterm lx" 
  2.2111 -	by (auto simp add: linearize_linear)
  2.2112 -      from lxly have lyeqy: "I_intterm ats y = I_intterm ats ly"
  2.2113 -	by (simp add: linearize_corr)
  2.2114 -      from lxly have lylin: "islinintterm ly" 
  2.2115 -	by (auto simp add: linearize_linear)
  2.2116 -      from "prems"
  2.2117 -      have lpeqle: "lp =  (Eq (lin_add(lx,lin_neg ly)) (Cst 0))"
  2.2118 -	by auto
  2.2119 -      moreover
  2.2120 -      have lin1: "islinintterm (Cst 1)" by simp
  2.2121 -      then
  2.2122 -      have ?thesis  
  2.2123 -	using lxlin lylin lin1 lin_add_lin lin_neg_lin "prems" lxly lpeqle
  2.2124 -	by (simp add: lin_add_corr lin_neg_corr lxeqx lyeqy)
  2.2125 -      
  2.2126 -    }
  2.2127 -    
  2.2128 -    moreover
  2.2129 -    {
  2.2130 -      assume "linearize x = None"
  2.2131 -      have ?thesis using "prems" by simp
  2.2132 -    }
  2.2133 -    
  2.2134 -    moreover
  2.2135 -    {
  2.2136 -      assume "linearize y = None"
  2.2137 -      then have ?thesis using "prems"
  2.2138 -	by (case_tac "linearize x", auto)
  2.2139 -    }
  2.2140 -    ultimately show ?thesis by blast
  2.2141 -  qed
  2.2142 -  
  2.2143 -next 
  2.2144 -  case (Divides d t)
  2.2145 -  show ?case
  2.2146 -    using "Divides.prems"
  2.2147 -    apply (case_tac "linearize d",auto)
  2.2148 -    apply (case_tac a, auto)
  2.2149 -    apply (case_tac "int = 0", auto)
  2.2150 -    apply (case_tac "linearize t", auto)
  2.2151 -    apply (simp add: linearize_corr)
  2.2152 -    apply (case_tac a, auto)
  2.2153 -    apply (case_tac "int = 0", auto)
  2.2154 -    by (case_tac "linearize t", auto simp add: linearize_corr)
  2.2155 +recdef zlfm "measure fmsize"
  2.2156 +  "zlfm (And p q) = And (zlfm p) (zlfm q)"
  2.2157 +  "zlfm (Or p q) = Or (zlfm p) (zlfm q)"
  2.2158 +  "zlfm (Imp p q) = Or (zlfm (NOT p)) (zlfm q)"
  2.2159 +  "zlfm (Iff p q) = Or (And (zlfm p) (zlfm q)) (And (zlfm (NOT p)) (zlfm (NOT q)))"
  2.2160 +  "zlfm (Lt a) = (let (c,r) = zsplit0 a in 
  2.2161 +     if c=0 then Lt r else 
  2.2162 +     if c>0 then (Lt (CX c r)) else (Gt (CX (- c) (Neg r))))"
  2.2163 +  "zlfm (Le a) = (let (c,r) = zsplit0 a in 
  2.2164 +     if c=0 then Le r else 
  2.2165 +     if c>0 then (Le (CX c r)) else (Ge (CX (- c) (Neg r))))"
  2.2166 +  "zlfm (Gt a) = (let (c,r) = zsplit0 a in 
  2.2167 +     if c=0 then Gt r else 
  2.2168 +     if c>0 then (Gt (CX c r)) else (Lt (CX (- c) (Neg r))))"
  2.2169 +  "zlfm (Ge a) = (let (c,r) = zsplit0 a in 
  2.2170 +     if c=0 then Ge r else 
  2.2171 +     if c>0 then (Ge (CX c r)) else (Le (CX (- c) (Neg r))))"
  2.2172 +  "zlfm (Eq a) = (let (c,r) = zsplit0 a in 
  2.2173 +     if c=0 then Eq r else 
  2.2174 +     if c>0 then (Eq (CX c r)) else (Eq (CX (- c) (Neg r))))"
  2.2175 +  "zlfm (NEq a) = (let (c,r) = zsplit0 a in 
  2.2176 +     if c=0 then NEq r else 
  2.2177 +     if c>0 then (NEq (CX c r)) else (NEq (CX (- c) (Neg r))))"
  2.2178 +  "zlfm (Dvd i a) = (if i=0 then zlfm (Eq a) 
  2.2179 +        else (let (c,r) = zsplit0 a in 
  2.2180 +              if c=0 then (Dvd (abs i) r) else 
  2.2181 +      if c>0 then (Dvd (abs i) (CX c r))
  2.2182 +      else (Dvd (abs i) (CX (- c) (Neg r)))))"
  2.2183 +  "zlfm (NDvd i a) = (if i=0 then zlfm (NEq a) 
  2.2184 +        else (let (c,r) = zsplit0 a in 
  2.2185 +              if c=0 then (NDvd (abs i) r) else 
  2.2186 +      if c>0 then (NDvd (abs i) (CX c r))
  2.2187 +      else (NDvd (abs i) (CX (- c) (Neg r)))))"
  2.2188 +  "zlfm (NOT (And p q)) = Or (zlfm (NOT p)) (zlfm (NOT q))"
  2.2189 +  "zlfm (NOT (Or p q)) = And (zlfm (NOT p)) (zlfm (NOT q))"
  2.2190 +  "zlfm (NOT (Imp p q)) = And (zlfm p) (zlfm (NOT q))"
  2.2191 +  "zlfm (NOT (Iff p q)) = Or (And(zlfm p) (zlfm(NOT q))) (And (zlfm(NOT p)) (zlfm q))"
  2.2192 +  "zlfm (NOT (NOT p)) = zlfm p"
  2.2193 +  "zlfm (NOT T) = F"
  2.2194 +  "zlfm (NOT F) = T"
  2.2195 +  "zlfm (NOT (Lt a)) = zlfm (Ge a)"
  2.2196 +  "zlfm (NOT (Le a)) = zlfm (Gt a)"
  2.2197 +  "zlfm (NOT (Gt a)) = zlfm (Le a)"
  2.2198 +  "zlfm (NOT (Ge a)) = zlfm (Lt a)"
  2.2199 +  "zlfm (NOT (Eq a)) = zlfm (NEq a)"
  2.2200 +  "zlfm (NOT (NEq a)) = zlfm (Eq a)"
  2.2201 +  "zlfm (NOT (Dvd i a)) = zlfm (NDvd i a)"
  2.2202 +  "zlfm (NOT (NDvd i a)) = zlfm (Dvd i a)"
  2.2203 +  "zlfm (NOT (Closed P)) = NClosed P"
  2.2204 +  "zlfm (NOT (NClosed P)) = Closed P"
  2.2205 +  "zlfm p = p" (hints simp add: fmsize_pos)
  2.2206 +
  2.2207 +lemma zlfm_I:
  2.2208 +  assumes qfp: "qfree p"
  2.2209 +  shows "(Ifm bbs (i#bs) (zlfm p) = Ifm bbs (i# bs) p) \<and> iszlfm (zlfm p)"
  2.2210 +  (is "(?I (?l p) = ?I p) \<and> ?L (?l p)")
  2.2211 +using qfp
  2.2212 +proof(induct p rule: zlfm.induct)
  2.2213 +  case (5 a) 
  2.2214 +  let ?c = "fst (zsplit0 a)"
  2.2215 +  let ?r = "snd (zsplit0 a)"
  2.2216 +  have spl: "zsplit0 a = (?c,?r)" by simp
  2.2217 +  from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  2.2218 +  have Ia:"Inum (i # bs) a = Inum (i #bs) (CX ?c ?r)" and nb: "numbound0 ?r" by auto 
  2.2219 +  let ?N = "\<lambda> t. Inum (i#bs) t"
  2.2220 +  from prems Ia nb  show ?case 
  2.2221 +    by (auto simp add: Let_def split_def ring_eq_simps) (cases "?r",auto)
  2.2222 +next
  2.2223 +  case (6 a)  
  2.2224 +  let ?c = "fst (zsplit0 a)"
  2.2225 +  let ?r = "snd (zsplit0 a)"
  2.2226 +  have spl: "zsplit0 a = (?c,?r)" by simp
  2.2227 +  from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  2.2228 +  have Ia:"Inum (i # bs) a = Inum (i #bs) (CX ?c ?r)" and nb: "numbound0 ?r" by auto 
  2.2229 +  let ?N = "\<lambda> t. Inum (i#bs) t"
  2.2230 +  from prems Ia nb  show ?case 
  2.2231 +    by (auto simp add: Let_def split_def ring_eq_simps) (cases "?r",auto)
  2.2232 +next
  2.2233 +  case (7 a)  
  2.2234 +  let ?c = "fst (zsplit0 a)"
  2.2235 +  let ?r = "snd (zsplit0 a)"
  2.2236 +  have spl: "zsplit0 a = (?c,?r)" by simp
  2.2237 +  from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  2.2238 +  have Ia:"Inum (i # bs) a = Inum (i #bs) (CX ?c ?r)" and nb: "numbound0 ?r" by auto 
  2.2239 +  let ?N = "\<lambda> t. Inum (i#bs) t"
  2.2240 +  from prems Ia nb  show ?case 
  2.2241 +    by (auto simp add: Let_def split_def ring_eq_simps) (cases "?r",auto)
  2.2242 +next
  2.2243 +  case (8 a)  
  2.2244 +  let ?c = "fst (zsplit0 a)"
  2.2245 +  let ?r = "snd (zsplit0 a)"
  2.2246 +  have spl: "zsplit0 a = (?c,?r)" by simp
  2.2247 +  from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  2.2248 +  have Ia:"Inum (i # bs) a = Inum (i #bs) (CX ?c ?r)" and nb: "numbound0 ?r" by auto 
  2.2249 +  let ?N = "\<lambda> t. Inum (i#bs) t"
  2.2250 +  from prems Ia nb  show ?case 
  2.2251 +    by (auto simp add: Let_def split_def ring_eq_simps) (cases "?r",auto)
  2.2252 +next
  2.2253 +  case (9 a)  
  2.2254 +  let ?c = "fst (zsplit0 a)"
  2.2255 +  let ?r = "snd (zsplit0 a)"
  2.2256 +  have spl: "zsplit0 a = (?c,?r)" by simp
  2.2257 +  from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  2.2258 +  have Ia:"Inum (i # bs) a = Inum (i #bs) (CX ?c ?r)" and nb: "numbound0 ?r" by auto 
  2.2259 +  let ?N = "\<lambda> t. Inum (i#bs) t"
  2.2260 +  from prems Ia nb  show ?case 
  2.2261 +    by (auto simp add: Let_def split_def ring_eq_simps) (cases "?r",auto)
  2.2262 +next
  2.2263 +  case (10 a)  
  2.2264 +  let ?c = "fst (zsplit0 a)"
  2.2265 +  let ?r = "snd (zsplit0 a)"
  2.2266 +  have spl: "zsplit0 a = (?c,?r)" by simp
  2.2267 +  from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  2.2268 +  have Ia:"Inum (i # bs) a = Inum (i #bs) (CX ?c ?r)" and nb: "numbound0 ?r" by auto 
  2.2269 +  let ?N = "\<lambda> t. Inum (i#bs) t"
  2.2270 +  from prems Ia nb  show ?case 
  2.2271 +    by (auto simp add: Let_def split_def ring_eq_simps) (cases "?r",auto)
  2.2272  next
  2.2273 -  case (NOT f) show ?case
  2.2274 -    using "prems"
  2.2275 -  proof-
  2.2276 -    have "(\<exists> lf. linform f = Some lf) \<or> (linform f = None)" by auto
  2.2277 -    moreover 
  2.2278 -    {
  2.2279 -      assume linf: "\<exists> lf. linform f = Some lf"
  2.2280 -      from prems have "isnnf (NOT f)" by simp
  2.2281 -      then have fnnf: "isnnf f" by (cases f) auto
  2.2282 -      from linf obtain "lf" where lf: "linform f = Some lf" by blast
  2.2283 -      then have "lp = NOT lf" using "prems" by auto
  2.2284 -      with "NOT.prems" "NOT.hyps" lf fnnf
  2.2285 -      have ?case by simp
  2.2286 -    }
  2.2287 -    moreover 
  2.2288 -    {
  2.2289 -      assume "linform f = None"
  2.2290 -      then 
  2.2291 -      have "linform (NOT f) = None" by simp
  2.2292 -      then 
  2.2293 -      have ?thesis  using "NOT.prems" by simp
  2.2294 -    }
  2.2295 -    ultimately show ?thesis by blast
  2.2296 -  qed
  2.2297 +  case (11 j a)  
  2.2298 +  let ?c = "fst (zsplit0 a)"
  2.2299 +  let ?r = "snd (zsplit0 a)"
  2.2300 +  have spl: "zsplit0 a = (?c,?r)" by simp
  2.2301 +  from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  2.2302 +  have Ia:"Inum (i # bs) a = Inum (i #bs) (CX ?c ?r)" and nb: "numbound0 ?r" by auto 
  2.2303 +  let ?N = "\<lambda> t. Inum (i#bs) t"
  2.2304 +  have "j=0 \<or> (j\<noteq>0 \<and> ?c = 0) \<or> (j\<noteq>0 \<and> ?c >0) \<or> (j\<noteq> 0 \<and> ?c<0)" by arith
  2.2305 +  moreover
  2.2306 +  {assume "j=0" hence z: "zlfm (Dvd j a) = (zlfm (Eq a))" by (simp add: Let_def) 
  2.2307 +    hence ?case using prems by (simp del: zlfm.simps add: zdvd_0_left)}
  2.2308 +  moreover
  2.2309 +  {assume "?c=0" and "j\<noteq>0" hence ?case 
  2.2310 +      using zsplit0_I[OF spl, where x="i" and bs="bs"] zdvd_abs1[where d="j"]
  2.2311 +      by (cases "?r", simp_all add: Let_def split_def)}
  2.2312 +  moreover
  2.2313 +  {assume cp: "?c > 0" and jnz: "j\<noteq>0" hence l: "?L (?l (Dvd j a))" 
  2.2314 +      by (simp add: nb Let_def split_def)
  2.2315 +    hence ?case using Ia cp jnz by (simp add: Let_def split_def 
  2.2316 +	zdvd_abs1[where d="j" and t="(?c*i) + ?N ?r", symmetric])}
  2.2317 +  moreover
  2.2318 +  {assume cn: "?c < 0" and jnz: "j\<noteq>0" hence l: "?L (?l (Dvd j a))" 
  2.2319 +      by (simp add: nb Let_def split_def)
  2.2320 +    hence ?case using Ia cn jnz zdvd_zminus_iff[where m="abs j" and n="?c*i + ?N ?r" ]
  2.2321 +      by (simp add: Let_def split_def 
  2.2322 +      zdvd_abs1[where d="j" and t="(?c*i) + ?N ?r", symmetric])}
  2.2323 +  ultimately show ?case by blast
  2.2324  next
  2.2325 -  case (Or f g) 
  2.2326 -  show ?case using "Or.hyps"
  2.2327 -  proof -
  2.2328 -    have "((\<exists> lf. linform f = Some lf ) \<and> (\<exists> lg. linform g = Some lg)) \<or> 
  2.2329 -      (linform f = None) \<or> (linform g = None)" by auto
  2.2330 -    moreover
  2.2331 -    {
  2.2332 -      assume linf: "\<exists> lf. linform f = Some lf"
  2.2333 -	and ling: "\<exists> lg. linform g = Some lg"
  2.2334 -      from linf obtain "lf" where lf: "linform f = Some lf" by blast
  2.2335 -      from ling obtain "lg" where lg: "linform g = Some lg" by blast
  2.2336 -      from lf lg have "linform (Or f g) = Some (Or lf lg)" by simp
  2.2337 -      then have "lp = Or lf lg" using lf lg "prems"  by simp
  2.2338 -      with lf lg "prems" have ?thesis by simp
  2.2339 -    }
  2.2340 -    moreover
  2.2341 -    {
  2.2342 -      assume "linform f = None"
  2.2343 -      then have ?thesis using "Or.prems"  by auto
  2.2344 -    }
  2.2345 -    moreover
  2.2346 -    {
  2.2347 -      assume "linform g = None"
  2.2348 -      then have ?thesis using "Or.prems"  by (case_tac "linform f", auto)
  2.2349 -      
  2.2350 -    }
  2.2351 -    ultimately show ?thesis by blast
  2.2352 -  qed
  2.2353 +  case (12 j a) 
  2.2354 +  let ?c = "fst (zsplit0 a)"
  2.2355 +  let ?r = "snd (zsplit0 a)"
  2.2356 +  have spl: "zsplit0 a = (?c,?r)" by simp
  2.2357 +  from zsplit0_I[OF spl, where x="i" and bs="bs"] 
  2.2358 +  have Ia:"Inum (i # bs) a = Inum (i #bs) (CX ?c ?r)" and nb: "numbound0 ?r" by auto 
  2.2359 +  let ?N = "\<lambda> t. Inum (i#bs) t"
  2.2360 +  have "j=0 \<or> (j\<noteq>0 \<and> ?c = 0) \<or> (j\<noteq>0 \<and> ?c >0) \<or> (j\<noteq> 0 \<and> ?c<0)" by arith
  2.2361 +  moreover
  2.2362 +  {assume "j=0" hence z: "zlfm (NDvd j a) = (zlfm (NEq a))" by (simp add: Let_def) 
  2.2363 +    hence ?case using prems by (simp del: zlfm.simps add: zdvd_0_left)}
  2.2364 +  moreover
  2.2365 +  {assume "?c=0" and "j\<noteq>0" hence ?case 
  2.2366 +      using zsplit0_I[OF spl, where x="i" and bs="bs"] zdvd_abs1[where d="j"]
  2.2367 +      by (cases "?r", simp_all add: Let_def split_def)}
  2.2368 +  moreover
  2.2369 +  {assume cp: "?c > 0" and jnz: "j\<noteq>0" hence l: "?L (?l (Dvd j a))" 
  2.2370 +      by (simp add: nb Let_def split_def)
  2.2371 +    hence ?case using Ia cp jnz by (simp add: Let_def split_def 
  2.2372 +	zdvd_abs1[where d="j" and t="(?c*i) + ?N ?r", symmetric])}
  2.2373 +  moreover
  2.2374 +  {assume cn: "?c < 0" and jnz: "j\<noteq>0" hence l: "?L (?l (Dvd j a))" 
  2.2375 +      by (simp add: nb Let_def split_def)
  2.2376 +    hence ?case using Ia cn jnz zdvd_zminus_iff[where m="abs j" and n="?c*i + ?N ?r" ]
  2.2377 +      by (simp add: Let_def split_def 
  2.2378 +      zdvd_abs1[where d="j" and t="(?c*i) + ?N ?r", symmetric])}
  2.2379 +  ultimately show ?case by blast
  2.2380 +qed auto
  2.2381 +
  2.2382 +consts 
  2.2383 +  plusinf:: "fm \<Rightarrow> fm" (* Virtual substitution of +\<infinity>*)
  2.2384 +  minusinf:: "fm \<Rightarrow> fm" (* Virtual substitution of -\<infinity>*)
  2.2385 +  \<delta> :: "fm \<Rightarrow> int" (* Compute lcm {d| N\<^isup>?\<^isup> Dvd c*x+t \<in> p}*)
  2.2386 +  d\<delta> :: "fm \<Rightarrow> int \<Rightarrow> bool" (* checks if a given l divides all the ds above*)
  2.2387 +
  2.2388 +recdef minusinf "measure size"
  2.2389 +  "minusinf (And p q) = And (minusinf p) (minusinf q)" 
  2.2390 +  "minusinf (Or p q) = Or (minusinf p) (minusinf q)" 
  2.2391 +  "minusinf (Eq  (CX c e)) = F"
  2.2392 +  "minusinf (NEq (CX c e)) = T"
  2.2393 +  "minusinf (Lt  (CX c e)) = T"
  2.2394 +  "minusinf (Le  (CX c e)) = T"
  2.2395 +  "minusinf (Gt  (CX c e)) = F"
  2.2396 +  "minusinf (Ge  (CX c e)) = F"
  2.2397 +  "minusinf p = p"
  2.2398 +
  2.2399 +lemma minusinf_qfree: "qfree p \<Longrightarrow> qfree (minusinf p)"
  2.2400 +  by (induct p rule: minusinf.induct, auto)
  2.2401 +
  2.2402 +recdef plusinf "measure size"
  2.2403 +  "plusinf (And p q) = And (plusinf p) (plusinf q)" 
  2.2404 +  "plusinf (Or p q) = Or (plusinf p) (plusinf q)" 
  2.2405 +  "plusinf (Eq  (CX c e)) = F"
  2.2406 +  "plusinf (NEq (CX c e)) = T"
  2.2407 +  "plusinf (Lt  (CX c e)) = F"
  2.2408 +  "plusinf (Le  (CX c e)) = F"
  2.2409 +  "plusinf (Gt  (CX c e)) = T"
  2.2410 +  "plusinf (Ge  (CX c e)) = T"
  2.2411 +  "plusinf p = p"
  2.2412 +
  2.2413 +recdef \<delta> "measure size"
  2.2414 +  "\<delta> (And p q) = ilcm (\<delta> p) (\<delta> q)" 
  2.2415 +  "\<delta> (Or p q) = ilcm (\<delta> p) (\<delta> q)" 
  2.2416 +  "\<delta> (Dvd i (CX c e)) = i"
  2.2417 +  "\<delta> (NDvd i (CX c e)) = i"
  2.2418 +  "\<delta> p = 1"
  2.2419 +
  2.2420 +recdef d\<delta> "measure size"
  2.2421 +  "d\<delta> (And p q) = (\<lambda> d. d\<delta> p d \<and> d\<delta> q d)" 
  2.2422 +  "d\<delta> (Or p q) = (\<lambda> d. d\<delta> p d \<and> d\<delta> q d)" 
  2.2423 +  "d\<delta> (Dvd i (CX c e)) = (\<lambda> d. i dvd d)"
  2.2424 +  "d\<delta> (NDvd i (CX c e)) = (\<lambda> d. i dvd d)"
  2.2425 +  "d\<delta> p = (\<lambda> d. True)"
  2.2426 +
  2.2427 +lemma delta_mono: 
  2.2428 +  assumes lin: "iszlfm p"
  2.2429 +  and d: "d dvd d'"
  2.2430 +  and ad: "d\<delta> p d"
  2.2431 +  shows "d\<delta> p d'"
  2.2432 +  using lin ad d
  2.2433 +proof(induct p rule: iszlfm.induct)
  2.2434 +  case (9 i c e)  thus ?case using d
  2.2435 +    by (simp add: zdvd_trans[where m="i" and n="d" and k="d'"])
  2.2436  next
  2.2437 -  case (And f g) 
  2.2438 -  show ?case using "And.hyps"
  2.2439 -  proof -
  2.2440 -    have "((\<exists> lf. linform f = Some lf ) \<and> (\<exists> lg. linform g = Some lg)) \<or> 
  2.2441 -      (linform f = None) \<or> (linform g = None)" by auto
  2.2442 -    moreover
  2.2443 -    {
  2.2444 -      assume linf: "\<exists> lf. linform f = Some lf"
  2.2445 -	and ling: "\<exists> lg. linform g = Some lg"
  2.2446 -      from linf obtain "lf" where lf: "linform f = Some lf" by blast
  2.2447 -      from ling obtain "lg" where lg: "linform g = Some lg" by blast
  2.2448 -      from lf lg have "linform (And f g) = Some (And lf lg)" by simp
  2.2449 -      then have "lp = And lf lg" using lf lg "prems"  by simp
  2.2450 -      with lf lg "prems" have ?thesis by simp
  2.2451 -    }
  2.2452 -    moreover
  2.2453 -    {
  2.2454 -      assume "linform f = None"
  2.2455 -      then have ?thesis using "And.prems"  by auto
  2.2456 -    }
  2.2457 -    moreover
  2.2458 -    {
  2.2459 -      assume "linform g = None"
  2.2460 -      then have ?thesis using "And.prems"  by (case_tac "linform f", auto)
  2.2461 -      
  2.2462 -    }
  2.2463 -    ultimately show ?thesis by blast
  2.2464 -  qed
  2.2465 +  case (10 i c e) thus ?case using d
  2.2466 +    by (simp add: zdvd_trans[where m="i" and n="d" and k="d'"])
  2.2467 +qed simp_all
  2.2468  
  2.2469 +lemma \<delta> : assumes lin:"iszlfm p"
  2.2470 +  shows "d\<delta> p (\<delta> p) \<and> \<delta> p >0"
  2.2471 +using lin
  2.2472 +proof (induct p rule: iszlfm.induct)
  2.2473 +  case (1 p q) 
  2.2474 +  let ?d = "\<delta> (And p q)"
  2.2475 +  from prems ilcm_pos have dp: "?d >0" by simp
  2.2476 +  have d1: "\<delta> p dvd \<delta> (And p q)" using prems ilcm_dvd1 by simp 
  2.2477 +   hence th: "d\<delta> p ?d" using delta_mono prems by auto
  2.2478 +  have "\<delta> q dvd \<delta> (And p q)" using prems ilcm_dvd2 by simp 
  2.2479 +  hence th': "d\<delta> q ?d" using delta_mono prems by auto
  2.2480 +  from th th' dp show ?case by simp 
  2.2481 +next
  2.2482 +  case (2 p q)  
  2.2483 +  let ?d = "\<delta> (And p q)"
  2.2484 +  from prems ilcm_pos have dp: "?d >0" by simp
  2.2485 +  have "\<delta> p dvd \<delta> (And p q)" using prems ilcm_dvd1 by simp hence th: "d\<delta> p ?d" using delta_mono prems by auto
  2.2486 +  have "\<delta> q dvd \<delta> (And p q)" using prems ilcm_dvd2 by simp hence th': "d\<delta> q ?d" using delta_mono prems by auto
  2.2487 +  from th th' dp show ?case by simp 
  2.2488  qed simp_all
  2.2489  
  2.2490  
  2.2491 -(* the result of linform is a linear formula *)
  2.2492 -lemma linform_lin: "\<And> lp. \<lbrakk> isnnf p ; linform p = Some lp\<rbrakk> \<Longrightarrow> islinform lp"
  2.2493 -proof (induct p rule: linform.induct)
  2.2494 -   case (Le x y)
  2.2495 -  have "((\<exists> lx. linearize x = Some lx) \<and> (\<exists> ly. linearize y = Some ly)) \<or> 
  2.2496 -    (linearize x = None) \<or> (linearize y = None) " by clarsimp
  2.2497 -  moreover 
  2.2498 -  {
  2.2499 -    assume linx: "\<exists> lx. linearize x = Some lx"
  2.2500 -      and liny: "\<exists> ly. linearize y = Some ly"
  2.2501 -    from linx obtain "lx" where lx: "linearize x = Some lx" by blast
  2.2502 -    from liny obtain "ly" where ly: "linearize y = Some ly" by blast
  2.2503 -    from lx have lxlin: "islinintterm lx" by (simp add: linearize_linear)
  2.2504 -    from ly have lylin: "islinintterm ly" by (simp add: linearize_linear)    
  2.2505 -    have lin1:"islinintterm (Cst 1)" by simp
  2.2506 -    have lin0: "islinintterm (Cst 0)" by simp
  2.2507 -    from "prems"  have "lp = Le (lin_add(lx,lin_neg ly)) (Cst 0)"
  2.2508 -      by auto
  2.2509 -    with lin0 lin1 lxlin lylin "prems" 
  2.2510 -    have ?case by (simp add: lin_add_lin lin_neg_lin)
  2.2511 -    
  2.2512 -  }
  2.2513 +consts 
  2.2514 +  a\<beta> :: "fm \<Rightarrow> int \<Rightarrow> fm" (* adjusts the coeffitients of a formula *)
  2.2515 +  d\<beta> :: "fm \<Rightarrow> int \<Rightarrow> bool" (* tests if all coeffs c of c divide a given l*)
  2.2516 +  \<zeta>  :: "fm \<Rightarrow> int" (* computes the lcm of all coefficients of x*)
  2.2517 +  \<beta> :: "fm \<Rightarrow> num list"
  2.2518 +  \<alpha> :: "fm \<Rightarrow> num list"
  2.2519  
  2.2520 -  moreover 
  2.2521 -  {
  2.2522 -    assume "linearize x = None"
  2.2523 -    then have ?case using "prems" by simp
  2.2524 -  }
  2.2525 -  moreover 
  2.2526 -  {
  2.2527 -    assume "linearize y = None"
  2.2528 -    then have ?case using "prems" by (case_tac "linearize x",simp_all)
  2.2529 -  }
  2.2530 -  ultimately show ?case by blast
  2.2531 -next
  2.2532 -   case (Eq x y)
  2.2533 -  have "((\<exists> lx. linearize x = Some lx) \<and> (\<exists> ly. linearize y = Some ly)) \<or> 
  2.2534 -    (linearize x = None) \<or> (linearize y = None) " by clarsimp
  2.2535 -  moreover 
  2.2536 -  {
  2.2537 -    assume linx: "\<exists> lx. linearize x = Some lx"
  2.2538 -      and liny: "\<exists> ly. linearize y = Some ly"
  2.2539 -    from linx obtain "lx" where lx: "linearize x = Some lx" by blast
  2.2540 -    from liny obtain "ly" where ly: "linearize y = Some ly" by blast
  2.2541 -    from lx have lxlin: "islinintterm lx" by (simp add: linearize_linear)
  2.2542 -    from ly have lylin: "islinintterm ly" by (simp add: linearize_linear)    
  2.2543 -    have lin1:"islinintterm (Cst 1)" by simp
  2.2544 -    have lin0: "islinintterm (Cst 0)" by simp
  2.2545 -    from "prems"  have "lp = Eq (lin_add(lx,lin_neg ly)) (Cst 0)"
  2.2546 -      by auto
  2.2547 -    with lin0 lin1 lxlin lylin "prems" 
  2.2548 -    have ?case by (simp add: lin_add_lin lin_neg_lin)
  2.2549 -    
  2.2550 -  }
  2.2551 +recdef a\<beta> "measure size"
  2.2552 +  "a\<beta> (And p q) = (\<lambda> k. And (a\<beta> p k) (a\<beta> q k))" 
  2.2553 +  "a\<beta> (Or p q) = (\<lambda> k. Or (a\<beta> p k) (a\<beta> q k))" 
  2.2554 +  "a\<beta> (Eq  (CX c e)) = (\<lambda> k. Eq (CX 1 (Mul (k div c) e)))"
  2.2555 +  "a\<beta> (NEq (CX c e)) = (\<lambda> k. NEq (CX 1 (Mul (k div c) e)))"
  2.2556 +  "a\<beta> (Lt  (CX c e)) = (\<lambda> k. Lt (CX 1 (Mul (k div c) e)))"
  2.2557 +  "a\<beta> (Le  (CX c e)) = (\<lambda> k. Le (CX 1 (Mul (k div c) e)))"
  2.2558 +  "a\<beta> (Gt  (CX c e)) = (\<lambda> k. Gt (CX 1 (Mul (k div c) e)))"
  2.2559 +  "a\<beta> (Ge  (CX c e)) = (\<lambda> k. Ge (CX 1 (Mul (k div c) e)))"
  2.2560 +  "a\<beta> (Dvd i (CX c e)) =(\<lambda> k. Dvd ((k div c)*i) (CX 1 (Mul (k div c) e)))"
  2.2561 +  "a\<beta> (NDvd i (CX c e))=(\<lambda> k. NDvd ((k div c)*i) (CX 1 (Mul (k div c) e)))"
  2.2562 +  "a\<beta> p = (\<lambda> k. p)"
  2.2563  
  2.2564 -  moreover 
  2.2565 -  {
  2.2566 -    assume "linearize x = None"
  2.2567 -    then have ?case using "prems" by simp
  2.2568 -  }
  2.2569 -  moreover 
  2.2570 -  {
  2.2571 -    assume "linearize y = None"
  2.2572 -    then have ?case using "prems" by (case_tac "linearize x",simp_all)
  2.2573 -  }
  2.2574 -  ultimately show ?case by blast
  2.2575 -next
  2.2576 -   case (Divides d t)
  2.2577 -   show ?case 
  2.2578 -     using prems
  2.2579 -     apply (case_tac "linearize d", auto)
  2.2580 -     apply (case_tac a, auto)
  2.2581 -     apply (case_tac "int = 0", auto)
  2.2582 +recdef d\<beta> "measure size"
  2.2583 +  "d\<beta> (And p q) = (\<lambda> k. (d\<beta> p k) \<and> (d\<beta> q k))" 
  2.2584 +  "d\<beta> (Or p q) = (\<lambda> k. (d\<beta> p k) \<and> (d\<beta> q k))" 
  2.2585 +  "d\<beta> (Eq  (CX c e)) = (\<lambda> k. c dvd k)"
  2.2586 +  "d\<beta> (NEq (CX c e)) = (\<lambda> k. c dvd k)"
  2.2587 +  "d\<beta> (Lt  (CX c e)) = (\<lambda> k. c dvd k)"
  2.2588 +  "d\<beta> (Le  (CX c e)) = (\<lambda> k. c dvd k)"
  2.2589 +  "d\<beta> (Gt  (CX c e)) = (\<lambda> k. c dvd k)"
  2.2590 +  "d\<beta> (Ge  (CX c e)) = (\<lambda> k. c dvd k)"
  2.2591 +  "d\<beta> (Dvd i (CX c e)) =(\<lambda> k. c dvd k)"
  2.2592 +  "d\<beta> (NDvd i (CX c e))=(\<lambda> k. c dvd k)"
  2.2593 +  "d\<beta> p = (\<lambda> k. True)"
  2.2594  
  2.2595 -     by (case_tac "linearize t",auto simp add: linearize_linear)
  2.2596 -next
  2.2597 -  case (Or f g)
  2.2598 - show ?case using "Or.hyps"
  2.2599 -  proof -
  2.2600 -    have "((\<exists> lf. linform f = Some lf ) \<and> (\<exists> lg. linform g = Some lg)) \<or> 
  2.2601 -      (linform f = None) \<or> (linform g = None)" by auto
  2.2602 -    moreover
  2.2603 -    {
  2.2604 -      assume linf: "\<exists> lf. linform f = Some lf"
  2.2605 -	and ling: "\<exists> lg. linform g = Some lg"
  2.2606 -      from linf obtain "lf" where lf: "linform f = Some lf" by blast
  2.2607 -      from ling obtain "lg" where lg: "linform g = Some lg" by blast
  2.2608 -      from lf lg have "linform (Or f g) = Some (Or lf lg)" by simp
  2.2609 -      then have "lp = Or lf lg" using lf lg "prems"  by simp
  2.2610 -      with lf lg "prems" have ?thesis by simp
  2.2611 -    }
  2.2612 -    moreover
  2.2613 -    {
  2.2614 -      assume "linform f = None"
  2.2615 -      then have ?thesis using "Or.prems"  by auto
  2.2616 -    }
  2.2617 -    moreover
  2.2618 -    {
  2.2619 -      assume "linform g = None"
  2.2620 -      then have ?thesis using "Or.prems"  by (case_tac "linform f", auto)
  2.2621 -      
  2.2622 -    }
  2.2623 -    ultimately show ?thesis by blast
  2.2624 -  qed
  2.2625 -next
  2.2626 -  case (And f g) 
  2.2627 -  show ?case using "And.hyps"
  2.2628 -  proof -
  2.2629 -    have "((\<exists> lf. linform f = Some lf ) \<and> (\<exists> lg. linform g = Some lg)) \<or> 
  2.2630 -      (linform f = None) \<or> (linform g = None)" by auto
  2.2631 -    moreover
  2.2632 -    {
  2.2633 -      assume linf: "\<exists> lf. linform f = Some lf"
  2.2634 -	and ling: "\<exists> lg. linform g = Some lg"
  2.2635 -      from linf obtain "lf" where lf: "linform f = Some lf" by blast
  2.2636 -      from ling obtain "lg" where lg: "linform g = Some lg" by blast
  2.2637 -      from lf lg have "linform (And f g) = Some (And lf lg)" by simp
  2.2638 -      then have "lp = And lf lg" using lf lg "prems"  by simp
  2.2639 -      with lf lg "prems" have ?thesis by simp
  2.2640 -    }
  2.2641 -    moreover
  2.2642 -    {
  2.2643 -      assume "linform f = None"
  2.2644 -      then have ?thesis using "And.prems"  by auto
  2.2645 -    }
  2.2646 -    moreover
  2.2647 -    {
  2.2648 -      assume "linform g = None"
  2.2649 -      then have ?thesis using "And.prems"  by (case_tac "linform f", auto)
  2.2650 -      
  2.2651 -    }
  2.2652 -    ultimately show ?thesis by blast
  2.2653 -  qed
  2.2654 -next
  2.2655 -  case (NOT f) show ?case
  2.2656 -    using "prems"
  2.2657 -  proof-
  2.2658 -    have "(\<exists> lf. linform f = Some lf) \<or> (linform f = None)" by auto
  2.2659 -    moreover 
  2.2660 -    {
  2.2661 -      assume linf: "\<exists> lf. linform f = Some lf"
  2.2662 -      from prems have "isnnf (NOT f)" by simp
  2.2663 -      then have fnnf: "isnnf f" by (cases f) auto
  2.2664 -      from linf obtain "lf" where lf: "linform f = Some lf" by blast
  2.2665 -      then have "lp = NOT lf" using "prems" by auto
  2.2666 -      with "NOT.prems" "NOT.hyps" lf fnnf
  2.2667 -      have ?thesis 
  2.2668 -	using fnnf
  2.2669 -	apply (cases f, auto) 
  2.2670 -	prefer 2
  2.2671 -	apply (case_tac "linearize intterm1",auto)
  2.2672 -	apply (case_tac a, auto)
  2.2673 -	apply (case_tac "int = 0", auto)
  2.2674 -	apply (case_tac "linearize intterm2") 
  2.2675 -	apply (auto simp add: linearize_linear)
  2.2676 -	apply (case_tac "linearize intterm1",auto)
  2.2677 -	by (case_tac "linearize intterm2") 
  2.2678 -      (auto simp add: linearize_linear lin_add_lin lin_neg_lin)
  2.2679 -    }
  2.2680 -    moreover 
  2.2681 -    {
  2.2682 -      assume "linform f = None"
  2.2683 -      then 
  2.2684 -      have "linform (NOT f) = None" by simp
  2.2685 -      then 
  2.2686 -      have ?thesis  using "NOT.prems" by simp
  2.2687 -    }
  2.2688 -    ultimately show ?thesis by blast
  2.2689 -  qed
  2.2690 -qed (simp_all)
  2.2691 +recdef \<zeta> "measure size"
  2.2692 +  "\<zeta> (And p q) = ilcm (\<zeta> p) (\<zeta> q)" 
  2.2693 +  "\<zeta> (Or p q) = ilcm (\<zeta> p) (\<zeta> q)" 
  2.2694 +  "\<zeta> (Eq  (CX c e)) = c"
  2.2695 +  "\<zeta> (NEq (CX c e)) = c"
  2.2696 +  "\<zeta> (Lt  (CX c e)) = c"
  2.2697 +  "\<zeta> (Le  (CX c e)) = c"
  2.2698 +  "\<zeta> (Gt  (CX c e)) = c"
  2.2699 +  "\<zeta> (Ge  (CX c e)) = c"
  2.2700 +  "\<zeta> (Dvd i (CX c e)) = c"
  2.2701 +  "\<zeta> (NDvd i (CX c e))= c"
  2.2702 +  "\<zeta> p = 1"
  2.2703  
  2.2704 -
  2.2705 -(* linform, if successful, preserves quantifier freeness *)
  2.2706 -lemma linform_isnnf: "islinform p \<Longrightarrow> isnnf p"
  2.2707 -by (induct p rule: islinform.induct) auto
  2.2708 -
  2.2709 -lemma linform_isqfree: "islinform p \<Longrightarrow> isqfree p"
  2.2710 -using linform_isnnf nnf_isqfree by simp
  2.2711 -
  2.2712 -lemma linform_qfree: "\<And> p'. \<lbrakk> isnnf p ; linform p = Some p'\<rbrakk> \<Longrightarrow> isqfree p'"
  2.2713 -using linform_isqfree linform_lin 
  2.2714 -by simp
  2.2715 -
  2.2716 -(* Definitions and lemmas about gcd and lcm *)
  2.2717 -definition
  2.2718 -  lcm :: "nat \<times> nat \<Rightarrow> nat" where
  2.2719 -  "lcm = (\<lambda>(m,n). m*n div gcd(m,n))"
  2.2720 +recdef \<beta> "measure size"
  2.2721 +  "\<beta> (And p q) = (\<beta> p @ \<beta> q)" 
  2.2722 +  "\<beta> (Or p q) = (\<beta> p @ \<beta> q)" 
  2.2723 +  "\<beta> (Eq  (CX c e)) = [Sub (C -1) e]"
  2.2724 +  "\<beta> (NEq (CX c e)) = [Neg e]"
  2.2725 +  "\<beta> (Lt  (CX c e)) = []"
  2.2726 +  "\<beta> (Le  (CX c e)) = []"
  2.2727 +  "\<beta> (Gt  (CX c e)) = [Neg e]"
  2.2728 +  "\<beta> (Ge  (CX c e)) = [Sub (C -1) e]"
  2.2729 +  "\<beta> p = []"
  2.2730  
  2.2731 -definition
  2.2732 -  ilcm :: "int \<Rightarrow> int \<Rightarrow> int" where
  2.2733 -  "ilcm = (\<lambda>i.\<lambda>j. int (lcm(nat(abs i),nat(abs j))))"
  2.2734 -
  2.2735 -(* ilcm_dvd12 are needed later *)
  2.2736 -lemma lcm_dvd1: 
  2.2737 -  assumes mpos: " m >0"
  2.2738 -  and npos: "n>0"
  2.2739 -  shows "m dvd (lcm(m,n))"
  2.2740 -proof-
  2.2741 -  have "gcd(m,n) dvd n" by simp
  2.2742 -  then obtain "k" where "n = gcd(m,n) * k" using dvd_def by auto
  2.2743 -  then have "m*n div gcd(m,n) = m*(gcd(m,n)*k) div gcd(m,n)" by (simp add: mult_ac)
  2.2744 -  also have "\<dots> = m*k" using mpos npos gcd_zero by simp
  2.2745 -  finally show ?thesis by (simp add: lcm_def)
  2.2746 -qed
  2.2747 -
  2.2748 -lemma lcm_dvd2: 
  2.2749 -  assumes mpos: " m >0"
  2.2750 -  and npos: "n>0"
  2.2751 -  shows "n dvd (lcm(m,n))"
  2.2752 -proof-
  2.2753 -  have "gcd(m,n) dvd m" by simp
  2.2754 -  then obtain "k" where "m = gcd(m,n) * k" using dvd_def by auto
  2.2755 -  then have "m*n div gcd(m,n) = (gcd(m,n)*k)*n div gcd(m,n)" by (simp add: mult_ac)
  2.2756 -  also have "\<dots> = n*k" using mpos npos gcd_zero by simp
  2.2757 -  finally show ?thesis by (simp add: lcm_def)
  2.2758 -qed
  2.2759 -
  2.2760 -lemma ilcm_dvd1: 
  2.2761 -assumes anz: "a \<noteq> 0" 
  2.2762 -  and bnz: "b \<noteq> 0"
  2.2763 -  shows "a dvd (ilcm a b)"
  2.2764 -proof-
  2.2765 -  let ?na = "nat (abs a)"
  2.2766 -  let ?nb = "nat (abs b)"
  2.2767 -  have nap: "?na >0" using anz by simp
  2.2768 -  have nbp: "?nb >0" using bnz by simp
  2.2769 -  from nap nbp have "?na dvd lcm(?na,?nb)" using lcm_dvd1 by simp
  2.2770 -  thus ?thesis by (simp add: ilcm_def dvd_int_iff)
  2.2771 -qed
  2.2772 -
  2.2773 -
  2.2774 -lemma ilcm_dvd2: 
  2.2775 -assumes anz: "a \<noteq> 0" 
  2.2776 -  and bnz: "b \<noteq> 0"
  2.2777 -  shows "b dvd (ilcm a b)"
  2.2778 -proof-
  2.2779 -  let ?na = "nat (abs a)"
  2.2780 -  let ?nb = "nat (abs b)"
  2.2781 -  have nap: "?na >0" using anz by simp
  2.2782 -  have nbp: "?nb >0" using bnz by simp
  2.2783 -  from nap nbp have "?nb dvd lcm(?na,?nb)" using lcm_dvd2 by simp
  2.2784 -  thus ?thesis by (simp add: ilcm_def dvd_int_iff)
  2.2785 -qed
  2.2786 -
  2.2787 -lemma zdvd_self_abs1: "(d::int) dvd (abs d)"
  2.2788 -by (case_tac "d <0", simp_all)
  2.2789 -
  2.2790 -lemma zdvd_self_abs2: "(abs (d::int)) dvd d"
  2.2791 -by (case_tac "d<0", simp_all)
  2.2792 -
  2.2793 -(* lcm a b is positive for positive a and b *)
  2.2794 -
  2.2795 -lemma lcm_pos: 
  2.2796 -  assumes mpos: "m > 0"
  2.2797 -  and npos: "n>0"
  2.2798 -  shows "lcm (m,n) > 0"
  2.2799 -
  2.2800 -proof(rule ccontr, simp add: lcm_def gcd_zero)
  2.2801 -assume h:"m*n div gcd(m,n) = 0"
  2.2802 -from mpos npos have "gcd (m,n) \<noteq> 0" using gcd_zero by simp
  2.2803 -hence gcdp: "gcd(m,n) > 0" by simp
  2.2804 -with h
  2.2805 -have "m*n < gcd(m,n)"
  2.2806 -  by (cases "m * n < gcd (m, n)") (auto simp add: div_if[OF gcdp, where m="m*n"])
  2.2807 -moreover 
  2.2808 -have "gcd(m,n) dvd m" by simp
  2.2809 - with mpos dvd_imp_le have t1:"gcd(m,n) \<le> m" by simp
  2.2810 - with npos have t1:"gcd(m,n)*n \<le> m*n" by simp
  2.2811 - have "gcd(m,n) \<le> gcd(m,n)*n" using npos by simp
  2.2812 - with t1 have "gcd(m,n) \<le> m*n" by arith
  2.2813 -ultimately show "False" by simp
  2.2814 -qed
  2.2815 -
  2.2816 -lemma ilcm_pos: 
  2.2817 -  assumes apos: " 0 < a"
  2.2818 -  and bpos: "0 < b" 
  2.2819 -  shows "0 < ilcm  a b"
  2.2820 -proof-
  2.2821 -  let ?na = "nat (abs a)"
  2.2822 -  let ?nb = "nat (abs b)"
  2.2823 -  have nap: "?na >0" using apos by simp
  2.2824 -  have nbp: "?nb >0" using bpos by simp
  2.2825 -  have "0 < lcm (?na,?nb)" by (rule lcm_pos[OF nap nbp])
  2.2826 -  thus ?thesis by (simp add: ilcm_def)
  2.2827 -qed
  2.2828 -
  2.2829 -(* fomlcm computes the lcm of all c, where c is the coeffitient of Var 0 *)
  2.2830 -consts formlcm :: "QF \<Rightarrow> int"
  2.2831 -recdef formlcm "measure size"
  2.2832 -"formlcm (Le (Add (Mult (Cst c) (Var 0)) r) (Cst i)) = abs c "
  2.2833 -"formlcm (Eq (Add (Mult (Cst c) (Var 0)) r) (Cst i)) = abs c "
  2.2834 -"formlcm (Divides (Cst d) (Add (Mult (Cst c) (Var 0)) r)) = abs c"
  2.2835 -"formlcm (NOT p) = formlcm p"
  2.2836 -"formlcm (And p q)= ilcm (formlcm p) (formlcm q)"
  2.2837 -"formlcm (Or p q) = ilcm (formlcm p) (formlcm q)"
  2.2838 -"formlcm p = 1"
  2.2839 -
  2.2840 -(* the property that formlcm should fullfill *)
  2.2841 -consts divideallc:: "int \<times> QF \<Rightarrow> bool"
  2.2842 -recdef divideallc "measure (\<lambda>(i,p). size p)"
  2.2843 -"divideallc (l,Le (Add (Mult (Cst c) (Var 0)) r) (Cst i)) = (c dvd l)"
  2.2844 -"divideallc (l,Eq (Add (Mult (Cst c) (Var 0)) r) (Cst i)) = (c dvd l)"
  2.2845 -"divideallc(l,Divides (Cst d) (Add (Mult (Cst c) (Var 0)) r)) = (c dvd l)"
  2.2846 -"divideallc (l,NOT p) = divideallc(l,p)"
  2.2847 -"divideallc (l,And p q) = (divideallc (l,p) \<and> divideallc (l,q))"
  2.2848 -"divideallc (l,Or p q) = (divideallc (l,p) \<and> divideallc (l,q))"
  2.2849 -"divideallc p = True"
  2.2850 +recdef \<alpha> "measure size"
  2.2851 +  "\<alpha> (And p q) = (\<alpha> p @ \<alpha> q)" 
  2.2852 +  "\<alpha> (Or p q) = (\<alpha> p @ \<alpha> q)" 
  2.2853 +  "\<alpha> (Eq  (CX c e)) = [Add (C -1) e]"
  2.2854 +  "\<alpha> (NEq (CX c e)) = [e]"
  2.2855 +  "\<alpha> (Lt  (CX c e)) = [e]"
  2.2856 +  "\<alpha> (Le  (CX c e)) = [Add (C -1) e]"
  2.2857 +  "\<alpha> (Gt  (CX c e)) = []"
  2.2858 +  "\<alpha> (Ge  (CX c e)) = []"
  2.2859 +  "\<alpha> p = []"
  2.2860 +consts mirror :: "fm \<Rightarrow> fm"
  2.2861 +recdef mirror "measure size"
  2.2862 +  "mirror (And p q) = And (mirror p) (mirror q)" 
  2.2863 +  "mirror (Or p q) = Or (mirror p) (mirror q)" 
  2.2864 +  "mirror (Eq  (CX c e)) = Eq (CX c (Neg e))"
  2.2865 +  "mirror (NEq (CX c e)) = NEq (CX c (Neg e))"
  2.2866 +  "mirror (Lt  (CX c e)) = Gt (CX c (Neg e))"
  2.2867 +  "mirror (Le  (CX c e)) = Ge (CX c (Neg e))"
  2.2868 +  "mirror (Gt  (CX c e)) = Lt (CX c (Neg e))"
  2.2869 +  "mirror (Ge  (CX c e)) = Le (CX c (Neg e))"
  2.2870 +  "mirror (Dvd i (CX c e)) = Dvd i (CX c (Neg e))"
  2.2871 +  "mirror (NDvd i (CX c e)) = NDvd i (CX c (Neg e))"
  2.2872 +  "mirror p = p"
  2.2873 +    (* Lemmas for the correctness of \<sigma>\<rho> *)
  2.2874 +lemma dvd1_eq1: "x >0 \<Longrightarrow> (x::int) dvd 1 = (x = 1)"
  2.2875 +by auto
  2.2876  
  2.2877 -(* formlcm retuns a positive integer *)
  2.2878 -lemma formlcm_pos: 
  2.2879 -  assumes linp: "islinform p"
  2.2880 -  shows "0 < formlcm p"
  2.2881 -using linp
  2.2882 -proof (induct p rule: formlcm.induct, simp_all add: ilcm_pos)
  2.2883 -  case (goal1 c r i)
  2.2884 -  have "i=0 \<or> i \<noteq> 0" by simp
  2.2885 -  moreover
  2.2886 -  {
  2.2887 -    assume "i \<noteq> 0" then have ?case using prems by simp
  2.2888 -  }
  2.2889 -  moreover 
  2.2890 -  {
  2.2891 -    assume iz: "i = 0"
  2.2892 -    then have "islinintterm (Add (Mult (Cst c) (Var 0)) r)" using prems by simp
  2.2893 -    then have "c\<noteq>0" 
  2.2894 -      using prems
  2.2895 -      by (simp add: islininttermc0r[where c="c" and n="0" and r="r"])
  2.2896 -    then have ?case by simp
  2.2897 -  }
  2.2898 -  ultimately 
  2.2899 -  show ?case by blast
  2.2900 -next 
  2.2901 -  case (goal2 c r i)
  2.2902 -  have "i=0 \<or> i \<noteq> 0" by simp
  2.2903 -  moreover
  2.2904 -  {
  2.2905 -    assume "i \<noteq> 0" then have ?case using prems by simp
  2.2906 -  }
  2.2907 -  moreover 
  2.2908 -  {
  2.2909 -    assume iz: "i = 0"
  2.2910 -    then have "islinintterm (Add (Mult (Cst c) (Var 0)) r)" using prems by simp
  2.2911 -    then have "c\<noteq>0" 
  2.2912 -      using prems
  2.2913 -      by (simp add: islininttermc0r[where c="c" and n="0" and r="r"])
  2.2914 -    then have ?case by simp
  2.2915 -  }
  2.2916 -  ultimately 
  2.2917 -  show ?case by blast
  2.2918 -
  2.2919 -next 
  2.2920 -  case (goal3 d c r)
  2.2921 -  show ?case using prems by (simp add: islininttermc0r[where c="c" and n="0" and r="r"])
  2.2922 +lemma minusinf_inf:
  2.2923 +  assumes linp: "iszlfm p"
  2.2924 +  and u: "d\<beta> p 1"
  2.2925 +  shows "\<exists> (z::int). \<forall> x < z. Ifm bbs (x#bs) (minusinf p) = Ifm bbs (x#bs) p"
  2.2926 +  (is "?P p" is "\<exists> (z::int). \<forall> x < z. ?I x (?M p) = ?I x p")
  2.2927 +using linp u
  2.2928 +proof (induct p rule: minusinf.induct)
  2.2929 +  case (1 p q) thus ?case 
  2.2930 +    by (auto simp add: dvd1_eq1) (rule_tac x="min z za" in exI,simp)
  2.2931 +next
  2.2932 +  case (2 p q) thus ?case 
  2.2933 +    by (auto simp add: dvd1_eq1) (rule_tac x="min z za" in exI,simp)
  2.2934  next
  2.2935 -  case (goal4 f)
  2.2936 -  show ?case using prems 
  2.2937 -    by (cases f,auto) (case_tac "intterm2", auto,case_tac "intterm1", auto)
  2.2938 -qed
  2.2939 -
  2.2940 -lemma divideallc_mono: "\<And> c. \<lbrakk> divideallc(c,p) ; c dvd d\<rbrakk> \<Longrightarrow> divideallc (d,p)"
  2.2941 -proof (induct d p rule: divideallc.induct, simp_all)
  2.2942 -  case (goal1 l a b) show ?case by ( rule zdvd_trans [where m="a" and n="b" and k="l"])
  2.2943 +  case (3 c e) hence c1: "c=1" and nb: "numbound0 e" using dvd1_eq1 by simp+
  2.2944 +  hence "\<forall> x<(- Inum (a#bs) e). c*x + Inum (x#bs) e \<noteq> 0"
  2.2945 +  proof(clarsimp)
  2.2946 +    fix x assume "x < (- Inum (a#bs) e)" and"x + Inum (x#bs) e = 0"
  2.2947 +    with numbound0_I[OF nb, where bs="bs" and b="a" and b'="x"]
  2.2948 +    show "False" by simp
  2.2949 +  qed
  2.2950 +  thus ?case by auto
  2.2951  next
  2.2952 -  case (goal2 l a b) show ?case by ( rule zdvd_trans [where m="a" and n="b" and k="l"])
  2.2953 -next
  2.2954 - case (goal3 l a b) show ?case by ( rule zdvd_trans [where m="a" and n="b" and k="l"])
  2.2955 +  case (4 c e) hence c1: "c=1" and nb: "numbound0 e" using dvd1_eq1 by simp+
  2.2956 +  hence "\<forall> x<(- Inum (a#bs) e). c*x + Inum (x#bs) e \<noteq> 0"
  2.2957 +  proof(clarsimp)
  2.2958 +    fix x assume "x < (- Inum (a#bs) e)" and"x + Inum (x#bs) e = 0"
  2.2959 +    with numbound0_I[OF nb, where bs="bs" and b="a" and b'="x"]
  2.2960 +    show "False" by simp
  2.2961 +  qed
  2.2962 +  thus ?case by auto
  2.2963  next
  2.2964 -  case (goal4 l f g k)
  2.2965 -  have  "divideallc (l,g)" using prems by clarsimp
  2.2966 -  moreover have "divideallc (l,f)" using prems by clarsimp
  2.2967 -  ultimately
  2.2968 -  show ?case  by simp
  2.2969 -next 
  2.2970 -  case (goal5 l f g k)
  2.2971 -  have  "divideallc (l,g)" using prems by clarsimp
  2.2972 -  moreover have "divideallc (l,f)" using prems by clarsimp
  2.2973 -  ultimately
  2.2974 -  show ?case  by simp
  2.2975 -  
  2.2976 -qed
  2.2977 -
  2.2978 -(* fomlcm retuns a number all coeffitients of Var 0 divide *)
  2.2979 -
  2.2980 -lemma formlcm_divideallc: 
  2.2981 -  assumes linp: "islinform p"
  2.2982 -  shows "divideallc(formlcm p, p)"
  2.2983 -using linp
  2.2984 -proof (induct p rule: formlcm.induct, simp_all add: zdvd_self_abs1)
  2.2985 -  case (goal1 f)
  2.2986 -  show ?case using prems
  2.2987 -    by (cases f,auto) (case_tac "intterm2", auto, case_tac "intterm1",auto)
  2.2988 -next 
  2.2989 -  case (goal2 f g)
  2.2990 -  have "formlcm f >0" using formlcm_pos prems by simp 
  2.2991 -    hence "formlcm f \<noteq> 0" by simp
  2.2992 -  moreover have "formlcm g > 0" using formlcm_pos prems by simp
  2.2993 -  hence "formlcm g \<noteq> 0" by simp
  2.2994 -  ultimately
  2.2995 -  show ?case using prems formlcm_pos
  2.2996 -     by (simp add: ilcm_dvd1 ilcm_dvd2 
  2.2997 -       divideallc_mono[where c="formlcm f" and d="ilcm (formlcm f) (formlcm g)"]  
  2.2998 -       divideallc_mono[where c="formlcm g" and d="ilcm (formlcm f) (formlcm g)"])
  2.2999 -next 
  2.3000 -  case (goal3 f g)
  2.3001 -  have "formlcm f >0" using formlcm_pos prems by simp 
  2.3002 -    hence "formlcm f \<noteq> 0" by simp
  2.3003 -  moreover have "formlcm g > 0" using formlcm_pos prems by simp
  2.3004 -  hence "formlcm g \<noteq> 0" by simp
  2.3005 -  ultimately
  2.3006 -  show ?case using prems 
  2.3007 -    by (simp add: ilcm_dvd1 ilcm_dvd2 
  2.3008 -      divideallc_mono[where c="formlcm f" and d="ilcm (formlcm f) (formlcm g)"]  
  2.3009 -      divideallc_mono[where c="formlcm g" and d="ilcm (formlcm f) (formlcm g)"])
  2.3010 -qed
  2.3011 -
  2.3012 -(* adjustcoeff transforms the formula given an l , look at correctness thm*)
  2.3013 -consts adjustcoeff :: "int \<times> QF \<Rightarrow> QF"
  2.3014 -recdef adjustcoeff "measure (\<lambda>(l,p). size p)"
  2.3015 -"adjustcoeff (l,(Le (Add (Mult (Cst c) (Var 0)) r) (Cst i))) = 
  2.3016 -  (if c\<le>0 then 
  2.3017 -  Le (Add (Mult (Cst -1) (Var 0)) (lin_mul (- (l div c), r))) (Cst (0::int))
  2.3018 -  else
  2.3019 -  Le (Add (Mult (Cst 1) (Var 0)) (lin_mul (l div c, r))) (Cst (0::int)))"
  2.3020 -"adjustcoeff (l,(Eq (Add (Mult (Cst c) (Var 0)) r) (Cst i))) = 
  2.3021 -  (Eq (Add (Mult (Cst 1) (Var 0)) (lin_mul (l div c, r))) (Cst (0::int)))"
  2.3022 -"adjustcoeff (l,Divides (Cst d) (Add (Mult (Cst c) (Var 0)) r)) = 
  2.3023 -  Divides (Cst ((l div c) * d))
  2.3024 -  (Add (Mult (Cst 1) (Var 0)) (lin_mul (l div c, r)))"
  2.3025 -"adjustcoeff (l,NOT (Divides (Cst d) (Add (Mult (Cst c) (Var 0)) r))) = NOT (Divides (Cst ((l div c) * d))
  2.3026 -  (Add (Mult (Cst 1) (Var 0)) (lin_mul (l div c, r))))"
  2.3027 -"adjustcoeff (l,(NOT(Eq (Add (Mult (Cst c) (Var 0)) r) (Cst i)))) = 
  2.3028 -  (NOT(Eq (Add (Mult (Cst 1) (Var 0)) (lin_mul (l div c, r))) (Cst (0::int))))"
  2.3029 -"adjustcoeff (l,And p q) = And (adjustcoeff (l,p)) (adjustcoeff(l,q))"
  2.3030 -"adjustcoeff (l,Or p q) = Or (adjustcoeff (l,p)) (adjustcoeff(l,q))"
  2.3031 -"adjustcoeff (l,p) = p"
  2.3032 -
  2.3033 -
  2.3034 -(* unitycoeff expects a quantifier free formula an transforms it to an equivalent formula where the bound variable occurs only with coeffitient 1  or -1 *)
  2.3035 -definition
  2.3036 -  unitycoeff :: "QF \<Rightarrow> QF" where
  2.3037 -  "unitycoeff p =
  2.3038 -  (let l = formlcm p;
  2.3039 -       p' = adjustcoeff (l,p)
  2.3040 -   in (if l=1 then p' else 
  2.3041 -      (And (Divides (Cst l) (Add (Mult (Cst 1) (Var 0)) (Cst 0))) p')))"
  2.3042 -
  2.3043 -(* what is a unified formula *)
  2.3044 -consts isunified :: "QF \<Rightarrow> bool"
  2.3045 -recdef isunified "measure size"
  2.3046 -"isunified (Le (Add (Mult (Cst i) (Var 0)) r) (Cst z)) = 
  2.3047 -  ((abs i) = 1  \<and> (islinform(Le (Add (Mult (Cst i) (Var 0)) r) (Cst z))))"
  2.3048 -"isunified (Eq (Add (Mult (Cst i) (Var 0)) r) (Cst z)) = 
  2.3049 -  ((abs i) = 1  \<and> (islinform(Le (Add (Mult (Cst i) (Var 0)) r) (Cst z))))"
  2.3050 -"isunified (NOT(Eq (Add (Mult (Cst i) (Var 0)) r) (Cst z))) = 
  2.3051 -  ((abs i) = 1  \<and> (islinform(Le (Add (Mult (Cst i) (Var 0)) r) (Cst z))))"
  2.3052 -"isunified (Divides (Cst d) (Add (Mult (Cst i) (Var 0)) r)) = 
  2.3053 -  ((abs i) = 1 \<and> (islinform(Divides (Cst d) (Add (Mult (Cst i) (Var 0)) r))))"
  2.3054 -"isunified (NOT(Divides (Cst d) (Add (Mult (Cst i) (Var 0)) r))) = 
  2.3055 -  ((abs i) = 1 \<and> (islinform(NOT(Divides (Cst d) (Add (Mult (Cst i) (Var 0)) r)))))"
  2.3056 -"isunified (And p q) = (isunified p \<and> isunified q)"
  2.3057 -"isunified (Or p q) = (isunified p \<and> isunified q)"
  2.3058 -"isunified p = islinform p"
  2.3059 -
  2.3060 -lemma unified_islinform: "isunified p \<Longrightarrow> islinform p"
  2.3061 -by (induct p rule: isunified.induct) auto
  2.3062 +  case (5 c e) hence c1: "c=1" and nb: "numbound0 e" using dvd1_eq1 by simp+
  2.3063 +  hence "\<forall> x<(- Inum (a#bs) e). c*x + Inum (x#bs) e < 0"
  2.3064 +  proof(clarsimp)
  2.3065 +    fix x assume "x < (- Inum (a#bs) e)" 
  2.3066 +    with numbound0_I[OF nb, where bs="bs" and b="a" and b'="x"]
  2.3067 +    show "x + Inum (x#bs) e < 0" by simp
  2.3068 +  qed
  2.3069 +  thus ?case by auto
  2.3070 +next
  2.3071 +  case (6 c e) hence c1: "c=1" and nb: "numbound0 e" using dvd1_eq1 by simp+
  2.3072 +  hence "\<forall> x<(- Inum (a#bs) e). c*x + Inum (x#bs) e \<le> 0"
  2.3073 +  proof(clarsimp)
  2.3074 +    fix x assume "x < (- Inum (a#bs) e)" 
  2.3075 +    with numbound0_I[OF nb, where bs="bs" and b="a" and b'="x"]
  2.3076 +    show "x + Inum (x#bs) e \<le> 0" by simp
  2.3077 +  qed
  2.3078 +  thus ?case by auto
  2.3079 +next
  2.3080 +  case (7 c e) hence c1: "c=1" and nb: "numbound0 e" using dvd1_eq1 by simp+
  2.3081 +  hence "\<forall> x<(- Inum (a#bs) e). \<not> (c*x + Inum (x#bs) e > 0)"
  2.3082 +  proof(clarsimp)
  2.3083 +    fix x assume "x < (- Inum (a#bs) e)" and"x + Inum (x#bs) e > 0"
  2.3084 +    with numbound0_I[OF nb, where bs="bs" and b="a" and b'="x"]
  2.3085 +    show "False" by simp
  2.3086 +  qed
  2.3087 +  thus ?case by auto
  2.3088 +next
  2.3089 +  case (8 c e) hence c1: "c=1" and nb: "numbound0 e" using dvd1_eq1 by simp+
  2.3090 +  hence "\<forall> x<(- Inum (a#bs) e). \<not> (c*x + Inum (x#bs) e \<ge> 0)"
  2.3091 +  proof(clarsimp)
  2.3092 +    fix x assume "x < (- Inum (a#bs) e)" and"x + Inum (x#bs) e \<ge> 0"
  2.3093 +    with numbound0_I[OF nb, where bs="bs" and b="a" and b'="x"]
  2.3094 +    show "False" by simp
  2.3095 +  qed
  2.3096 +  thus ?case by auto
  2.3097 +qed auto
  2.3098  
  2.3099 -lemma adjustcoeff_lenpos: 
  2.3100 -  "0 < n \<Longrightarrow> adjustcoeff (l, Le (Add (Mult (Cst i) (Var n)) r) (Cst c)) =
  2.3101 -    Le (Add (Mult (Cst i) (Var n)) r) (Cst c)"
  2.3102 -by (cases n, auto)
  2.3103 -
  2.3104 -lemma adjustcoeff_eqnpos: 
  2.3105 -  "0 < n \<Longrightarrow> adjustcoeff (l, Eq (Add (Mult (Cst i) (Var n)) r) (Cst c)) =
  2.3106 -    Eq (Add (Mult (Cst i) (Var n)) r) (Cst c)"
  2.3107 -by (cases n, auto)
  2.3108 -
  2.3109 -
  2.3110 -(* Properties of adjustcoeff and unitycoeff *)
  2.3111 -
  2.3112 -(* Some simple lemmas used afterwards *)
  2.3113 -lemma zmult_zle_mono: "(i::int) \<le> j \<Longrightarrow> 0 \<le> k \<Longrightarrow> k * i \<le> k * j"
  2.3114 -  apply (erule order_le_less [THEN iffD1, THEN disjE, of "0::int"])
  2.3115 -  apply (erule order_le_less [THEN iffD1, THEN disjE])
  2.3116 -  apply (rule order_less_imp_le)
  2.3117 -  apply (rule zmult_zless_mono2)
  2.3118 -  apply simp_all
  2.3119 -  done
  2.3120 +lemma minusinf_repeats:
  2.3121 +  assumes d: "d\<delta> p d" and linp: "iszlfm p"
  2.3122 +  shows "Ifm bbs ((x - k*d)#bs) (minusinf p) = Ifm bbs (x #bs) (minusinf p)"
  2.3123 +using linp d
  2.3124 +proof(induct p rule: iszlfm.induct) 
  2.3125 +  case (9 i c e) hence nbe: "numbound0 e"  and id: "i dvd d" by simp+
  2.3126 +    hence "\<exists> k. d=i*k" by (simp add: dvd_def)
  2.3127 +    then obtain "di" where di_def: "d=i*di" by blast
  2.3128 +    show ?case 
  2.3129 +    proof(simp add: numbound0_I[OF nbe,where bs="bs" and b="x - k * d" and b'="x"] right_diff_distrib, rule iffI)
  2.3130 +      assume 
  2.3131 +	"i dvd c * x - c*(k*d) + Inum (x # bs) e"
  2.3132 +      (is "?ri dvd ?rc*?rx - ?rc*(?rk*?rd) + ?I x e" is "?ri dvd ?rt")
  2.3133 +      hence "\<exists> (l::int). ?rt = i * l" by (simp add: dvd_def)
  2.3134 +      hence "\<exists> (l::int). c*x+ ?I x e = i*l+c*(k * i*di)" 
  2.3135 +	by (simp add: ring_eq_simps di_def)
  2.3136 +      hence "\<exists> (l::int). c*x+ ?I x e = i*(l + c*k*di)"
  2.3137 +	by (simp add: ring_eq_simps)
  2.3138 +      hence "\<exists> (l::int). c*x+ ?I x e = i*l" by blast
  2.3139 +      thus "i dvd c*x + Inum (x # bs) e" by (simp add: dvd_def) 
  2.3140 +    next
  2.3141 +      assume 
  2.3142 +	"i dvd c*x + Inum (x # bs) e" (is "?ri dvd ?rc*?rx+?e")
  2.3143 +      hence "\<exists> (l::int). c*x+?e = i*l" by (simp add: dvd_def)
  2.3144 +      hence "\<exists> (l::int). c*x - c*(k*d) +?e = i*l - c*(k*d)" by simp
  2.3145 +      hence "\<exists> (l::int). c*x - c*(k*d) +?e = i*l - c*(k*i*di)" by (simp add: di_def)
  2.3146 +      hence "\<exists> (l::int). c*x - c*(k*d) +?e = i*((l - c*k*di))" by (simp add: ring_eq_simps)
  2.3147 +      hence "\<exists> (l::int). c*x - c * (k*d) +?e = i*l"
  2.3148 +	by blast
  2.3149 +      thus "i dvd c*x - c*(k*d) + Inum (x # bs) e" by (simp add: dvd_def)
  2.3150 +    qed
  2.3151 +next
  2.3152 +  case (10 i c e)  hence nbe: "numbound0 e"  and id: "i dvd d" by simp+
  2.3153 +    hence "\<exists> k. d=i*k" by (simp add: dvd_def)
  2.3154 +    then obtain "di" where di_def: "d=i*di" by blast
  2.3155 +    show ?case 
  2.3156 +    proof(simp add: numbound0_I[OF nbe,where bs="bs" and b="x - k * d" and b'="x"] right_diff_distrib, rule iffI)
  2.3157 +      assume 
  2.3158 +	"i dvd c * x - c*(k*d) + Inum (x # bs) e"
  2.3159 +      (is "?ri dvd ?rc*?rx - ?rc*(?rk*?rd) + ?I x e" is "?ri dvd ?rt")
  2.3160 +      hence "\<exists> (l::int). ?rt = i * l" by (simp add: dvd_def)
  2.3161 +      hence "\<exists> (l::int). c*x+ ?I x e = i*l+c*(k * i*di)" 
  2.3162 +	by (simp add: ring_eq_simps di_def)
  2.3163 +      hence "\<exists> (l::int). c*x+ ?I x e = i*(l + c*k*di)"
  2.3164 +	by (simp add: ring_eq_simps)
  2.3165 +      hence "\<exists> (l::int). c*x+ ?I x e = i*l" by blast
  2.3166 +      thus "i dvd c*x + Inum (x # bs) e" by (simp add: dvd_def) 
  2.3167 +    next
  2.3168 +      assume 
  2.3169 +	"i dvd c*x + Inum (x # bs) e" (is "?ri dvd ?rc*?rx+?e")
  2.3170 +      hence "\<exists> (l::int). c*x+?e = i*l" by (simp add: dvd_def)
  2.3171 +      hence "\<exists> (l::int). c*x - c*(k*d) +?e = i*l - c*(k*d)" by simp
  2.3172 +      hence "\<exists> (l::int). c*x - c*(k*d) +?e = i*l - c*(k*i*di)" by (simp add: di_def)
  2.3173 +      hence "\<exists> (l::int). c*x - c*(k*d) +?e = i*((l - c*k*di))" by (simp add: ring_eq_simps)
  2.3174 +      hence "\<exists> (l::int). c*x - c * (k*d) +?e = i*l"
  2.3175 +	by blast
  2.3176 +      thus "i dvd c*x - c*(k*d) + Inum (x # bs) e" by (simp add: dvd_def)
  2.3177 +    qed
  2.3178 +qed (auto simp add: nth_pos2 numbound0_I[where bs="bs" and b="x - k*d" and b'="x"])
  2.3179  
  2.3180 -lemma zmult_zle_mono_eq:
  2.3181 -  assumes kpos: "0 < k"
  2.3182 -  shows "((i::int) \<le> j) = (k*i \<le> k*j)" (is "?P = ?Q")
  2.3183 -proof
  2.3184 -  assume P: ?P
  2.3185 -  from kpos have kge0: "0 \<le> k" by simp
  2.3186 -  show ?Q
  2.3187 -    by (rule zmult_zle_mono[OF P kge0])
  2.3188 -next 
  2.3189 -  assume ?Q
  2.3190 -  then have "k*i - k*j \<le> 0" by simp
  2.3191 -  then have le1: "k*(i-j) \<le> k*0"
  2.3192 -    by (simp add: zdiff_zmult_distrib2)
  2.3193 -  have "i -j \<le> 0" 
  2.3194 -    by (rule mult_left_le_imp_le[OF le1 kpos])
  2.3195 -  then 
  2.3196 -  show ?P by simp
  2.3197 -qed
  2.3198 -  
  2.3199 -
  2.3200 -lemma adjustcoeff_le_corr:
  2.3201 -  assumes lpos: "0 < l"
  2.3202 -  and ipos: "0 < (i::int)"
  2.3203 -  and dvd: "i dvd l"
  2.3204 -  shows "(i*x + r \<le> 0) = (l*x + ((l div i)*r) \<le> 0)"
  2.3205 -proof-
  2.3206 -  from lpos ipos have ilel: "i\<le>l" by (simp add: zdvd_imp_le [OF dvd lpos])
  2.3207 -  from ipos have inz: "i \<noteq> 0" by simp
  2.3208 -  have "i div i\<le> l div i"
  2.3209 -    by (simp add: zdiv_mono1[OF ilel ipos])
  2.3210 -  then have ldivipos:"0 < l div i" 
  2.3211 -    by (simp add: zdiv_self[OF inz])
  2.3212 -  
  2.3213 -  from dvd have "\<exists>i'. i*i' = l" by (auto simp add: dvd_def)
  2.3214 -  then obtain "i'" where ii'eql: "i*i' = l" by blast
  2.3215 -  have "(i * x + r \<le> 0) = (l div i * (i * x + r) \<le> l div i * 0)"
  2.3216 -    by (rule zmult_zle_mono_eq[OF ldivipos, where i="i*x + r" and j="0"])
  2.3217 -  also
  2.3218 -  have "(l div i * (i * x + r) \<le> l div i * 0) = ((l div i * i) * x + ((l div i)*r) \<le> 0)"
  2.3219 -    by (simp add: mult_ac)
  2.3220 -  also have "((l div i * i) * x + ((l div i)*r) \<le> 0) = (l*x + ((l div i)*r) \<le> 0)"
  2.3221 -    using sym[OF ii'eql] inz
  2.3222 -    by (simp add: zmult_ac)
  2.3223 -  finally  
  2.3224 -  show ?thesis
  2.3225 -    by simp
  2.3226 -qed
  2.3227 -
  2.3228 -lemma adjustcoeff_le_corr2:
  2.3229 -  assumes lpos: "0 < l"
  2.3230 -  and ineg: "(i::int) < 0"
  2.3231 -  and dvd: "i dvd l"
  2.3232 -  shows "(i*x + r \<le> 0) = ((-l)*x + ((-(l div i))*r) \<le> 0)"
  2.3233 +    (* Is'nt this beautiful?*)
  2.3234 +lemma minusinf_ex:
  2.3235 +  assumes lin: "iszlfm p" and u: "d\<beta> p 1"
  2.3236 +  and exmi: "\<exists> (x::int). Ifm bbs (x#bs) (minusinf p)" (is "\<exists> x. ?P1 x")
  2.3237 +  shows "\<exists> (x::int). Ifm bbs (x#bs) p" (is "\<exists> x. ?P x")
  2.3238  proof-
  2.3239 -  from dvd have midvdl: "-i dvd l" by simp
  2.3240 -  from ineg have mipos: "0 < -i" by simp
  2.3241 -  from lpos ineg have milel: "-i\<le>l" by (simp add: zdvd_imp_le [OF midvdl lpos])
  2.3242 -  from ineg have inz: "i \<noteq> 0" by simp
  2.3243 -  have "l div i\<le> -i div i"
  2.3244 -    by (simp add: zdiv_mono1_neg[OF milel ineg])
  2.3245 -  then have "l div i \<le> -1" 
  2.3246 -    apply (simp add: zdiv_zminus1_eq_if[OF inz, where a="i"])
  2.3247 -    by (simp add: zdiv_self[OF inz])
  2.3248 -  then have ldivineg: "l div i < 0" by simp
  2.3249 -  then have mldivipos: "0 < - (l div i)" by simp
  2.3250 -  
  2.3251 -  from dvd have "\<exists>i'. i*i' = l" by (auto simp add: dvd_def)
  2.3252 -  then obtain "i'" where ii'eql: "i*i' = l" by blast
  2.3253 -  have "(i * x + r \<le> 0) = (- (l div i) * (i * x + r) \<le> - (l div i) * 0)"
  2.3254 -    by (rule zmult_zle_mono_eq[OF mldivipos, where i="i*x + r" and j="0"])
  2.3255 -  also
  2.3256 -  have "(- (l div i) * (i * x + r) \<le> - (l div i) * 0) = (-((l div i) * i) * x \<le> (l div i)*r)"
  2.3257 -    by (simp add: mult_ac)
  2.3258 -  also have " (-((l div i) * i) * x \<le> (l div i)*r) = (- (l*x) \<le> (l div i)*r)"
  2.3259 -    using sym[OF ii'eql] inz
  2.3260 -    by (simp add: zmult_ac)
  2.3261 -  finally  
  2.3262 -  show ?thesis
  2.3263 -    by simp
  2.3264 -qed
  2.3265 -
  2.3266 -(* FIXME : Move this theorem above, it simplifies the 2 theorems above : adjustcoeff_le_corr1,2 *)
  2.3267 -lemma dvd_div_pos: 
  2.3268 -  assumes bpos: "0 < (b::int)"
  2.3269 -  and anz: "a\<noteq>0"
  2.3270 -  and dvd: "a dvd b"
  2.3271 -  shows "(b div a)*a = b"
  2.3272 -proof-
  2.3273 -  from anz have "0 < a \<or> a < 0" by arith
  2.3274 -  moreover
  2.3275 -  {
  2.3276 -    assume apos: "0 < a" 
  2.3277 -    from bpos apos have aleb: "a\<le>b" by (simp add: zdvd_imp_le [OF dvd bpos])
  2.3278 -    have "a div a\<le> b div a"
  2.3279 -      by (simp add: zdiv_mono1[OF aleb apos])
  2.3280 -    then have bdivapos:"0 < b div a" 
  2.3281 -      by (simp add: zdiv_self[OF anz])
  2.3282 -    
  2.3283 -    from dvd have "\<exists>a'. a*a' = b" by (auto simp add: dvd_def)
  2.3284 -    then obtain "a'" where aa'eqb: "a*a' = b" by blast
  2.3285 -    then have ?thesis  using anz sym[OF aa'eqb] by simp
  2.3286 -    
  2.3287 -  }
  2.3288 -  moreover
  2.3289 -  {
  2.3290 -    assume aneg: "a < 0"
  2.3291 -    from dvd have midvdb: "-a dvd b" by simp
  2.3292 -    from aneg have mapos: "0 < -a" by simp
  2.3293 -    from bpos aneg have maleb: "-a\<le>b" by (simp add: zdvd_imp_le [OF midvdb bpos])
  2.3294 -    from aneg have anz: "a \<noteq> 0" by simp
  2.3295 -    have "b div a\<le> -a div a"
  2.3296 -      by (simp add: zdiv_mono1_neg[OF maleb aneg])
  2.3297 -    then have "b div a \<le> -1" 
  2.3298 -      apply (simp add: zdiv_zminus1_eq_if[OF anz, where a="a"])
  2.3299 -      by (simp add: zdiv_self[OF anz])
  2.3300 -    then have bdivaneg: "b div a < 0" by simp
  2.3301 -    then have mbdivapos: "0 < - (b div a)" by simp
  2.3302 -    
  2.3303 -    from dvd have "\<exists>a'. a*a' = b" by (auto simp add: dvd_def)
  2.3304 -    then obtain "a'" where aa'eqb: "a*a' = b" by blast
  2.3305 -    then have ?thesis using anz sym[OF aa'eqb] by (simp)
  2.3306 -  }
  2.3307 -  ultimately show ?thesis by blast
  2.3308 -qed
  2.3309 -
  2.3310 -lemma adjustcoeff_eq_corr: 
  2.3311 -  assumes lpos: "(0::int) < l"
  2.3312 -  and inz: "i \<noteq> 0"
  2.3313 -  and dvd: "i dvd l"
  2.3314 -  shows "(i*x + r = 0) = (l*x + ((l div i)*r) = 0)"
  2.3315 -proof-
  2.3316 -  have ldvdii: "(l div i)*i = l" by (rule dvd_div_pos[OF lpos inz dvd])
  2.3317 -  have ldivinz: "l div i \<noteq> 0" using inz ldvdii lpos by auto
  2.3318 -  have "(i*x + r = 0) = ((l div i)*(i*x + r) = (l div i)*0)"
  2.3319 -    using ldivinz by arith
  2.3320 -  also have "\<dots> = (((l div i)*i)*x + (l div i)*r = 0)"
  2.3321 -    by (simp add: zmult_ac)
  2.3322 -  finally show ?thesis using ldvdii by simp
  2.3323 +  let ?d = "\<delta> p"
  2.3324 +  from \<delta> [OF lin] have dpos: "?d >0" by simp
  2.3325 +  from \<delta> [OF lin] have alld: "d\<delta> p ?d" by simp
  2.3326 +  from minusinf_repeats[OF alld lin] have th1:"\<forall> x k. ?P1 x = ?P1 (x - (k * ?d))" by simp
  2.3327 +  from minusinf_inf[OF lin u] have th2:"\<exists> z. \<forall> x. x<z \<longrightarrow> (?P x = ?P1 x)" by blast
  2.3328 +  from minusinfinity [OF dpos th1 th2] exmi show ?thesis by blast
  2.3329  qed
  2.3330  
  2.3331 -
  2.3332 -
  2.3333 -(* Correctness theorem for adjustcoeff *)
  2.3334 -lemma adjustcoeff_corr:
  2.3335 -  assumes linp: "islinform p"
  2.3336 -  and alldvd: "divideallc (l,p)"
  2.3337 -  and lpos: "0 < l"
  2.3338 -  shows "qinterp (a#ats) p = qinterp ((a*l)#ats) (adjustcoeff(l, p))"
  2.3339 -using linp alldvd
  2.3340 -proof (induct p rule: islinform.induct,simp_all)
  2.3341 -  case (goal1 t c)
  2.3342 -  from prems have cz: "c=0" by simp
  2.3343 -    then have ?case
  2.3344 -      using prems
  2.3345 -    proof(induct t rule: islinintterm.induct)
  2.3346 -      case (2 i n i') show ?case using prems
  2.3347 -	proof-
  2.3348 -	  from prems have "i\<noteq>0" by simp
  2.3349 -	  then 
  2.3350 -	  have "(n=0 \<and> i < 0) \<or> (n=0 \<and> i > 0) \<or> n\<noteq>0" by arith
  2.3351 -	  moreover 
  2.3352 -	  {
  2.3353 -	    assume "n\<noteq>0" then have ?thesis 
  2.3354 -	      by (simp add: nth_pos2 adjustcoeff_lenpos)
  2.3355 -	  }
  2.3356 -	  moreover
  2.3357 -	  {
  2.3358 -	    assume nz: "n=0"
  2.3359 -	      and ipos: "0 < i"
  2.3360 -	    from prems nz have idvdl: "i dvd l" by simp
  2.3361 -	    have "(i*a + i' \<le> 0) = (l*a+ ((l div i)*i') \<le> 0)" 
  2.3362 -	      by (rule adjustcoeff_le_corr[OF lpos ipos idvdl])
  2.3363 -	    then 
  2.3364 -	    have ?thesis using prems by (simp add: mult_ac)
  2.3365 -	  }
  2.3366 -	  moreover
  2.3367 -	  {
  2.3368 -	    assume nz: "n=0"
  2.3369 -	      and ineg: "i < 0"
  2.3370 -	    from prems nz have idvdl: "i dvd l" by simp
  2.3371 -	    have "(i*a+i' \<le> 0) = (-l*a + (-(l div i) * i') \<le> 0)"
  2.3372 -	      by (rule adjustcoeff_le_corr2[OF lpos ineg idvdl])
  2.3373 -	    then 
  2.3374 -	    have ?thesis using prems
  2.3375 -	      by (simp add: zmult_ac)
  2.3376 -	  }
  2.3377 -	  ultimately show ?thesis by blast
  2.3378 -	qed
  2.3379 -      next
  2.3380 -	case (3 i n i' n' r) show ?case  using prems
  2.3381 -	proof-
  2.3382 -	  from prems 
  2.3383 -	  have lininrp: "islinintterm (Add (Mult (Cst i') (Var n')) r)" 
  2.3384 -	    by simp
  2.3385 -	  then
  2.3386 -	  have "islint (Add (Mult (Cst i') (Var n')) (r))" 
  2.3387 -	    by (simp add: islinintterm_eq_islint)
  2.3388 -	  then have linr: "islintn(Suc n',r)"
  2.3389 -	    by (simp add: islinintterm_subt[OF lininrp] islinintterm_eq_islint islint_def)
  2.3390 -	  from lininrp have linr2: "islinintterm r"
  2.3391 -	    by (simp add: islinintterm_subt[OF lininrp])
  2.3392 -	  from prems have "n < n'" by simp
  2.3393 -	  then have nppos: "0 < n'" by simp
  2.3394 -	  from prems have "i\<noteq>0" by simp
  2.3395 -	  then 
  2.3396 -	  have "(n=0 \<and> i < 0) \<or> (n=0 \<and> i > 0) \<or> n\<noteq>0" by arith
  2.3397 -	  moreover 
  2.3398 -	  {
  2.3399 -	    assume nnz: "n\<noteq>0"
  2.3400 -	    from linr have ?thesis using nppos nnz intterm_novar0[OF lininrp] prems
  2.3401 -	      apply (simp add: adjustcoeff_lenpos linterm_novar0[OF linr, where x="a" and y="a*l"])
  2.3402 -	      by (simp add: nth_pos2)
  2.3403 -	      
  2.3404 -	  }
  2.3405 -	  moreover
  2.3406 -	  {
  2.3407 -	    assume nz: "n=0"
  2.3408 -	      and ipos: "0 < i"
  2.3409 -	    from prems nz have idvdl: "i dvd l" by simp
  2.3410 -	    have "(i * a + (i' * (a # ats) ! n' + I_intterm (a # ats) r) \<le> 0) =
  2.3411 -	      (l * a + l div i * (i' * (a # ats) ! n' + I_intterm (a # ats) r) \<le> 0)"
  2.3412 -	      by (rule adjustcoeff_le_corr[OF lpos ipos idvdl])
  2.3413 -	    then 
  2.3414 -	    have ?thesis using prems linr linr2
  2.3415 -	      by (simp add: mult_ac nth_pos2 lin_mul_corr 
  2.3416 -		linterm_novar0[OF linr, where x="a" and y="a*l"])
  2.3417 -	  }
  2.3418 -	  moreover
  2.3419 -	  {
  2.3420 -	    assume nz: "n=0"
  2.3421 -	      and ineg: "i < 0"
  2.3422 -	    from prems nz have idvdl: "i dvd l" by simp
  2.3423 -	    have "(i * a + (i' * (a # ats) ! n' + I_intterm (a # ats) r) \<le> 0) =
  2.3424 -	      (- l * a + - (l div i) * (i' * (a # ats) ! n' + I_intterm (a # ats) r) \<le> 0)"
  2.3425 -	      by (rule adjustcoeff_le_corr2[OF lpos ineg idvdl, where  x="a" and r="(i'* (a#ats) ! n' + I_intterm (a#ats) r )"])
  2.3426 -	    then 
  2.3427 -	    have ?thesis using prems linr linr2
  2.3428 -	      by (simp add: zmult_ac nth_pos2 lin_mul_corr 
  2.3429 -		linterm_novar0[OF linr, where x="a" and y="a*l"] )
  2.3430 -	  }
  2.3431 -	  ultimately show ?thesis by blast
  2.3432 -	qed	  
  2.3433 -    qed simp_all
  2.3434 -    then show ?case by simp 
  2.3435 -  
  2.3436 -next
  2.3437 -  case (goal2 t c)
  2.3438 -  from prems have cz: "c=0" by simp
  2.3439 -    then have ?case
  2.3440 -      using prems
  2.3441 -    proof(induct t rule: islinintterm.induct)
  2.3442 -      case (2 i n i') show ?case using prems
  2.3443 -	proof-
  2.3444 -	  from prems have inz: "i\<noteq>0" by simp
  2.3445 -	  then 
  2.3446 -	  have "n=0 \<or> n\<noteq>0" by arith
  2.3447 -	  moreover 
  2.3448 -	  {
  2.3449 -	    assume "n\<noteq>0" then have ?thesis 
  2.3450 -	      by (simp add: nth_pos2 adjustcoeff_eqnpos)
  2.3451 -	  }
  2.3452 -	  moreover
  2.3453 -	  {
  2.3454 -	    assume nz: "n=0"
  2.3455 -	    from prems nz have idvdl: "i dvd l" by simp
  2.3456 -	    have "(i*a + i' = 0) = (l*a+ ((l div i)*i') = 0)" 
  2.3457 -	      by (rule adjustcoeff_eq_corr[OF lpos inz idvdl])
  2.3458 -	    then 
  2.3459 -	    have ?thesis using prems by (simp add: mult_ac)
  2.3460 -	  }
  2.3461 -	  ultimately show ?thesis by blast
  2.3462 -	qed
  2.3463 -      next
  2.3464 -	case (3 i n i' n' r) show ?case  using prems
  2.3465 -	proof-
  2.3466 -	  from prems 
  2.3467 -	  have lininrp: "islinintterm (Add (Mult (Cst i') (Var n')) r)" 
  2.3468 -	    by simp
  2.3469 -	  then
  2.3470 -	  have "islint (Add (Mult (Cst i') (Var n')) (r))" 
  2.3471 -	    by (simp add: islinintterm_eq_islint)
  2.3472 -	  then have linr: "islintn(Suc n',r)"
  2.3473 -	    by (simp add: islinintterm_subt[OF lininrp] islinintterm_eq_islint islint_def)
  2.3474 -	  from lininrp have linr2: "islinintterm r"
  2.3475 -	    by (simp add: islinintterm_subt[OF lininrp])
  2.3476 -	  from prems have "n < n'" by simp
  2.3477 -	  then have nppos: "0 < n'" by simp
  2.3478 -	  from prems have "i\<noteq>0" by simp
  2.3479 -	  then 
  2.3480 -	  have "n=0 \<or> n\<noteq>0" by arith
  2.3481 -	  moreover 
  2.3482 -	  {
  2.3483 -	    assume nnz: "n\<noteq>0"
  2.3484 -	    from linr have ?thesis using nppos nnz intterm_novar0[OF lininrp] prems
  2.3485 -	      apply (simp add: adjustcoeff_eqnpos linterm_novar0[OF linr, where x="a" and y="a*l"])
  2.3486 -	      by (simp add: nth_pos2)
  2.3487 -	      
  2.3488 -	  }
  2.3489 -	  moreover
  2.3490 -	  {
  2.3491 -	    assume nz: "n=0"
  2.3492 -	    from prems have inz: "i \<noteq> 0" by auto
  2.3493 -	    from prems nz have idvdl: "i dvd l" by simp
  2.3494 -	    have "(i * a + (i' * (a # ats) ! n' + I_intterm (a # ats) r) = 0) =
  2.3495 -	      (l * a + l div i * (i' * (a # ats) ! n' + I_intterm (a # ats) r) = 0)"
  2.3496 -	      by (rule adjustcoeff_eq_corr[OF lpos inz idvdl])
  2.3497 -	    then 
  2.3498 -	    have ?thesis using prems linr linr2
  2.3499 -	      by (simp add: mult_ac nth_pos2 lin_mul_corr 
  2.3500 -		linterm_novar0[OF linr, where x="a" and y="a*l"])
  2.3501 -	  }
  2.3502 -	  ultimately show ?thesis by blast
  2.3503 -	qed	  
  2.3504 -    qed simp_all
  2.3505 -    then show ?case by simp 
  2.3506 -  
  2.3507 -next
  2.3508 -  case (goal3 d t) show ?case
  2.3509 -    using prems
  2.3510 -    proof (induct t rule: islinintterm.induct)
  2.3511 -      case (2 i n i') 
  2.3512 -      have "n=0 \<or> (\<exists>m. (n = Suc m))" by arith
  2.3513 -      moreover
  2.3514 -      {
  2.3515 -	assume "\<exists>m. n = Suc m"
  2.3516 -	then have ?case using prems  by auto
  2.3517 -      }
  2.3518 -      moreover 
  2.3519 -      {
  2.3520 -	assume nz: "n=0"
  2.3521 -	from prems have inz: "i\<noteq>0" by simp
  2.3522 -	from prems have idvdl: "i dvd l" by simp
  2.3523 -	have ldiviieql: "l div i * i = l" by (rule dvd_div_pos[OF lpos inz idvdl])
  2.3524 -	with lpos have ldivinz: "0 \<noteq> l div i" by auto
  2.3525 -	  
  2.3526 -	then have ?case using prems
  2.3527 -	  apply simp
  2.3528 -	  apply (simp add: 
  2.3529 -	    ac_dvd_eq[OF ldivinz, where m="d" and c="i" and n="a" and t="i'"] 
  2.3530 -	    ldiviieql)
  2.3531 -	  by (simp add: zmult_commute)
  2.3532 -      }
  2.3533 -      ultimately show ?case by blast
  2.3534 -
  2.3535 -    next 
  2.3536 -      case (3 i n i' n' r)
  2.3537 -      from prems 
  2.3538 -      have lininrp: "islinintterm (Add (Mult (Cst i') (Var n')) r)" 
  2.3539 -	by simp
  2.3540 -      then
  2.3541 -      have "islint (Add (Mult (Cst i') (Var n')) (r))" 
  2.3542 -	by (simp add: islinintterm_eq_islint)
  2.3543 -      then have linr: "islintn(Suc n',r)"
  2.3544 -	by (simp add: islinintterm_subt[OF lininrp] islinintterm_eq_islint islint_def)
  2.3545 -      from lininrp have linr2: "islinintterm r"
  2.3546 -	by (simp add: islinintterm_subt[OF lininrp])
  2.3547 -      from prems have "n < n'" by simp
  2.3548 -      then have nppos: "0 < n'" by simp
  2.3549 -      from prems have inz: "i\<noteq>0" by simp
  2.3550 -      
  2.3551 -      have "n=0 \<or> (\<exists>m. (n = Suc m))" by arith
  2.3552 -      moreover
  2.3553 -      {
  2.3554 -	assume "\<exists>m. n = Suc m"
  2.3555 -	then have npos: "0 < n" by arith
  2.3556 -	have ?case using nppos intterm_novar0[OF lininrp] prems
  2.3557 -	  apply (auto simp add: linterm_novar0[OF linr, where x="a" and y="a*l"])
  2.3558 -	  by (simp_all add: nth_pos2)
  2.3559 -      }
  2.3560 -      moreover 
  2.3561 -      {
  2.3562 -	assume nz: "n=0"
  2.3563 -	from prems have idvdl: "i dvd l" by simp
  2.3564 -	have ldiviieql: "l div i * i = l" by (rule dvd_div_pos[OF lpos inz idvdl])
  2.3565 -	with lpos have ldivinz: "0 \<noteq> l div i" by auto
  2.3566 -	  
  2.3567 -	then have ?case using prems linr2 linr
  2.3568 -	  apply (simp add: nth_pos2 lin_mul_corr linterm_novar0)
  2.3569 -	  
  2.3570 -	  apply (simp add: ac_dvd_eq[OF ldivinz, where m="d" and c="i" and n="a" and t="(i' * ats ! (n' - Suc 0) + I_intterm (a # ats) r)"] ldiviieql)
  2.3571 -	  by (simp add: zmult_ac linterm_novar0[OF linr, where x="a" and y="a*l"])
  2.3572 -      }
  2.3573 -      ultimately show ?case by blast
  2.3574 -      
  2.3575 -    qed simp_all
  2.3576 -next
  2.3577 -  case (goal4 d t) show ?case
  2.3578 -    using prems
  2.3579 -    proof (induct t rule: islinintterm.induct)
  2.3580 -      case (2 i n i') 
  2.3581 -      have "n=0 \<or> (\<exists>m. (n = Suc m))" by arith
  2.3582 -      moreover
  2.3583 -      {
  2.3584 -	assume "\<exists>m. n = Suc m"
  2.3585 -	then have ?case using prems  by auto
  2.3586 -      }
  2.3587 -      moreover 
  2.3588 -      {
  2.3589 -	assume nz: "n=0"
  2.3590 -	from prems have inz: "i\<noteq>0" by simp
  2.3591 -	from prems have idvdl: "i dvd l" by simp
  2.3592 -	have ldiviieql: "l div i * i = l" by (rule dvd_div_pos[OF lpos inz idvdl])
  2.3593 -	with lpos have ldivinz: "0 \<noteq> l div i" by auto
  2.3594 -	  
  2.3595 -	then have ?case using prems
  2.3596 -	  apply simp
  2.3597 -	  apply (simp add: 
  2.3598 -	    ac_dvd_eq[OF ldivinz, where m="d" and c="i" and n="a" and t="i'"] 
  2.3599 -	    ldiviieql)
  2.3600 -	  by (simp add: zmult_commute)
  2.3601 -      }
  2.3602 -      ultimately show ?case by blast
  2.3603 -
  2.3604 -    next 
  2.3605 -      case (3 i n i' n' r)
  2.3606 -      from prems 
  2.3607 -      have lininrp: "islinintterm (Add (Mult (Cst i') (Var n')) r)" 
  2.3608 -	by simp
  2.3609 -      then
  2.3610 -      have "islint (Add (Mult (Cst i') (Var n')) (r))" 
  2.3611 -	by (simp add: islinintterm_eq_islint)
  2.3612 -      then have linr: "islintn(Suc n',r)"
  2.3613 -	by (simp add: islinintterm_subt[OF lininrp] islinintterm_eq_islint islint_def)
  2.3614 -      from lininrp have linr2: "islinintterm r"
  2.3615 -	by (simp add: islinintterm_subt[OF lininrp])
  2.3616 -      from prems have "n < n'" by simp
  2.3617 -      then have nppos: "0 < n'" by simp
  2.3618 -      from prems have inz: "i\<noteq>0" by simp
  2.3619 -      
  2.3620 -      have "n=0 \<or> (\<exists>m. (n = Suc m))" by arith
  2.3621 -      moreover
  2.3622 -      {
  2.3623 -	assume "\<exists>m. n = Suc m"
  2.3624 -	then have npos: "0 < n" by arith
  2.3625 -	have ?case using nppos intterm_novar0[OF lininrp] prems
  2.3626 -	  apply (auto simp add: linterm_novar0[OF linr, where x="a" and y="a*l"])
  2.3627 -	  by (simp_all add: nth_pos2)
  2.3628 -      }
  2.3629 -      moreover 
  2.3630 -      {
  2.3631 -	assume nz: "n=0"
  2.3632 -	from prems have idvdl: "i dvd l" by simp
  2.3633 -	have ldiviieql: "l div i * i = l" by (rule dvd_div_pos[OF lpos inz idvdl])
  2.3634 -	with lpos have ldivinz: "0 \<noteq> l div i" by auto
  2.3635 -	  
  2.3636 -	then have ?case using prems linr2 linr
  2.3637 -	  apply (simp add: nth_pos2 lin_mul_corr linterm_novar0)
  2.3638 -	  
  2.3639 -	  apply (simp add: ac_dvd_eq[OF ldivinz, where m="d" and c="i" and n="a" and t="(i' * ats ! (n' - Suc 0) + I_intterm (a # ats) r)"] ldiviieql)
  2.3640 -	  by (simp add: zmult_ac linterm_novar0[OF linr, where x="a" and y="a*l"])
  2.3641 -      }
  2.3642 -      ultimately show ?case by blast
  2.3643 -      
  2.3644 -    qed simp_all
  2.3645 -next
  2.3646 -    case (goal5 t c)
  2.3647 -  from prems have cz: "c=0" by simp
  2.3648 -    then have ?case
  2.3649 -      using prems
  2.3650 -    proof(induct t rule: islinintterm.induct)
  2.3651 -      case (2 i n i') show ?case using prems
  2.3652 -	proof-
  2.3653 -	  from prems have inz: "i\<noteq>0" by simp
  2.3654 -	  then 
  2.3655 -	  have "n=0 \<or> n\<noteq>0" by arith
  2.3656 -	  moreover 
  2.3657 -	  {
  2.3658 -	    assume "n\<noteq>0" then have ?thesis
  2.3659 -	      using prems
  2.3660 -	      by (cases n, simp_all)
  2.3661 -	  }
  2.3662 -	  moreover
  2.3663 -	  {
  2.3664 -	    assume nz: "n=0"
  2.3665 -	    from prems nz have idvdl: "i dvd l" by simp
  2.3666 -	    have "(i*a + i' = 0) = (l*a+ ((l div i)*i') = 0)" 
  2.3667 -	      by (rule adjustcoeff_eq_corr[OF lpos inz idvdl])
  2.3668 -	    then 
  2.3669 -	    have ?thesis using prems by (simp add: mult_ac)
  2.3670 -	  }
  2.3671 -	  ultimately show ?thesis by blast
  2.3672 -	qed
  2.3673 -      next
  2.3674 -	case (3 i n i' n' r) show ?case  using prems
  2.3675 -	proof-
  2.3676 -	  from prems 
  2.3677 -	  have lininrp: "islinintterm (Add (Mult (Cst i') (Var n')) r)" 
  2.3678 -	    by simp
  2.3679 -	  then
  2.3680 -	  have "islint (Add (Mult (Cst i') (Var n')) (r))" 
  2.3681 -	    by (simp add: islinintterm_eq_islint)
  2.3682 -	  then have linr: "islintn(Suc n',r)"
  2.3683 -	    by (simp add: islinintterm_subt[OF lininrp] islinintterm_eq_islint islint_def)
  2.3684 -	  from lininrp have linr2: "islinintterm r"
  2.3685 -	    by (simp add: islinintterm_subt[OF lininrp])
  2.3686 -	  from prems have "n < n'" by simp
  2.3687 -	  then have nppos: "0 < n'" by simp
  2.3688 -	  from prems have "i\<noteq>0" by simp
  2.3689 -	  then 
  2.3690 -	  have "n=0 \<or> n\<noteq>0" by arith
  2.3691 -	  moreover 
  2.3692 -	  {
  2.3693 -	    assume nnz: "n\<noteq>0"
  2.3694 -	    then have ?thesis using prems linr nppos nnz intterm_novar0[OF lininrp]
  2.3695 -	      by (cases n, simp_all)
  2.3696 -	    (simp add: nth_pos2 linterm_novar0[OF linr, where x="a" and y="a*l"])
  2.3697 -	  }
  2.3698 -	  moreover
  2.3699 -	  {
  2.3700 -	    assume nz: "n=0"
  2.3701 -	    from prems have inz: "i \<noteq> 0" by auto
  2.3702 -	    from prems nz have idvdl: "i dvd l" by simp
  2.3703 -	    have "(i * a + (i' * (a # ats) ! n' + I_intterm (a # ats) r) = 0) =
  2.3704 -	      (l * a + l div i * (i' * (a # ats) ! n' + I_intterm (a # ats) r) = 0)"
  2.3705 -	      by (rule adjustcoeff_eq_corr[OF lpos inz idvdl])
  2.3706 -	    then 
  2.3707 -	    have ?thesis using prems linr linr2
  2.3708 -	      by (simp add: mult_ac nth_pos2 lin_mul_corr 
  2.3709 -		linterm_novar0[OF linr, where x="a" and y="a*l"])
  2.3710 -	  }
  2.3711 -	  ultimately show ?thesis by blast
  2.3712 -	qed	  
  2.3713 -    qed simp_all
  2.3714 -    then show ?case by simp 
  2.3715 -  
  2.3716 -qed
  2.3717 -
  2.3718 -(* unitycoeff preserves semantics *)
  2.3719 -lemma unitycoeff_corr:
  2.3720 -  assumes linp: "islinform p"
  2.3721 -  shows "qinterp ats (QEx p) = qinterp ats (QEx (unitycoeff p))"
  2.3722 +    (*	And This ???*)
  2.3723 +lemma minusinf_bex:
  2.3724 +  assumes lin: "iszlfm p"
  2.3725 +  shows "(\<exists> (x::int). Ifm bbs (x#bs) (minusinf p)) = 
  2.3726 +         (\<exists> (x::int)\<in> {1..\<delta> p}. Ifm bbs (x#bs) (minusinf p))"
  2.3727 +  (is "(\<exists> x. ?P x) = _")
  2.3728  proof-
  2.3729 -  
  2.3730 -  have lpos: "0 < formlcm p" by (rule formlcm_pos[OF linp])
  2.3731 -  have dvd : "divideallc (formlcm p, p)" by (rule formlcm_divideallc[OF linp])
  2.3732 -  show ?thesis  using prems lpos dvd 
  2.3733 -  proof (simp add: unitycoeff_def Let_def,case_tac "formlcm p = 1",
  2.3734 -      simp_all add: adjustcoeff_corr)
  2.3735 -    show "(\<exists>x. qinterp (x * formlcm p # ats) (adjustcoeff (formlcm p, p))) =
  2.3736 -      (\<exists>x. formlcm p dvd x \<and>
  2.3737 -      qinterp (x # ats) (adjustcoeff (formlcm p, p)))"
  2.3738 -      (is "(\<exists>x. ?P(x* (formlcm p))) = (\<exists>x. formlcm p dvd x \<and> ?P x)")
  2.3739 -    proof-
  2.3740 -      have "(\<exists>x. ?P(x* (formlcm p))) = (\<exists>x. ?P((formlcm p)*x))"
  2.3741 -	by (simp add: mult_commute)
  2.3742 -      also have "(\<exists>x. ?P((formlcm p)*x)) = (\<exists>x. (formlcm p dvd x) \<and> ?P x)"
  2.3743 -	by (simp add: unity_coeff_ex[where P="?P"])
  2.3744 -      finally show ?thesis by simp
  2.3745 -    qed
  2.3746 -  qed
  2.3747 -qed
  2.3748 -
  2.3749 -(* the resul of adjustcoeff is unified for all l with divideallc (l,p) *)
  2.3750 -lemma adjustcoeff_unified: 
  2.3751 -  assumes linp: "islinform p"
  2.3752 -  and dvdc: "divideallc(l,p)"
  2.3753 -  and lpos: "l > 0"
  2.3754 -  shows "isunified (adjustcoeff(l, p))"
  2.3755 -  using linp dvdc lpos
  2.3756 -  proof(induct l p rule: adjustcoeff.induct,simp_all add: lin_mul_lintn islinintterm_eq_islint islint_def)
  2.3757 -    case (goal1 l d c r)
  2.3758 -    from prems have "c >0 \<or> c < 0" by auto
  2.3759 -    moreover {
  2.3760 -      assume cpos: "c > 0 "
  2.3761 -      from prems have lp: "l > 0" by simp
  2.3762 -      from prems have cdvdl: "c dvd l" by simp
  2.3763 -      have clel: "c \<le> l" by (rule zdvd_imp_le[OF cdvdl lp])
  2.3764 -      have "c div c \<le>  l div c" by (rule zdiv_mono1[OF clel cpos])
  2.3765 -      then have ?case using cpos by (simp add: zdiv_self)      
  2.3766 -    }
  2.3767 -    moreover {
  2.3768 -      assume cneg: "c < 0"
  2.3769 -      
  2.3770 -     have mcpos: "-c > 0" by simp
  2.3771 -      then have mcnz: "-c \<noteq> 0" by simp
  2.3772 -      from prems have mcdvdl: "-c dvd l" 
  2.3773 -	by simp 
  2.3774 -      then have l1:"l mod -c = 0" by (simp add: zdvd_iff_zmod_eq_0)
  2.3775 -      from prems have lp: "l >0" by simp
  2.3776 -      have mclel: "-c \<le> l" by (rule zdvd_imp_le[OF mcdvdl lp])
  2.3777 -      have "l div c = (-l div -c)"  by simp
  2.3778 -      also have "\<dots> = - (l div -c)" using l1
  2.3779 -	by (simp only: zdiv_zminus1_eq_if[OF mcnz, where a="l"]) simp
  2.3780 -      finally have diveq: "l div c = - (l div -c)" by simp
  2.3781 -      
  2.3782 -      have "-c div -c \<le> l div -c" by (rule zdiv_mono1[OF mclel mcpos])
  2.3783 -      then have "0 < l div -c" using cneg
  2.3784 -	by (simp add: zdiv_self)
  2.3785 -      then have ?case using diveq by simp
  2.3786 -    }
  2.3787 -    ultimately  show ?case by blast
  2.3788 -  next
  2.3789 -    case (goal2 l p)    from prems have "c >0 \<or> c < 0" by auto
  2.3790 -    moreover {
  2.3791 -      assume cpos: "c > 0 "
  2.3792 -      from prems have lp: "l > 0" by simp
  2.3793 -      from prems have cdvdl: "c dvd l" by simp
  2.3794 -      have clel: "c \<le> l" by (rule zdvd_imp_le[OF cdvdl lp])
  2.3795 -      have "c div c \<le>  l div c" by (rule zdiv_mono1[OF clel cpos])
  2.3796 -      then have ?case using cpos by (simp add: zdiv_self)      
  2.3797 -    }
  2.3798 -    moreover {
  2.3799 -      assume cneg: "c < 0"
  2.3800 -      
  2.3801 -     have mcpos: "-c > 0" by simp
  2.3802 -      then have mcnz: "-c \<noteq> 0" by simp
  2.3803 -      from prems have mcdvdl: "-c dvd l" 
  2.3804 -	by simp 
  2.3805 -      then have l1:"l mod -c = 0" by (simp add: zdvd_iff_zmod_eq_0)
  2.3806 -      from prems have lp: "l >0" by simp
  2.3807 -      have mclel: "-c \<le> l" by (rule zdvd_imp_le[OF mcdvdl lp])
  2.3808 -      have "l div c = (-l div -c)"  by simp
  2.3809 -      also have "\<dots> = - (l div -c)" using l1
  2.3810 -	by (simp only: zdiv_zminus1_eq_if[OF mcnz, where a="l"]) simp
  2.3811 -      finally have diveq: "l div c = - (l div -c)" by simp
  2.3812 -      
  2.3813 -      have "-c div -c \<le> l div -c" by (rule zdiv_mono1[OF mclel mcpos])
  2.3814 -      then have "0 < l div -c" using cneg
  2.3815 -	by (simp add: zdiv_self)
  2.3816 -      then have ?case using diveq by simp
  2.3817 -    }
  2.3818 -    ultimately  show ?case by blast
  2.3819 -  qed
  2.3820 -
  2.3821 -lemma adjustcoeff_lcm_unified:
  2.3822 -  assumes linp: "islinform p"
  2.3823 -  shows "isunified (adjustcoeff(formlcm p, p))"
  2.3824 -using linp adjustcoeff_unified formlcm_pos formlcm_divideallc
  2.3825 -by simp
  2.3826 -
  2.3827 -(* the result of unitycoeff is unified *)
  2.3828 -lemma unitycoeff_unified:
  2.3829 -  assumes linp: "islinform p"
  2.3830 -  shows "isunified (unitycoeff p)"
  2.3831 -using linp formlcm_pos[OF linp]
  2.3832 -proof (auto simp add: unitycoeff_def Let_def adjustcoeff_lcm_unified)
  2.3833 -  assume f1: "formlcm p = 1"
  2.3834 -  have "isunified (adjustcoeff(formlcm p, p))" 
  2.3835 -    by (rule adjustcoeff_lcm_unified[OF linp])
  2.3836 -  with f1 
  2.3837 -  show "isunified (adjustcoeff(1,p))" by simp
  2.3838 -qed
  2.3839 -
  2.3840 -lemma unified_isnnf: 
  2.3841 -  assumes unifp: "isunified p"
  2.3842 -  shows "isnnf p"
  2.3843 -  using unified_islinform[OF unifp] linform_isnnf
  2.3844 -  by simp
  2.3845 -
  2.3846 -lemma unified_isqfree: "isunified p\<Longrightarrow> isqfree p"
  2.3847 -using unified_islinform linform_isqfree
  2.3848 -by auto
  2.3849 -
  2.3850 -(* Plus/Minus infinity , B and A set definitions *)
  2.3851 -
  2.3852 -consts minusinf :: "QF \<Rightarrow> QF"
  2.3853 -       plusinf  :: "QF \<Rightarrow> QF"
  2.3854 -       aset     :: "QF \<Rightarrow> intterm list"
  2.3855 -       bset     :: "QF \<Rightarrow> intterm list"
  2.3856 -
  2.3857 -recdef minusinf "measure size"
  2.3858 -"minusinf (Le (Add (Mult (Cst c) (Var 0)) r) z) =
  2.3859 -  (if c < 0 then F else T)"
  2.3860 -"minusinf (Eq (Add (Mult (Cst c) (Var 0)) r) z) = F"
  2.3861 -"minusinf (NOT(Eq (Add (Mult (Cst c) (Var 0)) r) z)) = T"
  2.3862 -"minusinf (And p q) = And (minusinf p) (minusinf q)"
  2.3863 -"minusinf (Or p q) = Or (minusinf p) (minusinf q)"
  2.3864 -"minusinf p = p"
  2.3865 -
  2.3866 -recdef plusinf "measure size"
  2.3867 -"plusinf (Le (Add (Mult (Cst c) (Var 0)) r) z) =
  2.3868 -  (if c < 0 then T else F)"
  2.3869 -"plusinf (Eq (Add (Mult (Cst c) (Var 0)) r) z) = F"
  2.3870 -"plusinf (NOT (Eq (Add (Mult (Cst c) (Var 0)) r) z)) = T"
  2.3871 -"plusinf (And p q) = And (plusinf p) (plusinf q)"
  2.3872 -"plusinf (Or p q) = Or (plusinf p) (plusinf q)"
  2.3873 -"plusinf p = p"
  2.3874 -
  2.3875 -recdef bset "measure size"
  2.3876 -"bset (Le (Add (Mult (Cst c) (Var 0)) r) z) = 
  2.3877 - (if c < 0 then [lin_add(r,(Cst -1)), r]
  2.3878 -         else [lin_add(lin_neg r,(Cst -1))])"
  2.3879 -"bset (Eq (Add (Mult (Cst c) (Var 0)) r) z) =  
  2.3880 -  (if c < 0 then [lin_add(r,(Cst -1))]
  2.3881 -         else [lin_add(lin_neg r,(Cst -1))])"
  2.3882 -"bset (NOT(Eq (Add (Mult (Cst c) (Var 0)) r) z)) =  
  2.3883 -  (if c < 0 then [r]
  2.3884 -         else [lin_neg r])"
  2.3885 -"bset (And p q) = (bset p) @ (bset q)"
  2.3886 -"bset (Or p q) = (bset p) @ (bset q)"
  2.3887 -"bset p = []"
  2.3888 -
  2.3889 -recdef aset "measure size"
  2.3890 -"aset (Le (Add (Mult (Cst c) (Var 0)) r) z) = 
  2.3891 -  (if c < 0 then [lin_add (r, Cst 1)]
  2.3892 -         else [lin_add (lin_neg r, Cst 1), lin_neg r])"
  2.3893 -"aset (Eq (Add (Mult (Cst c) (Var 0)) r) z) = 
  2.3894 -  (if c < 0 then [lin_add(r,(Cst 1))]
  2.3895 -       else [lin_add(lin_neg r,(Cst 1))])"
  2.3896 -"aset (NOT(Eq (Add (Mult (Cst c) (Var 0)) r) z)) = 
  2.3897 -  (if c < 0 then [r] 
  2.3898 -      else [lin_neg r])"
  2.3899 -"aset (And p q) = (aset p) @ (aset q)"
  2.3900 -"aset (Or p q) = (aset p) @ (aset q)"
  2.3901 -"aset p = []"
  2.3902 -
  2.3903 -(* divlcm computes \<delta> = lcm d , where d | x +t occurs in p *)
  2.3904 -consts divlcm :: "QF \<Rightarrow> int"
  2.3905 -recdef divlcm "measure size"
  2.3906 -"divlcm (Divides (Cst d) (Add (Mult (Cst c) (Var 0)) r)) = (abs d)"
  2.3907 -"divlcm (NOT p) = divlcm p"
  2.3908 -"divlcm (And p q)= ilcm (divlcm p) (divlcm q)"
  2.3909 -"divlcm (Or p q) = ilcm (divlcm p) (divlcm q)"
  2.3910 -"divlcm p = 1"
  2.3911 -
  2.3912 -(* the preoperty of \<delta> *)
  2.3913 -consts alldivide :: "int \<times> QF \<Rightarrow> bool"
  2.3914 -recdef alldivide "measure (%(d,p). size p)"
  2.3915 -"alldivide (d,(Divides (Cst d') (Add (Mult (Cst c) (Var 0)) r))) = 
  2.3916 -  (d' dvd d)"
  2.3917 -"alldivide (d,(NOT p)) = alldivide (d,p)"
  2.3918 -"alldivide (d,(And p q)) = (alldivide (d,p) \<and> alldivide (d,q))"
  2.3919 -"alldivide (d,(Or p q)) = ((alldivide (d,p)) \<and> (alldivide (d,q)))"
  2.3920 -"alldivide (d,p) = True"
  2.3921 -
  2.3922 -(* alldivide is monotone *)
  2.3923 -lemma alldivide_mono: "\<And> d'. \<lbrakk> alldivide (d,p) ; d dvd d'\<rbrakk> \<Longrightarrow> alldivide (d',p)"
  2.3924 -proof(induct d p rule: alldivide.induct, simp_all add: ilcm_dvd1 ilcm_dvd2)
  2.3925 -  fix "d1" "d2" "d3"
  2.3926 -  assume th1:"d2 dvd (d1::int)"
  2.3927 -    and th2: "d1 dvd d3"
  2.3928 -  show "d2 dvd d3" by (rule zdvd_trans[OF th1 th2])
  2.3929 -qed
  2.3930 -
  2.3931 -(* Some simple lemmas *)
  2.3932 -lemma zdvd_eq_zdvd_abs: " (d::int) dvd d' = (d dvd (abs d')) "
  2.3933 -proof-
  2.3934 -  have "d' < 0 \<or> d' \<ge> 0" by arith
  2.3935 -  moreover
  2.3936 -  {
  2.3937 -    assume dn': "d' < 0"
  2.3938 -    then have "abs d' = - d'" by simp
  2.3939 -    then 
  2.3940 -    have ?thesis by (simp)
  2.3941 -  }
  2.3942 -  moreover 
  2.3943 -  {
  2.3944 -    assume dp': "d' \<ge> 0"
  2.3945 -    then have "abs d' = d'" by simp
  2.3946 -    then have ?thesis  by simp
  2.3947 -  }
  2.3948 -    ultimately show ?thesis by blast
  2.3949 -qed
  2.3950 -
  2.3951 -lemma zdvd_refl_abs: "(d::int) dvd (abs d)"
  2.3952 -proof-
  2.3953 -  have "d dvd d" by simp
  2.3954 -  then show ?thesis by (simp add: iffD1 [OF zdvd_eq_zdvd_abs [where d = "d" and d'="d"]])
  2.3955 -qed
  2.3956 -
  2.3957 -(* \<delta> > 0*)
  2.3958 -lemma divlcm_pos: 
  2.3959 -  assumes 
  2.3960 -  linp: "islinform p"
  2.3961 -  shows "0 < divlcm p"
  2.3962 -using linp
  2.3963 -proof (induct p rule: divlcm.induct,simp_all add: ilcm_pos)
  2.3964 -  case (goal1 f) show ?case 
  2.3965 -    using prems 
  2.3966 -    by (cases f, auto) (case_tac "intterm1", auto)
  2.3967 -qed
  2.3968 -
  2.3969 -lemma nz_le: "(x::int) > 0 \<Longrightarrow> x \<noteq> 0" by auto
  2.3970 -(* divlcm is correct *)
  2.3971 -lemma divlcm_corr:
  2.3972 -  assumes 
  2.3973 -  linp: "islinform p"
  2.3974 -  shows "alldivide (divlcm p,p)"
  2.3975 -  using linp divlcm_pos
  2.3976 -proof (induct p rule: divlcm.induct,simp_all add: zdvd_refl_abs,clarsimp simp add: Nat.gr0_conv_Suc)
  2.3977 -  case (goal1 f)
  2.3978 -  have "islinform f" using prems  
  2.3979 -    by (cases f, auto) (case_tac "intterm2", auto,case_tac "intterm1", auto)
  2.3980 -  then have "alldivide (divlcm f, f)"  using prems by simp
  2.3981 -  moreover have "divlcm (NOT f) = divlcm f" by simp
  2.3982 -  moreover have "alldivide (x,f) = alldivide (x,NOT f)" by simp
  2.3983 -  ultimately show ?case by simp
  2.3984 -next
  2.3985 -  case (goal2 f g)
  2.3986 -  have dvd1: "(divlcm f) dvd (ilcm (divlcm f) (divlcm g))" 
  2.3987 -    using prems by(simp add: ilcm_dvd1 nz_le)
  2.3988 -  have dvd2: "(divlcm g) dvd (ilcm (divlcm f) (divlcm g))" 
  2.3989 -    using prems by (simp add: ilcm_dvd2 nz_le)
  2.3990 -  from dvd1 prems 
  2.3991 -  have "alldivide (ilcm (divlcm f) (divlcm g), f)" 
  2.3992 -    by (simp add: alldivide_mono[where d= "divlcm f" and p="f" and d' ="ilcm (divlcm f) (divlcm g)"])
  2.3993 -  moreover   from dvd2 prems 
  2.3994 -   have "alldivide (ilcm (divlcm f) (divlcm g), g)" 
  2.3995 -    by (simp add: alldivide_mono[where d= "divlcm g" and p="g" and d' ="ilcm (divlcm f) (divlcm g)"])
  2.3996 -  ultimately show ?case by simp
  2.3997 -next
  2.3998 -  case (goal3 f g)
  2.3999 -  have dvd1: "(divlcm f) dvd (ilcm (divlcm f) (divlcm g))" 
  2.4000 -    using prems by (simp add: nz_le ilcm_dvd1)
  2.4001 -  have dvd2: "(divlcm g) dvd (ilcm (divlcm f) (divlcm g))" 
  2.4002 -    using prems by (simp add: nz_le ilcm_dvd2)
  2.4003 -  from dvd1 prems 
  2.4004 -  have "alldivide (ilcm (divlcm f) (divlcm g), f)" 
  2.4005 -    by (simp add: alldivide_mono[where d= "divlcm f" and p="f" and d' ="ilcm (divlcm f) (divlcm g)"])
  2.4006 -  moreover   from dvd2 prems 
  2.4007 -   have "alldivide (ilcm (divlcm f) (divlcm g), g)" 
  2.4008 -    by (simp add: alldivide_mono[where d= "divlcm g" and p="g" and d' ="ilcm (divlcm f) (divlcm g)"])
  2.4009 -  ultimately show ?case by simp
  2.4010 -qed
  2.4011 -
  2.4012 -
  2.4013 -(* Properties of  minusinf and plusinf*)
  2.4014 -
  2.4015 -(* minusinf p and p are the same for minusinfity \<dots> *)
  2.4016 -lemma minusinf_eq: 
  2.4017 -  assumes unifp: "isunified p" 
  2.4018 -  shows "\<exists> z. \<forall> x. x < z \<longrightarrow> (qinterp (x#ats) p = qinterp (x#ats) (minusinf p))"
  2.4019 -using unifp unified_islinform[OF unifp]
  2.4020 -proof (induct p rule: minusinf.induct)
  2.4021 -  case (1 c r z)
  2.4022 -  have "c <0 \<or> 0 \<le> c" by arith
  2.4023 -  moreover 
  2.4024 -  {
  2.4025 -    assume cneg: " c < 0"
  2.4026 -    from prems have z0: "z= Cst 0" 
  2.4027 -      by (cases z,auto)
  2.4028 -    with prems have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" 
  2.4029 -      by simp
  2.4030 -
  2.4031 -    from prems z0 have ?case 
  2.4032 -      proof-
  2.4033 -	show ?thesis
  2.4034 -	  using prems z0
  2.4035 -      apply auto
  2.4036 -      apply (rule exI[where x="I_intterm (a # ats) r"])
  2.4037 -      apply (rule allI)
  2.4038 -      proof-
  2.4039 -	fix x
  2.4040 -	show "x < I_intterm (a # ats) r \<longrightarrow> \<not> - x + I_intterm (x # ats) r \<le> 0"
  2.4041 -	  by (simp add: intterm_novar0[OF lincnr, where x="a" and y="x"])
  2.4042 -      qed
  2.4043 -    qed
  2.4044 -  }
  2.4045 -  moreover
  2.4046 -  {
  2.4047 -    assume cpos: "0 \<le> c"
  2.4048 -    from prems have z0: "z= Cst 0" 
  2.4049 -      by (cases z) auto
  2.4050 -    with prems have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" 
  2.4051 -      by simp
  2.4052 -    
  2.4053 -    from prems z0 have ?case
  2.4054 -      proof-
  2.4055 -	show ?thesis
  2.4056 -	  using prems z0
  2.4057 -      apply auto
  2.4058 -      apply (rule exI[where x="-(I_intterm (a # ats) r)"])
  2.4059 -      apply (rule allI)
  2.4060 -      proof-
  2.4061 -	fix x
  2.4062 -	show "x < - I_intterm (a # ats) r \<longrightarrow> x + I_intterm (x # ats) r \<le> 0"
  2.4063 -	  by (simp add: intterm_novar0[OF lincnr, where x="a" and y="x"])
  2.4064 -      qed
  2.4065 -    qed
  2.4066 -  }
  2.4067 -    
  2.4068 -    ultimately show ?case by blast
  2.4069 -next
  2.4070 -  case (2 c r z)
  2.4071 -  from prems have z0: "z= Cst 0" 
  2.4072 -    by (cases z,auto)
  2.4073 -  with prems have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" 
  2.4074 -    by simp
  2.4075 -  have "c <0 \<or> 0 \<le> c" by arith
  2.4076 -  moreover 
  2.4077 -  {
  2.4078 -    assume cneg: " c < 0"
  2.4079 -    from prems z0 have ?case 
  2.4080 -      proof-
  2.4081 -	show ?thesis
  2.4082 -	  using prems z0
  2.4083 -      apply auto
  2.4084 -      apply (rule exI[where x="I_intterm (a # ats) r"])
  2.4085 -      apply (rule allI)
  2.4086 -      proof-
  2.4087 -	fix x
  2.4088 -	show "x < I_intterm (a # ats) r \<longrightarrow> \<not> - x + I_intterm (x # ats) r = 0"
  2.4089 -	  by (simp add: intterm_novar0[OF lincnr, where x="a" and y="x"])
  2.4090 -      qed
  2.4091 -    qed
  2.4092 -  }
  2.4093 -  moreover
  2.4094 -  {
  2.4095 -    assume cpos: "0 \<le> c"
  2.4096 -    from prems z0 have ?case
  2.4097 -      proof-
  2.4098 -	show ?thesis
  2.4099 -	  using prems z0
  2.4100 -      apply auto
  2.4101 -      apply (rule exI[where x="-(I_intterm (a # ats) r)"])
  2.4102 -      apply (rule allI)
  2.4103 -      proof-
  2.4104 -	fix x
  2.4105 -	show "x < - I_intterm (a # ats) r \<longrightarrow> x + I_intterm (x # ats) r \<noteq> 0"
  2.4106 -	  by (simp add: intterm_novar0[OF lincnr, where x="a" and y="x"])
  2.4107 -      qed
  2.4108 -    qed
  2.4109 -  }
  2.4110 -    
  2.4111 -    ultimately show ?case by blast
  2.4112 -next
  2.4113 -  case (3 c r z)
  2.4114 -  from prems have z0: "z= Cst 0" 
  2.4115 -    by (cases z,auto)
  2.4116 -  with prems have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" 
  2.4117 -    by simp
  2.4118 -  have "c <0 \<or> 0 \<le> c" by arith
  2.4119 -  moreover 
  2.4120 -  {
  2.4121 -    assume cneg: " c < 0"
  2.4122 -    from prems z0 have ?case 
  2.4123 -      proof-
  2.4124 -	show ?thesis
  2.4125 -	  using prems z0
  2.4126 -      apply auto
  2.4127 -      apply (rule exI[where x="I_intterm (a # ats) r"])
  2.4128 -      apply (rule allI)
  2.4129 -      proof-
  2.4130 -	fix x
  2.4131 -	show "x < I_intterm (a # ats) r \<longrightarrow> \<not> - x + I_intterm (x # ats) r = 0"
  2.4132 -	  by (simp add: intterm_novar0[OF lincnr, where x="a" and y="x"])
  2.4133 -      qed
  2.4134 -    qed
  2.4135 -  }
  2.4136 -  moreover
  2.4137 -  {
  2.4138 -    assume cpos: "0 \<le> c"
  2.4139 -    from prems z0 have ?case
  2.4140 -      proof-
  2.4141 -	show ?thesis
  2.4142 -	  using prems z0
  2.4143 -      apply auto
  2.4144 -      apply (rule exI[where x="-(I_intterm (a # ats) r)"])
  2.4145 -      apply (rule allI)
  2.4146 -      proof-
  2.4147 -	fix x
  2.4148 -	show "x < - I_intterm (a # ats) r \<longrightarrow> x + I_intterm (x # ats) r \<noteq> 0"
  2.4149 -	  by (simp add: intterm_novar0[OF lincnr, where x="a" and y="x"])
  2.4150 -      qed
  2.4151 -    qed
  2.4152 -  }
  2.4153 -    
  2.4154 -    ultimately show ?case by blast
  2.4155 -next
  2.4156 -  
  2.4157 -  case (4 f g) 
  2.4158 -  from prems obtain "zf" where 
  2.4159 -    zf:"\<forall>x<zf. qinterp (x # ats) f = qinterp (x # ats) (minusinf f)" by auto
  2.4160 -  from prems obtain "zg" where 
  2.4161 -    zg:"\<forall>x<zg. qinterp (x # ats) g = qinterp (x # ats) (minusinf g)" by auto
  2.4162 -  from zf zg show ?case 
  2.4163 -    apply auto
  2.4164 -    apply (rule exI[where x="min zf zg"])
  2.4165 -    by simp
  2.4166 -  
  2.4167 -next case (5 f g)  
  2.4168 -  from prems obtain "zf" where 
  2.4169 -    zf:"\<forall>x<zf. qinterp (x # ats) f = qinterp (x # ats) (minusinf f)" by auto
  2.4170 -  from prems obtain "zg" where 
  2.4171 -    zg:"\<forall>x<zg. qinterp (x # ats) g = qinterp (x # ats) (minusinf g)" by auto
  2.4172 -  from zf zg show ?case 
  2.4173 -    apply auto
  2.4174 -    apply (rule exI[where x="min zf zg"])
  2.4175 -    by simp
  2.4176 -  
  2.4177 -qed simp_all
  2.4178 -
  2.4179 -(* miusinf p behaves periodically*)
  2.4180 -lemma minusinf_repeats: 
  2.4181 -  assumes alldvd: "alldivide (d,p)"
  2.4182 -  and unity: "isunified p"
  2.4183 -  shows "qinterp (x#ats) (minusinf p) = qinterp ((x + c*d)#ats) (minusinf p)"
  2.4184 -  using alldvd unity unified_islinform[OF unity]
  2.4185 -proof(induct p rule: islinform.induct, simp_all)
  2.4186 -  case (goal1 t a)
  2.4187 -  show ?case
  2.4188 -    using prems
  2.4189 -    apply (cases t, simp_all add: nth_pos2)
  2.4190 -    apply (case_tac "intterm1", simp_all)
  2.4191 -    apply (case_tac "intterm1a",simp_all)
  2.4192 -    by (case_tac "intterm2a",simp_all)
  2.4193 -  (case_tac "nat",simp_all add: nth_pos2 intterm_novar0[where x="x" and y="x+c*d"])
  2.4194 -next 
  2.4195 -  case (goal2 t a)
  2.4196 -  show ?case
  2.4197 -    using prems
  2.4198 -    apply (cases t, simp_all add: nth_pos2)
  2.4199 -    apply (case_tac "intterm1", simp_all)
  2.4200 -    apply (case_tac "intterm1a",simp_all)
  2.4201 -    by (case_tac "intterm2a",simp_all)
  2.4202 -  (case_tac "nat",simp_all add: nth_pos2 intterm_novar0[where x="x" and y="x+c*d"])
  2.4203 -next 
  2.4204 -  case (goal3 a t)
  2.4205 -  show ?case using prems
  2.4206 -
  2.4207 -  proof(induct t rule: islinintterm.induct, simp_all add: nth_pos2)
  2.4208 -    case (goal1 i n i')
  2.4209 -    show ?case
  2.4210 -      using prems
  2.4211 -    proof(cases n, simp_all, case_tac "i=1", simp,
  2.4212 -	simp add: dvd_period[where a="a" and d="d" and x="x" and c="c"])
  2.4213 -      case goal1
  2.4214 -      from prems have "(abs i = 1) \<and> i \<noteq> 1" by auto 
  2.4215 -      then  have im1: "i=-1" by arith
  2.4216 -      then have "(a dvd i*x + i') = (a dvd x + (-i'))" 
  2.4217 -	by (simp add: uminus_dvd_conv'[where d="a" and t="-x +i'"])
  2.4218 -      moreover 
  2.4219 -      from im1 have "(a dvd i*x + (i*(c * d)) + i') = (a dvd (x + c*d - i'))"
  2.4220 -	apply simp
  2.4221 -	apply (simp add: uminus_dvd_conv'[where d="a" and t="-x - c * d + i'"])
  2.4222 -	by (simp add: zadd_ac)
  2.4223 -      ultimately 
  2.4224 -      have eq1:"((a dvd i*x + i') = (a dvd i*x + (i*(c * d)) + i')) = 
  2.4225 -	((a dvd x + (-i'))  = (a dvd (x + c*d - i')))" by simp
  2.4226 -      moreover 
  2.4227 -      have dvd2: "(a dvd x + (-i')) = (a dvd x + c * d + (-i'))"
  2.4228 -	by (rule dvd_period[where a="a" and d="d" and x="x" and c="c"], assumption)
  2.4229 -      ultimately show ?case by simp
  2.4230 -    qed
  2.4231 -  next
  2.4232 -    case (goal2 i n i' n' r)
  2.4233 -    have "n = 0 \<or> 0 < n" by arith
  2.4234 -    moreover 
  2.4235 -    {
  2.4236 -      assume npos: "0 < n"
  2.4237 -      from prems have "n < n'" by simp then have "0 < n'" by simp
  2.4238 -      moreover from prems
  2.4239 -      have linr: "islinintterm (Add (Mult (Cst i') (Var n')) r)" by simp
  2.4240 -      ultimately have ?case 
  2.4241 -	using prems npos
  2.4242 -	by (simp add: nth_pos2 intterm_novar0[OF linr,where x="x" and y="x + c*d"])
  2.4243 -    }
  2.4244 -    moreover 
  2.4245 -    {
  2.4246 -      assume n0: "n=0"
  2.4247 -      from prems have lin2: "islinintterm (Add (Mult (Cst i') (Var n')) r)" by simp
  2.4248 -      from prems have "n < n'" by simp then have npos': "0 < n'" by simp
  2.4249 -      with prems have ?case
  2.4250 -      proof(simp add: intterm_novar0[OF lin2, where x="x" and y="x+c*d"] 
  2.4251 -	  nth_pos2 dvd_period,case_tac "i=1",
  2.4252 -	  simp add: dvd_period[where a="a" and d="d" and x="x" and c="c"], simp)
  2.4253 -	case goal1
  2.4254 -	from prems have "abs i = 1 \<and> i\<noteq>1" by auto
  2.4255 -	then have mi: "i = -1" by arith
  2.4256 -	have "(a dvd -x + (i' * ats ! (n' - Suc 0) + I_intterm ((x + c * d) # ats) r)) = 
  2.4257 -	  (a dvd x + (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r))" 
  2.4258 -	  by (simp add: 
  2.4259 -	    uminus_dvd_conv'[where d="a" and 
  2.4260 -	    t="-x + (i' * ats ! (n' - Suc 0) + I_intterm ((x + c * d) # ats) r)"])
  2.4261 -	also 
  2.4262 -	have "(a dvd x + (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r)) = 
  2.4263 -	  (a dvd x +c*d + (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r))"
  2.4264 -	  by (rule dvd_period[where a="a" and d="d" and x="x" and c="c"], assumption)
  2.4265 -	also 
  2.4266 -	have "(a dvd x +c*d + 
  2.4267 -	  (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r)) = 
  2.4268 -	  (a dvd -(x +c*d + 
  2.4269 -	  (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r)))"
  2.4270 -	  by (rule uminus_dvd_conv'[where d="a" and 
  2.4271 -	    t="x +c*d + (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r)"])
  2.4272 -	also
  2.4273 -	have "(a dvd -(x +c*d + 
  2.4274 -	  (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r)))
  2.4275 -	  = (a dvd
  2.4276 -          - x - c * d + (i' * ats ! (n' - Suc 0) + I_intterm ((x + c * d) # ats) r))" 
  2.4277 -	  by (auto,simp_all add: zadd_ac)
  2.4278 -	finally show ?case using mi by auto
  2.4279 -      qed
  2.4280 -    }
  2.4281 -    ultimately show ?case by blast
  2.4282 -  qed
  2.4283 -next 
  2.4284 -  case (goal4 a t)
  2.4285 -  show ?case using prems 
  2.4286 -  proof(induct t rule: islinintterm.induct, simp_all,case_tac "n=0",
  2.4287 -      simp_all add: nth_pos2)
  2.4288 -    case (goal1 i n i')
  2.4289 -    show ?case
  2.4290 -      using prems
  2.4291 -    proof(case_tac "i=1", simp,
  2.4292 -	simp add: dvd_period[where a="a" and d="d" and x="x" and c="c"])
  2.4293 -      case goal1
  2.4294 -      from prems have "abs i = 1 \<and> i\<noteq>1" by auto 
  2.4295 -      then have im1: "i=-1" by arith
  2.4296 -      then have "(a dvd i*x + i') = (a dvd x + (-i'))" 
  2.4297 -	by (simp add: uminus_dvd_conv'[where d="a" and t="-x +i'"])
  2.4298 -      moreover 
  2.4299 -      from im1 have "(a dvd i*x + (i*(c * d)) + i') = (a dvd (x + c*d - i'))"
  2.4300 -	apply simp
  2.4301 -	apply (simp add: uminus_dvd_conv'[where d="a" and t="-x - c * d + i'"])
  2.4302 -	by (simp add: zadd_ac)
  2.4303 -      ultimately 
  2.4304 -      have eq1:"((a dvd i*x + i') = (a dvd i*x + (i*(c * d)) + i')) = 
  2.4305 -	((a dvd x + (-i'))  = (a dvd (x + c*d - i')))" by simp
  2.4306 -      moreover 
  2.4307 -      have dvd2: "(a dvd x + (-i')) = (a dvd x + c * d + (-i'))"
  2.4308 -	by (rule dvd_period[where a="a" and d="d" and x="x" and c="c"], assumption)
  2.4309 -      ultimately show ?thesis by simp
  2.4310 -    qed
  2.4311 -  next
  2.4312 -    case (goal2 i n i' n' r)
  2.4313 -    have "n = 0 \<or> 0 < n" by arith
  2.4314 -    moreover 
  2.4315 -    {
  2.4316 -      assume npos: "0 < n"
  2.4317 -      from prems have "n < n'" by simp then have "0 < n'" by simp
  2.4318 -      moreover from prems
  2.4319 -      have linr: "islinintterm (Add (Mult (Cst i') (Var n')) r)" by simp
  2.4320 -      ultimately have ?case 
  2.4321 -	using prems npos
  2.4322 -	by (simp add: nth_pos2 intterm_novar0[OF linr,where x="x" and y="x + c*d"])
  2.4323 -    }
  2.4324 -    moreover 
  2.4325 -    {
  2.4326 -      assume n0: "n=0"
  2.4327 -      from prems have lin2: "islinintterm (Add (Mult (Cst i') (Var n')) r)" by simp
  2.4328 -      from prems have "n < n'" by simp then have npos': "0 < n'" by simp
  2.4329 -      with prems have ?case
  2.4330 -      proof(simp add: intterm_novar0[OF lin2, where x="x" and y="x+c*d"] 
  2.4331 -	  nth_pos2 dvd_period,case_tac "i=1",
  2.4332 -	  simp add: dvd_period[where a="a" and d="d" and x="x" and c="c"], simp)
  2.4333 -	case goal1
  2.4334 -	from prems have "abs i = 1 \<and> i\<noteq>1" by auto
  2.4335 -	then have mi: "i = -1" by arith
  2.4336 -	have "(a dvd -x + (i' * ats ! (n' - Suc 0) + I_intterm ((x + c * d) # ats) r)) = 
  2.4337 -	  (a dvd x + (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r))" 
  2.4338 -	  by (simp add: 
  2.4339 -	    uminus_dvd_conv'[where d="a" and 
  2.4340 -	    t="-x + (i' * ats ! (n' - Suc 0) + I_intterm ((x + c * d) # ats) r)"])
  2.4341 -	also 
  2.4342 -	have "(a dvd x + (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r)) = 
  2.4343 -	  (a dvd x +c*d + (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r))"
  2.4344 -	  by (rule dvd_period[where a="a" and d="d" and x="x" and c="c"], assumption)
  2.4345 -	also 
  2.4346 -	have "(a dvd x +c*d + 
  2.4347 -	  (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r)) = 
  2.4348 -	  (a dvd -(x +c*d + 
  2.4349 -	  (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r)))"
  2.4350 -	  by (rule uminus_dvd_conv'[where d="a" and 
  2.4351 -	    t="x +c*d + (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r)"])
  2.4352 -	also
  2.4353 -	have "(a dvd -(x +c*d + 
  2.4354 -	  (-i' * ats ! (n' - Suc 0) - I_intterm ((x + c * d) # ats) r)))
  2.4355 -	  = (a dvd
  2.4356 -          - x - c * d + (i' * ats ! (n' - Suc 0) + I_intterm ((x + c * d) # ats) r))" 
  2.4357 -	  by (auto,simp_all add: zadd_ac)
  2.4358 -	finally show ?case using mi by auto
  2.4359 -      qed
  2.4360 -    }
  2.4361 -    ultimately show ?case by blast
  2.4362 -  qed
  2.4363 -next 
  2.4364 -  case (goal5 t a)
  2.4365 -  show ?case
  2.4366 -    using prems
  2.4367 -    apply (cases t, simp_all add: nth_pos2)
  2.4368 -    apply (case_tac "intterm1", simp_all)
  2.4369 -    apply (case_tac "intterm1a",simp_all)
  2.4370 -    by (case_tac "intterm2a",simp_all)
  2.4371 -  (case_tac "nat",simp_all add: nth_pos2 intterm_novar0[where x="x" and y="x+c*d"])
  2.4372 -qed
  2.4373 -
  2.4374 -lemma minusinf_repeats2:
  2.4375 -  assumes alldvd: "alldivide (d,p)"
  2.4376 -  and unity: "isunified p"
  2.4377 -  shows "\<forall> x k. (qinterp (x#ats) (minusinf p) = qinterp ((x - k*d)#ats) (minusinf p))" 
  2.4378 -  (is "\<forall> x k. ?P x = ?P (x - k*d)")
  2.4379 -proof(rule allI, rule allI)
  2.4380 -  fix x k
  2.4381 -  show "?P x = ?P (x - k*d)"
  2.4382 -  proof-
  2.4383 -    have "?P x = ?P (x + (-k)*d)" by (rule minusinf_repeats[OF alldvd unity])
  2.4384 -    then have "?P x = ?P (x - (k*d))" by simp
  2.4385 -    then show ?thesis by blast 
  2.4386 -  qed
  2.4387 +  let ?d = "\<delta> p"
  2.4388 +  from \<delta> [OF lin] have dpos: "?d >0" by simp
  2.4389 +  from \<delta> [OF lin] have alld: "d\<delta> p ?d" by simp
  2.4390 +  from minusinf_repeats[OF alld lin] have th1:"\<forall> x k. ?P x = ?P (x - (k * ?d))" by simp
  2.4391 +  from minf_vee[OF dpos th1] show ?thesis by blast
  2.4392  qed
  2.4393  
  2.4394  
  2.4395 -(* existence for minusinf p is existence for p *)
  2.4396 -lemma minusinf_lemma:
  2.4397 -  assumes unifp: "isunified p"
  2.4398 -  and exminf: "\<exists> j \<in> {1 ..d}. qinterp (j#ats) (minusinf p)" (is "\<exists> j \<in> {1 .. d}. ?P1 j")
  2.4399 -  shows "\<exists> x. qinterp (x#ats) p" (is "\<exists> x. ?P x")
  2.4400 -proof-
  2.4401 -  from exminf obtain "j" where P1j: "?P1 j" by blast
  2.4402 -  have ePeqP1: "\<exists>z. \<forall> x. x < z \<longrightarrow> (?P x = ?P1 x)"
  2.4403 -    by (rule minusinf_eq[OF unifp])
  2.4404 -  then obtain "z" where P1eqP : "\<forall> x. x < z \<longrightarrow> (?P x = ?P1 x)" by blast
  2.4405 -  let ?d = "divlcm p"
  2.4406 -  have alldvd: "alldivide (?d,p)" using unified_islinform[OF unifp] divlcm_corr
  2.4407 -    by auto
  2.4408 -  have dpos: "0 < ?d" using unified_islinform[OF unifp] divlcm_pos
  2.4409 -    by simp
  2.4410 -  have P1eqP1 : "\<forall> x k. ?P1 x = ?P1 (x - k*(?d))"
  2.4411 -    by (rule minusinf_repeats2[OF alldvd unifp])
  2.4412 -  let ?w = "j - (abs (j-z) +1)* ?d"
  2.4413 -  show "\<exists> x. ?P x"
  2.4414 -  proof
  2.4415 -    have w: "?w < z" 
  2.4416 -      by (rule decr_lemma[OF dpos])
  2.4417 -    
  2.4418 -    have "?P1 j = ?P1 ?w" using P1eqP1 by blast
  2.4419 -    also have "\<dots> = ?P ?w"  using w P1eqP by blast
  2.4420 -    finally show "?P ?w" using P1j by blast
  2.4421 -  qed
  2.4422 -qed
  2.4423 +lemma mirror\<alpha>\<beta>:
  2.4424 +  assumes lp: "iszlfm p"
  2.4425 +  shows "(Inum (i#bs)) ` set (\<alpha> p) = (Inum (i#bs)) ` set (\<beta> (mirror p))"
  2.4426 +using lp
  2.4427 +by (induct p rule: mirror.induct, auto)
  2.4428  
  2.4429 -(* limited search for the withness for minusinf p, due to peridicity *)
  2.4430 -lemma minusinf_disj:
  2.4431 -  assumes unifp: "isunified p"
  2.4432 -  shows "(\<exists> x. qinterp (x#ats) (minusinf p)) = 
  2.4433 -  (\<exists> j \<in> { 1.. divlcm p}. qinterp (j#ats) (minusinf p))" 
  2.4434 -  (is "(\<exists> x. ?P x) = (\<exists> j \<in> { 1.. ?d}. ?P j)")
  2.4435 -proof
  2.4436 -  have linp: "islinform p" by (rule unified_islinform[OF unifp])
  2.4437 -  have dpos: "0 < ?d" by (rule divlcm_pos[OF linp])
  2.4438 -  have alldvd: "alldivide(?d,p)" by (rule divlcm_corr[OF linp])
  2.4439 -  {
  2.4440 -    assume "\<exists> j\<in> {1 .. ?d}. ?P j"
  2.4441 -    then show "\<exists> x. ?P x" using dpos  by auto
  2.4442 -  next
  2.4443 -    assume "\<exists> x. ?P x"
  2.4444 -    then obtain "x" where P: "?P x" by blast
  2.4445 -    have modd: "\<forall>x k. ?P x = ?P (x - k*?d)"
  2.4446 -      by (rule minusinf_repeats2[OF alldvd unifp])
  2.4447 -    
  2.4448 -    have "x mod ?d = x - (x div ?d)*?d"
  2.4449 -      by(simp add:zmod_zdiv_equality mult_ac eq_diff_eq)
  2.4450 -    hence Pmod: "?P x = ?P (x mod ?d)" using modd by simp
  2.4451 -    show "\<exists> j\<in> {1 .. ?d}. ?P j"
  2.4452 -    proof (cases)
  2.4453 -      assume "x mod ?d = 0"
  2.4454 -      hence "?P 0" using P Pmod by simp
  2.4455 -      moreover have "?P 0 = ?P (0 - (-1)*?d)" using modd by blast
  2.4456 -      ultimately have "?P ?d" by simp
  2.4457 -      moreover have "?d \<in> {1 .. ?d}" using dpos 
  2.4458 -	by (simp add:atLeastAtMost_iff)
  2.4459 -      ultimately show "\<exists> j\<in> {1 .. ?d}. ?P j" ..
  2.4460 -    next 
  2.4461 -      assume not0: "x mod ?d \<noteq> 0"
  2.4462 -      have "?P(x mod ?d)" using dpos P Pmod by(simp add:pos_mod_sign pos_mod_bound)
  2.4463 -      moreover have "x mod ?d : {1 .. ?d}"
  2.4464 -      proof -
  2.4465 -	have "0 \<le> x mod ?d" by(rule pos_mod_sign[OF dpos])
  2.4466 -	moreover have "x mod ?d < ?d"  by(rule pos_mod_bound[OF dpos])
  2.4467 -	ultimately show ?thesis using not0 by(simp add:atLeastAtMost_iff)
  2.4468 -      qed
  2.4469 -      ultimately show "\<exists> j\<in> {1 .. ?d}. ?P j" ..
  2.4470 -    qed
  2.4471 -  }
  2.4472 -qed
  2.4473 -
  2.4474 -lemma minusinf_qfree:
  2.4475 -  assumes linp : "islinform p"
  2.4476 -  shows "isqfree (minusinf p)"
  2.4477 -  using linp
  2.4478 - by (induct p rule: minusinf.induct) auto 
  2.4479 -
  2.4480 -(* Properties of bset and a set *)
  2.4481 +lemma mirror: 
  2.4482 +  assumes lp: "iszlfm p"
  2.4483 +  shows "Ifm bbs (x#bs) (mirror p) = Ifm bbs ((- x)#bs) p" 
  2.4484 +using lp
  2.4485 +proof(induct p rule: iszlfm.induct)
  2.4486 +  case (9 j c e) hence nb: "numbound0 e" by simp
  2.4487 +  have "Ifm bbs (x#bs) (mirror (Dvd j (CX c e))) = (j dvd c*x - Inum (x#bs) e)" (is "_ = (j dvd c*x - ?e)") by simp
  2.4488 +    also have "\<dots> = (j dvd (- (c*x - ?e)))"
  2.4489 +    by (simp only: zdvd_zminus_iff)
  2.4490 +  also have "\<dots> = (j dvd (c* (- x)) + ?e)"
  2.4491 +    apply (simp only: minus_mult_right[symmetric] minus_mult_left[symmetric] diff_def zadd_ac zminus_zadd_distrib)
  2.4492 +    by (simp add: ring_eq_simps)
  2.4493 +  also have "\<dots> = Ifm bbs ((- x)#bs) (Dvd j (CX c e))"
  2.4494 +    using numbound0_I[OF nb, where bs="bs" and b="x" and b'="- x"]
  2.4495 +    by simp
  2.4496 +  finally show ?case .
  2.4497 +next
  2.4498 +    case (10 j c e) hence nb: "numbound0 e" by simp
  2.4499 +  have "Ifm bbs (x#bs) (mirror (Dvd j (CX c e))) = (j dvd c*x - Inum (x#bs) e)" (is "_ = (j dvd c*x - ?e)") by simp
  2.4500 +    also have "\<dots> = (j dvd (- (c*x - ?e)))"
  2.4501 +    by (simp only: zdvd_zminus_iff)
  2.4502 +  also have "\<dots> = (j dvd (c* (- x)) + ?e)"
  2.4503 +    apply (simp only: minus_mult_right[symmetric] minus_mult_left[symmetric] diff_def zadd_ac zminus_zadd_distrib)
  2.4504 +    by (simp add: ring_eq_simps)
  2.4505 +  also have "\<dots> = Ifm bbs ((- x)#bs) (Dvd j (CX c e))"
  2.4506 +    using numbound0_I[OF nb, where bs="bs" and b="x" and b'="- x"]
  2.4507 +    by simp
  2.4508 +  finally show ?case by simp
  2.4509 +qed (auto simp add: numbound0_I[where bs="bs" and b="x" and b'="- x"] nth_pos2)
  2.4510  
  2.4511 -(* The elements of a bset are linear *) 
  2.4512 -lemma bset_lin:
  2.4513 -  assumes unifp: "isunified p"
  2.4514 -  shows "\<forall> b \<in> set (bset p). islinintterm b"
  2.4515 -using unifp unified_islinform[OF unifp]
  2.4516 -proof (induct p rule: bset.induct, auto)
  2.4517 -  case (goal1 c r z)
  2.4518 -  from prems have "z = Cst 0" by (cases z, simp_all)
  2.4519 -  then have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" using prems by simp
  2.4520 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.4521 -  have "islinintterm (Cst -1)" by simp
  2.4522 -  then show ?case using linr lin_add_lin by simp
  2.4523 -next 
  2.4524 -  case (goal2 c r z)
  2.4525 -  from prems have "z = Cst 0" by (cases z, simp_all)
  2.4526 -  then have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" using prems by simp
  2.4527 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.4528 -  show ?case by (rule linr)
  2.4529 -next
  2.4530 -  case (goal3 c r z)
  2.4531 -  from prems have "z = Cst 0" by (cases z, simp_all) 
  2.4532 -  then have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" using prems by simp
  2.4533 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.4534 -  have "islinintterm (Cst -1)" by simp
  2.4535 -  then show ?case using linr lin_add_lin lin_neg_lin by simp
  2.4536 -next
  2.4537 -  case (goal4 c r z)
  2.4538 -  from prems have "z = Cst 0" by (cases z, simp_all) 
  2.4539 -  then have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" using prems by simp
  2.4540 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.4541 -  have "islinintterm (Cst -1)" by simp
  2.4542 -  then show ?case using linr lin_add_lin lin_neg_lin by simp
  2.4543 -next
  2.4544 -  case (goal5 c r z)
  2.4545 -  from prems have "z = Cst 0" by (cases z, simp_all) 
  2.4546 -  then have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" using prems by simp
  2.4547 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.4548 -  have "islinintterm (Cst -1)" by simp
  2.4549 -  then show ?case using linr lin_add_lin lin_neg_lin by simp
  2.4550 -next
  2.4551 -  case (goal6 c r z)
  2.4552 -  from prems have "z = Cst 0" by (cases z, simp_all) 
  2.4553 -  then have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" using prems by simp
  2.4554 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.4555 -  have "islinintterm (Cst -1)" by simp
  2.4556 -  then show ?case using linr lin_add_lin lin_neg_lin by simp
  2.4557 -next
  2.4558 -  case (goal7 c r z)
  2.4559 -  from prems have "z = Cst 0" by (cases z, simp_all) 
  2.4560 -  then have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" using prems by simp
  2.4561 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.4562 -  have "islinintterm (Cst -1)" by simp
  2.4563 -  then show ?case using linr lin_add_lin lin_neg_lin by simp
  2.4564 -qed
  2.4565 +lemma mirror_l: "iszlfm p \<and> d\<beta> p 1 
  2.4566 +  \<Longrightarrow> iszlfm (mirror p) \<and> d\<beta> (mirror p) 1"
  2.4567 +by (induct p rule: mirror.induct, auto)
  2.4568  
  2.4569 -(* The third lemma in Norrisch's Paper *)
  2.4570 -lemma bset_disj_repeat:
  2.4571 -  assumes unifp: "isunified p"
  2.4572 -  and alldvd: "alldivide (d,p)"
  2.4573 -  and dpos: "0 < d"
  2.4574 -  and nob: "(qinterp (x#ats) q) \<and> \<not>(\<exists>j\<in> {1 .. d}. \<exists> b \<in> set (bset p). (qinterp (((I_intterm (a#ats) b) + j)#ats) q)) \<and>(qinterp (x#ats) p)" 
  2.4575 -  (is "?Q x \<and> \<not>(\<exists> j\<in> {1.. d}. \<exists> b\<in> ?B. ?Q (?I a b + j)) \<and> ?P x") 
  2.4576 -    shows "?P (x -d)"  
  2.4577 -  using unifp nob alldvd unified_islinform[OF unifp]
  2.4578 -proof (induct p rule: islinform.induct,auto)
  2.4579 -  case (goal1 t)
  2.4580 -  from prems 
  2.4581 -  have lint: "islinintterm t" by simp
  2.4582 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.4583 -    by (induct t rule: islinintterm.induct) auto
  2.4584 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.4585 -  moreover
  2.4586 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.4587 -    then obtain "i" "n" "r" where 
  2.4588 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.4589 -      by blast
  2.4590 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.4591 -      by simp
  2.4592 -    have linr: "islinintterm r" 
  2.4593 -      by (rule islinintterm_subt[OF lininr])
  2.4594 -    have "n=0 \<or> n>0" by arith
  2.4595 -    moreover {assume "n>0" then have ?case 
  2.4596 -	using prems
  2.4597 -	by (simp add: nth_pos2 
  2.4598 -	  intterm_novar0[OF lininr, where x="x" and y="x-d"]) }
  2.4599 -    moreover 
  2.4600 -    {assume nz: "n = 0"
  2.4601 -      from prems have "abs i = 1" by auto 
  2.4602 -      then have "i = -1 \<or> i =1" by arith
  2.4603 -      moreover
  2.4604 -      {
  2.4605 -	assume i1: "i=1"
  2.4606 -	have ?case  using dpos prems  
  2.4607 -	  by (auto simp add: intterm_novar0[OF lininr, where x="x" and y="x - d"])
  2.4608 -      }
  2.4609 -      moreover 
  2.4610 -      {
  2.4611 -	assume im1: "i = -1"
  2.4612 -	have ?case 
  2.4613 -	  using prems 
  2.4614 -	proof(auto simp add: intterm_novar0[OF lininr, where x="x - d" and y="x"], cases)
  2.4615 -	  assume "- x + d +  ?I x r \<le> 0"
  2.4616 -	  then show "- x + d + ?I x r \<le> 0" .
  2.4617 -	next 
  2.4618 -	  assume np: "\<not> - x + d +  ?I x r \<le> 0"
  2.4619 -	  then have ltd:"x - ?I x r \<le> d - 1" by simp 
  2.4620 -	  from prems have "-x + ?I x r \<le> 0" by simp
  2.4621 -	  then have ge0: "x - ?I x r \<ge> 0" 
  2.4622 -	    by simp
  2.4623 -	  from ltd ge0 have "x - ?I x r = 0 \<or> (1 \<le> x - ?I x r \<and> x - ?I x r \<le> d - 1) " by arith
  2.4624 -	  moreover
  2.4625 -	  {
  2.4626 -	    assume "x - ?I x r = 0"
  2.4627 -	    then have xeqr: "x = ?I x r" by simp
  2.4628 -	    from prems have "?Q x" by simp
  2.4629 -	    with xeqr have qr:"?Q (?I x r)" by simp
  2.4630 -	    from prems have lininr: "islinintterm (Add (Mult (Cst i) (Var 0)) r)" by simp
  2.4631 -	    have "islinintterm r" by (rule islinintterm_subt[OF lininr])
  2.4632 -	    from prems 
  2.4633 -	    have "\<forall>j\<in>{1..d}. \<not> ?Q (?I a r + -1 + j)"
  2.4634 -	      using linr by (auto simp add: lin_add_corr)
  2.4635 -	    moreover from dpos have "1 \<in> {1..d}" by simp
  2.4636 -	    ultimately have " \<not> ?Q (?I a r + -1 + 1)" by blast
  2.4637 -	    with dpos linr have "\<not> ?Q (?I x r)"
  2.4638 -	      by (simp add: intterm_novar0[OF lininr, where x="x" and y="a"] lin_add_corr)
  2.4639 -	    with qr have "- x + d + ?I x r \<le> 0" by simp
  2.4640 -	  }
  2.4641 -	  moreover
  2.4642 -	  {
  2.4643 -	    assume gt0: "1 \<le> x - ?I x r \<and> x - ?I x r \<le> d - 1"
  2.4644 -	    then have "\<exists> j\<in> {1 .. d - 1}. x - ?I x r =  j" by simp
  2.4645 -	    then have "\<exists> j\<in> {1 .. d}. x - ?I x r =  j" by auto
  2.4646 -	    then obtain  "j" where con: "1\<le>j \<and> j \<le> d  \<and> x - ?I x r = j" by auto
  2.4647 -	    then have xeqr: "x = ?I x r + j" by auto
  2.4648 -	    with prems have "?Q (?I x r + j)" by simp
  2.4649 -	    with con have qrpj: "\<exists> j\<in> {1 .. d}. ?Q (?I x r + j)" by auto
  2.4650 -	    from prems have "\<forall>j\<in>{1..d}. \<not> ?Q (?I a r + j)" by auto
  2.4651 -	    then have "\<not> (\<exists> j\<in>{1..d}. ?Q (?I x r + j))" 
  2.4652 -	      by (simp add: intterm_novar0[OF lininr, where x="x" and y="a"])
  2.4653 -	    with qrpj prems have "- x + d + ?I x r \<le> 0" by simp 
  2.4654 -	    
  2.4655 -	  }
  2.4656 -	  ultimately show "- x + d + ?I x r \<le> 0" by blast
  2.4657 -	qed
  2.4658 -      }
  2.4659 -      ultimately have ?case by blast
  2.4660 -    }
  2.4661 -    ultimately have ?case by blast
  2.4662 -  }
  2.4663 -  ultimately show ?case by blast
  2.4664 -next  
  2.4665 -  case (goal3 a t)
  2.4666 -  from prems 
  2.4667 -  have lint: "islinintterm t" by simp
  2.4668 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.4669 -    by (induct t rule: islinintterm.induct) auto
  2.4670 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.4671 -  moreover
  2.4672 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.4673 -    then obtain "i" "n" "r" where 
  2.4674 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.4675 -      by blast
  2.4676 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.4677 -      by simp
  2.4678 -    have linr: "islinintterm r" 
  2.4679 -      by (rule islinintterm_subt[OF lininr])
  2.4680 -    have "n=0 \<or> n>0" by arith
  2.4681 -    moreover {assume "n>0" then have ?case using prems 
  2.4682 -	by (simp add: nth_pos2 
  2.4683 -	  intterm_novar0[OF lininr, where x="x" and y="x-d"]) }
  2.4684 -    moreover {
  2.4685 -      assume nz: "n=0"
  2.4686 -      from prems have "abs i = 1" by auto
  2.4687 -      then have ipm: "i=1 \<or> i = -1" by arith
  2.4688 -      from nz prems have advdixr: "a dvd (i * x) + I_intterm (x # ats) r" 
  2.4689 -	by simp
  2.4690 -      from prems have "a dvd d" by simp
  2.4691 -      then have advdid: "a dvd i*d" using ipm by auto  
  2.4692 -      have ?case
  2.4693 -      using prems ipm 
  2.4694 -      by (auto simp add: intterm_novar0[OF lininr, where x="x-d" and y="x"] dvd_period[OF advdid, where x="i*x" and c="-1"])
  2.4695 -  }
  2.4696 -  ultimately have ?case by blast
  2.4697 -  } ultimately show ?case by blast
  2.4698 -next
  2.4699 +lemma mirror_\<delta>: "iszlfm p \<Longrightarrow> \<delta> (mirror p) = \<delta> p"
  2.4700 +by (induct p rule: mirror.induct,auto)
  2.4701 +
  2.4702 +lemma \<beta>_numbound0: assumes lp: "iszlfm p"
  2.4703 +  shows "\<forall> b\<in> set (\<beta> p). numbound0 b"
  2.4704 +  using lp by (induct p rule: \<beta>.induct,auto)
  2.4705  
  2.4706 -  case (goal4 a t)
  2.4707 -  from prems 
  2.4708 -  have lint: "islinintterm t" by simp
  2.4709 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.4710 -    by (induct t rule: islinintterm.induct) auto
  2.4711 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.4712 -  moreover
  2.4713 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.4714 -    then obtain "i" "n" "r" where 
  2.4715 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.4716 -      by blast
  2.4717 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.4718 -      by simp
  2.4719 -    have linr: "islinintterm r" 
  2.4720 -      by (rule islinintterm_subt[OF lininr])
  2.4721 +lemma d\<beta>_mono: 
  2.4722 +  assumes linp: "iszlfm p"
  2.4723 +  and dr: "d\<beta> p l"
  2.4724 +  and d: "l dvd l'"
  2.4725 +  shows "d\<beta> p l'"
  2.4726 +using dr linp zdvd_trans[where n="l" and k="l'", simplified d]
  2.4727 +by (induct p rule: iszlfm.induct) simp_all
  2.4728 +
  2.4729 +lemma \<alpha>_l: assumes lp: "iszlfm p"
  2.4730 +  shows "\<forall> b\<in> set (\<alpha> p). numbound0 b"
  2.4731 +using lp
  2.4732 +by(induct p rule: \<alpha>.induct, auto)
  2.4733  
  2.4734 -    have "n=0 \<or> n>0" by arith
  2.4735 -    moreover {assume "n>0" then have ?case using prems 
  2.4736 -	by (simp add: nth_pos2 
  2.4737 -	  intterm_novar0[OF lininr, where x="x" and y="x-d"]) }
  2.4738 -    moreover {
  2.4739 -      assume nz: "n=0"
  2.4740 -      from prems have "abs i = 1" by auto
  2.4741 -      then have ipm: "i =1 \<or> i = -1" by arith
  2.4742 -      from nz prems have advdixr: "\<not> (a dvd (i * x) + I_intterm (x # ats) r)" 
  2.4743 -	by simp
  2.4744 -      from prems have "a dvd d" by simp
  2.4745 -      then have advdid: "a dvd i*d" using ipm by auto
  2.4746 -      have ?case
  2.4747 -      using prems ipm 
  2.4748 -      by (auto simp add: intterm_novar0[OF lininr, where x="x-d" and y="x"] dvd_period[OF advdid, where x="i*x" and c="-1"])
  2.4749 -  }
  2.4750 -  ultimately have ?case by blast
  2.4751 -  } ultimately show ?case by blast
  2.4752 -next 
  2.4753 -  case (goal2 t)
  2.4754 -  from prems
  2.4755 -  have lint: "islinintterm t" by simp
  2.4756 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.4757 -    by (induct t rule: islinintterm.induct) auto
  2.4758 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.4759 -  moreover
  2.4760 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.4761 -    then obtain "i" "n" "r" where 
  2.4762 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.4763 -      by blast
  2.4764 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.4765 -      by simp
  2.4766 -    have linr: "islinintterm r" 
  2.4767 -      by (rule islinintterm_subt[OF lininr])
  2.4768 -    have "n=0 \<or> n>0" by arith
  2.4769 -    moreover {assume "n>0" then have ?case 
  2.4770 -	using prems
  2.4771 -	by (simp add: nth_pos2 
  2.4772 -	  intterm_novar0[OF lininr, where x="x" and y="x-d"]) }
  2.4773 -    moreover 
  2.4774 -    {assume nz: "n = 0"
  2.4775 -      from prems have "abs i = 1" by auto 
  2.4776 -      then have "i = -1 \<or> i =1" by arith
  2.4777 -      moreover
  2.4778 -      {
  2.4779 -	assume i1: "i=1"
  2.4780 -	with prems have px: "x + ?I x r = 0" by simp
  2.4781 -	then have "x = (- ?I x r - 1) + 1" by simp
  2.4782 -	hence q1: "?Q ((- ?I x r - 1) + 1)" by simp
  2.4783 -	from prems have "\<not> (?Q ((?I a (lin_add(lin_neg r, Cst -1))) + 1))"
  2.4784 -	  by auto
  2.4785 -	hence "\<not> (?Q ((- ?I a r - 1) + 1))" 
  2.4786 -	  using lin_add_corr lin_neg_corr linr lin_neg_lin
  2.4787 -	  by simp
  2.4788 -	hence "\<not> (?Q ((- ?I x r - 1) + 1))" 
  2.4789 -	  using intterm_novar0[OF lininr, where x="x" and y="a"]
  2.4790 -	  by simp
  2.4791 -	with q1 have  ?case by simp
  2.4792 -      }
  2.4793 -      moreover 
  2.4794 -      {
  2.4795 -	assume im1: "i = -1"
  2.4796 -	with prems have px: "-x + ?I x r = 0" by simp
  2.4797 -	then have "x = ?I x r" by simp
  2.4798 -	hence q1: "?Q (?I x r)" by simp
  2.4799 -	from prems have "\<not> (?Q ((?I a (lin_add(r, Cst -1))) + 1))"
  2.4800 -	  by auto
  2.4801 -	hence "\<not> (?Q (?I a r))" 
  2.4802 -	  using lin_add_corr lin_neg_corr linr lin_neg_lin
  2.4803 -	  by simp
  2.4804 -	hence "\<not> (?Q (?I x r ))" 
  2.4805 -	  using intterm_novar0[OF lininr, where x="x" and y="a"]
  2.4806 -	  by simp
  2.4807 -	with q1 have  ?case by simp
  2.4808 -      }
  2.4809 -      ultimately have ?case by blast
  2.4810 -    }
  2.4811 -    ultimately have ?case by blast
  2.4812 -  }
  2.4813 -  ultimately show ?case by blast
  2.4814 +lemma \<zeta>: 
  2.4815 +  assumes linp: "iszlfm p"
  2.4816 +  shows "\<zeta> p > 0 \<and> d\<beta> p (\<zeta> p)"
  2.4817 +using linp
  2.4818 +proof(induct p rule: iszlfm.induct)
  2.4819 +  case (1 p q)
  2.4820 +  from prems have dl1: "\<zeta> p dvd ilcm (\<zeta> p) (\<zeta> q)" 
  2.4821 +    by (simp add: ilcm_dvd1[where a="\<zeta> p" and b="\<zeta> q"])
  2.4822 +  from prems have dl2: "\<zeta> q dvd ilcm (\<zeta> p) (\<zeta> q)" 
  2.4823 +    by (simp add: ilcm_dvd2[where a="\<zeta> p" and b="\<zeta> q"])
  2.4824 +  from prems d\<beta>_mono[where p = "p" and l="\<zeta> p" and l'="ilcm (\<zeta> p) (\<zeta> q)"] 
  2.4825 +    d\<beta>_mono[where p = "q" and l="\<zeta> q" and l'="ilcm (\<zeta> p) (\<zeta> q)"] 
  2.4826 +    dl1 dl2 show ?case by (auto simp add: ilcm_pos)
  2.4827  next
  2.4828 -  case (goal5 t)
  2.4829 -  from prems
  2.4830 -  have lint: "islinintterm t" by simp
  2.4831 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.4832 -    by (induct t rule: islinintterm.induct) auto
  2.4833 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.4834 -  moreover
  2.4835 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.4836 -    then obtain "i" "n" "r" where 
  2.4837 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.4838 -      by blast
  2.4839 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.4840 -      by simp
  2.4841 -    have linr: "islinintterm r" 
  2.4842 -      by (rule islinintterm_subt[OF lininr])
  2.4843 -    have "n=0 \<or> n>0" by arith
  2.4844 -    moreover {assume "n>0" then have ?case 
  2.4845 -	using prems
  2.4846 -	by (simp add: nth_pos2 
  2.4847 -	  intterm_novar0[OF lininr, where x="x" and y="x-d"]) }
  2.4848 -    moreover 
  2.4849 -    {assume nz: "n = 0"
  2.4850 -      from prems have "abs i = 1" by auto 
  2.4851 -      then have "i = -1 \<or> i =1" by arith
  2.4852 -      moreover
  2.4853 -      {
  2.4854 -	assume i1: "i=1"
  2.4855 -	with prems have px: "x -d + ?I (x-d) r = 0" by simp
  2.4856 -	hence "x = (- ?I x r) + d" 
  2.4857 -	  using intterm_novar0[OF lininr, where x="x" and y="x-d"]
  2.4858 -	  by simp
  2.4859 -	hence q1: "?Q (- ?I x r + d)" by simp
  2.4860 -	from prems have "\<not> (?Q ((?I a (lin_neg r)) + d))"
  2.4861 -	  by auto
  2.4862 -	hence "\<not> (?Q (- ?I a r + d))" 
  2.4863 -	  using lin_neg_corr linr by simp
  2.4864 -	hence "\<not> (?Q ((- ?I x r + d)))" 
  2.4865 -	  using intterm_novar0[OF lininr, where x="x" and y="a"]
  2.4866 -	  by simp
  2.4867 -	with q1 have  ?case by simp
  2.4868 -      }
  2.4869 -      moreover 
  2.4870 -      {
  2.4871 -	assume im1: "i = -1"
  2.4872 -	with prems have px: "- (x -d) + ?I (x - d) r = 0" by simp
  2.4873 -	then have "x = ?I x r + d "
  2.4874 - 	  using intterm_novar0[OF lininr, where x="x" and y="x-d"]
  2.4875 -	  by simp
  2.4876 -	hence q1: "?Q (?I x r + d)" by simp
  2.4877 -	from prems have "\<not> (?Q ((?I a r) + d))"
  2.4878 -	  by auto
  2.4879 -	hence "\<not> (?Q (?I x r + d))" 
  2.4880 -	  using intterm_novar0[OF lininr, where x="x" and y="a"]
  2.4881 -	  by simp
  2.4882 -	with q1 have  ?case by simp
  2.4883 -      }
  2.4884 -      ultimately have ?case by blast
  2.4885 -    }
  2.4886 -    ultimately have ?case by blast
  2.4887 -  }
  2.4888 -  ultimately show ?case by blast
  2.4889 -  
  2.4890 -qed
  2.4891 -  
  2.4892 -lemma bset_disj_repeat2:
  2.4893 -  assumes unifp: "isunified p"
  2.4894 -
  2.4895 -  shows "\<forall> x. \<not>(\<exists>j\<in> {1 .. (divlcm p)}. \<exists> b \<in> set (bset p). 
  2.4896 -  (qinterp (((I_intterm (a#ats) b) + j)#ats) p))  
  2.4897 -  \<longrightarrow> (qinterp (x#ats) p) \<longrightarrow> (qinterp ((x - (divlcm p))#ats) p)" 
  2.4898 -  (is "\<forall> x. \<not>(\<exists> j\<in> {1 .. ?d}. \<exists> b\<in> ?B. ?P (?I a b + j)) \<longrightarrow> ?P x \<longrightarrow> ?P (x - ?d)")
  2.4899 -proof
  2.4900 -  fix x
  2.4901 -  have linp: "islinform p" by (rule unified_islinform[OF unifp])
  2.4902 -  have dpos: "?d > 0" by (rule divlcm_pos[OF linp])
  2.4903 -  have alldvd: "alldivide(?d,p)" by (rule divlcm_corr[OF linp])
  2.4904 -    show "\<not>(\<exists> j\<in> {1 .. ?d}. \<exists> b\<in> ?B. ?P (?I a b + j)) \<longrightarrow> ?P x \<longrightarrow> ?P (x - ?d)"
  2.4905 -    using prems bset_disj_repeat[OF unifp alldvd dpos]
  2.4906 -    by blast
  2.4907 -qed
  2.4908 -
  2.4909 -(* Cooper's theorem in the minusinfinity version *)
  2.4910 -lemma cooper_mi_eq: 
  2.4911 -  assumes unifp : "isunified p"
  2.4912 -  shows "(\<exists> x. qinterp (x#ats) p) = 
  2.4913 -  ((\<exists> j \<in> {1 .. (divlcm p)}. qinterp (j#ats) (minusinf p)) \<or> 
  2.4914 -  (\<exists> j \<in> {1 .. (divlcm p)}. \<exists> b \<in> set (bset p). 
  2.4915 -  qinterp (((I_intterm (a#ats) b) + j)#ats) p))"
  2.4916 -  (is "(\<exists> x. ?P x) = ((\<exists> j\<in> {1 .. ?d}. ?MP j) \<or> (\<exists> j \<in> ?D. \<exists> b\<in> ?B. ?P (?I a b + j)))")
  2.4917 -proof-
  2.4918 -  have linp :"islinform p" by (rule unified_islinform[OF unifp])
  2.4919 -  have dpos: "?d > 0" by (rule divlcm_pos[OF linp])
  2.4920 -  have alldvd: "alldivide(?d,p)" by (rule divlcm_corr[OF linp])
  2.4921 -  have eMPimpeP: "(\<exists>j \<in> ?D. ?MP j) \<longrightarrow> (\<exists>x. ?P x)"
  2.4922 -    by (simp add: minusinf_lemma[OF unifp, where d="?d" and ats="ats"])
  2.4923 -  have ePimpeP: "(\<exists> j \<in> ?D. \<exists> b\<in> ?B. ?P (?I a b + j)) \<longrightarrow> (\<exists> x. ?P x)"
  2.4924 -    by blast
  2.4925 -  have bst_rep: "\<forall> x. \<not> (\<exists> j \<in> ?D. \<exists> b \<in> ?B. ?P (?I a b + j)) \<longrightarrow> ?P x \<longrightarrow> ?P (x - ?d)"
  2.4926 -    by (rule bset_disj_repeat2[OF unifp])
  2.4927 -  have MPrep: "\<forall> x k. ?MP x = ?MP (x- k*?d)"
  2.4928 -    by (rule minusinf_repeats2[OF alldvd unifp])
  2.4929 -  have MPeqP: "\<exists> z. \<forall>  x < z. ?P x = ?MP x"
  2.4930 -    by (rule minusinf_eq[OF unifp])
  2.4931 -  let ?B'= "{?I a b| b. b\<in> ?B}"
  2.4932 -  from bst_rep have bst_rep2: "\<forall>x. \<not> (\<exists>j\<in>?D. \<exists>b\<in> ?B'. ?P (b+j)) \<longrightarrow> ?P x \<longrightarrow> ?P (x - ?d)"
  2.4933 -    by auto
  2.4934 -  show ?thesis 
  2.4935 -  using cpmi_eq[OF dpos MPeqP bst_rep2 MPrep]
  2.4936 -  by auto
  2.4937 -qed
  2.4938 -
  2.4939 -(* A formalized analogy between aset, bset, plusinfinity and minusinfinity *)
  2.4940 +  case (2 p q)
  2.4941 +  from prems have dl1: "\<zeta> p dvd ilcm (\<zeta> p) (\<zeta> q)" 
  2.4942 +    by (simp add: ilcm_dvd1[where a="\<zeta> p" and b="\<zeta> q"])
  2.4943 +  from prems have dl2: "\<zeta> q dvd ilcm (\<zeta> p) (\<zeta> q)" 
  2.4944 +    by (simp add: ilcm_dvd2[where a="\<zeta> p" and b="\<zeta> q"])
  2.4945 +  from prems d\<beta>_mono[where p = "p" and l="\<zeta> p" and l'="ilcm (\<zeta> p) (\<zeta> q)"] 
  2.4946 +    d\<beta>_mono[where p = "q" and l="\<zeta> q" and l'="ilcm (\<zeta> p) (\<zeta> q)"] 
  2.4947 +    dl1 dl2 show ?case by (auto simp add: ilcm_pos)
  2.4948 +qed (auto simp add: ilcm_pos)
  2.4949  
  2.4950 -consts mirror:: "QF \<Rightarrow> QF"
  2.4951 -recdef mirror "measure size"
  2.4952 -"mirror (Le (Add (Mult (Cst c) (Var 0)) r) z) =
  2.4953 -  (Le (Add (Mult (Cst (- c)) (Var 0)) r) z)"
  2.4954 -"mirror (Eq (Add (Mult (Cst c) (Var 0)) r) z) =
  2.4955 -  (Eq (Add (Mult (Cst (- c)) (Var 0)) r) z)"
  2.4956 -"mirror (Divides (Cst d) (Add (Mult (Cst c) (Var 0)) r)) = 
  2.4957 -  (Divides (Cst d) (Add (Mult (Cst (- c)) (Var 0)) r))"
  2.4958 -"mirror (NOT(Divides (Cst d) (Add (Mult (Cst c) (Var 0)) r))) = 
  2.4959 -  (NOT(Divides (Cst d) (Add (Mult (Cst (- c)) (Var 0)) r)))"
  2.4960 -"mirror (NOT(Eq (Add (Mult (Cst c) (Var 0)) r) z)) =
  2.4961 -  (NOT(Eq (Add (Mult (Cst (- c)) (Var 0)) r) z))"
  2.4962 -"mirror (And p q) = And (mirror p) (mirror q)"
  2.4963 -"mirror (Or p q) = Or (mirror p) (mirror q)"
  2.4964 -"mirror p = p"
  2.4965 -(* mirror preserves unifiedness *)
  2.4966 -
  2.4967 -lemma[simp]: "(abs (i::int) = 1) = (i =1 \<or> i = -1)"  by arith
  2.4968 -lemma mirror_unified:
  2.4969 -  assumes unif: "isunified p"
  2.4970 -  shows "isunified (mirror p)"
  2.4971 -  using unif
  2.4972 -proof (induct p rule: mirror.induct, simp_all)
  2.4973 -  case (goal1 c r z)
  2.4974 -  from prems have zz: "z = Cst 0" by (cases z, simp_all) 
  2.4975 -  then show ?case using prems 
  2.4976 -    by (auto simp add: islinintterm_eq_islint islint_def)
  2.4977 -next 
  2.4978 -  case (goal2 c r z)
  2.4979 -  from prems have zz: "z = Cst 0" by (cases z, simp_all) 
  2.4980 -  then show ?case using prems 
  2.4981 -    by (auto simp add: islinintterm_eq_islint islint_def)
  2.4982 +lemma a\<beta>: assumes linp: "iszlfm p" and d: "d\<beta> p l" and lp: "l > 0"
  2.4983 +  shows "iszlfm (a\<beta> p l) \<and> d\<beta> (a\<beta> p l) 1 \<and> (Ifm bbs (l*x #bs) (a\<beta> p l) = Ifm bbs (x#bs) p)"
  2.4984 +using linp d
  2.4985 +proof (induct p rule: iszlfm.induct)
  2.4986 +  case (5 c e) hence cp: "c>0" and be: "numbound0 e" and d': "c dvd l" by simp+
  2.4987 +    from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2.4988 +    from cp have cnz: "c \<noteq> 0" by simp
  2.4989 +    have "c div c\<le> l div c"
  2.4990 +      by (simp add: zdiv_mono1[OF clel cp])
  2.4991 +    then have ldcp:"0 < l div c" 
  2.4992 +      by (simp add: zdiv_self[OF cnz])
  2.4993 +    have "c * (l div c) = c* (l div c) + l mod c" using d' zdvd_iff_zmod_eq_0[where m="c" and n="l"] by simp
  2.4994 +    hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2.4995 +      by simp
  2.4996 +    hence "(l*x + (l div c) * Inum (x # bs) e < 0) =
  2.4997 +          ((c * (l div c)) * x + (l div c) * Inum (x # bs) e < 0)"
  2.4998 +      by simp
  2.4999 +    also have "\<dots> = ((l div c) * (c*x + Inum (x # bs) e) < (l div c) * 0)" by (simp add: ring_eq_simps)
  2.5000 +    also have "\<dots> = (c*x + Inum (x # bs) e < 0)"
  2.5001 +    using mult_less_0_iff [where a="(l div c)" and b="c*x + Inum (x # bs) e"] ldcp by simp
  2.5002 +  finally show ?case using numbound0_I[OF be,where b="l*x" and b'="x" and bs="bs"] be  by simp
  2.5003  next
  2.5004 -  case (goal3 d c r) show ?case using prems by (auto simp add: islinintterm_eq_islint islint_def) 
  2.5005 -next 
  2.5006 -  case (goal4 d c r) show ?case using prems  by (auto simp add: islinintterm_eq_islint islint_def)
  2.5007 -next 
  2.5008 - case (goal5 c r z)
  2.5009 -  from prems have zz: "z = Cst 0" by (cases z, simp_all) 
  2.5010 -  then show ?case using prems 
  2.5011 -    by (auto simp add: islinintterm_eq_islint islint_def)
  2.5012 -qed
  2.5013 -
  2.5014 -(* relationship between plusinf and minusinf *)
  2.5015 -lemma plusinf_eq_minusinf_mirror:
  2.5016 -  assumes unifp: "isunified p"
  2.5017 -  shows "(qinterp (x#ats) (plusinf p)) = (qinterp ((- x)#ats) (minusinf (mirror p)))"
  2.5018 -using unifp unified_islinform[OF unifp]
  2.5019 -proof (induct p rule: islinform.induct, simp_all)
  2.5020 -  case (goal1 t z)
  2.5021 -  from prems 
  2.5022 -  have lint: "islinintterm t" by simp
  2.5023 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5024 -    by (induct t rule: islinintterm.induct) auto
  2.5025 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5026 -  moreover
  2.5027 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5028 -    then obtain "i" "n" "r" where 
  2.5029 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5030 -      by blast
  2.5031 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5032 +  case (6 c e) hence cp: "c>0" and be: "numbound0 e" and d': "c dvd l" by simp+
  2.5033 +    from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2.5034 +    from cp have cnz: "c \<noteq> 0" by simp
  2.5035 +    have "c div c\<le> l div c"
  2.5036 +      by (simp add: zdiv_mono1[OF clel cp])
  2.5037 +    then have ldcp:"0 < l div c" 
  2.5038 +      by (simp add: zdiv_self[OF cnz])
  2.5039 +    have "c * (l div c) = c* (l div c) + l mod c" using d' zdvd_iff_zmod_eq_0[where m="c" and n="l"] by simp
  2.5040 +    hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2.5041        by simp
  2.5042 -    have linr: "islinintterm r" 
  2.5043 -      by (rule islinintterm_subt[OF lininr])
  2.5044 -    have ?case using prems 
  2.5045 -      by (cases n, auto simp add: nth_pos2 
  2.5046 -	  intterm_novar0[OF lininr, where x="x" and y="-x"] )}
  2.5047 -  ultimately show ?case by blast
  2.5048 -    
  2.5049 +    hence "(l*x + (l div c) * Inum (x# bs) e \<le> 0) =
  2.5050 +          ((c * (l div c)) * x + (l div c) * Inum (x # bs) e \<le> 0)"
  2.5051 +      by simp
  2.5052 +    also have "\<dots> = ((l div c) * (c * x + Inum (x # bs) e) \<le> ((l div c)) * 0)" by (simp add: ring_eq_simps)
  2.5053 +    also have "\<dots> = (c*x + Inum (x # bs) e \<le> 0)"
  2.5054 +    using mult_le_0_iff [where a="(l div c)" and b="c*x + Inum (x # bs) e"] ldcp by simp
  2.5055 +  finally show ?case using numbound0_I[OF be,where b="l*x" and b'="x" and bs="bs"]  be by simp
  2.5056  next
  2.5057 -  case (goal2 t z)
  2.5058 -  from prems 
  2.5059 -  have lint: "islinintterm t" by simp
  2.5060 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5061 -    by (induct t rule: islinintterm.induct) auto
  2.5062 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5063 -  moreover
  2.5064 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5065 -    then obtain "i" "n" "r" where 
  2.5066 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5067 -      by blast
  2.5068 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5069 +  case (7 c e) hence cp: "c>0" and be: "numbound0 e" and d': "c dvd l" by simp+
  2.5070 +    from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2.5071 +    from cp have cnz: "c \<noteq> 0" by simp
  2.5072 +    have "c div c\<le> l div c"
  2.5073 +      by (simp add: zdiv_mono1[OF clel cp])
  2.5074 +    then have ldcp:"0 < l div c" 
  2.5075 +      by (simp add: zdiv_self[OF cnz])
  2.5076 +    have "c * (l div c) = c* (l div c) + l mod c" using d' zdvd_iff_zmod_eq_0[where m="c" and n="l"] by simp
  2.5077 +    hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2.5078        by simp
  2.5079 -    have linr: "islinintterm r" 
  2.5080 -      by (rule islinintterm_subt[OF lininr])
  2.5081 -    have ?case using prems 
  2.5082 -      by (cases n, auto simp add: nth_pos2 
  2.5083 -	  intterm_novar0[OF lininr, where x="x" and y="-x"] )}
  2.5084 -  ultimately show ?case by blast
  2.5085 -next
  2.5086 -  case (goal3 d t)
  2.5087 -  
  2.5088 - from prems 
  2.5089 -  have lint: "islinintterm t" by simp
  2.5090 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5091 -    by (induct t rule: islinintterm.induct) auto
  2.5092 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5093 -  moreover
  2.5094 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5095 -    then obtain "i" "n" "r" where 
  2.5096 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5097 -      by blast
  2.5098 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5099 +    hence "(l*x + (l div c)* Inum (x # bs) e > 0) =
  2.5100 +          ((c * (l div c)) * x + (l div c) * Inum (x # bs) e > 0)"
  2.5101        by simp
  2.5102 -    have linr: "islinintterm r" 
  2.5103 -      by (rule islinintterm_subt[OF lininr])
  2.5104 -
  2.5105 -    have ?case using prems 
  2.5106 -      by (cases n, simp_all add: nth_pos2 
  2.5107 -	  intterm_novar0[OF lininr, where x="x" and y="-x"] )}
  2.5108 -  ultimately show ?case by blast
  2.5109 +    also have "\<dots> = ((l div c) * (c * x + Inum (x # bs) e) > ((l div c)) * 0)" by (simp add: ring_eq_simps)
  2.5110 +    also have "\<dots> = (c * x + Inum (x # bs) e > 0)"
  2.5111 +    using zero_less_mult_iff [where a="(l div c)" and b="c * x + Inum (x # bs) e"] ldcp by simp
  2.5112 +  finally show ?case using numbound0_I[OF be,where b="(l * x)" and b'="x" and bs="bs"]  be  by simp
  2.5113  next
  2.5114 -
  2.5115 -  case (goal4 d t)
  2.5116 -  
  2.5117 - from prems 
  2.5118 -  have lint: "islinintterm t" by simp
  2.5119 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5120 -    by (induct t rule: islinintterm.induct) auto
  2.5121 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5122 -  moreover
  2.5123 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5124 -    then obtain "i" "n" "r" where 
  2.5125 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5126 -      by blast
  2.5127 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5128 +  case (8 c e) hence cp: "c>0" and be: "numbound0 e" and d': "c dvd l" by simp+
  2.5129 +    from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2.5130 +    from cp have cnz: "c \<noteq> 0" by simp
  2.5131 +    have "c div c\<le> l div c"
  2.5132 +      by (simp add: zdiv_mono1[OF clel cp])
  2.5133 +    then have ldcp:"0 < l div c" 
  2.5134 +      by (simp add: zdiv_self[OF cnz])
  2.5135 +    have "c * (l div c) = c* (l div c) + l mod c" using d' zdvd_iff_zmod_eq_0[where m="c" and n="l"] by simp
  2.5136 +    hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2.5137        by simp
  2.5138 -    have linr: "islinintterm r" 
  2.5139 -      by (rule islinintterm_subt[OF lininr])
  2.5140 -
  2.5141 -    have ?case using prems 
  2.5142 -      by (cases n, simp_all add: nth_pos2 
  2.5143 -	  intterm_novar0[OF lininr, where x="x" and y="-x"] )}
  2.5144 -  ultimately show ?case by blast
  2.5145 +    hence "(l*x + (l div c)* Inum (x # bs) e \<ge> 0) =
  2.5146 +          ((c*(l div c))*x + (l div c)* Inum (x # bs) e \<ge> 0)"
  2.5147 +      by simp
  2.5148 +    also have "\<dots> = ((l div c)*(c*x + Inum (x # bs) e) \<ge> ((l div c)) * 0)" 
  2.5149 +      by (simp add: ring_eq_simps)
  2.5150 +    also have "\<dots> = (c*x + Inum (x # bs) e \<ge> 0)" using ldcp 
  2.5151 +      zero_le_mult_iff [where a="l div c" and b="c*x + Inum (x # bs) e"] by simp
  2.5152 +  finally show ?case using be numbound0_I[OF be,where b="l*x" and b'="x" and bs="bs"]  
  2.5153 +    by simp
  2.5154  next
  2.5155 -  case (goal5 t z)
  2.5156 -  from prems 
  2.5157 -  have lint: "islinintterm t" by simp
  2.5158 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5159 -    by (induct t rule: islinintterm.induct) auto
  2.5160 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5161 -  moreover
  2.5162 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5163 -    then obtain "i" "n" "r" where 
  2.5164 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5165 -      by blast
  2.5166 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5167 +  case (3 c e) hence cp: "c>0" and be: "numbound0 e" and d': "c dvd l" by simp+
  2.5168 +    from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2.5169 +    from cp have cnz: "c \<noteq> 0" by simp
  2.5170 +    have "c div c\<le> l div c"
  2.5171 +      by (simp add: zdiv_mono1[OF clel cp])
  2.5172 +    then have ldcp:"0 < l div c" 
  2.5173 +      by (simp add: zdiv_self[OF cnz])
  2.5174 +    have "c * (l div c) = c* (l div c) + l mod c" using d' zdvd_iff_zmod_eq_0[where m="c" and n="l"] by simp
  2.5175 +    hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2.5176        by simp
  2.5177 -    have linr: "islinintterm r" 
  2.5178 -      by (rule islinintterm_subt[OF lininr])
  2.5179 -    have ?case using prems 
  2.5180 -      by (cases n, auto simp add: nth_pos2 
  2.5181 -	  intterm_novar0[OF lininr, where x="x" and y="-x"] )}
  2.5182 -  ultimately show ?case by blast
  2.5183 -qed
  2.5184 -
  2.5185 -(* relationship between aset abd bset *)
  2.5186 -lemma aset_eq_bset_mirror: 
  2.5187 -  assumes unifp: "isunified p"
  2.5188 -  shows "set (aset p) = set (map lin_neg (bset (mirror p)))"
  2.5189 -using unifp
  2.5190 -proof(induct p rule: mirror.induct)
  2.5191 -  case (1 c r z) 
  2.5192 -  from prems have zz: "z = Cst 0"
  2.5193 -    by (cases z, auto)
  2.5194 -  from prems zz have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" by simp
  2.5195 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.5196 -  have neg1eqm1: "Cst 1 = lin_neg (Cst -1)" by (simp add: lin_neg_def)
  2.5197 -  have negm1eq1: "Cst -1 = lin_neg (Cst 1)" by (simp add: lin_neg_def)
  2.5198 -  show ?case  using prems linr zz apply (auto simp add: lin_neg_lin_add_distrib lin_neg_idemp neg1eqm1)
  2.5199 -    by (simp add: negm1eq1 lin_neg_idemp sym[OF lin_neg_lin_add_distrib] lin_add_lin)
  2.5200 +    hence "(l * x + (l div c) * Inum (x # bs) e = 0) =
  2.5201 +          ((c * (l div c)) * x + (l div c) * Inum (x # bs) e = 0)"
  2.5202 +      by simp
  2.5203 +    also have "\<dots> = ((l div c) * (c * x + Inum (x # bs) e) = ((l div c)) * 0)" by (simp add: ring_eq_simps)
  2.5204 +    also have "\<dots> = (c * x + Inum (x # bs) e = 0)"
  2.5205 +    using mult_eq_0_iff [where a="(l div c)" and b="c * x + Inum (x # bs) e"] ldcp by simp
  2.5206 +  finally show ?case using numbound0_I[OF be,where b="(l * x)" and b'="x" and bs="bs"]  be  by simp
  2.5207  next
  2.5208 -  case (2 c r z)   from prems have zz: "z = Cst 0"
  2.5209 -    by (cases z, auto)
  2.5210 -  from prems zz have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" by simp
  2.5211 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.5212 -  have neg1eqm1: "Cst 1 = lin_neg (Cst -1)" by (simp add: lin_neg_def)
  2.5213 -  have negm1eq1: "Cst -1 = lin_neg (Cst 1)" by (simp add: lin_neg_def)
  2.5214 -  show ?case  using prems linr zz
  2.5215 -    by (auto simp add: lin_neg_lin_add_distrib lin_neg_idemp neg1eqm1)
  2.5216 -  (simp add: negm1eq1 lin_neg_idemp sym[OF lin_neg_lin_add_distrib] lin_add_lin lin_neg_lin)
  2.5217 -
  2.5218 +  case (4 c e) hence cp: "c>0" and be: "numbound0 e" and d': "c dvd l" by simp+
  2.5219 +    from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2.5220 +    from cp have cnz: "c \<noteq> 0" by simp
  2.5221 +    have "c div c\<le> l div c"
  2.5222 +      by (simp add: zdiv_mono1[OF clel cp])
  2.5223 +    then have ldcp:"0 < l div c" 
  2.5224 +      by (simp add: zdiv_self[OF cnz])
  2.5225 +    have "c * (l div c) = c* (l div c) + l mod c" using d' zdvd_iff_zmod_eq_0[where m="c" and n="l"] by simp
  2.5226 +    hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2.5227 +      by simp
  2.5228 +    hence "(l * x + (l div c) * Inum (x # bs) e \<noteq> 0) =
  2.5229 +          ((c * (l div c)) * x + (l div c) * Inum (x # bs) e \<noteq> 0)"
  2.5230 +      by simp
  2.5231 +    also have "\<dots> = ((l div c) * (c * x + Inum (x # bs) e) \<noteq> ((l div c)) * 0)" by (simp add: ring_eq_simps)
  2.5232 +    also have "\<dots> = (c * x + Inum (x # bs) e \<noteq> 0)"
  2.5233 +    using zero_le_mult_iff [where a="(l div c)" and b="c * x + Inum (x # bs) e"] ldcp by simp
  2.5234 +  finally show ?case using numbound0_I[OF be,where b="(l * x)" and b'="x" and bs="bs"]  be  by simp
  2.5235  next
  2.5236 -  case (5 c r z)  from prems have zz: "z = Cst 0"
  2.5237 -    by (cases z, auto)
  2.5238 -  from prems zz have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" by simp
  2.5239 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.5240 -  have neg1eqm1: "Cst 1 = lin_neg (Cst -1)" by (simp add: lin_neg_def)
  2.5241 -  have negm1eq1: "Cst -1 = lin_neg (Cst 1)" by (simp add: lin_neg_def)
  2.5242 -  show ?case  using prems linr zz
  2.5243 -    by(auto simp add: lin_neg_lin_add_distrib lin_neg_idemp neg1eqm1)
  2.5244 -  
  2.5245 -qed simp_all
  2.5246 -
  2.5247 -(* relationship between aset abd bset 2*)
  2.5248 -lemma aset_eq_bset_mirror2: 
  2.5249 -  assumes unifp: "isunified p"
  2.5250 -  shows "aset p = map lin_neg (bset (mirror p))"
  2.5251 -using unifp
  2.5252 -proof(induct p rule: mirror.induct)
  2.5253 -  case (1 c r z) 
  2.5254 -  from prems have zz: "z = Cst 0"
  2.5255 -    by (cases z, auto)
  2.5256 -  from prems zz have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" by simp
  2.5257 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.5258 -  have neg1eqm1: "Cst 1 = lin_neg (Cst -1)" by (simp add: lin_neg_def)
  2.5259 -  have negm1eq1: "Cst -1 = lin_neg (Cst 1)" by (simp add: lin_neg_def)
  2.5260 -  show ?case  using prems linr zz
  2.5261 -    apply (simp add: lin_neg_lin_add_distrib lin_neg_idemp neg1eqm1)
  2.5262 -    apply (simp add: negm1eq1 lin_neg_idemp sym[OF lin_neg_lin_add_distrib] lin_add_lin)
  2.5263 -    by arith
  2.5264 +  case (9 j c e) hence cp: "c>0" and be: "numbound0 e" and jp: "j > 0" and d': "c dvd l" by simp+
  2.5265 +    from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2.5266 +    from cp have cnz: "c \<noteq> 0" by simp
  2.5267 +    have "c div c\<le> l div c"
  2.5268 +      by (simp add: zdiv_mono1[OF clel cp])
  2.5269 +    then have ldcp:"0 < l div c" 
  2.5270 +      by (simp add: zdiv_self[OF cnz])
  2.5271 +    have "c * (l div c) = c* (l div c) + l mod c" using d' zdvd_iff_zmod_eq_0[where m="c" and n="l"] by simp
  2.5272 +    hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2.5273 +      by simp
  2.5274 +    hence "(\<exists> (k::int). l * x + (l div c) * Inum (x # bs) e = ((l div c) * j) * k) = (\<exists> (k::int). (c * (l div c)) * x + (l div c) * Inum (x # bs) e = ((l div c) * j) * k)"  by simp
  2.5275 +    also have "\<dots> = (\<exists> (k::int). (l div c) * (c * x + Inum (x # bs) e - j * k) = (l div c)*0)" by (simp add: ring_eq_simps)
  2.5276 +    also have "\<dots> = (\<exists> (k::int). c * x + Inum (x # bs) e - j * k = 0)"
  2.5277 +    using zero_le_mult_iff [where a="(l div c)" and b="c * x + Inum (x # bs) e - j * k"] ldcp by simp
  2.5278 +  also have "\<dots> = (\<exists> (k::int). c * x + Inum (x # bs) e = j * k)" by simp
  2.5279 +  finally show ?case using numbound0_I[OF be,where b="(l * x)" and b'="x" and bs="bs"] be  mult_strict_mono[OF ldcp jp ldcp ] by (simp add: dvd_def)
  2.5280  next
  2.5281 -  case (2 c r z)   from prems have zz: "z = Cst 0"
  2.5282 -    by (cases z, auto)
  2.5283 -  from prems zz have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" by simp
  2.5284 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.5285 -  have neg1eqm1: "Cst 1 = lin_neg (Cst -1)" by (simp add: lin_neg_def)
  2.5286 -  have negm1eq1: "Cst -1 = lin_neg (Cst 1)" by (simp add: lin_neg_def)
  2.5287 -  show ?case  using prems linr zz
  2.5288 -    by(auto simp add: lin_neg_lin_add_distrib lin_neg_idemp neg1eqm1)
  2.5289 -    (simp add: negm1eq1 lin_neg_idemp sym[OF lin_neg_lin_add_distrib] lin_add_lin lin_neg_lin)
  2.5290 -
  2.5291 -next
  2.5292 -  case (5 c r z)  from prems have zz: "z = Cst 0"
  2.5293 -    by (cases z, auto)
  2.5294 -  from prems zz have lincnr: "islinintterm (Add (Mult (Cst c) (Var 0)) r)" by simp
  2.5295 -  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.5296 -  have neg1eqm1: "Cst 1 = lin_neg (Cst -1)" by (simp add: lin_neg_def)
  2.5297 -  have negm1eq1: "Cst -1 = lin_neg (Cst 1)" by (simp add: lin_neg_def)
  2.5298 -  show ?case  using prems linr zz
  2.5299 -    by(auto simp add: lin_neg_lin_add_distrib lin_neg_idemp neg1eqm1)
  2.5300 -  
  2.5301 -qed simp_all
  2.5302 -
  2.5303 -(* mirror preserves divlcm *)
  2.5304 -lemma divlcm_mirror_eq:
  2.5305 -  assumes unifp: "isunified p"
  2.5306 -  shows "divlcm p = divlcm (mirror p)"
  2.5307 -  using unifp
  2.5308 -by (induct p rule: mirror.induct) auto
  2.5309 +  case (10 j c e) hence cp: "c>0" and be: "numbound0 e" and jp: "j > 0" and d': "c dvd l" by simp+
  2.5310 +    from lp cp have clel: "c\<le>l" by (simp add: zdvd_imp_le [OF d' lp])
  2.5311 +    from cp have cnz: "c \<noteq> 0" by simp
  2.5312 +    have "c div c\<le> l div c"
  2.5313 +      by (simp add: zdiv_mono1[OF clel cp])
  2.5314 +    then have ldcp:"0 < l div c" 
  2.5315 +      by (simp add: zdiv_self[OF cnz])
  2.5316 +    have "c * (l div c) = c* (l div c) + l mod c" using d' zdvd_iff_zmod_eq_0[where m="c" and n="l"] by simp
  2.5317 +    hence cl:"c * (l div c) =l" using zmod_zdiv_equality[where a="l" and b="c", symmetric] 
  2.5318 +      by simp
  2.5319 +    hence "(\<exists> (k::int). l * x + (l div c) * Inum (x # bs) e = ((l div c) * j) * k) = (\<exists> (k::int). (c * (l div c)) * x + (l div c) * Inum (x # bs) e = ((l div c) * j) * k)"  by simp
  2.5320 +    also have "\<dots> = (\<exists> (k::int). (l div c) * (c * x + Inum (x # bs) e - j * k) = (l div c)*0)" by (simp add: ring_eq_simps)
  2.5321 +    also have "\<dots> = (\<exists> (k::int). c * x + Inum (x # bs) e - j * k = 0)"
  2.5322 +    using zero_le_mult_iff [where a="(l div c)" and b="c * x + Inum (x # bs) e - j * k"] ldcp by simp
  2.5323 +  also have "\<dots> = (\<exists> (k::int). c * x + Inum (x # bs) e = j * k)" by simp
  2.5324 +  finally show ?case using numbound0_I[OF be,where b="(l * x)" and b'="x" and bs="bs"] be  mult_strict_mono[OF ldcp jp ldcp ] by (simp add: dvd_def)
  2.5325 +qed (simp_all add: nth_pos2 numbound0_I[where bs="bs" and b="(l * x)" and b'="x"])
  2.5326  
  2.5327 -(* mirror almost preserves semantics *)  
  2.5328 -lemma mirror_interp: 
  2.5329 -  assumes unifp: "isunified p"
  2.5330 -  shows "(qinterp (x#ats) p) = (qinterp ((- x)#ats) (mirror p))" (is "?P x = ?MP (-x)")
  2.5331 -using unifp unified_islinform[OF unifp]
  2.5332 -proof (induct p rule: islinform.induct)
  2.5333 -  case (1 t z)
  2.5334 -  from prems have zz: "z = 0" by simp
  2.5335 -  from prems 
  2.5336 -  have lint: "islinintterm t" by simp
  2.5337 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5338 -    by (induct t rule: islinintterm.induct) auto
  2.5339 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5340 -  moreover
  2.5341 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5342 -    then obtain "i" "n" "r" where 
  2.5343 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5344 -      by blast
  2.5345 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5346 -      by simp
  2.5347 -    have linr: "islinintterm r" 
  2.5348 -      by (rule islinintterm_subt[OF lininr])
  2.5349 -    have ?case using prems zz
  2.5350 -      by (cases n) (simp_all add: nth_pos2 
  2.5351 -	intterm_novar0[OF lininr, where x="x" and y="-x"])
  2.5352 -  }
  2.5353 -  ultimately show ?case by blast
  2.5354 -next
  2.5355 -  case (2 t z)
  2.5356 -  from prems have zz: "z = 0" by simp
  2.5357 -  from prems 
  2.5358 -  have lint: "islinintterm t" by simp
  2.5359 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5360 -    by (induct t rule: islinintterm.induct) auto
  2.5361 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5362 -  moreover
  2.5363 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5364 -    then obtain "i" "n" "r" where 
  2.5365 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5366 -      by blast
  2.5367 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5368 -      by simp
  2.5369 -    have linr: "islinintterm r" 
  2.5370 -      by (rule islinintterm_subt[OF lininr])
  2.5371 -    have ?case using prems zz
  2.5372 -      by (cases n) (simp_all add: nth_pos2 
  2.5373 -	intterm_novar0[OF lininr, where x="x" and y="-x"])
  2.5374 -  }
  2.5375 -  ultimately show ?case by blast
  2.5376 -next
  2.5377 -  case (3 d t) 
  2.5378 -  from prems 
  2.5379 -  have lint: "islinintterm t" by simp
  2.5380 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5381 -    by (induct t rule: islinintterm.induct) auto
  2.5382 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5383 -  moreover
  2.5384 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5385 -    then obtain "i" "n" "r" where 
  2.5386 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5387 -      by blast
  2.5388 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5389 -      by simp
  2.5390 -    have linr: "islinintterm r" 
  2.5391 -      by (rule islinintterm_subt[OF lininr])
  2.5392 -    have ?case
  2.5393 -      using prems linr 
  2.5394 -      by (cases n) (simp_all add: nth_pos2
  2.5395 -	intterm_novar0[OF lininr, where x="x" and y="-x"])
  2.5396 -  }
  2.5397 -  ultimately show ?case by blast
  2.5398 -next
  2.5399 -
  2.5400 -  case (6 d t) 
  2.5401 -  from prems 
  2.5402 -  have lint: "islinintterm t" by simp
  2.5403 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5404 -    by (induct t rule: islinintterm.induct) auto
  2.5405 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5406 -  moreover
  2.5407 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5408 -    then obtain "i" "n" "r" where 
  2.5409 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5410 -      by blast
  2.5411 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5412 -      by simp
  2.5413 -    have linr: "islinintterm r" 
  2.5414 -      by (rule islinintterm_subt[OF lininr])
  2.5415 -    have ?case
  2.5416 -      using prems linr 
  2.5417 -      by (cases n) (simp_all add: nth_pos2
  2.5418 -	intterm_novar0[OF lininr, where x="x" and y="-x"])
  2.5419 -  }
  2.5420 -  ultimately show ?case by blast
  2.5421 -next 
  2.5422 -  case (7 t z)
  2.5423 -  from prems have zz: "z = 0" by simp
  2.5424 -  from prems 
  2.5425 -  have lint: "islinintterm t" by simp
  2.5426 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5427 -    by (induct t rule: islinintterm.induct) auto
  2.5428 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5429 -  moreover
  2.5430 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5431 -    then obtain "i" "n" "r" where 
  2.5432 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5433 -      by blast
  2.5434 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5435 -      by simp
  2.5436 -    have linr: "islinintterm r" 
  2.5437 -      by (rule islinintterm_subt[OF lininr])
  2.5438 -    have ?case using prems zz
  2.5439 -      by (cases n) (simp_all add: nth_pos2 
  2.5440 -	intterm_novar0[OF lininr, where x="x" and y="-x"])
  2.5441 -  }
  2.5442 -  ultimately show ?case by blast 
  2.5443 -qed simp_all
  2.5444 -
  2.5445 -
  2.5446 -lemma mirror_interp2: 
  2.5447 -  assumes unifp: "islinform p"
  2.5448 -  shows "(qinterp (x#ats) p) = (qinterp ((- x)#ats) (mirror p))" (is "?P x = ?MP (-x)")
  2.5449 -using unifp 
  2.5450 -proof (induct p rule: islinform.induct)
  2.5451 -  case (1 t z)
  2.5452 -  from prems have zz: "z = 0" by simp
  2.5453 -  from prems 
  2.5454 -  have lint: "islinintterm t" by simp
  2.5455 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5456 -    by (induct t rule: islinintterm.induct) auto
  2.5457 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5458 -  moreover
  2.5459 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5460 -    then obtain "i" "n" "r" where 
  2.5461 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5462 -      by blast
  2.5463 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5464 -      by simp
  2.5465 -    have linr: "islinintterm r" 
  2.5466 -      by (rule islinintterm_subt[OF lininr])
  2.5467 -    have ?case using prems zz
  2.5468 -      by (cases n) (simp_all add: nth_pos2 
  2.5469 -	intterm_novar0[OF lininr, where x="x" and y="-x"])
  2.5470 -  }
  2.5471 -  ultimately show ?case by blast
  2.5472 -next
  2.5473 -  case (2 t z)
  2.5474 -  from prems have zz: "z = 0" by simp
  2.5475 -  from prems 
  2.5476 -  have lint: "islinintterm t" by simp
  2.5477 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5478 -    by (induct t rule: islinintterm.induct) auto
  2.5479 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5480 -  moreover
  2.5481 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5482 -    then obtain "i" "n" "r" where 
  2.5483 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5484 -      by blast
  2.5485 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5486 -      by simp
  2.5487 -    have linr: "islinintterm r" 
  2.5488 -      by (rule islinintterm_subt[OF lininr])
  2.5489 -    have ?case using prems zz
  2.5490 -      by (cases n) (simp_all add: nth_pos2 
  2.5491 -	intterm_novar0[OF lininr, where x="x" and y="-x"])
  2.5492 -  }
  2.5493 -  ultimately show ?case by blast
  2.5494 -next
  2.5495 -  case (3 d t) 
  2.5496 -  from prems 
  2.5497 -  have lint: "islinintterm t" by simp
  2.5498 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5499 -    by (induct t rule: islinintterm.induct) auto
  2.5500 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5501 -  moreover
  2.5502 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5503 -    then obtain "i" "n" "r" where 
  2.5504 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5505 -      by blast
  2.5506 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5507 -      by simp
  2.5508 -    have linr: "islinintterm r" 
  2.5509 -      by (rule islinintterm_subt[OF lininr])
  2.5510 -    have ?case
  2.5511 -      using prems linr 
  2.5512 -      by (cases n) (simp_all add: nth_pos2
  2.5513 -	intterm_novar0[OF lininr, where x="x" and y="-x"])
  2.5514 -  }
  2.5515 -  ultimately show ?case by blast
  2.5516 -next
  2.5517 -
  2.5518 -  case (6 d t) 
  2.5519 -  from prems 
  2.5520 -  have lint: "islinintterm t" by simp
  2.5521 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5522 -    by (induct t rule: islinintterm.induct) auto
  2.5523 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5524 -  moreover
  2.5525 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5526 -    then obtain "i" "n" "r" where 
  2.5527 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5528 -      by blast
  2.5529 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5530 -      by simp
  2.5531 -    have linr: "islinintterm r" 
  2.5532 -      by (rule islinintterm_subt[OF lininr])
  2.5533 -    have ?case
  2.5534 -      using prems linr 
  2.5535 -      by (cases n) (simp_all add: nth_pos2
  2.5536 -	intterm_novar0[OF lininr, where x="x" and y="-x"])
  2.5537 -  }
  2.5538 -  ultimately show ?case by blast
  2.5539 -next 
  2.5540 -  case (7 t z)
  2.5541 -  from prems have zz: "z = 0" by simp
  2.5542 -  from prems 
  2.5543 -  have lint: "islinintterm t" by simp
  2.5544 -  then have "(\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r) \<or> (\<exists> i. t = Cst i)"
  2.5545 -    by (induct t rule: islinintterm.induct) auto
  2.5546 -  moreover{ assume "\<exists> i. t = Cst i" then have ?case using prems by auto }
  2.5547 -  moreover
  2.5548 -  { assume "\<exists> i n r. t = Add (Mult (Cst i) (Var n) ) r"
  2.5549 -    then obtain "i" "n" "r" where 
  2.5550 -      inr_def: "t = Add (Mult (Cst i) (Var n) ) r" 
  2.5551 -      by blast
  2.5552 -    with lint have lininr: "islinintterm (Add (Mult (Cst i) (Var n) ) r)" 
  2.5553 -      by simp
  2.5554 -    have linr: "islinintterm r" 
  2.5555 -      by (rule islinintterm_subt[OF lininr])
  2.5556 -    have ?case using prems zz
  2.5557 -      by (cases n) (simp_all add: nth_pos2 
  2.5558 -	intterm_novar0[OF lininr, where x="x" and y="-x"])
  2.5559 -  }
  2.5560 -  ultimately show ?case by blast 
  2.5561 -qed simp_all
  2.5562 -
  2.5563 -(* mirror preserves existence *)
  2.5564 -lemma mirror_ex: 
  2.5565 -  assumes unifp: "isunified p"
  2.5566 -  shows "(\<exists> x. (qinterp (x#ats) p)) = (\<exists> y. (qinterp (y#ats) (mirror p)))" 
  2.5567 -  (is "(\<exists> x. ?P x) = (\<exists> y. ?MP y)")
  2.5568 -proof
  2.5569 -  assume "\<exists> x. ?P x"
  2.5570 -  then obtain "x" where px:"?P x" by blast
  2.5571 -  have "?MP (-x)" 
  2.5572 -    using px
  2.5573 -    by(simp add: mirror_interp[OF unifp, where x="x"])
  2.5574 -  then show "\<exists> y. ?MP y" by blast
  2.5575 -next 
  2.5576 -  assume "\<exists> y. ?MP y"
  2.5577 -  then obtain "y" where mpy: "?MP y" by blast
  2.5578 -  have "?P (-y)"
  2.5579 -    using mpy
  2.5580 -    by (simp add: mirror_interp[OF unifp, where x="-y"])
  2.5581 -  then show "\<exists> x. ?P x" by blast
  2.5582 +lemma a\<beta>_ex: assumes linp: "iszlfm p" and d: "d\<beta> p l" and lp: "l>0"
  2.5583 +  shows "(\<exists> x. l dvd x \<and> Ifm bbs (x #bs) (a\<beta> p l)) = (\<exists> (x::int). Ifm bbs (x#bs) p)"
  2.5584 +  (is "(\<exists> x. l dvd x \<and> ?P x) = (\<exists> x. ?P' x)")
  2.5585 +proof-
  2.5586 +  have "(\<exists> x. l dvd x \<and> ?P x) = (\<exists> (x::int). ?P (l*x))"
  2.5587 +    using unity_coeff_ex[where l="l" and P="?P", simplified] by simp
  2.5588 +  also have "\<dots> = (\<exists> (x::int). ?P' x)" using a\<beta>[OF linp d lp] by simp
  2.5589 +  finally show ?thesis  . 
  2.5590  qed
  2.5591  
  2.5592 -lemma mirror_ex2: 
  2.5593 -  assumes unifp: "isunified p"
  2.5594 -  shows "qinterp ats (QEx p) = qinterp ats (QEx (mirror p))"
  2.5595 -using mirror_ex[OF unifp] by simp
  2.5596 -
  2.5597 -  
  2.5598 -(* Cooper's theorem in its plusinfinity version *)
  2.5599 -lemma cooper_pi_eq:
  2.5600 -  assumes unifp : "isunified p"
  2.5601 -  shows "(\<exists> x. qinterp (x#ats) p) = 
  2.5602 -  ((\<exists> j \<in> {1 .. (divlcm p)}. qinterp (-j#ats) (plusinf p)) \<or> 
  2.5603 -  (\<exists> j \<in> {1 .. (divlcm p)}. \<exists> b \<in> set (aset p). 
  2.5604 -  qinterp (((I_intterm (a#ats) b) - j)#ats) p))"
  2.5605 -  (is "(\<exists> x. ?P x) = ((\<exists> j\<in> {1 .. ?d}. ?PP (-j)) \<or> (\<exists> j \<in> ?D. \<exists> b\<in> ?A. ?P (?I a b - j)))")
  2.5606 -proof-
  2.5607 -  have unifmp: "isunified (mirror p)" by (rule mirror_unified[OF unifp])
  2.5608 -  have th1: 
  2.5609 -    "(\<exists> j\<in> {1 .. ?d}. ?PP (-j)) = (\<exists> j\<in> {1..?d}.  qinterp (j # ats) (minusinf (mirror p)))"
  2.5610 -    by (simp add: plusinf_eq_minusinf_mirror[OF unifp])
  2.5611 -  have dth: "?d = divlcm (mirror p)"
  2.5612 -    by (rule divlcm_mirror_eq[OF unifp])
  2.5613 -  have "(\<exists> j \<in> ?D. \<exists> b\<in> ?A. ?P (?I a b - j)) = 
  2.5614 -    (\<exists> j\<in> ?D. \<exists> b \<in> set (map lin_neg (bset (mirror p))). ?P (?I a b - j))"
  2.5615 -    by (simp only: aset_eq_bset_mirror[OF unifp])
  2.5616 -  also have "\<dots> = (\<exists> j\<in> ?D. \<exists> b \<in> set (bset (mirror p)). ?P (?I a (lin_neg b) - j))"
  2.5617 -    by simp
  2.5618 -  also have "\<dots> = (\<exists> j\<in> ?D. \<exists> b \<in> set (bset (mirror p)). ?P (-(?I a b + j)))"
  2.5619 -  proof
  2.5620 -    assume "\<exists>j\<in>{1..divlcm p}.
  2.5621 -      \<exists>b\<in>set (bset (mirror p)). qinterp ((I_intterm (a # ats) (lin_neg b) - j) # ats) p"
  2.5622 -    then
  2.5623 -    obtain "j" and "b" where 
  2.5624 -      pbmj: "j\<in> ?D \<and> b\<in> set (bset (mirror p)) \<and> ?P (?I a (lin_neg b) - j)" by blast
  2.5625 -    then have linb: "islinintterm b" 
  2.5626 -      by (auto simp add:bset_lin[OF unifmp])
  2.5627 -    from linb pbmj have "?P (-(?I a b + j))" by (simp add: lin_neg_corr)
  2.5628 -    then show "\<exists> j\<in> ?D. \<exists> b \<in> set (bset (mirror p)). ?P (-(?I a b + j))"
  2.5629 -      using pbmj
  2.5630 -      by auto
  2.5631 -  next 
  2.5632 -    assume "\<exists> j\<in> ?D. \<exists> b \<in> set (bset (mirror p)). ?P (-(?I a b + j))"
  2.5633 -    then obtain "j" and "b" where 
  2.5634 -      pbmj: "j\<in> ?D \<and> b\<in> set (bset (mirror p)) \<and> ?P (-(?I a b + j))"
  2.5635 -      by blast
  2.5636 -    then have linb: "islinintterm b" 
  2.5637 -      by (auto simp add:bset_lin[OF unifmp])
  2.5638 -    from linb pbmj have "?P (?I a (lin_neg b) - j)"  
  2.5639 -      by (simp add: lin_neg_corr)
  2.5640 -    then show "\<exists> j\<in> ?D. \<exists> b \<in> set (bset (mirror p)). ?P (?I a (lin_neg b) - j)"
  2.5641 -      using pbmj by auto
  2.5642 -  qed
  2.5643 -  finally 
  2.5644 -  have bth: "(\<exists> j\<in> ?D. \<exists> b\<in> ?A. ?P (?I a b - j)) =
  2.5645 -    (\<exists>j\<in> ?D. \<exists> b\<in>set (bset (mirror p)). 
  2.5646 -    qinterp ((I_intterm (a # ats) b + j) # ats) (mirror p))"
  2.5647 -    by (simp add: mirror_interp[OF unifp] zadd_ac)
  2.5648 -  from bth dth th1
  2.5649 -  have "(\<exists> x. ?P x) = (\<exists> x. qinterp (x#ats) (mirror p))"
  2.5650 -    by (simp add: mirror_ex[OF unifp])
  2.5651 -  also have "\<dots> = ((\<exists>j\<in>{1..divlcm (mirror p)}. qinterp (j # ats) (minusinf (mirror p))) \<or>
  2.5652 -    (\<exists>j\<in>{1..divlcm (mirror p)}.
  2.5653 -    \<exists>b\<in>set (bset (mirror p)). qinterp ((I_intterm (a # ats) b + j) # ats) (mirror p)))"
  2.5654 -    (is "(\<exists> x. ?MP x) = ((\<exists> j\<in> ?DM. ?MPM j) \<or> (\<exists> j \<in> ?DM. \<exists> b\<in> ?BM. ?MP (?I a b + j)))")
  2.5655 -    by (rule cooper_mi_eq[OF unifmp])
  2.5656 -  also 
  2.5657 -  have "\<dots> = ((\<exists> j\<in> ?D. ?PP (-j)) \<or> (\<exists> j \<in> ?D. \<exists> b\<in> ?BM. ?MP (?I a b + j)))"
  2.5658 -    using bth th1 dth by simp
  2.5659 -  finally  show ?thesis using sym[OF bth] by simp
  2.5660 -qed
  2.5661 -   
  2.5662 -
  2.5663 -(* substitution of a term into a Qfree formula, substitution of Bound 0 by i*)
  2.5664 +lemma \<beta>:
  2.5665 +  assumes lp: "iszlfm p"
  2.5666 +  and u: "d\<beta> p 1"
  2.5667 +  and d: "d\<delta> p d"
  2.5668 +  and dp: "d > 0"
  2.5669 +  and nob: "\<not>(\<exists>(j::int) \<in> {1 .. d}. \<exists> b\<in> (Inum (a#bs)) ` set(\<beta> p). x = b + j)"
  2.5670 +  and p: "Ifm bbs (x#bs) p" (is "?P x")
  2.5671 +  shows "?P (x - d)"
  2.5672 +using lp u d dp nob p
  2.5673 +proof(induct p rule: iszlfm.induct)
  2.5674 +  case (5 c e) hence c1: "c=1" and  bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp+
  2.5675 +    with dp p c1 numbound0_I[OF bn,where b="(x-d)" and b'="x" and bs="bs"] prems
  2.5676 +    show ?case by simp
  2.5677 +next
  2.5678 +  case (6 c e)  hence c1: "c=1" and  bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp+
  2.5679 +    with dp p c1 numbound0_I[OF bn,where b="(x-d)" and b'="x" and bs="bs"] prems
  2.5680 +    show ?case by simp
  2.5681 +next
  2.5682 +  case (7 c e) hence p: "Ifm bbs (x #bs) (Gt (CX c e))" and c1: "c=1" and bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp+
  2.5683 +    let ?e = "Inum (x # bs) e"
  2.5684 +    {assume "(x-d) +?e > 0" hence ?case using c1 
  2.5685 +      numbound0_I[OF bn,where b="(x-d)" and b'="x" and bs="bs"] by simp}
  2.5686 +    moreover
  2.5687 +    {assume H: "\<not> (x-d) + ?e > 0" 
  2.5688 +      let ?v="Neg e"
  2.5689 +      have vb: "?v \<in> set (\<beta> (Gt (CX c e)))" by simp
  2.5690 +      from prems(11)[simplified simp_thms Inum.simps \<beta>.simps set.simps bex_simps numbound0_I[OF bn,where b="a" and b'="x" and bs="bs"]] 
  2.5691 +      have nob: "\<not> (\<exists> j\<in> {1 ..d}. x =  - ?e + j)" by auto 
  2.5692 +      from H p have "x + ?e > 0 \<and> x + ?e \<le> d" by (simp add: c1)
  2.5693 +      hence "x + ?e \<ge> 1 \<and> x + ?e \<le> d"  by simp
  2.5694 +      hence "\<exists> (j::int) \<in> {1 .. d}. j = x + ?e" by simp
  2.5695 +      hence "\<exists> (j::int) \<in> {1 .. d}. x = (- ?e + j)" 
  2.5696 +	by (simp add: ring_eq_simps)
  2.5697 +      with nob have ?case by auto}
  2.5698 +    ultimately show ?case by blast
  2.5699 +next
  2.5700 +  case (8 c e) hence p: "Ifm bbs (x #bs) (Ge (CX c e))" and c1: "c=1" and bn:"numbound0 e" 
  2.5701 +    using dvd1_eq1[where x="c"] by simp+
  2.5702 +    let ?e = "Inum (x # bs) e"
  2.5703 +    {assume "(x-d) +?e \<ge> 0" hence ?case using  c1 
  2.5704 +      numbound0_I[OF bn,where b="(x-d)" and b'="x" and bs="bs"]
  2.5705 +	by simp}
  2.5706 +    moreover
  2.5707 +    {assume H: "\<not> (x-d) + ?e \<ge> 0" 
  2.5708 +      let ?v="Sub (C -1) e"
  2.5709 +      have vb: "?v \<in> set (\<beta> (Ge (CX c e)))" by simp
  2.5710 +      from prems(11)[simplified simp_thms Inum.simps \<beta>.simps set.simps bex_simps numbound0_I[OF bn,where b="a" and b'="x" and bs="bs"]] 
  2.5711 +      have nob: "\<not> (\<exists> j\<in> {1 ..d}. x =  - ?e - 1 + j)" by auto 
  2.5712 +      from H p have "x + ?e \<ge> 0 \<and> x + ?e < d" by (simp add: c1)
  2.5713 +      hence "x + ?e +1 \<ge> 1 \<and> x + ?e + 1 \<le> d"  by simp
  2.5714 +      hence "\<exists> (j::int) \<in> {1 .. d}. j = x + ?e + 1" by simp
  2.5715 +      hence "\<exists> (j::int) \<in> {1 .. d}. x= - ?e - 1 + j" by (simp add: ring_eq_simps)
  2.5716 +      with nob have ?case by simp }
  2.5717 +    ultimately show ?case by blast
  2.5718 +next
  2.5719 +  case (3 c e) hence p: "Ifm bbs (x #bs) (Eq (CX c e))" (is "?p x") and c1: "c=1" and bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp+
  2.5720 +    let ?e = "Inum (x # bs) e"
  2.5721 +    let ?v="(Sub (C -1) e)"
  2.5722 +    have vb: "?v \<in> set (\<beta> (Eq (CX c e)))" by simp
  2.5723 +    from p have "x= - ?e" by (simp add: c1) with prems(11) show ?case using dp
  2.5724 +      by simp (erule ballE[where x="1"],
  2.5725 +	simp_all add:ring_eq_simps numbound0_I[OF bn,where b="x"and b'="a"and bs="bs"])
  2.5726 +next
  2.5727 +  case (4 c e)hence p: "Ifm bbs (x #bs) (NEq (CX c e))" (is "?p x") and c1: "c=1" and bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp+
  2.5728 +    let ?e = "Inum (x # bs) e"
  2.5729 +    let ?v="Neg e"
  2.5730 +    have vb: "?v \<in> set (\<beta> (NEq (CX c e)))" by simp
  2.5731 +    {assume "x - d + Inum (((x -d)) # bs) e \<noteq> 0" 
  2.5732 +      hence ?case by (simp add: c1)}
  2.5733 +    moreover
  2.5734 +    {assume H: "x - d + Inum (((x -d)) # bs) e = 0"
  2.5735 +      hence "x = - Inum (((x -d)) # bs) e + d" by simp
  2.5736 +      hence "x = - Inum (a # bs) e + d"
  2.5737 +	by (simp add: numbound0_I[OF bn,where b="x - d"and b'="a"and bs="bs"])
  2.5738 +       with prems(11) have ?case using dp by simp}
  2.5739 +  ultimately show ?case by blast
  2.5740 +next 
  2.5741 +  case (9 j c e) hence p: "Ifm bbs (x #bs) (Dvd j (CX c e))" (is "?p x") and c1: "c=1" and bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp+
  2.5742 +    let ?e = "Inum (x # bs) e"
  2.5743 +    from prems have id: "j dvd d" by simp
  2.5744 +    from c1 have "?p x = (j dvd (x+ ?e))" by simp
  2.5745 +    also have "\<dots> = (j dvd x - d + ?e)" 
  2.5746 +      using dvd_period[OF id, where x="x" and c="-1" and t="?e"] by simp
  2.5747 +    finally show ?case 
  2.5748 +      using numbound0_I[OF bn,where b="(x-d)" and b'="x" and bs="bs"] c1 p by simp
  2.5749 +next
  2.5750 +  case (10 j c e) hence p: "Ifm bbs (x #bs) (NDvd j (CX c e))" (is "?p x") and c1: "c=1" and bn:"numbound0 e" using dvd1_eq1[where x="c"] by simp+
  2.5751 +    let ?e = "Inum (x # bs) e"
  2.5752 +    from prems have id: "j dvd d" by simp
  2.5753 +    from c1 have "?p x = (\<not> j dvd (x+ ?e))" by simp
  2.5754 +    also have "\<dots> = (\<not> j dvd x - d + ?e)" 
  2.5755 +      using dvd_period[OF id, where x="x" and c="-1" and t="?e"] by simp
  2.5756 +    finally show ?case using numbound0_I[OF bn,where b="(x-d)" and b'="x" and bs="bs"] c1 p by simp
  2.5757 +qed (auto simp add: numbound0_I[where bs="bs" and b="(x - d)" and b'="x"] nth_pos2)
  2.5758  
  2.5759 -consts subst_it:: "intterm \<Rightarrow> intterm \<Rightarrow> intterm"
  2.5760 -primrec
  2.5761 -"subst_it i (Cst b) = Cst b"
  2.5762 -"subst_it i (Var n) = (if n = 0 then i else Var n)"
  2.5763 -"subst_it i (Neg it) = Neg (subst_it i it)"
  2.5764 -"subst_it i (Add it1 it2) = Add (subst_it i it1) (subst_it i it2)" 
  2.5765 -"subst_it i (Sub it1 it2) = Sub (subst_it i it1) (subst_it i it2)"
  2.5766 -"subst_it i (Mult it1 it2) = Mult (subst_it i it1) (subst_it i it2)"
  2.5767 -
  2.5768 -
  2.5769 -(* subst_it preserves semantics *)
  2.5770 -lemma subst_it_corr: 
  2.5771 -"I_intterm (a#ats) (subst_it i t) = I_intterm ((I_intterm (a#ats) i)#ats) t"
  2.5772 -by (induct t rule: subst_it.induct, simp_all add: nth_pos2)
  2.5773 -
  2.5774 -consts subst_p:: "intterm \<Rightarrow> QF \<Rightarrow> QF"
  2.5775 -primrec
  2.5776 -"subst_p i (Le it1 it2) = Le (subst_it i it1) (subst_it i it2)"
  2.5777 -"subst_p i (Lt it1 it2) = Lt (subst_it i it1) (subst_it i it2)"
  2.5778 -"subst_p i (Ge it1 it2) = Ge (subst_it i it1) (subst_it i it2)"
  2.5779 -"subst_p i (Gt it1 it2) = Gt (subst_it i it1) (subst_it i it2)"
  2.5780 -"subst_p i (Eq it1 it2) = Eq (subst_it i it1) (subst_it i it2)"
  2.5781 -"subst_p i (Divides d t) = Divides (subst_it i d) (subst_it i t)"
  2.5782 -"subst_p i T = T"
  2.5783 -"subst_p i F = F"
  2.5784 -"subst_p i (And p q) = And (subst_p i p) (subst_p i q)"
  2.5785 -"subst_p i (Or p q) = Or (subst_p i p) (subst_p i q)"
  2.5786 -"subst_p i (Imp p q) = Imp (subst_p i p) (subst_p i q)"
  2.5787 -"subst_p i (Equ p q) = Equ (subst_p i p) (subst_p i q)"
  2.5788 -"subst_p i (NOT p) = (NOT (subst_p i p))"
  2.5789 -
  2.5790 -(* subs_p preserves correctness *)
  2.5791 -lemma subst_p_corr: 
  2.5792 -  assumes qf: "isqfree p" 
  2.5793 -  shows "qinterp (a # ats) (subst_p i p) = qinterp ((I_intterm (a#ats) i)#ats) p "
  2.5794 -  using qf
  2.5795 -by (induct p rule: subst_p.induct) (simp_all add: subst_it_corr)
  2.5796 -
  2.5797 -(* novar0 p is true if the fomula doese not depend on the quantified variable*)
  2.5798 -consts novar0I:: "intterm \<Rightarrow> bool"
  2.5799 -primrec
  2.5800 -"novar0I (Cst i) = True"
  2.5801 -"novar0I (Var n) = (n > 0)"
  2.5802 -"novar0I (Neg a) = (novar0I a)"
  2.5803 -"novar0I (Add a b) = (novar0I a \<and> novar0I b)"
  2.5804 -"novar0I (Sub a b) = (novar0I a \<and> novar0I b)"
  2.5805 -"novar0I (Mult a b) = (novar0I a \<and> novar0I b)"
  2.5806 -
  2.5807 -consts novar0:: "QF \<Rightarrow> bool"
  2.5808 -recdef novar0 "measure size"
  2.5809 -"novar0 (Lt a b) = (novar0I a \<and> novar0I b)"
  2.5810 -"novar0 (Gt a b) = (novar0I a \<and> novar0I b)"
  2.5811 -"novar0 (Le a b) = (novar0I a \<and> novar0I b)"
  2.5812 -"novar0 (Ge a b) = (novar0I a \<and> novar0I b)"
  2.5813 -"novar0 (Eq a b) = (novar0I a \<and> novar0I b)"
  2.5814 -"novar0 (Divides a b) = (novar0I a \<and> novar0I b)"
  2.5815 -"novar0 T = True" 
  2.5816 -"novar0 F = True"
  2.5817 -"novar0 (NOT p) = novar0 p" 
  2.5818 -"novar0 (And p q) = (novar0 p \<and> novar0 q)"
  2.5819 -"novar0 (Or p q)  = (novar0 p \<and> novar0 q)"
  2.5820 -"novar0 (Imp p q) = (novar0 p \<and> novar0 q)"
  2.5821 -"novar0 (Equ p q) = (novar0 p \<and> novar0 q)"
  2.5822 -"novar0 p = False"
  2.5823 -
  2.5824 -(* Interpretation of terms, that doese not depend on Var 0 *)
  2.5825 -lemma I_intterm_novar0:
  2.5826 -  assumes nov0: "novar0I x"
  2.5827 -  shows "I_intterm (a#ats) x = I_intterm (b#ats) x"
  2.5828 -using nov0
  2.5829 -by (induct x) (auto simp add: nth_pos2)
  2.5830 -
  2.5831 -(* substition is meaningless for term independent of Var 0*)
  2.5832 -lemma subst_p_novar0_corr:
  2.5833 -assumes qfp: "isqfree p"
  2.5834 -  and nov0: "novar0I i"
  2.5835 -  shows "qinterp (a#ats) (subst_p i p) = qinterp (I_intterm (b#ats) i#ats) p"
  2.5836 -proof-
  2.5837 -  have "qinterp (a#ats) (subst_p i p) = qinterp (I_intterm (a#ats) i#ats) p"
  2.5838 -    by (rule subst_p_corr[OF qfp])
  2.5839 -  moreover have "I_intterm (a#ats) i#ats = I_intterm (b#ats) i#ats"
  2.5840 -    by (simp add: I_intterm_novar0[OF nov0, where a="a" and b="b"])
  2.5841 -  ultimately show ?thesis by simp
  2.5842 +lemma \<beta>':   
  2.5843 +  assumes lp: "iszlfm p"
  2.5844 +  and u: "d\<beta> p 1"
  2.5845 +  and d: "d\<delta> p d"
  2.5846 +  and dp: "d > 0"
  2.5847 +  shows "\<forall> x. \<not>(\<exists>(j::int) \<in> {1 .. d}. \<exists> b\<in> set(\<beta> p). Ifm bbs ((Inum (a#bs) b + j) #bs) p) \<longrightarrow> Ifm bbs (x#bs) p \<longrightarrow> Ifm bbs ((x - d)#bs) p" (is "\<forall> x. ?b \<longrightarrow> ?P x \<longrightarrow> ?P (x - d)")
  2.5848 +proof(clarify)
  2.5849 +  fix x 
  2.5850 +  assume nb:"?b" and px: "?P x" 
  2.5851 +  hence nb2: "\<not>(\<exists>(j::int) \<in> {1 .. d}. \<exists> b\<in> (Inum (a#bs)) ` set(\<beta> p). x = b + j)"
  2.5852 +    by auto
  2.5853 +  from  \<beta>[OF lp u d dp nb2 px] show "?P (x -d )" .
  2.5854  qed
  2.5855  
  2.5856 -(* linearity and independence on Var 0*)
  2.5857 -lemma lin_novar0: 
  2.5858 -  assumes linx: "islinintterm x"
  2.5859 -  and nov0: "novar0I x"
  2.5860 -  shows "\<exists> n > 0. islintn(n,x)"
  2.5861 -using linx nov0
  2.5862 -by (induct x rule: islinintterm.induct) auto
  2.5863 -
  2.5864 -lemma lintnpos_novar0:
  2.5865 - assumes  npos: "n > 0"
  2.5866 -  and linx: "islintn(n,x)"
  2.5867 -  shows "novar0I x"
  2.5868 -using npos linx
  2.5869 -by (induct n x rule: islintn.induct) auto
  2.5870 -
  2.5871 -(* lin_add preserves independence on Var 0*)
  2.5872 -lemma lin_add_novar0:
  2.5873 -  assumes nov0a: "novar0I a"
  2.5874 -  and nov0b : "novar0I b"
  2.5875 -  and lina : "islinintterm a"
  2.5876 -  and linb: "islinintterm b"
  2.5877 -  shows "novar0I (lin_add (a,b))"
  2.5878 +theorem cp_thm:
  2.5879 +  assumes lp: "iszlfm p"
  2.5880 +  and u: "d\<beta> p 1"
  2.5881 +  and d: "d\<delta> p d"
  2.5882 +  and dp: "d > 0"
  2.5883 +  shows "(\<exists> (x::int). Ifm bbs (x #bs) p) = (\<exists> j\<in> {1.. d}. Ifm bbs (j #bs) (minusinf p) \<or> (\<exists> b \<in> set (\<beta> p). Ifm bbs ((Inum (i#bs) b + j) #bs) p))"
  2.5884 +  (is "(\<exists> (x::int). ?P (x)) = (\<exists> j\<in> ?D. ?M j \<or> (\<exists> b\<in> ?B. ?P (?I b + j)))")
  2.5885  proof-
  2.5886 -  have "\<exists> na > 0. islintn(na, a)" by (rule lin_novar0[OF lina nov0a]) 
  2.5887 -  then obtain "na" where na: "na > 0 \<and> islintn(na,a)" by blast
  2.5888 -  have "\<exists> nb > 0. islintn(nb, b)" by (rule lin_novar0[OF linb nov0b]) 
  2.5889 -  then obtain "nb" where nb: "nb > 0 \<and> islintn(nb,b)" by blast
  2.5890 -  from na have napos: "na > 0" by simp
  2.5891 -  from na have linna: "islintn(na,a)" by simp
  2.5892 -  from nb have nbpos: "nb > 0" by simp
  2.5893 -  from nb have linnb: "islintn(nb,b)" by simp
  2.5894 -  have "min na nb \<le> min na nb" by simp
  2.5895 -  then have "islintn (min na nb, lin_add(a,b))" by (simp add: lin_add_lint[OF linna linnb])
  2.5896 -  moreover have "min na nb > 0" using napos nbpos by (simp add: min_def)
  2.5897 -  ultimately show ?thesis by (simp only: lintnpos_novar0)
  2.5898 -qed
  2.5899 -
  2.5900 -(* lin__mul preserves independence on Var 0*)
  2.5901 -lemma lin_mul_novar0:
  2.5902 -  assumes linx: "islinintterm x"
  2.5903 -  and nov0: "novar0I x"
  2.5904 -  shows "novar0I (lin_mul(i,x))"
  2.5905 -  using linx nov0
  2.5906 -proof (induct i x rule: lin_mul.induct, auto)
  2.5907 -  case (goal1 c c' n r)
  2.5908 -  from prems have lincnr: "islinintterm (Add (Mult (Cst c') (Var n)) r)" by simp
  2.5909 -  have "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.5910 -  then show ?case using prems by simp
  2.5911 -qed
  2.5912 -    
  2.5913 -(* lin_neg preserves indepenednce on Var 0*)
  2.5914 -lemma lin_neg_novar0:
  2.5915 -  assumes linx: "islinintterm x"
  2.5916 -  and nov0: "novar0I x"
  2.5917 -  shows "novar0I (lin_neg x)"
  2.5918 -by (auto simp add: lin_mul_novar0 linx nov0 lin_neg_def)
  2.5919 -
  2.5920 -(* subterms of linear terms are independent on Var 0*)
  2.5921 -lemma intterm_subt_novar0:
  2.5922 -  assumes lincnr: "islinintterm (Add (Mult (Cst c) (Var n)) r)"
  2.5923 -  shows "novar0I r"
  2.5924 -proof-
  2.5925 -  have cnz: "c \<noteq> 0" by (rule islinintterm_cnz[OF lincnr])
  2.5926 -  have "islintn(0,Add (Mult (Cst c) (Var n)) r)" using lincnr
  2.5927 -    by (simp only: islinintterm_eq_islint islint_def)
  2.5928 -  then have "islintn (n+1,r)" by auto
  2.5929 -  moreover have "n+1 >0 " by arith
  2.5930 -  ultimately show ?thesis 
  2.5931 -    using lintnpos_novar0
  2.5932 -    by auto
  2.5933 +  from minusinf_inf[OF lp u] 
  2.5934 +  have th: "\<exists>(z::int). \<forall>x<z. ?P (x) = ?M x" by blast
  2.5935 +  let ?B' = "{?I b | b. b\<in> ?B}"
  2.5936 +  have BB': "(\<exists>j\<in>?D. \<exists>b\<in> ?B. ?P (?I b +j)) = (\<exists> j \<in> ?D. \<exists> b \<in> ?B'. ?P (b + j))" by auto
  2.5937 +  hence th2: "\<forall> x. \<not> (\<exists> j \<in> ?D. \<exists> b \<in> ?B'. ?P ((b + j))) \<longrightarrow> ?P (x) \<longrightarrow> ?P ((x - d))" 
  2.5938 +    using \<beta>'[OF lp u d dp, where a="i" and bbs = "bbs"] by blast
  2.5939 +  from minusinf_repeats[OF d lp]
  2.5940 +  have th3: "\<forall> x k. ?M x = ?M (x-k*d)" by simp
  2.5941 +  from cpmi_eq[OF dp th th2 th3] BB' show ?thesis by blast
  2.5942  qed
  2.5943  
  2.5944 -(* decrease the De-Bruijn indices*)
  2.5945 -consts decrvarsI:: "intterm \<Rightarrow> intterm"
  2.5946 -primrec
  2.5947 -"decrvarsI (Cst i) = (Cst i)"
  2.5948 -"decrvarsI (Var n) = (Var (n - 1))"
  2.5949 -"decrvarsI (Neg a) = (Neg (decrvarsI a))"
  2.5950 -"decrvarsI (Add a b) = (Add (decrvarsI a) (decrvarsI b))"
  2.5951 -"decrvarsI (Sub a b) = (Sub (decrvarsI a) (decrvarsI b))"
  2.5952 -"decrvarsI (Mult a b) = (Mult (decrvarsI a) (decrvarsI b))"
  2.5953 -
  2.5954 -(* One can decrease the indics for terms and formulae independent on Var 0*)
  2.5955 -lemma intterm_decrvarsI:
  2.5956 -  assumes nov0: "novar0I t"
  2.5957 -  shows "I_intterm (a#ats) t = I_intterm ats (decrvarsI t)"
  2.5958 -using nov0
  2.5959 -by (induct t) (auto simp add: nth_pos2)
  2.5960 -
  2.5961 -consts decrvars:: "QF \<Rightarrow> QF"
  2.5962 -primrec
  2.5963 -"decrvars (Lt a b) = (Lt (decrvarsI a) (decrvarsI b))"
  2.5964 -"decrvars (Gt a b) = (Gt (decrvarsI a) (decrvarsI b))"
  2.5965 -"decrvars (Le a b) = (Le (decrvarsI a) (decrvarsI b))"
  2.5966 -"decrvars (Ge a b) = (Ge (decrvarsI a) (decrvarsI b))"
  2.5967 -"decrvars (Eq a b) = (Eq (decrvarsI a) (decrvarsI b))"
  2.5968 -"decrvars (Divides a b) = (Divides (decrvarsI a) (decrvarsI b))"
  2.5969 -"decrvars T = T" 
  2.5970 -"decrvars F = F"
  2.5971 -"decrvars (NOT p) = (NOT (decrvars p))" 
  2.5972 -"decrvars (And p q) = (And (decrvars p) (decrvars q))"
  2.5973 -"decrvars (Or p q)  = (Or (decrvars p) (decrvars q))"
  2.5974 -"decrvars (Imp p q) = (Imp (decrvars p) (decrvars q))"
  2.5975 -"decrvars (Equ p q) = (Equ (decrvars p) (decrvars q))"
  2.5976 -
  2.5977 -(* decrvars preserves quantifier freeness*)
  2.5978 -lemma decrvars_qfree: "isqfree p \<Longrightarrow> isqfree (decrvars p)"
  2.5979 -by (induct p rule: isqfree.induct, auto)
  2.5980 -
  2.5981 -lemma novar0_qfree: "novar0 p \<Longrightarrow> isqfree p"
  2.5982 -by (induct p) auto
  2.5983 -
  2.5984 -lemma qinterp_novar0:
  2.5985 -  assumes nov0: "novar0 p"
  2.5986 -  shows "qinterp (a#ats) p = qinterp ats (decrvars p)"
  2.5987 -using nov0
  2.5988 -by(induct p) (simp_all add: intterm_decrvarsI)
  2.5989 +    (* Implement the right hand sides of Cooper's theorem and Ferrante and Rackoff. *)
  2.5990 +lemma mirror_ex: 
  2.5991 +  assumes lp: "iszlfm p"
  2.5992 +  shows "(\<exists> x. Ifm bbs (x#bs) (mirror p)) = (\<exists> x. Ifm bbs (x#bs) p)"
  2.5993 +  (is "(\<exists> x. ?I x ?mp) = (\<exists> x. ?I x p)")
  2.5994 +proof(auto)
  2.5995 +  fix x assume "?I x ?mp" hence "?I (- x) p" using mirror[OF lp] by blast
  2.5996 +  thus "\<exists> x. ?I x p" by blast
  2.5997 +next
  2.5998 +  fix x assume "?I x p" hence "?I (- x) ?mp" 
  2.5999 +    using mirror[OF lp, where x="- x", symmetric] by auto
  2.6000 +  thus "\<exists> x. ?I x ?mp" by blast
  2.6001 +qed
  2.6002 +  
  2.6003 +  
  2.6004 +lemma cp_thm': 
  2.6005 +  assumes lp: "iszlfm p"
  2.6006 +  and up: "d\<beta> p 1" and dd: "d\<delta> p d" and dp: "d > 0"
  2.6007 +  shows "(\<exists> x. Ifm bbs (x#bs) p) = ((\<exists> j\<in> {1 .. d}. Ifm bbs (j#bs) (minusinf p)) \<or> (\<exists> j\<in> {1.. d}. \<exists> b\<in> (Inum (i#bs)) ` set (\<beta> p). Ifm bbs ((b+j)#bs) p))"
  2.6008 +  using cp_thm[OF lp up dd dp,where i="i"] by auto
  2.6009  
  2.6010 -(* All elements of bset p doese not depend on Var 0*)
  2.6011 -lemma bset_novar0:
  2.6012 -  assumes unifp: "isunified p"
  2.6013 -  shows "\<forall> b\<in> set (bset p). novar0I b "
  2.6014 -  using unifp
  2.6015 -proof(induct p rule: bset.induct)
  2.6016 -  case (1 c r z) 
  2.6017 -  from prems have zz: "z = Cst 0" by (cases "z", auto) 
  2.6018 -    from prems zz have lincnr: "islinintterm(Add (Mult (Cst c) (Var 0)) r)" by simp
  2.6019 -    have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.6020 -    have novar0r: "novar0I r" by (rule intterm_subt_novar0[OF lincnr])
  2.6021 -    from prems zz have "c = 1 \<or> c = -1" by auto
  2.6022 -    moreover 
  2.6023 -    {
  2.6024 -      assume c1: "c=1"
  2.6025 -      have lin1: "islinintterm (Cst 1)" by simp
  2.6026 -      have novar01: "novar0I (Cst 1)" by simp
  2.6027 -      then have ?case 
  2.6028 -	using prems zz novar0r lin1 novar01
  2.6029 -	by (auto simp add: lin_add_novar0 lin_neg_novar0 linr lin_neg_lin)
  2.6030 -    }
  2.6031 -    moreover 
  2.6032 -    {
  2.6033 -      assume c1: "c= -1"
  2.6034 -      have lin1: "islinintterm (Cst -1)" by simp
  2.6035 -      have novar01: "novar0I (Cst -1)" by simp
  2.6036 -      then have ?case 
  2.6037 -	using prems zz novar0r lin1 novar01
  2.6038 -	by (auto simp add: lin_add_novar0 lin_neg_novar0 linr lin_neg_lin)
  2.6039 -    }
  2.6040 -    ultimately show ?case by blast
  2.6041 -next 
  2.6042 -  case (2 c r z) 
  2.6043 -  from prems have zz: "z = Cst 0" by (cases "z", auto) 
  2.6044 -    from prems zz have lincnr: "islinintterm(Add (Mult (Cst c) (Var 0)) r)" by simp
  2.6045 -    have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.6046 -    have novar0r: "novar0I r" by (rule intterm_subt_novar0[OF lincnr])
  2.6047 -    from prems zz have "c = 1 \<or> c = -1" by auto
  2.6048 -    moreover 
  2.6049 -    {
  2.6050 -      assume c1: "c=1"
  2.6051 -      have lin1: "islinintterm (Cst 1)" by simp
  2.6052 -      have novar01: "novar0I (Cst 1)" by simp
  2.6053 -      then have ?case 
  2.6054 -	using prems zz novar0r lin1 novar01
  2.6055 -	by (auto simp add: lin_add_novar0 lin_neg_novar0 linr lin_neg_lin)
  2.6056 -    }
  2.6057 -    moreover 
  2.6058 -    {
  2.6059 -      assume c1: "c= -1"
  2.6060 -      have lin1: "islinintterm (Cst -1)" by simp
  2.6061 -      have novar01: "novar0I (Cst -1)" by simp
  2.6062 -      then have ?case 
  2.6063 -	using prems zz novar0r lin1 novar01
  2.6064 -	by (auto simp add: lin_add_novar0 lin_neg_novar0 linr lin_neg_lin)
  2.6065 -    }
  2.6066 -    ultimately show ?case by blast
  2.6067 -next 
  2.6068 -  case (3 c r z) 
  2.6069 -  from prems have zz: "z = Cst 0" by (cases "z", auto) 
  2.6070 -    from prems zz have lincnr: "islinintterm(Add (Mult (Cst c) (Var 0)) r)" by simp
  2.6071 -    have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  2.6072 -    have novar0r: "novar0I r" by (rule intterm_subt_novar0[OF lincnr])
  2.6073 -    from prems zz have "c = 1 \<or> c = -1" by auto
  2.6074 -    moreover 
  2.6075 -    {
  2.6076 -      assume c1: "c=1"
  2.6077 -      have lin1: "islinintterm (Cst 1)" by simp
  2.6078 -      have novar01: "novar0I (Cst 1)" by simp
  2.6079 -      then have ?case 
  2.6080 -	using prems zz novar0r lin1 novar01
  2.6081 -	by (auto simp add: lin_add_novar0 lin_neg_novar0 linr lin_neg_lin)
  2.6082 -    }
  2.6083 -    moreover 
  2.6084 -    {
  2.6085 -      assume c1: "c= -1"
  2.6086 -      have lin1: "islinintterm (Cst -1)" by simp
  2.6087 -      have novar01: "novar0I (Cst -1)" by simp
  2.6088 -      then have ?case 
  2.6089 -	using prems zz novar0r lin1 novar01
  2.6090 -	by (auto simp add: lin_add_novar0 lin_neg_novar0 linr lin_neg_lin)
  2.6091 -    }
  2.6092 -    ultimately show ?case by blast
  2.6093 -qed auto
  2.6094 -
  2.6095 -(* substitution preserves independence on Var 0*)
  2.6096 -lemma subst_it_novar0:
  2.6097 -  assumes nov0x: "novar0I x"
  2.6098 -  shows "novar0I (subst_it x t)"
  2.6099 -  using nov0x
  2.6100 -  by (induct t) auto
  2.6101 -
  2.6102 -lemma subst_p_novar0:
  2.6103 -  assumes nov0x:"novar0I x"
  2.6104 -  and qfp: "isqfree p"
  2.6105 -  shows "novar0 (subst_p x p)"
  2.6106 -  using nov0x qfp
  2.6107 -  by (induct p rule: novar0.induct) (simp_all add: subst_it_novar0)
  2.6108 +constdefs unit:: "fm \<Rightarrow> fm \<times> num list \<times> int"
  2.6109 +  "unit p \<equiv> (let p' = zlfm p ; l = \<zeta> p' ; q = And (Dvd l (CX 1 (C 0))) (a\<beta> p' l); d = \<delta> q;
  2.6110 +             B = remdups (map simpnum (\<beta> q)) ; a = remdups (map simpnum (\<alpha> q))
  2.6111 +             in if length B \<le> length a then (q,B,d) else (mirror q, a,d))"
  2.6112  
  2.6113 -(* linearize preserves independence on Var 0 *)
  2.6114 -lemma linearize_novar0: 
  2.6115 -  assumes nov0t: "novar0I t "
  2.6116 -  shows "\<And> t'. linearize t = Some t' \<Longrightarrow> novar0I t'"
  2.6117 -using nov0t
  2.6118 -proof(induct t rule: novar0I.induct)
  2.6119 -  case (Neg a)
  2.6120 -  let ?la = "linearize a"
  2.6121 -  from prems have "\<exists> a'. ?la = Some a'" by (cases ?la, auto)
  2.6122 -  then obtain "a'" where "?la = Some a'" by blast
  2.6123 -  with prems have nv0a':"novar0I a'" by simp
  2.6124 -  have "islinintterm a'" using prems by (simp add: linearize_linear)
  2.6125 -  with nv0a' have "novar0I (lin_neg a')" 
  2.6126 -    by (simp add: lin_neg_novar0)
  2.6127 -  then 
  2.6128 -  show ?case using prems by simp 
  2.6129 -next 
  2.6130 -  case (Add a b) 
  2.6131 -  let ?la = "linearize a"
  2.6132 -  let ?lb = "linearize b"
  2.6133 -  from prems have linab: "linearize (Add a b) = Some t'" by simp
  2.6134 -  then have "\<exists> a'. ?la = Some a'" by (cases ?la) auto
  2.6135 -  then obtain "a'" where "?la = Some a'" by blast
  2.6136 -  with prems have nv0a':"novar0I a'" by simp
  2.6137 -  have lina': "islinintterm a'" using prems by (simp add: linearize_linear)
  2.6138 -  from linab have "\<exists> b'. ?lb = Some b'"
  2.6139 -    by (cases ?la, auto) (cases ?lb, auto)
  2.6140 -  then obtain "b'" where "?lb = Some b'" by blast
  2.6141 -  with prems have nv0b':"novar0I b'" by simp
  2.6142 -  have linb': "islinintterm b'" using prems by (simp add: linearize_linear)
  2.6143 -  then show ?case using prems lina' linb' nv0a' nv0b'
  2.6144 -    by (auto simp add: lin_add_novar0)
  2.6145 -next 
  2.6146 -  case (Sub a b)
  2.6147 -    let ?la = "linearize a"
  2.6148 -  let ?lb = "linearize b"
  2.6149 -  from prems have linab: "linearize (Sub a b) = Some t'" by simp
  2.6150 -  then have "\<exists> a'. ?la = Some a'" by (cases ?la) auto
  2.6151 -  then obtain "a'" where "?la = Some a'" by blast
  2.6152 -  with prems have nv0a':"novar0I a'" by simp
  2.6153 -  have lina': "islinintterm a'" using prems by (simp add: linearize_linear)
  2.6154 -  from linab have "\<exists> b'. ?lb = Some b'"
  2.6155 -    by (cases ?la, auto) (cases ?lb, auto)
  2.6156 -  then obtain "b'" where "?lb = Some b'" by blast
  2.6157 -  with prems have nv0b':"novar0I b'" by simp
  2.6158 -  have linb': "islinintterm b'" using prems by (simp add: linearize_linear)
  2.6159 -  then show ?case using prems lina' linb' nv0a' nv0b'
  2.6160 -    by (auto simp add: lin_add_novar0 lin_neg_novar0 lin_neg_lin)
  2.6161 -next 
  2.6162 -  case (Mult a b)     
  2.6163 -  let ?la = "linearize a"
  2.6164 -  let ?lb = "linearize b"
  2.6165 -  from prems have linab: "linearize (Mult a b) = Some t'" by simp
  2.6166 -  then have "\<exists> a'. ?la = Some a'" by (cases ?la, auto)
  2.6167 -  then obtain "a'" where "?la = Some a'" by blast
  2.6168 -  with prems have nv0a':"novar0I a'" by simp
  2.6169 -  have lina': "islinintterm a'" using prems by (simp add: linearize_linear)
  2.6170 -  from prems linab have "\<exists> b'. ?lb = Some b'"
  2.6171 -    apply (cases ?la, auto)
  2.6172 -    by (cases "a'",auto) (cases ?lb, auto)+
  2.6173 -  then obtain "b'" where "?lb = Some b'" by blast
  2.6174 -  with prems have nv0b':"novar0I b'" by simp
  2.6175 -  have linb': "islinintterm b'" using prems by (simp add: linearize_linear)
  2.6176 -  then show ?case using prems lina' linb' nv0a' nv0b' 
  2.6177 -    by (cases "a'",auto simp add: lin_mul_novar0)
  2.6178 -  (cases "b'",auto simp add: lin_mul_novar0)
  2.6179 -qed auto
  2.6180 -
  2.6181 -
  2.6182 -(* simplification of formulae *)
  2.6183 -consts psimpl :: "QF \<Rightarrow> QF"
  2.6184 -recdef psimpl "measure size"
  2.6185 -"psimpl (Le l r) = 
  2.6186 -  (case (linearize (Sub l r)) of
  2.6187 -   None \<Rightarrow> Le l r
  2.6188 - | Some x \<Rightarrow> (case x of 
  2.6189 -       Cst i \<Rightarrow> (if i \<le> 0 then T else F)
  2.6190 -     | _ \<Rightarrow> (Le x (Cst 0))))"
  2.6191 -"psimpl (Eq l r) = 
  2.6192 -  (case (linearize (Sub l r)) of
  2.6193 -   None \<Rightarrow> Eq l r
  2.6194 - | Some x \<Rightarrow> (case x of 
  2.6195 -       Cst i \<Rightarrow> (if i = 0 then T else F)
  2.6196 -     | _ \<Rightarrow> (Eq x (Cst 0))))"
  2.6197 -
  2.6198 -"psimpl (Divides (Cst d) t) = 
  2.6199 -  (case (linearize t) of
  2.6200 -  None \<Rightarrow> (Divides (Cst d) t)
  2.6201 -  | Some c \<Rightarrow> (case c of
  2.6202 -     Cst i \<Rightarrow> (if d dvd i then T else F)
  2.6203 -   | _ \<Rightarrow>  (Divides (Cst d) c)))"
  2.6204 +lemma unit: assumes qf: "qfree p"
  2.6205 +  shows "\<And> q B d. unit p = (q,B,d) \<Longrightarrow> ((\<exists> x. Ifm bbs (x#bs) p) = (\<exists> x. Ifm bbs (x#bs) q)) \<and> (Inum (i#bs)) ` set B = (Inum (i#bs)) ` set (\<beta> q) \<and> d\<beta> q 1 \<and> d\<delta> q d \<and> d >0 \<and> iszlfm q \<and> (\<forall> b\<in> set B. numbound0 b)"
  2.6206 +proof-
  2.6207 +  fix q B d 
  2.6208 +  assume qBd: "unit p = (q,B,d)"
  2.6209 +  let ?thes = "((\<exists> x. Ifm bbs (x#bs) p) = (\<exists> x. Ifm bbs (x#bs) q)) \<and>
  2.6210 +    Inum (i#bs) ` set B = Inum (i#bs) ` set (\<beta> q) \<and>
  2.6211 +    d\<beta> q 1 \<and> d\<delta> q d \<and> 0 < d \<and> iszlfm q \<and> (\<forall> b\<in> set B. numbound0 b)"
  2.6212 +  let ?I = "\<lambda> x p. Ifm bbs (x#bs) p"
  2.6213 +  let ?p' = "zlfm p"
  2.6214 +  let ?l = "\<zeta> ?p'"
  2.6215 +  let ?q = "And (Dvd ?l (CX 1 (C 0))) (a\<beta> ?p' ?l)"
  2.6216 +  let ?d = "\<delta> ?q"
  2.6217 +  let ?B = "set (\<beta> ?q)"
  2.6218 +  let ?B'= "remdups (map simpnum (\<beta> ?q))"
  2.6219 +  let ?A = "set (\<alpha> ?q)"
  2.6220 +  let ?A'= "remdups (map simpnum (\<alpha> ?q))"
  2.6221 +  from conjunct1[OF zlfm_I[OF qf, where bs="bs"]] 
  2.6222 +  have pp': "\<forall> i. ?I i ?p' = ?I i p" by auto
  2.6223 +  from conjunct2[OF zlfm_I[OF qf, where bs="bs" and i="i"]]
  2.6224 +  have lp': "iszlfm ?p'" . 
  2.6225 +  from lp' \<zeta>[where p="?p'"] have lp: "?l >0" and dl: "d\<beta> ?p' ?l" by auto
  2.6226 +  from a\<beta>_ex[where p="?p'" and l="?l" and bs="bs", OF lp' dl lp] pp'
  2.6227 +  have pq_ex:"(\<exists> (x::int). ?I x p) = (\<exists> x. ?I x ?q)" by simp 
  2.6228 +  from lp' lp a\<beta>[OF lp' dl lp] have lq:"iszlfm ?q" and uq: "d\<beta> ?q 1"  by auto
  2.6229 +  from \<delta>[OF lq] have dp:"?d >0" and dd: "d\<delta> ?q ?d" by blast+
  2.6230 +  let ?N = "\<lambda> t. Inum (i#bs) t"
  2.6231 +  have "?N ` set ?B' = ((?N o simpnum) ` ?B)" by auto 
  2.6232 +  also have "\<dots> = ?N ` ?B" using simpnum_ci[where bs="i#bs"] by auto
  2.6233 +  finally have BB': "?N ` set ?B' = ?N ` ?B" .
  2.6234 +  have "?N ` set ?A' = ((?N o simpnum) ` ?A)" by auto 
  2.6235 +  also have "\<dots> = ?N ` ?A" using simpnum_ci[where bs="i#bs"] by auto
  2.6236 +  finally have AA': "?N ` set ?A' = ?N ` ?A" .
  2.6237 +  from \<beta>_numbound0[OF lq] have B_nb:"\<forall> b\<in> set ?B'. numbound0 b"
  2.6238 +    by (simp add: simpnum_numbound0)
  2.6239 +  from \<alpha>_l[OF lq] have A_nb: "\<forall> b\<in> set ?A'. numbound0 b"
  2.6240 +    by (simp add: simpnum_numbound0)
  2.6241 +    {assume "length ?B' \<le> length ?A'"
  2.6242 +    hence q:"q=?q" and "B = ?B'" and d:"d = ?d"
  2.6243 +      using qBd by (auto simp add: Let_def unit_def)
  2.6244 +    with BB' B_nb have b: "?N ` (set B) = ?N ` set (\<beta> q)" 
  2.6245 +      and bn: "\<forall>b\<in> set B. numbound0 b" by simp+ 
  2.6246 +  with pq_ex dp uq dd lq q d have ?thes by simp}
  2.6247 +  moreover 
  2.6248 +  {assume "\<not> (length ?B' \<le> length ?A')"
  2.6249 +    hence q:"q=mirror ?q" and "B = ?A'" and d:"d = ?d"
  2.6250 +      using qBd by (auto simp add: Let_def unit_def)
  2.6251 +    with AA' mirror\<alpha>\<beta>[OF lq] A_nb have b:"?N ` (set B) = ?N ` set (\<beta> q)" 
  2.6252 +      and bn: "\<forall>b\<in> set B. numbound0 b" by simp+
  2.6253 +    from mirror_ex[OF lq] pq_ex q 
  2.6254 +    have pqm_eq:"(\<exists> (x::int). ?I x p) = (\<exists> (x::int). ?I x q)" by simp
  2.6255 +    from lq uq q mirror_l[where p="?q"]
  2.6256 +    have lq': "iszlfm q" and uq: "d\<beta> q 1" by auto
  2.6257 +    from \<delta>[OF lq'] mirror_\<delta>[OF lq] q d have dq:"d\<delta> q d " by auto
  2.6258 +    from pqm_eq b bn uq lq' dp dq q dp d have ?thes by simp
  2.6259 +  }
  2.6260 +  ultimately show ?thes by blast
  2.6261 +qed
  2.6262 +    (* Cooper's Algorithm *)
  2.6263  
  2.6264 -"psimpl (And p q) = 
  2.6265 -  (let p'= psimpl p
  2.6266 -  in (case p' of 
  2.6267 -       F \<Rightarrow> F
  2.6268 -      |T \<Rightarrow> psimpl q
  2.6269 -      | _ \<Rightarrow> let q' = psimpl q
  2.6270 -             in (case q' of
  2.6271 -                     F \<Rightarrow> F
  2.6272 -                   | T \<Rightarrow> p'
  2.6273 -                   | _ \<Rightarrow> (And p' q'))))"
  2.6274 -
  2.6275 -"psimpl (Or p q) = 
  2.6276 -  (let p'= psimpl p
  2.6277 -  in (case p' of 
  2.6278 -        T \<Rightarrow> T
  2.6279 -      | F \<Rightarrow> psimpl q
  2.6280 -      | _ \<Rightarrow> let q' = psimpl q
  2.6281 -             in (case q' of
  2.6282 -                     T \<Rightarrow> T
  2.6283 -                   | F \<Rightarrow> p'
  2.6284 -                   | _ \<Rightarrow> (Or p' q'))))"
  2.6285 -
  2.6286 -"psimpl (Imp p q) = 
  2.6287 -  (let p'= psimpl p
  2.6288 -  in (case p' of 
  2.6289 -       F \<Rightarrow> T
  2.6290 -      |T \<Rightarrow> psimpl q
  2.6291 -      | NOT p1 \<Rightarrow> let q' = psimpl q
  2.6292 -             in (case q' of
  2.6293 -                     F \<Rightarrow> p1
  2.6294 -                   | T \<Rightarrow> T
  2.6295 -                   | _ \<Rightarrow> (Or p1 q'))
  2.6296 -      | _ \<Rightarrow> let q' = psimpl q
  2.6297 -             in (case q' of
  2.6298 -                     F \<Rightarrow> NOT p'
  2.6299 -                   | T \<Rightarrow> T
  2.6300 -                   | _ \<Rightarrow> (Imp p' q'))))"
  2.6301 +constdefs cooper :: "fm \<Rightarrow> fm"
  2.6302 +  "cooper p \<equiv> 
  2.6303 +  (let (q,B,d) = unit p; js = iupt (1,d);
  2.6304 +       mq = simpfm (minusinf q);
  2.6305 +       md = evaldjf (\<lambda> j. simpfm (subst0 (C j) mq)) js
  2.6306 +   in if md = T then T else
  2.6307 +    (let qd = evaldjf (\<lambda> (b,j). simpfm (subst0 (Add b (C j)) q)) 
  2.6308 +                               (allpairs Pair B js)
  2.6309 +     in decr (disj md qd)))"
  2.6310 +lemma cooper: assumes qf: "qfree p"
  2.6311 +  shows "((\<exists> x. Ifm bbs (x#bs) p) = (Ifm bbs bs (cooper p))) \<and> qfree (cooper p)" 
  2.6312 +  (is "(?lhs = ?rhs) \<and> _")
  2.6313 +proof-
  2.6314  
  2.6315 -"psimpl (Equ p q) = 
  2.6316 -  (let p'= psimpl p ; q' = psimpl q
  2.6317 -  in (case p' of 
  2.6318 -        T \<Rightarrow> q'
  2.6319 -      | F \<Rightarrow> (case q' of
  2.6320 -                  T \<Rightarrow> F
  2.6321 -                | F \<Rightarrow> T
  2.6322 -                | NOT q1 \<Rightarrow> q1
  2.6323 -                | _ \<Rightarrow> NOT q')
  2.6324 -      | NOT p1 \<Rightarrow>  (case q' of
  2.6325 -                  T \<Rightarrow> p'
  2.6326 -                | F \<Rightarrow> p1
  2.6327 -                | NOT q1 \<Rightarrow> (Equ p1 q1)
  2.6328 -                | _ \<Rightarrow> (Equ p' q'))
  2.6329 -      | _ \<Rightarrow> (case q' of
  2.6330 -                  T \<Rightarrow> p'
  2.6331 -                | F \<Rightarrow> NOT p'
  2.6332 -                | _ \<Rightarrow> (Equ p' q'))))"
  2.6333 -
  2.6334 -"psimpl (NOT p) = 
  2.6335 -  (let p' = psimpl p
  2.6336 -  in ( case p' of 
  2.6337 -       F \<Rightarrow> T
  2.6338 -     | T \<Rightarrow> F
  2.6339 -     | NOT p1 \<Rightarrow> p1 
  2.6340 -     | _ \<Rightarrow> (NOT p')))"
  2.6341 -"psimpl p = p"
  2.6342 -
  2.6343 -(* psimpl preserves semantics *)
  2.6344 -lemma psimpl_corr: "qinterp ats p = qinterp ats (psimpl p)"
  2.6345 -proof(induct p rule: psimpl.induct)
  2.6346 -  case (1 l r)
  2.6347 -  have "(\<exists> lx. linearize (Sub l r) = Some lx) \<or> (linearize (Sub l r) = None)" by auto
  2.6348 -  moreover
  2.6349 -  {
  2.6350 -    assume lin: "\<exists> lx. linearize (Sub l r) = Some lx"
  2.6351 -    from lin obtain "lx" where lx: "linearize (Sub l r) = Some lx" by blast
  2.6352 -    from lx have "I_intterm ats (Sub l r) = I_intterm ats lx"
  2.6353 -      by (rule linearize_corr[where t="Sub l r" and t'= "lx"])
  2.6354 -    then have feq: "qinterp ats (Le l r) = qinterp ats (Le lx (Cst 0))" by (simp , arith)
  2.6355 -    from lx have lxlin: "islinintterm lx" by (rule linearize_linear)
  2.6356 -    from lxlin feq have ?case 
  2.6357 -      proof-
  2.6358 -	have "(\<exists> i. lx = Cst i) \<or> (\<not> (\<exists> i. lx = Cst i))" by blast
  2.6359 -	moreover
  2.6360 -	{
  2.6361 -	  assume lxcst: "\<exists> i. lx = Cst i"
  2.6362 -	  from lxcst obtain "i" where lxi: "lx = Cst i" by blast
  2.6363 -	  with feq have "qinterp ats (Le l r) = (i \<le> 0)" by simp
  2.6364 -	  then have ?case using prems by simp
  2.6365 -	}
  2.6366 -	moreover 
  2.6367 -	{
  2.6368 -	  assume "(\<not> (\<exists> i. lx = Cst i))"
  2.6369 -	  then have "(case lx of 
  2.6370 -	    Cst i \<Rightarrow> (if i \<le> 0 then T else F)
  2.6371 -	    | _ \<Rightarrow> (Le lx (Cst 0))) = (Le lx (Cst 0))" 
  2.6372 -	    by (case_tac "lx::intterm", auto)
  2.6373 -	  with prems lxlin feq have ?case by auto
  2.6374 -	}
  2.6375 -	ultimately show ?thesis  by blast
  2.6376 -      qed
  2.6377 -  }
  2.6378 -  moreover
  2.6379 -  {
  2.6380 -    assume "linearize (Sub l r) = None"
  2.6381 -    then have ?case using prems by simp
  2.6382 -  }
  2.6383 -  ultimately show ?case by blast
  2.6384 -  
  2.6385 -next 
  2.6386 -  case (2 l r)
  2.6387 -  have "(\<exists> lx. linearize (Sub l r) = Some lx) \<or> (linearize (Sub l r) = None)" by auto
  2.6388 +  let ?I = "\<lambda> x p. Ifm bbs (x#bs) p"
  2.6389 +  let ?q = "fst (unit p)"
  2.6390 +  let ?B = "fst (snd(unit p))"
  2.6391 +  let ?d = "snd (snd (unit p))"
  2.6392 +  let ?js = "iupt (1,?d)"
  2.6393 +  let ?mq = "minusinf ?q"
  2.6394 +  let ?smq = "simpfm ?mq"
  2.6395 +  let ?md = "evaldjf (\<lambda> j. simpfm (subst0 (C j) ?smq)) ?js"
  2.6396 +  let ?N = "\<lambda> t. Inum (i#bs) t"
  2.6397 +  let ?qd = "evaldjf (\<lambda> (b,j). simpfm (subst0 (Add b (C j)) ?q)) (allpairs Pair ?B ?js)"
  2.6398 +  have qbf:"unit p = (?q,?B,?d)" by simp
  2.6399 +  from unit[OF qf qbf] have pq_ex: "(\<exists>(x::int). ?I x p) = (\<exists> (x::int). ?I x ?q)" and 
  2.6400 +    B:"?N ` set ?B = ?N ` set (\<beta> ?q)" and 
  2.6401 +    uq:"d\<beta> ?q 1" and dd: "d\<delta> ?q ?d" and dp: "?d > 0" and 
  2.6402 +    lq: "iszlfm ?q" and 
  2.6403 +    Bn: "\<forall> b\<in> set ?B. numbound0 b" by auto
  2.6404 +  from zlin_qfree[OF lq] have qfq: "qfree ?q" .
  2.6405 +  from simpfm_qf[OF minusinf_qfree[OF qfq]] have qfmq: "qfree ?smq".
  2.6406 +  have jsnb: "\<forall> j \<in> set ?js. numbound0 (C j)" by simp
  2.6407 +  hence "\<forall> j\<in> set ?js. bound0 (subst0 (C j) ?smq)" 
  2.6408 +    by (auto simp only: subst0_bound0[OF qfmq])
  2.6409 +  hence th: "\<forall> j\<in> set ?js. bound0 (simpfm (subst0 (C j) ?smq))"
  2.6410 +    by (auto simp add: simpfm_bound0)
  2.6411 +  from evaldjf_bound0[OF th] have mdb: "bound0 ?md" by simp 
  2.6412 +  from Bn jsnb have "\<forall> (b,j) \<in> set (allpairs Pair ?B ?js). numbound0 (Add b (C j))"
  2.6413 +    by (simp add: allpairs_set)
  2.6414 +  hence "\<forall> (b,j) \<in> set (allpairs Pair ?B ?js). bound0 (subst0 (Add b (C j)) ?q)"
  2.6415 +    using subst0_bound0[OF qfq] by blast
  2.6416 +  hence "\<forall> (b,j) \<in> set (allpairs Pair ?B ?js). bound0 (simpfm (subst0 (Add b (C j)) ?q))"
  2.6417 +    using simpfm_bound0  by blast
  2.6418 +  hence th': "\<forall> x \<in> set (allpairs Pair ?B ?js). bound0 ((\<lambda> (b,j). simpfm (subst0 (Add b (C j)) ?q)) x)"
  2.6419 +    by auto 
  2.6420 +  from evaldjf_bound0 [OF th'] have qdb: "bound0 ?qd" by simp
  2.6421 +  from mdb qdb 
  2.6422 +  have mdqdb: "bound0 (disj ?md ?qd)" by (simp only: disj_def, cases "?md=T \<or> ?qd=T", simp_all)
  2.6423 +  from trans [OF pq_ex cp_thm'[OF lq uq dd dp,where i="i"]] B
  2.6424 +  have "?lhs = (\<exists> j\<in> {1.. ?d}. ?I j ?mq \<or> (\<exists> b\<in> ?N ` set ?B. Ifm bbs ((b+ j)#bs) ?q))" by auto
  2.6425 +  also have "\<dots> = (\<exists> j\<in> {1.. ?d}. ?I j ?mq \<or> (\<exists> b\<in> set ?B. Ifm bbs ((?N b+ j)#bs) ?q))" by simp
  2.6426 +  also have "\<dots> = ((\<exists> j\<in> {1.. ?d}. ?I j ?mq ) \<or> (\<exists> j\<in> {1.. ?d}. \<exists> b\<in> set ?B. Ifm bbs ((?N (Add b (C j)))#bs) ?q))" by (simp only: Inum.simps) blast
  2.6427 +  also have "\<dots> = ((\<exists> j\<in> {1.. ?d}. ?I j ?smq ) \<or> (\<exists> j\<in> {1.. ?d}. \<exists> b\<in> set ?B. Ifm bbs ((?N (Add b (C j)))#bs) ?q))" by (simp add: simpfm) 
  2.6428 +  also have "\<dots> = ((\<exists> j\<in> set ?js. (\<lambda> j. ?I i (simpfm (subst0 (C j) ?smq))) j) \<or> (\<exists> j\<in> set ?js. \<exists> b\<in> set ?B. Ifm bbs ((?N (Add b (C j)))#bs) ?q))"
  2.6429 +    by (simp only: simpfm subst0_I[OF qfmq] iupt_set) auto
  2.6430 +  also have "\<dots> = (?I i (evaldjf (\<lambda> j. simpfm (subst0 (C j) ?smq)) ?js) \<or> (\<exists> j\<in> set ?js. \<exists> b\<in> set ?B. ?I i (subst0 (Add b (C j)) ?q)))" 
  2.6431 +   by (simp only: evaldjf_ex subst0_I[OF qfq])
  2.6432 + also have "\<dots>= (?I i ?md \<or> (\<exists> (b,j) \<in> set (allpairs Pair ?B ?js). (\<lambda> (b,j). ?I i (simpfm (subst0 (Add b (C j)) ?q))) (b,j)))"
  2.6433 +   by (simp only: simpfm allpairs_set) blast
  2.6434 + also have "\<dots> = (?I i ?md \<or> (?I i (evaldjf (\<lambda> (b,j). simpfm (subst0 (Add b (C j)) ?q)) (allpairs Pair ?B ?js))))"
  2.6435 +   by (simp only: evaldjf_ex[where bs="i#bs" and f="\<lambda> (b,j). simpfm (subst0 (Add b (C j)) ?q)" and ps="allpairs Pair ?B ?js"]) (auto simp add: split_def) 
  2.6436 + finally have mdqd: "?lhs = (?I i ?md \<or> ?I i ?qd)" by simp  
  2.6437 +  also have "\<dots> = (?I i (disj ?md ?qd))" by (simp add: disj)
  2.6438 +  also have "\<dots> = (Ifm bbs bs (decr (disj ?md ?qd)))" by (simp only: decr [OF mdqdb]) 
  2.6439 +  finally have mdqd2: "?lhs = (Ifm bbs bs (decr (disj ?md ?qd)))" . 
  2.6440 +  {assume mdT: "?md = T"
  2.6441 +    hence cT:"cooper p = T" 
  2.6442 +      by (simp only: cooper_def unit_def split_def Let_def if_True) simp
  2.6443 +    from mdT have lhs:"?lhs" using mdqd by simp 
  2.6444 +    from mdT have "?rhs" by (simp add: cooper_def unit_def split_def)
  2.6445 +    with lhs cT have ?thesis by simp }
  2.6446    moreover
  2.6447 -  {
  2.6448 -    assume lin: "\<exists> lx. linearize (Sub l r) = Some lx"
  2.6449 -    from lin obtain "lx" where lx: "linearize (Sub l r) = Some lx" by blast
  2.6450 -    from lx have "I_intterm ats (Sub l r) = I_intterm ats lx"
  2.6451 -      by (rule linearize_corr[where t="Sub l r" and t'= "lx"])
  2.6452 -    then have feq: "qinterp ats (Eq l r) = qinterp ats (Eq lx (Cst 0))" by (simp , arith)
  2.6453 -    from lx have lxlin: "islinintterm lx" by (rule linearize_linear)
  2.6454 -    from lxlin feq have ?case 
  2.6455 -      proof-
  2.6456 -	have "(\<exists> i. lx = Cst i) \<or> (\<not> (\<exists> i. lx = Cst i))" by blast
  2.6457 -	moreover
  2.6458 -	{
  2.6459 -	  assume lxcst: "\<exists> i. lx = Cst i"
  2.6460 -	  from lxcst obtain "i" where lxi: "lx = Cst i" by blast
  2.6461 -	  with feq have "qinterp ats (Eq l r) = (i = 0)" by simp
  2.6462 -	  then have ?case using prems by simp
  2.6463 -	}
  2.6464 -	moreover 
  2.6465 -	{
  2.6466 -	  assume "(\<not> (\<exists> i. lx = Cst i))"
  2.6467 -	  then have "(case lx of 
  2.6468 -	    Cst i \<Rightarrow> (if i = 0 then T else F)
  2.6469 -	    | _ \<Rightarrow> (Eq lx (Cst 0))) = (Eq lx (Cst 0))" 
  2.6470 -	    by (case_tac "lx::intterm", auto)
  2.6471 -	  with prems lxlin feq have ?case by auto
  2.6472 -	}
  2.6473 -	ultimately show ?thesis  by blast
  2.6474 -      qed
  2.6475 -  }
  2.6476 -  moreover
  2.6477 -  {
  2.6478 -    assume "linearize (Sub l r) = None"
  2.6479 -    then have ?case using prems by simp
  2.6480 -  }
  2.6481 -  ultimately show ?case by blast
  2.6482 -  
  2.6483 -next 
  2.6484 -    
  2.6485 -  case (3 d t)  
  2.6486 -  have "(\<exists> lt. linearize t = Some lt) \<or> (linearize t = None)" by auto
  2.6487 -  moreover
  2.6488 -  {
  2.6489 -    assume lin: "\<exists> lt. linearize t  = Some lt"
  2.6490 -    from lin obtain "lt" where lt: "linearize t = Some lt" by blast
  2.6491 -    from lt have "I_intterm ats t = I_intterm ats lt"
  2.6492 -      by (rule linearize_corr[where t="t" and t'= "lt"])
  2.6493 -    then have feq: "qinterp ats (Divides (Cst d) t) = qinterp ats (Divides (Cst d) lt)" by (simp)
  2.6494 -    from lt have ltlin: "islinintterm lt" by (rule linearize_linear)
  2.6495 -    from ltlin feq have ?case using prems  apply simp by (case_tac "lt::intterm", simp_all)
  2.6496 -  }
  2.6497 -  moreover
  2.6498 -  {
  2.6499 -    assume "linearize t = None"
  2.6500 -    then have ?case using prems by simp
  2.6501 -  }
  2.6502 -  ultimately show ?case by blast
  2.6503 -  
  2.6504 -next 
  2.6505 -  case (4 f g)
  2.6506 -
  2.6507 -    let ?sf = "psimpl f"
  2.6508 -  let ?sg = "psimpl g"
  2.6509 -  show ?case using prems 
  2.6510 -    by (cases ?sf, simp_all add: Let_def) (cases ?sg, simp_all)+
  2.6511 -next
  2.6512 -  case (5 f g)
  2.6513 -      let ?sf = "psimpl f"
  2.6514 -  let ?sg = "psimpl g"
  2.6515 -  show ?case using prems
  2.6516 -    apply (cases ?sf, simp_all add: Let_def) 
  2.6517 -    apply (cases ?sg, simp_all)
  2.6518 -    apply (cases ?sg, simp_all)
  2.6519 -    apply (cases ?sg, simp_all)
  2.6520 -    apply (cases ?sg, simp_all)
  2.6521 -    apply (cases ?sg, simp_all)
  2.6522 -    apply (cases ?sg, simp_all)
  2.6523 -    apply (cases ?sg, simp_all)
  2.6524 -    apply blast
  2.6525 -    apply (cases ?sg, simp_all)
  2.6526 -    apply (cases ?sg, simp_all)
  2.6527 -     apply (cases ?sg, simp_all)
  2.6528 -   apply blast
  2.6529 -    apply (cases ?sg, simp_all)
  2.6530 -    by (cases ?sg, simp_all) (cases ?sg, simp_all)
  2.6531 -next
  2.6532 -  case (6 f g)
  2.6533 -  let ?sf = "psimpl f"
  2.6534 -  let ?sg = "psimpl g"
  2.6535 -  show ?case using prems 
  2.6536 -    apply(simp add: Let_def)
  2.6537 -    apply(cases ?sf,simp_all)
  2.6538 -    apply (simp_all add: Let_def)
  2.6539 -    apply(cases ?sg, simp_all)
  2.6540 -    apply(cases ?sg, simp_all)
  2.6541 -    apply(cases ?sg, simp_all)
  2.6542 -    apply(cases ?sg, simp_all)
  2.6543 -    apply(cases ?sg, simp_all)
  2.6544 -    apply(cases ?sg, simp_all)
  2.6545 -    apply(cases ?sg, simp_all)
  2.6546 -    apply blast
  2.6547 -    apply blast
  2.6548 -    apply blast
  2.6549 -    apply blast
  2.6550 -    apply blast
  2.6551 -    apply blast
  2.6552 -    apply blast
  2.6553 -    apply blast
  2.6554 -    apply blast
  2.6555 -    apply blast
  2.6556 -    apply blast
  2.6557 -    apply blast
  2.6558 -    apply blast
  2.6559 -    apply(cases ?sg, simp_all)
  2.6560 -    apply(cases ?sg, simp_all)
  2.6561 -    apply(cases ?sg, simp_all)
  2.6562 -    apply(cases ?sg, simp_all)
  2.6563 -    apply(cases ?sg, simp_all)
  2.6564 -    apply(cases ?sg, simp_all)
  2.6565 -    done
  2.6566 -next
  2.6567 -  case (7 f g)
  2.6568 -  let ?sf = "psimpl f"
  2.6569 -  let ?sg = "psimpl g"
  2.6570 -  show ?case 
  2.6571 -    using prems
  2.6572 -    by (cases ?sf, simp_all add: Let_def) (cases ?sg, simp_all)+
  2.6573 -next
  2.6574 -  case (8 f) show ?case 
  2.6575 -    using prems
  2.6576 -    apply (simp add: Let_def)
  2.6577 -    by (case_tac "psimpl f", simp_all)
  2.6578 -qed simp_all
  2.6579 -
  2.6580 -(* psimpl preserves independence on Var 0*)
  2.6581 -lemma psimpl_novar0:
  2.6582 -  assumes nov0p: "novar0 p"
  2.6583 -  shows "novar0 (psimpl p)"
  2.6584 -  using nov0p
  2.6585 -proof (induct p rule: psimpl.induct)
  2.6586 -  case (1 l r)
  2.6587 -  let ?ls = "linearize (Sub l r)"
  2.6588 -  have "?ls = None \<or> (\<exists> x. ?ls = Some x)" by auto
  2.6589 -  moreover
  2.6590 -  {
  2.6591 -    assume "?ls = None" then have ?case using prems by simp
  2.6592 -  }
  2.6593 -  moreover {
  2.6594 -    assume "\<exists> x. ?ls = Some x"
  2.6595 -    then obtain "x" where ls_d: "?ls = Some x" by blast
  2.6596 -    from prems have "novar0I l" by simp
  2.6597 -    moreover from prems have "novar0I r" by simp
  2.6598 -    ultimately have nv0s: "novar0I (Sub l r)" by simp
  2.6599 -    from prems have "novar0I x" 
  2.6600 -      by (simp add: linearize_novar0[OF nv0s, where t'="x"])
  2.6601 -    then have ?case
  2.6602 -      using prems
  2.6603 -      by (cases "x") auto
  2.6604 -  }
  2.6605 -  ultimately show ?case by blast
  2.6606 -next
  2.6607 -  case (2 l r)
  2.6608 -  let ?ls = "linearize (Sub l r)"
  2.6609 -  have "?ls = None \<or> (\<exists> x. ?ls = Some x)" by auto
  2.6610 -  moreover
  2.6611 -  {
  2.6612 -    assume "?ls = None" then have ?case using prems by simp
  2.6613 -  }
  2.6614 -  moreover {
  2.6615 -    assume "\<exists> x. ?ls = Some x"
  2.6616 -    then obtain "x" where ls_d: "?ls = Some x" by blast
  2.6617 -    from prems have "novar0I l" by simp
  2.6618 -    moreover from prems have "novar0I r" by simp
  2.6619 -    ultimately have nv0s: "novar0I (Sub l r)" by simp
  2.6620 -    from prems have "novar0I x" 
  2.6621 -      by (simp add: linearize_novar0[OF nv0s, where t'="x"])
  2.6622 -    then have ?case using prems by (cases "x") auto
  2.6623 -  }
  2.6624 -  ultimately show ?case by blast
  2.6625 -next
  2.6626 -  case (3 d t)
  2.6627 -  let ?lt = "linearize t"
  2.6628 -  have "?lt = None \<or> (\<exists> x. ?lt = Some x)"  by auto
  2.6629 -  moreover 
  2.6630 -  { assume "?lt = None" then have ?case using prems by simp }
  2.6631 -  moreover {
  2.6632 -    assume "\<exists>x. ?lt = Some x"
  2.6633 -    then obtain "x" where x_d: "?lt = Some x" by blast
  2.6634 -    from prems have nv0t: "novar0I t" by simp
  2.6635 -    with x_d have "novar0I x" 
  2.6636 -      by (simp add: linearize_novar0[OF nv0t])
  2.6637 -    with prems have ?case 
  2.6638 -      by (cases "x") simp_all
  2.6639 -  }
  2.6640 -  ultimately show ?case by blast
  2.6641 -next
  2.6642 -  case (4 f g)
  2.6643 -  let ?sf = "psimpl f"
  2.6644 -  let ?sg = "psimpl g"
  2.6645 -  show ?case using prems 
  2.6646 -    by (cases ?sf, simp_all add: Let_def) (cases ?sg,simp_all)+
  2.6647 -next
  2.6648 -  case (5 f g)
  2.6649 -  let ?sf = "psimpl f"
  2.6650 -  let ?sg = "psimpl g"
  2.6651 -  show ?case using prems
  2.6652 -    by (cases ?sf, simp_all add: Let_def) (cases ?sg,simp_all)+
  2.6653 -next
  2.6654 -  case (6 f g)
  2.6655 -  let ?sf = "psimpl f"
  2.6656 -  let ?sg = "psimpl g"
  2.6657 -  show ?case using prems
  2.6658 -    by (cases ?sf, simp_all add: Let_def) (cases ?sg,simp_all)+
  2.6659 -next
  2.6660 -  case (7 f g)
  2.6661 -  let ?sf = "psimpl f"
  2.6662 -  let ?sg = "psimpl g"
  2.6663 -  show ?case using prems
  2.6664 -    by (cases ?sf, simp_all add: Let_def) (cases ?sg,simp_all)+
  2.6665 -next
  2.6666 -  case (8 f)
  2.6667 -  let ?sf = "psimpl f"
  2.6668 -  from prems have nv0sf:"novar0 ?sf" by simp
  2.6669 -  show ?case using prems nv0sf by (cases ?sf, auto simp add: Let_def)
  2.6670 -qed simp_all
  2.6671 -
  2.6672 -(* implements a disj of p applied to all elements of the list*)
  2.6673 -consts explode_disj :: "(intterm list \<times> QF) \<Rightarrow> QF"
  2.6674 -recdef explode_disj "measure (\<lambda>(is,p). length is)"
  2.6675 -"explode_disj ([],p) = F"
  2.6676 -"explode_disj (i#is,p) = 
  2.6677 -  (let pi = psimpl (subst_p i p)
  2.6678 -   in ( case pi of
  2.6679 -        T \<Rightarrow> T 
  2.6680 -       | F \<Rightarrow> explode_disj (is,p)
  2.6681 -       | _ \<Rightarrow> (let r = explode_disj (is,p)
  2.6682 -               in (case r of
  2.6683 -                      T \<Rightarrow> T
  2.6684 -                    | F \<Rightarrow> pi
  2.6685 -                    | _ \<Rightarrow> Or pi r))))"
  2.6686 -
  2.6687 -(* correctness theorem for one iteration of explode_disj *)
  2.6688 -lemma explode_disj_disj: 
  2.6689 -  assumes qfp: "isqfree p"
  2.6690 -  shows "(qinterp (x#xs) (explode_disj(i#is,p))) = 
  2.6691 -  (qinterp (x#xs) (subst_p i p) \<or> (qinterp (x#xs) (explode_disj(is,p))))"
  2.6692 -  using qfp
  2.6693 -proof-
  2.6694 -  let ?pi = "psimpl (subst_p i p)"
  2.6695 -  have pi: "qinterp (x#xs) ?pi = qinterp (x#xs) (subst_p i p)"
  2.6696 -    by (simp add: psimpl_corr[where p="(subst_p i p)"])
  2.6697 -  let ?dp = "explode_disj(is,p)"
  2.6698 -  show ?thesis using pi
  2.6699 -  proof (cases)
  2.6700 -    assume "?pi= T \<or> ?pi = F"
  2.6701 -    then show ?thesis using pi by (case_tac "?pi::QF", auto)
  2.6702 -    
  2.6703 -  next
  2.6704 -    assume notTF: "\<not> (?pi = T \<or> ?pi = F)" 
  2.6705 -    let ?dp = "explode_disj(is,p)"
  2.6706 -    have dp_cases: "explode_disj(i#is,p) = 
  2.6707 -      (case (explode_disj(is,p)) of
  2.6708 -      T \<Rightarrow> T
  2.6709 -      | F \<Rightarrow> psimpl (subst_p i p)
  2.6710 -      | _ \<Rightarrow> Or (psimpl (subst_p i p)) (explode_disj(is,p)))" using notTF
  2.6711 -      by (cases "?pi")
  2.6712 -    (simp_all add: Let_def cong del: QF.weak_case_cong)
  2.6713 -    show ?thesis using pi dp_cases notTF
  2.6714 -    proof(cases)
  2.6715 -      assume "?dp = T \<or> ?dp = F"
  2.6716 -      then show ?thesis 
  2.6717 -	using pi dp_cases
  2.6718 -	by (cases "?dp") auto
  2.6719 -    next
  2.6720 -      assume "\<not> (?dp = T \<or> ?dp = F)"
  2.6721 -      then show ?thesis using pi dp_cases notTF
  2.6722 -	by (cases ?dp) auto 
  2.6723 -    qed
  2.6724 -  qed
  2.6725 -qed
  2.6726 -
  2.6727 -(* correctness theorem for explode_disj *)
  2.6728 -lemma explode_disj_corr: 
  2.6729 -  assumes qfp: "isqfree p"
  2.6730 -  shows "(\<exists> x \<in> set xs. qinterp (a#ats) (subst_p x p)) = 
  2.6731 -  (qinterp (a#ats) (explode_disj(xs,p)))" (is "(\<exists> x \<in> set xs. ?P x) = (?DP a xs )")
  2.6732 -  using qfp
  2.6733 -  proof (induct xs)
  2.6734 -    case Nil show ?case by simp
  2.6735 -  next 
  2.6736 -    case (Cons y ys)
  2.6737 -    have "(\<exists> x \<in> set (y#ys). ?P x) = (?P y \<or> (\<exists> x\<in> set ys. ?P x))"
  2.6738 -      by auto
  2.6739 -    also have "\<dots> = (?P y \<or> ?DP a ys)" using "Cons.hyps" qfp by auto 
  2.6740 -    also have "\<dots> = ?DP a (y#ys)" using explode_disj_disj[OF qfp] by auto
  2.6741 -    finally show ?case by simp
  2.6742 -qed
  2.6743 -
  2.6744 -(* explode_disj preserves independence on Var 0*)
  2.6745 -lemma explode_disj_novar0:
  2.6746 -  assumes nov0xs: "\<forall>x \<in> set xs. novar0I x"
  2.6747 -  and qfp: "isqfree p"
  2.6748 -  shows "novar0 (explode_disj (xs,p))"
  2.6749 -  using nov0xs qfp
  2.6750 -proof (induct xs, auto simp add: Let_def)
  2.6751 -  case (goal1 a as)
  2.6752 -  let ?q = "subst_p a p"
  2.6753 -  let ?qs = "psimpl ?q"
  2.6754 -  have "?qs = T \<or> ?qs = F \<or> (?qs \<noteq> T \<or> ?qs \<noteq> F)" by simp
  2.6755 -  moreover
  2.6756 -  { assume "?qs = T"  then have ?case  by simp }
  2.6757 -  moreover
  2.6758 -  { assume "?qs = F"  then have ?case by simp }
  2.6759 -  moreover
  2.6760 -  {
  2.6761 -    assume qsnTF: "?qs \<noteq> T \<and> ?qs \<noteq> F"
  2.6762 -    let ?r = "explode_disj (as,p)"
  2.6763 -    have nov0qs: "novar0 ?qs"
  2.6764 -      using prems
  2.6765 -      by (auto simp add: psimpl_novar0 subst_p_novar0)
  2.6766 -    have "?r = T \<or> ?r = F \<or> (?r \<noteq> T \<or> ?r \<noteq> F)" by simp
  2.6767 -    moreover
  2.6768 -    { assume "?r = T" then have ?case by (cases ?qs) auto  }
  2.6769 -    moreover
  2.6770 -    { assume "?r = F"  then have ?case  using nov0qs by (cases ?qs, auto)  }
  2.6771 -    moreover
  2.6772 -    { assume "?r \<noteq> T \<and> ?r \<noteq> F"  then have ?case using nov0qs prems qsnTF
  2.6773 -	by (cases ?qs, auto simp add: Let_def) (cases ?r,auto)+
  2.6774 -    }
  2.6775 -    ultimately have ?case by blast
  2.6776 -  }
  2.6777 -  ultimately show ?case by blast
  2.6778 -qed  
  2.6779 -  
  2.6780 -(* Some simple lemmas used for technical reasons *)
  2.6781 -lemma eval_Or_cases: 
  2.6782 -  "qinterp (a#ats) (case f of 
  2.6783 -       T \<Rightarrow> T
  2.6784 -       | F \<Rightarrow> g
  2.6785 -       | _ \<Rightarrow> (case g of 
  2.6786 -                     T \<Rightarrow> T
  2.6787 -                   | F \<Rightarrow> f
  2.6788 -                   | _ \<Rightarrow> Or f g)) = (qinterp (a#ats) f \<or> qinterp (a#ats) g)"
  2.6789 -proof-
  2.6790 -  let ?result = "
  2.6791 -    (case f of 
  2.6792 -    T \<Rightarrow> T
  2.6793 -    | F \<Rightarrow> g
  2.6794 -    | _ \<Rightarrow> (case g of 
  2.6795 -    T \<Rightarrow> T
  2.6796 -    | F \<Rightarrow> f
  2.6797 -    | _ \<Rightarrow> Or f g))"
  2.6798 -  have "f = T \<or> f = F \<or> (f \<noteq> T \<and> f\<noteq> F)" by auto
  2.6799 -  moreover 
  2.6800 -  {
  2.6801 -    assume fT: "f = T"
  2.6802 -    then have ?thesis by auto
  2.6803 -  }
  2.6804 -  moreover 
  2.6805 -  {
  2.6806 -    assume "f=F"
  2.6807 -    then have ?thesis by auto
  2.6808 -  }
  2.6809 -  moreover 
  2.6810 -  {
  2.6811 -    assume fnT: "f\<noteq>T"
  2.6812 -      and fnF: "f\<noteq>F"
  2.6813 -    have "g = T \<or> g = F \<or> (g \<noteq> T \<and> g\<noteq> F)" by auto
  2.6814 -    moreover 
  2.6815 -    {
  2.6816 -      assume "g=T"
  2.6817 -      then have ?thesis using fnT fnF by (cases f, auto)
  2.6818 -    }
  2.6819 -    moreover 
  2.6820 -    {
  2.6821 -      assume "g=F"
  2.6822 -      then have ?thesis using fnT fnF by (cases f, auto)
  2.6823 -    }
  2.6824 -    moreover 
  2.6825 -    {
  2.6826 -      assume gnT: "g\<noteq>T"
  2.6827 -	and gnF: "g\<noteq>F"
  2.6828 -      then have "?result = (case g of 
  2.6829 -        T \<Rightarrow> T
  2.6830 -        | F \<Rightarrow> f
  2.6831 -        | _ \<Rightarrow> Or f g)"
  2.6832 -	using fnT fnF
  2.6833 -	by (cases f, auto)
  2.6834 -      also have "\<dots> = Or f g"
  2.6835 -	using gnT gnF
  2.6836 -	by (cases g, auto)
  2.6837 -      finally have "?result = Or f g" by simp
  2.6838 -      then
  2.6839 -      have  ?thesis by simp
  2.6840 -    }
  2.6841 -    ultimately have ?thesis by blast
  2.6842 -	   
  2.6843 -  }
  2.6844 -  
  2.6845 +  {assume mdT: "?md \<noteq> T" hence "cooper p = decr (disj ?md ?qd)" 
  2.6846 +      by (simp only: cooper_def unit_def split_def Let_def if_False) 
  2.6847 +    with mdqd2 decr_qf[OF mdqdb] have ?thesis by simp }
  2.6848    ultimately show ?thesis by blast
  2.6849  qed
  2.6850  
  2.6851 -lemma or_case_novar0:
  2.6852 -  assumes fnTF: "f \<noteq> T \<and> f \<noteq> F"
  2.6853 -  and gnTF: "g \<noteq> T \<and> g \<noteq> F"
  2.6854 -  and f0: "novar0 f"
  2.6855 -  and g0: "novar0 g"
  2.6856 -  shows "novar0 
  2.6857 -     (case f of T \<Rightarrow> T | F \<Rightarrow> g
  2.6858 -     | _ \<Rightarrow> (case g of T \<Rightarrow> T | F \<Rightarrow> f | _ \<Rightarrow> Or f g))"
  2.6859 -using fnTF gnTF f0 g0
  2.6860 -by (cases f, auto) (cases g, auto)+
  2.6861 +constdefs pa:: "fm \<Rightarrow> fm"
  2.6862 +  "pa \<equiv> (\<lambda> p. qelim (prep p) cooper)"
  2.6863  
  2.6864 -
  2.6865 -(* An implementation of sets trough lists *)
  2.6866 -definition
  2.6867 -  list_insert :: "'a \<Rightarrow> 'a list \<Rightarrow> 'a list" where
  2.6868 -  "list_insert x xs = (if x mem xs then xs else x#xs)"
  2.6869 -
  2.6870 -lemma list_insert_set: "set (list_insert x xs) = set (x#xs)"
  2.6871 -by(induct xs) (auto simp add: list_insert_def)
  2.6872 -
  2.6873 -consts list_union :: "('a list \<times> 'a list) \<Rightarrow> 'a list"
  2.6874 +theorem mirqe: "(Ifm bbs bs (pa p) = Ifm bbs bs p) \<and> qfree (pa p)"
  2.6875 +  using qelim_ci cooper prep by (auto simp add: pa_def)
  2.6876  
  2.6877 -recdef list_union "measure (\<lambda>(xs,ys). length xs)"
  2.6878 -"list_union ([], ys) = ys"
  2.6879 -"list_union (xs, []) = xs"
  2.6880 -"list_union (x#xs,ys) = list_insert x (list_union (xs,ys))"
  2.6881 -
  2.6882 -lemma list_union_set: "set (list_union(xs,ys)) = set (xs@ys)"
  2.6883 -  by(induct xs ys rule: list_union.induct, auto simp add:list_insert_set)
  2.6884 -
  2.6885 -
  2.6886 -consts list_set ::"'a list \<Rightarrow> 'a list"
  2.6887 -primrec 
  2.6888 -  "list_set [] = []"
  2.6889 -  "list_set (x#xs) = list_insert x (list_set xs)"
  2.6890 -
  2.6891 -lemma list_set_set: "set xs = set (list_set xs)"
  2.6892 -by (induct xs) (auto simp add: list_insert_set)
  2.6893 -
  2.6894 -consts iupto :: "int \<times> int \<Rightarrow> int list"
  2.6895 -recdef iupto "measure (\<lambda> (i,j). nat (j - i +1))"
  2.6896 -"iupto(i,j) = (if j<i then [] else (i#(iupto(i+1,j))))"
  2.6897 -
  2.6898 -(* correctness theorem for iupto *)
  2.6899 -lemma iupto_set: "set (iupto(i,j)) = {i .. j}"
  2.6900 -proof(induct rule: iupto.induct)
  2.6901 -  case (1 a b)
  2.6902 -  show ?case
  2.6903 -    using prems by (simp add: simp_from_to)
  2.6904 -qed
  2.6905 +declare zdvd_iff_zmod_eq_0 [code] 
  2.6906 +code_module GeneratedCooper
  2.6907 +file "generated_cooper.ML"
  2.6908 +contains pa = "pa"
  2.6909 +test = "%x . pa (E(A(Imp (Ge (Sub (Bound 0) (Bound 1))) (E(E(Eq(Sub(Add(Mul 3 (Bound 1)) (Mul 5 (Bound 0))) (Bound 2))))))))"
  2.6910  
  2.6911 -consts all_sums :: "int \<times> intterm list \<Rightarrow> intterm list"
  2.6912 -recdef all_sums "measure (\<lambda>(i,is). length is)"
  2.6913 -"all_sums (j,[]) = []"
  2.6914 -"all_sums (j,i#is) = (map (\<lambda>x. lin_add (i,(Cst x))) (iupto(1,j))@(all_sums (j,is)))"
  2.6915 -(* all_sums preserves independence on Var 0*)
  2.6916 -lemma all_sums_novar0:
  2.6917 -  assumes nov0xs: "\<forall> x\<in> set xs. novar0I x"
  2.6918 -  and linxs: "\<forall> x\<in> set xs. islinintterm x "
  2.6919 -  shows "\<forall> x\<in> set (all_sums (d,xs)). novar0I x"
  2.6920 -  using nov0xs linxs
  2.6921 -proof(induct d xs rule: all_sums.induct)
  2.6922 -  case 1 show ?case by simp
  2.6923 -next 
  2.6924 -  case (2 j a as)
  2.6925 -  have lina: "islinintterm a" using "2.prems" by auto
  2.6926 -  have nov0a: "novar0I a" using "2.prems" by auto
  2.6927 -  let ?ys = "map (\<lambda>x. lin_add (a,(Cst x))) (iupto(1,j))"
  2.6928 -  have nov0ys: "\<forall> y\<in> set ?ys. novar0I y"
  2.6929 -  proof-
  2.6930 -    have linx: "\<forall> x \<in> set (iupto(1,j)). islinintterm (Cst x)" by simp
  2.6931 -    have nov0x: "\<forall> x \<in> set (iupto(1,j)). novar0I (Cst x)" by simp
  2.6932 -    with nov0a lina linx have "\<forall> x\<in> set (iupto(1,j)). novar0I (lin_add (a,Cst x))" 
  2.6933 -      by (simp add: lin_add_novar0)
  2.6934 -    then show ?thesis by auto
  2.6935 -  qed
  2.6936 -  from "2.prems"
  2.6937 -  have linas: "\<forall>u\<in>set as. islinintterm u" by auto
  2.6938 -  from "2.prems" have nov0as: "\<forall>u\<in>set as. novar0I u" by auto
  2.6939 -  from "2.hyps" linas nov0as have nov0alls: "\<forall>u\<in>set (all_sums (j, as)). novar0I u" by simp
  2.6940 -  from nov0alls nov0ys have 
  2.6941 -    cs: "(\<forall> u\<in> set (?ys@ (all_sums (j,as))). novar0I u)"
  2.6942 -    by (simp only: sym[OF list_all_iff]) auto
  2.6943 -  
  2.6944 -  have "all_sums(j,a#as) = ?ys@(all_sums(j,as))"
  2.6945 -    by simp
  2.6946 -  then 
  2.6947 -  have "?case = (\<forall> x\<in> set (?ys@ (all_sums (j,as))). novar0I x)"
  2.6948 -    by auto
  2.6949 -  with cs show ?case by blast
  2.6950 -qed
  2.6951 +ML{* use "generated_cooper.ML"; 
  2.6952 +     GeneratedCooper.test (); *}
  2.6953 +use "coopereif.ML"
  2.6954 +oracle linzqe_oracle ("term") = Coopereif.cooper_oracle
  2.6955 +use"coopertac.ML"
  2.6956 +setup "LinZTac.setup"
  2.6957  
  2.6958 -(* correctness theorem for all_sums*)
  2.6959 -lemma all_sums_ex: 
  2.6960 -  "(\<exists> j\<in> {1..d}. \<exists> b\<in> (set xs). P (lin_add(b,Cst j))) = 
  2.6961 -  (\<exists> x\<in> set (all_sums (d,xs)). P x)"
  2.6962 -proof(induct d xs rule: all_sums.induct)
  2.6963 -  case (1 a) show ?case by simp
  2.6964 -next 
  2.6965 -  case (2 a y ys)
  2.6966 -  have "(\<exists> x\<in> set (map (\<lambda>x. lin_add (y,(Cst x))) (iupto(1,a))) . P x) = 
  2.6967 -    (\<exists> j\<in> set (iupto(1,a)). P (lin_add(y,Cst j)))" 
  2.6968 -    by auto
  2.6969 -  also have "\<dots> = (\<exists> j\<in> {1..a}. P (lin_add(y,Cst j)))" 
  2.6970 -    by (simp only : iupto_set)
  2.6971 -  finally
  2.6972 -  have dsj1:"(\<exists>j\<in>{1..a}. P (lin_add (y, Cst j))) = (\<exists>x\<in>set (map (\<lambda>x. lin_add (y, Cst x)) (iupto (1, a))). P x)" by simp
  2.6973 -  
  2.6974 -  from prems have "(\<exists> j\<in> {1..a}. \<exists> b\<in> (set (y#ys)). P (lin_add(b,Cst j))) = 
  2.6975 -    ((\<exists> j\<in> {1..a}. P (lin_add(y,Cst j))) \<or> (\<exists> j\<in> {1..a}. \<exists> b \<in> set ys. P (lin_add(b,Cst j))))" by auto
  2.6976 -  also
  2.6977 -  have " \<dots> = ((\<exists> j\<in> {1..a}. P (lin_add(y,Cst j))) \<or> (\<exists> x\<in> set (all_sums(a, ys)). P x))" using prems by simp
  2.6978 -  also have "\<dots> = ((\<exists>x\<in>set (map (\<lambda>x. lin_add (y, Cst x)) (iupto (1, a))). P x) \<or> (\<exists>x\<in>set (all_sums (a, ys)). P x))" using dsj1 by simp
  2.6979 -  also have "\<dots> = (\<exists> x\<in> (set (map (\<lambda>x. lin_add (y, Cst x)) (iupto (1, a)))) \<union> (set (all_sums(a, ys))). P x)" by blast
  2.6980 -  finally show ?case by simp
  2.6981 -qed
  2.6982 +  (* Tests *)
  2.6983 +lemma "\<exists> (j::int). \<forall> x\<ge>j. (\<exists> a b. x = 3*a+5*b)"
  2.6984 +by cooper
  2.6985  
  2.6986 -
  2.6987 -
  2.6988 -(* explode_minf (p,B)  assumes that p is unified and B = bset p, it computes the rhs of cooper_mi_eq*)
  2.6989 -
  2.6990 -consts explode_minf :: "(QF \<times> intterm list) \<Rightarrow> QF"
  2.6991 -recdef explode_minf "measure size"
  2.6992 -"explode_minf (q,B) = 
  2.6993 -  (let d = divlcm q;
  2.6994 -       pm = minusinf q;
  2.6995 -        dj1 = explode_disj ((map Cst (iupto (1, d))),pm)
  2.6996 -   in (case dj1 of 
  2.6997 -         T \<Rightarrow> T
  2.6998 -       | F \<Rightarrow> explode_disj (all_sums (d,B),q)
  2.6999 -        | _ \<Rightarrow> (let dj2 = explode_disj (all_sums (d,B),q)
  2.7000 -              in ( case dj2 of 
  2.7001 -                     T \<Rightarrow> T
  2.7002 -                   | F \<Rightarrow> dj1
  2.7003 -                   | _ \<Rightarrow> Or dj1 dj2))))"
  2.7004 +lemma "ALL (x::int) >=8. EX i j. 5*i + 3*j = x" by cooper
  2.7005 +theorem "(\<forall>(y::int). 3 dvd y) ==> \<forall>(x::int). b < x --> a \<le> x"
  2.7006 +  by cooper
  2.7007  
  2.7008 -(* The result of the rhs of cooper's theorem doese not depend on Var 0*)
  2.7009 -lemma explode_minf_novar0:
  2.7010 -  assumes unifp : "isunified p"
  2.7011 -  and bst: "set (bset p) = set B"
  2.7012 -  shows "novar0 (explode_minf (p,B))"
  2.7013 -proof-
  2.7014 -  let ?d = "divlcm p"
  2.7015 -  let ?pm = "minusinf p"
  2.7016 -  let ?dj1 = "explode_disj (map Cst (iupto(1,?d)),?pm)"
  2.7017 -  
  2.7018 -  have qfpm: "isqfree ?pm"  using unified_islinform[OF unifp] minusinf_qfree by simp
  2.7019 -  have dpos: "?d >0" using unified_islinform[OF unifp] divlcm_pos by simp 
  2.7020 -  have "\<forall> x\<in> set (map Cst (iupto(1,?d))). novar0I x" by auto
  2.7021 -  then have dj1_nov0: "novar0 ?dj1" using qfpm explode_disj_novar0 by simp
  2.7022 -  
  2.7023 -  let ?dj2 = "explode_disj (all_sums (?d,B),p)"
  2.7024 -  have 
  2.7025 -    bstlin: "\<forall>b\<in>set B. islinintterm b"
  2.7026 -    using bset_lin[OF unifp] bst
  2.7027 -    by simp
  2.7028 -  
  2.7029 -  have bstnov0: "\<forall>b\<in>set B. novar0I b"
  2.7030 -    using bst bset_novar0[OF unifp] by simp
  2.7031 -  have allsnov0: "\<forall>x\<in>set (all_sums(?d,B)). novar0I x "
  2.7032 -    by (simp add:all_sums_novar0[OF bstnov0 bstlin] )
  2.7033 -  then have dj2_nov0: "novar0 ?dj2" 
  2.7034 -    using explode_disj_novar0 unified_isqfree[OF unifp] bst by simp
  2.7035 -  have "?dj1 = T \<or> ?dj1 = F \<or> (?dj1 \<noteq> T \<and> ?dj1 \<noteq> F)" by auto
  2.7036 -  moreover
  2.7037 -  { assume "?dj1 = T" then have ?thesis by simp }
  2.7038 -  moreover
  2.7039 -  { assume "?dj1 = F" then have ?thesis using bst dj2_nov0 by (simp add: Let_def)}
  2.7040 -  moreover
  2.7041 -  {
  2.7042 -    assume dj1nFT:"?dj1 \<noteq> T \<and> ?dj1 \<noteq> F"
  2.7043 -    
  2.7044 -    have "?dj2 = T \<or> ?dj2 = F \<or> (?dj2 \<noteq> T \<and> ?dj2 \<noteq> F)" by auto
  2.7045 -    moreover
  2.7046 -    { assume "?dj2 = T" then have ?thesis by (cases ?dj1) simp_all }
  2.7047 -    moreover
  2.7048 -    { assume "?dj2 = F" then have ?thesis using dj1_nov0 bst
  2.7049 -	by (cases ?dj1) (simp_all add: Let_def)}
  2.7050 -    moreover
  2.7051 -    {
  2.7052 -      assume dj2_nTF:"?dj2 \<noteq> T \<and> ?dj2 \<noteq> F"
  2.7053 -      let ?res = "\<lambda>f. \<lambda>g. (case f of T \<Rightarrow> T | F \<Rightarrow> g
  2.7054 -	| _ \<Rightarrow> (case g of T \<Rightarrow> T| F \<Rightarrow> f| _ \<Rightarrow> Or f g))"
  2.7055 -      have expth: "explode_minf (p,B) = ?res ?dj1 ?dj2"
  2.7056 -	by (simp add: Let_def del: iupto.simps split del: split_if
  2.7057 -	  cong del: QF.weak_case_cong)
  2.7058 -      then have ?thesis
  2.7059 -	using prems or_case_novar0 [OF dj1nFT dj2_nTF dj1_nov0 dj2_nov0]
  2.7060 -	by (simp add: Let_def del: iupto.simps cong del: QF.weak_case_cong)
  2.7061 -    }
  2.7062 -    ultimately have ?thesis by blast
  2.7063 -  }
  2.7064 -  ultimately show ?thesis by blast
  2.7065 -qed
  2.7066 -  
  2.7067 -(* explode_minf computes the rhs of cooper's thm*)
  2.7068 -lemma explode_minf_corr:
  2.7069 -  assumes unifp : "isunified p"
  2.7070 -  and bst: "set (bset p) = set B"
  2.7071 -  shows "(\<exists> x . qinterp (x#ats) p) = (qinterp (a#ats) (explode_minf (p,B)))"
  2.7072 -  (is "(\<exists> x. ?P x) = (?EXP a p)")
  2.7073 -proof-
  2.7074 -  let ?d = "divlcm p"
  2.7075 -  let ?pm = "minusinf p"
  2.7076 -  let ?dj1 = "explode_disj (map Cst (iupto(1,?d)),?pm)"
  2.7077 -  have qfpm: "isqfree ?pm"  using unified_islinform[OF unifp] minusinf_qfree by simp 
  2.7078 -  have nnfp: "isnnf p" by (rule unified_isnnf[OF unifp])
  2.7079 +theorem "!! (y::int) (z::int) (n::int). 3 dvd z ==> 2 dvd (y::int) ==>
  2.7080 +  (\<exists>(x::int).  2*x =  y) & (\<exists>(k::int). 3*k = z)"
  2.7081 +  by cooper
  2.7082 +
  2.7083 +theorem "!! (y::int) (z::int) n. Suc(n::nat) < 6 ==>  3 dvd z ==>
  2.7084 +  2 dvd (y::int) ==> (\<exists>(x::int).  2*x =  y) & (\<exists>(k::int). 3*k = z)"
  2.7085 +  by cooper
  2.7086 +
  2.7087 +theorem "\<forall>(x::nat). \<exists>(y::nat). (0::nat) \<le> 5 --> y = 5 + x "
  2.7088 +  by cooper
  2.7089  
  2.7090 -  have "(\<exists>j\<in>{1..?d}. qinterp (j # ats) (minusinf p))
  2.7091 -    = (\<exists>j\<in> set (iupto(1,?d)). qinterp (j#ats) (minusinf p))"
  2.7092 -    (is "(\<exists> j\<in> {1..?d}. ?QM j) = \<dots>")
  2.7093 -    by (simp add: sym[OF iupto_set] )
  2.7094 -  also
  2.7095 -  have "\<dots> =(\<exists>j\<in> set (iupto(1,?d)). qinterp ((I_intterm (a#ats) (Cst j))#ats) (minusinf p))"
  2.7096 -    by simp
  2.7097 -  also have 
  2.7098 -    "\<dots> = (\<exists>j\<in> set (map Cst (iupto(1,?d))). qinterp ((I_intterm (a#ats) j)#ats) (minusinf p))" by simp
  2.7099 -  also have 
  2.7100 -    "\<dots> = 
  2.7101 -    (\<exists>j\<in> set (map Cst (iupto(1,?d))). qinterp (a#ats) (subst_p j (minusinf p)))"
  2.7102 -    by (simp add: subst_p_corr[OF qfpm])
  2.7103 -  finally have dj1_thm: 
  2.7104 -    "(\<exists> j\<in> {1..?d}. ?QM j) = (qinterp (a#ats) ?dj1)"
  2.7105 -    by (simp only: explode_disj_corr[OF qfpm])
  2.7106 -  let ?dj2 = "explode_disj (all_sums (?d,B),p)"
  2.7107 -  have 
  2.7108 -    bstlin: "\<forall>b\<in>set B. islinintterm b" 
  2.7109 -    using bst by (simp add: bset_lin[OF unifp])
  2.7110 -  have bstnov0: "\<forall>b\<in>set B. novar0I b" 
  2.7111 -    using bst by (simp add: bset_novar0[OF unifp])
  2.7112 -  have allsnov0: "\<forall>x\<in>set (all_sums(?d,B)). novar0I x "
  2.7113 -    by (simp add:all_sums_novar0[OF bstnov0 bstlin] )
  2.7114 -  have "(\<exists> j\<in> {1..?d}. \<exists> b\<in> set B. ?P (I_intterm (a#ats) b + j)) = 
  2.7115 -   (\<exists> j\<in> {1..?d}. \<exists> b\<in> set B. ?P (I_intterm (a#ats) (lin_add(b,Cst j))))"
  2.7116 -    using bst by (auto simp add: lin_add_corr bset_lin[OF unifp])
  2.7117 -  also have "\<dots> = (\<exists> x \<in> set (all_sums (?d, B)). ?P (I_intterm (a#ats) x))"
  2.7118 -    by (simp add: all_sums_ex[where P="\<lambda> t. ?P (I_intterm (a#ats) t)"])
  2.7119 -  finally 
  2.7120 -  have "(\<exists> j\<in> {1..?d}. \<exists> b\<in> set B. ?P (I_intterm (a#ats) b + j)) = 
  2.7121 -    (\<exists> x \<in> set (all_sums (?d, B)). qinterp (a#ats) (subst_p x p))"
  2.7122 -    using allsnov0 prems linform_isqfree unified_islinform[OF unifp]
  2.7123 -    by (simp add: all_sums_ex subst_p_corr)
  2.7124 -  also have "\<dots> = (qinterp (a#ats) ?dj2)"
  2.7125 -    using linform_isqfree unified_islinform[OF unifp]
  2.7126 -    by (simp add: explode_disj_corr)
  2.7127 -  finally have dj2th: 
  2.7128 -    "(\<exists> j\<in> {1..?d}. \<exists> b\<in> set B. ?P (I_intterm (a#ats) b + j)) =  
  2.7129 -    (qinterp (a#ats) ?dj2)" by simp
  2.7130 -  let ?result = "\<lambda>f. \<lambda>g. 
  2.7131 -    (case f of 
  2.7132 -    T \<Rightarrow> T
  2.7133 -    | F \<Rightarrow> g
  2.7134 -    | _ \<Rightarrow> (case g of 
  2.7135 -    T \<Rightarrow> T
  2.7136 -    | F \<Rightarrow> f
  2.7137 -    | _ \<Rightarrow> Or f g))"
  2.7138 -  have "?EXP a p =  qinterp (a#ats) (?result ?dj1 ?dj2)"
  2.7139 -    by (simp only: explode_minf.simps Let_def)
  2.7140 -  also
  2.7141 -  have "\<dots> = (qinterp (a#ats) ?dj1 \<or> qinterp (a#ats) ?dj2)" 
  2.7142 -    by (rule eval_Or_cases[where f="?dj1" and g="?dj2" and a="a" and ats="ats"])
  2.7143 -  also 
  2.7144 -  have "\<dots> = ((\<exists> j\<in> {1..?d}. ?QM j) \<or> 
  2.7145 -    (\<exists> j\<in> {1..?d}. \<exists> b\<in> set B. ?P (I_intterm (a#ats) b + j)))"
  2.7146 -    by (simp add: dj1_thm dj2th)
  2.7147 -  also
  2.7148 -  have "\<dots> = (\<exists> x. ?P x)"
  2.7149 -    using bst sym[OF cooper_mi_eq[OF unifp]] by simp
  2.7150 -  finally show ?thesis by simp
  2.7151 -qed
  2.7152 +lemma "ALL (x::int) >=8. EX i j. 5*i + 3*j = x" by cooper 
  2.7153 +lemma "ALL (y::int) (z::int) (n::int). 3 dvd z --> 2 dvd (y::int) --> (EX (x::int).  2*x =  y) & (EX (k::int). 3*k = z)" by cooper
  2.7154 +lemma "ALL(x::int) y. x < y --> 2 * x + 1 < 2 * y" by cooper
  2.7155 +lemma "ALL(x::int) y. 2 * x + 1 ~= 2 * y" by cooper
  2.7156 +lemma "EX(x::int) y. 0 < x  & 0 <= y  & 3 * x - 5 * y = 1" by cooper
  2.7157 +lemma "~ (EX(x::int) (y::int) (z::int). 4*x + (-6::int)*y = 1)" by cooper
  2.7158 +lemma "ALL(x::int). (2 dvd x) --> (EX(y::int). x = 2*y)" by cooper
  2.7159 +lemma "ALL(x::int). (2 dvd x) --> (EX(y::int). x = 2*y)" by cooper
  2.7160 +lemma "ALL(x::int). (2 dvd x) = (EX(y::int). x = 2*y)" by cooper
  2.7161 +lemma "ALL(x::int). ((2 dvd x) = (ALL(y::int). x ~= 2*y + 1))" by cooper
  2.7162 +lemma "~ (ALL(x::int). ((2 dvd x) = (ALL(y::int). x ~= 2*y+1) | (EX(q::int) (u::int) i. 3*i + 2*q - u < 17) --> 0 < x | ((~ 3 dvd x) &(x + 8 = 0))))" by cooper
  2.7163 +lemma "~ (ALL(i::int). 4 <= i --> (EX x y. 0 <= x & 0 <= y & 3 * x + 5 * y = i))" 
  2.7164 +  by cooper
  2.7165 +lemma "EX j. ALL (x::int) >= j. EX i j. 5*i + 3*j = x" by cooper
  2.7166  
  2.7167 +theorem "(\<forall>(y::int). 3 dvd y) ==> \<forall>(x::int). b < x --> a \<le> x"
  2.7168 +  by cooper
  2.7169  
  2.7170 -lemma explode_minf_corr2:
  2.7171 -  assumes unifp : "isunified p"
  2.7172 -  and bst: "set (bset p) = set B"
  2.7173 -  shows "(qinterp ats (QEx p)) = (qinterp ats (decrvars(explode_minf (p,B))))"
  2.7174 -  (is "?P = (?Qe p)")
  2.7175 -proof-
  2.7176 -  have "?P = (\<exists>x. qinterp (x#ats) p)" by simp
  2.7177 -  also have "\<dots>  = (qinterp (a # ats) (explode_minf (p,B)))"
  2.7178 -    using unifp bst explode_minf_corr by simp
  2.7179 -  finally have ex: "?P = (qinterp (a # ats) (explode_minf (p,B)))" .
  2.7180 -  have nv0: "novar0 (explode_minf (p,B))"
  2.7181 -    by (rule explode_minf_novar0[OF unifp])
  2.7182 -  show ?thesis
  2.7183 -    using qinterp_novar0[OF nv0] ex by simp
  2.7184 -qed
  2.7185 -
  2.7186 -(* An implementation of cooper's method for both plus/minus/infinity *)
  2.7187 +theorem "!! (y::int) (z::int) (n::int). 3 dvd z ==> 2 dvd (y::int) ==>
  2.7188 +  (\<exists>(x::int).  2*x =  y) & (\<exists>(k::int). 3*k = z)"
  2.7189 +  by cooper
  2.7190  
  2.7191 -(* unify the formula *)
  2.7192 -definition unify:: "QF \<Rightarrow> (QF \<times> intterm list)" where
  2.7193 -  "unify p =
  2.7194 -  (let q = unitycoeff p;
  2.7195 -       B = list_set(bset q);
  2.7196 -       A = list_set (aset q)
  2.7197 -  in
  2.7198 -  if (length B \<le> length A)
  2.7199 -             then (q,B)
  2.7200 -             else (mirror q, map lin_neg A))"
  2.7201 -  
  2.7202 -(* unify behaves like unitycoeff *)
  2.7203 -lemma unify_ex:
  2.7204 -  assumes linp: "islinform p"
  2.7205 -  shows "qinterp ats (QEx p) = qinterp ats (QEx (fst (unify p)))"
  2.7206 -proof-
  2.7207 -  have "length (list_set(bset (unitycoeff p))) \<le> length (list_set (aset (unitycoeff p))) \<or> length (list_set(bset (unitycoeff p))) > length (list_set (aset (unitycoeff p)))" by arith
  2.7208 -  moreover
  2.7209 -  {
  2.7210 -    assume "length (list_set(bset (unitycoeff p))) \<le> length (list_set (aset (unitycoeff p)))"