The oracle for Presburger has been changer: It is automatically generated form a verified formaliztion of Cooper's Algorithm ex/Reflected_Presburger.thy
authorchaieb
Wed Sep 14 17:25:52 2005 +0200 (2005-09-14)
changeset 17378105519771c67
parent 17377 afaa031ed4da
child 17379 85109eec887b
The oracle for Presburger has been changer: It is automatically generated form a verified formaliztion of Cooper's Algorithm ex/Reflected_Presburger.thy
comm_ring : a reflected Method for proving equalities in a commutative ring
src/HOL/Commutative_Ring.thy
src/HOL/Integ/Presburger.thy
src/HOL/Integ/cooper_dec.ML
src/HOL/Integ/reflected_cooper.ML
src/HOL/Integ/reflected_presburger.ML
src/HOL/IsaMakefile
src/HOL/Presburger.thy
src/HOL/Tools/Presburger/cooper_dec.ML
src/HOL/Tools/Presburger/reflected_cooper.ML
src/HOL/Tools/Presburger/reflected_presburger.ML
src/HOL/Tools/comm_ring.ML
src/HOL/ex/Commutative_RingEx.thy
src/HOL/ex/Commutative_Ring_Complete.thy
src/HOL/ex/ROOT.ML
src/HOL/ex/Reflected_Presburger.thy
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/HOL/Commutative_Ring.thy	Wed Sep 14 17:25:52 2005 +0200
     1.3 @@ -0,0 +1,310 @@
     1.4 +
     1.5 +(*  ID:         $Id$
     1.6 +    Author:     Bernhard Haeupler
     1.7 +
     1.8 +  Proving equalities in a commutative Ring done "right" in Isabelle/HOL
     1.9 +*)
    1.10 +
    1.11 +theory Commutative_Ring
    1.12 +imports List
    1.13 +uses ("comm_ring.ML")
    1.14 +begin
    1.15 +
    1.16 +  (* Syntax of multivariate polynomials (pol) and polynomial expressions*)
    1.17 +datatype 'a pol = 
    1.18 +  Pc 'a 
    1.19 +  | Pinj nat "'a pol" 
    1.20 +  | PX "'a pol" nat "'a pol"
    1.21 +
    1.22 +datatype 'a polex = 
    1.23 +  Pol "'a pol" 
    1.24 +  | Add "'a polex" "'a polex" 
    1.25 +  | Sub "'a polex" "'a polex" 
    1.26 +  | Mul "'a polex" "'a polex" 
    1.27 +  | Pow "'a polex" nat
    1.28 +  | Neg "'a polex"
    1.29 +
    1.30 +  (* Interpretation functions for the shadow syntax *)
    1.31 +consts 
    1.32 +  Ipol :: "('a::{comm_ring,recpower}) list \<Rightarrow> 'a pol \<Rightarrow> 'a"
    1.33 +  Ipolex :: "('a::{comm_ring,recpower}) list \<Rightarrow> 'a polex \<Rightarrow> 'a"
    1.34 +
    1.35 +primrec
    1.36 +  "Ipol l (Pc c) = c"
    1.37 +  "Ipol l (Pinj i P) = Ipol (drop i l) P"
    1.38 +  "Ipol l (PX P x Q) = (Ipol l P)*((hd l)^x) + (Ipol (drop 1 l) Q)"
    1.39 +
    1.40 +primrec
    1.41 +  "Ipolex l (Pol P) = Ipol l P"
    1.42 +  "Ipolex l (Add P Q) = (Ipolex l P) + (Ipolex l Q)"
    1.43 +  "Ipolex l (Sub P Q) = (Ipolex l P) - (Ipolex l Q)"
    1.44 +  "Ipolex l (Mul P Q) = (Ipolex l P) * (Ipolex l Q)"
    1.45 +  "Ipolex l (Pow p n) = (Ipolex l p) ^ n"
    1.46 +  "Ipolex l (Neg P) = -(Ipolex l P)"
    1.47 +
    1.48 +  (* Create polynomial normalized polynomials given normalized inputs *)
    1.49 +constdefs mkPinj :: "nat \<Rightarrow> 'a pol \<Rightarrow> 'a pol"
    1.50 +  mkPinj_def: "mkPinj x P \<equiv> (case P of   
    1.51 +  (Pc c) \<Rightarrow> (Pc c) |
    1.52 +  (Pinj y P) \<Rightarrow> Pinj (x+y) P |
    1.53 +  (PX p1 y p2) \<Rightarrow> Pinj x P )"
    1.54 +
    1.55 +constdefs mkPX :: "('a::{comm_ring,recpower}) pol \<Rightarrow> nat \<Rightarrow> 'a pol \<Rightarrow> 'a pol"
    1.56 +  mkPX_def: "mkPX P i Q == (case P of
    1.57 +  (Pc c) \<Rightarrow> (if (c = 0) then (mkPinj 1 Q) else (PX P i Q)) |
    1.58 +  (Pinj j R) \<Rightarrow> (PX P i Q) |
    1.59 +  (PX P2 i2 Q2) \<Rightarrow> (if (Q2 = (Pc 0)) then (PX P2 (i+i2) Q) else (PX P i Q)) )"
    1.60 +
    1.61 +  (* Defining the basic ring operations on normalized polynomials *)
    1.62 +consts
    1.63 +add :: "(('a::{comm_ring,recpower}) pol) \<times> ('a pol) \<Rightarrow> 'a pol"
    1.64 +mul :: "(('a::{comm_ring,recpower}) pol) \<times> ('a pol) \<Rightarrow> 'a pol"
    1.65 +neg :: "('a::{comm_ring,recpower}) pol \<Rightarrow> 'a pol"
    1.66 +sqr :: "('a::{comm_ring,recpower}) pol  \<Rightarrow> 'a pol"
    1.67 +pow :: "('a::{comm_ring,recpower}) pol \<times> nat \<Rightarrow> 'a pol"
    1.68 +
    1.69 +
    1.70 +  (* Addition *)
    1.71 +recdef add "measure (\<lambda>(x, y). size x + size y)"
    1.72 +  "add (Pc a, Pc b) = Pc (a+b)"
    1.73 +  "add (Pc c, Pinj i P) = Pinj i (add (P, Pc c))"
    1.74 +  "add (Pinj i P, Pc c) = Pinj i (add (P, Pc c))"
    1.75 +  "add (Pc c, PX P i Q) = PX P i (add (Q, Pc c))"
    1.76 +  "add (PX P i Q, Pc c) = PX P i (add (Q, Pc c))"
    1.77 +  "add (Pinj x P, Pinj y Q) = 
    1.78 +  (if x=y then mkPinj x (add (P, Q)) 
    1.79 +   else (if x>y then mkPinj y (add (Pinj (x-y) P, Q))
    1.80 +         else mkPinj x (add (Pinj (y-x) Q, P)) ))"
    1.81 +  "add (Pinj x P, PX Q y R) = 
    1.82 +  (if x=0 then add(P, PX Q y R) 
    1.83 +   else (if x=1 then PX Q y (add (R, P)) 
    1.84 +         else PX Q y (add (R, Pinj (x - 1) P))))"
    1.85 +  "add (PX P x R, Pinj y Q) = 
    1.86 +  (if y=0 then add(PX P x R, Q) 
    1.87 +   else (if y=1 then PX P x (add (R, Q)) 
    1.88 +         else PX P x (add (R, Pinj (y - 1) Q))))"
    1.89 +  "add (PX P1 x P2, PX Q1 y Q2) = 
    1.90 +  (if x=y then mkPX (add (P1, Q1)) x (add (P2, Q2)) 
    1.91 +  else (if x>y then mkPX (add (PX P1 (x-y) (Pc 0), Q1)) y (add (P2,Q2)) 
    1.92 +        else mkPX (add (PX Q1 (y-x) (Pc 0), P1)) x (add (P2,Q2)) ))"
    1.93 +
    1.94 +  (* Multiplication *)
    1.95 +recdef mul "measure (\<lambda>(x, y). size x + size y)"
    1.96 +  "mul (Pc a, Pc b) = Pc (a*b)"
    1.97 +  "mul (Pc c, Pinj i P) = (if c=0 then Pc 0 else mkPinj i (mul (P, Pc c)))"
    1.98 +  "mul (Pinj i P, Pc c) = (if c=0 then Pc 0 else mkPinj i (mul (P, Pc c)))"
    1.99 +  "mul (Pc c, PX P i Q) = 
   1.100 +  (if c=0 then Pc 0 else mkPX (mul (P, Pc c)) i (mul (Q, Pc c)))"
   1.101 +  "mul (PX P i Q, Pc c) = 
   1.102 +  (if c=0 then Pc 0 else mkPX (mul (P, Pc c)) i (mul (Q, Pc c)))"
   1.103 +  "mul (Pinj x P, Pinj y Q) = 
   1.104 +  (if x=y then mkPinj x (mul (P, Q)) 
   1.105 +   else (if x>y then mkPinj y (mul (Pinj (x-y) P, Q))
   1.106 +         else mkPinj x (mul (Pinj (y-x) Q, P)) ))"
   1.107 +  "mul (Pinj x P, PX Q y R) = 
   1.108 +  (if x=0 then mul(P, PX Q y R) 
   1.109 +   else (if x=1 then mkPX (mul (Pinj x P, Q)) y (mul (R, P)) 
   1.110 +         else mkPX (mul (Pinj x P, Q)) y (mul (R, Pinj (x - 1) P))))"
   1.111 +  "mul (PX P x R, Pinj y Q) = 
   1.112 +  (if y=0 then mul(PX P x R, Q) 
   1.113 +   else (if y=1 then mkPX (mul (Pinj y Q, P)) x (mul (R, Q)) 
   1.114 +         else mkPX (mul (Pinj y Q, P)) x (mul (R, Pinj (y - 1) Q))))"
   1.115 +  "mul (PX P1 x P2, PX Q1 y Q2) =  
   1.116 +  add (mkPX (mul (P1, Q1)) (x+y) (mul (P2, Q2)), 
   1.117 +  add (mkPX (mul (P1, mkPinj 1 Q2)) x (Pc 0), mkPX (mul (Q1, mkPinj 1 P2)) y (Pc 0)) )"
   1.118 +(hints simp add: mkPinj_def split: pol.split)
   1.119 +
   1.120 +  (* Negation*)
   1.121 +primrec
   1.122 +  "neg (Pc c) = (Pc (-c))"
   1.123 +  "neg (Pinj i P) = Pinj i (neg P)"
   1.124 +  "neg (PX P x Q) = PX (neg P) x (neg Q)"
   1.125 +
   1.126 +  (* Substraction*)
   1.127 +constdefs sub :: "(('a::{comm_ring,recpower}) pol) \<Rightarrow> ('a pol) \<Rightarrow> 'a pol"
   1.128 +  "sub p q \<equiv> add (p,neg q)"
   1.129 +
   1.130 +  (* Square for Fast Exponentation *)
   1.131 +primrec
   1.132 +  "sqr (Pc c) = Pc (c*c)"
   1.133 +  "sqr (Pinj i P) = mkPinj i (sqr P)"
   1.134 +  "sqr (PX A x B) = add (mkPX (sqr A) (x+x) (sqr B), mkPX (mul (mul (Pc (1+1), A), mkPinj 1 B)) x (Pc 0))"
   1.135 +
   1.136 +  (* Fast Exponentation *)
   1.137 +lemma pow_wf:"odd n \<longrightarrow> (n::nat) div 2 < n" by(cases n, auto)
   1.138 +recdef pow "measure (\<lambda>(x, y). y)"
   1.139 +  "pow (p, 0) = Pc 1"
   1.140 +  "pow (p, n) = (if even n then (pow (sqr p, n div 2)) else mul (p, pow (sqr p, n div 2)))"
   1.141 +(hints simp add: pow_wf)
   1.142 +
   1.143 +lemma pow_if: "pow (p,n) = (if n=0 then Pc 1 else (if even n then (pow (sqr p, n div 2)) else mul (p, pow (sqr p, n div 2))))"
   1.144 +by (cases n) simp_all
   1.145 +
   1.146 +(*
   1.147 +lemma number_of_nat_B0: "(number_of (w BIT bit.B0) ::nat) = 2* (number_of w)"
   1.148 +by simp
   1.149 +
   1.150 +lemma number_of_nat_even: "even (number_of (w BIT bit.B0)::nat)"
   1.151 +by simp
   1.152 +  
   1.153 +lemma pow_even : "pow (p, number_of(w BIT bit.B0)) = pow (sqr p, number_of w)"
   1.154 +  ( is "pow(?p,?n) = pow (_,?n2)")
   1.155 +proof-
   1.156 +  have "even ?n" by simp
   1.157 +  hence "pow (p, ?n) = pow (sqr p, ?n div 2)" 
   1.158 +    apply simp
   1.159 +    apply (cases "IntDef.neg (number_of w)")
   1.160 +    apply simp
   1.161 +    done  
   1.162 +*)
   1.163 +  (* Normalization of polynomial expressions *)
   1.164 +
   1.165 +consts norm :: "('a::{comm_ring,recpower}) polex \<Rightarrow> 'a pol"
   1.166 +primrec
   1.167 +  "norm (Pol P) = P"
   1.168 +  "norm (Add P Q) = add (norm P, norm Q)"
   1.169 +  "norm (Sub p q) = sub (norm p) (norm q)"
   1.170 +  "norm (Mul P Q) = mul (norm P, norm Q)"
   1.171 +  "norm (Pow p n) = pow (norm p, n)"
   1.172 +  "norm (Neg P) = neg (norm P)"
   1.173 +
   1.174 +  (* mkPinj preserve semantics *)
   1.175 +lemma mkPinj_ci: "ALL a l. Ipol l (mkPinj a B) = Ipol l (Pinj a B)"
   1.176 +  by(induct B, auto simp add: mkPinj_def ring_eq_simps)
   1.177 +
   1.178 +  (* mkPX preserves semantics *)
   1.179 +lemma mkPX_ci: "ALL b l. Ipol l (mkPX A b C) = Ipol l (PX A b C)"
   1.180 +  by(case_tac A, auto simp add: mkPX_def mkPinj_ci power_add ring_eq_simps)
   1.181 +
   1.182 +  (* Correctness theorems for the implemented operations *)
   1.183 +  (* Negation *)
   1.184 +lemma neg_ci: "ALL l. Ipol l (neg P) = -(Ipol l P)"
   1.185 +  by(induct P, auto)
   1.186 +
   1.187 +  (* Addition *)
   1.188 +lemma add_ci: "ALL l. Ipol l (add (P, Q)) = Ipol l P + Ipol l Q"
   1.189 +proof(induct P Q rule: add.induct)
   1.190 +  case (6 x P y Q)
   1.191 +  have "x < y \<or> x = y \<or> x > y" by arith
   1.192 +  moreover
   1.193 +  { assume "x<y" hence "EX d. d+x=y" by arith
   1.194 +    then obtain d where "d+x=y"..
   1.195 +    with prems have ?case by (auto simp add: mkPinj_ci ring_eq_simps) }
   1.196 +  moreover
   1.197 +  { assume "x=y" with prems have ?case by (auto simp add: mkPinj_ci)}
   1.198 +  moreover
   1.199 +  { assume "x>y" hence "EX d. d+y=x" by arith
   1.200 +    then obtain d where "d+y=x"..
   1.201 +    with prems have ?case by (auto simp add: mkPinj_ci ring_eq_simps) }
   1.202 +  ultimately show ?case by blast
   1.203 +next 
   1.204 +  case (7 x P Q y R)
   1.205 +  have "x=0 \<or> (x = 1) \<or> (x > 1)" by arith
   1.206 +  moreover
   1.207 +  { assume "x=0" with prems have ?case by auto }
   1.208 +  moreover
   1.209 +  { assume "x=1" with prems have ?case by (auto simp add: ring_eq_simps) }
   1.210 +  moreover
   1.211 +  { assume "x > 1" from prems have ?case by(cases x, auto) }
   1.212 +  ultimately show ?case by blast
   1.213 +next
   1.214 +  case (8 P x R y Q)
   1.215 +  have "(y = 0) \<or> (y = 1) \<or> (y > 1)" by arith
   1.216 +  moreover
   1.217 +  {assume "y=0" with prems have ?case by simp}
   1.218 +  moreover
   1.219 +  {assume "y=1" with prems have ?case by simp}
   1.220 +  moreover
   1.221 +  {assume "y>1" hence "EX d. d+1=y" by arith
   1.222 +    then obtain d where "d+1=y" ..
   1.223 +    with prems have ?case by auto }
   1.224 +  ultimately show ?case by blast
   1.225 +next 
   1.226 +  case (9 P1 x P2 Q1 y Q2)
   1.227 +  have "y < x \<or> x = y \<or> x < y" by arith
   1.228 +  moreover
   1.229 +  {assume "y < x" hence "EX d. d+y=x" by arith
   1.230 +    then obtain d where "d+y=x"..
   1.231 +    with prems have ?case by (auto simp add: power_add mkPX_ci ring_eq_simps) }
   1.232 +  moreover
   1.233 +  {assume "x=y" with prems have ?case by(auto simp add: mkPX_ci ring_eq_simps) }
   1.234 +  moreover
   1.235 +  {assume "x<y" hence "EX d. d+x=y" by arith
   1.236 +    then obtain d where "d+x=y" ..
   1.237 +    with prems have ?case by (auto simp add: mkPX_ci power_add ring_eq_simps) }
   1.238 +  ultimately show ?case by blast
   1.239 +qed (auto simp add: ring_eq_simps)
   1.240 +
   1.241 +    (* Multiplication *)
   1.242 +lemma mul_ci: "ALL l. Ipol l (mul (P, Q)) = Ipol l P * Ipol l Q" 
   1.243 +  by (induct P Q rule: mul.induct, auto simp add: mkPX_ci mkPinj_ci ring_eq_simps add_ci power_add) 
   1.244 +
   1.245 +  (* Substraction *)
   1.246 +lemma sub_ci: "\<forall> l. Ipol l (sub p q) = (Ipol l p) - (Ipol l q)"
   1.247 +  by (auto simp add: add_ci neg_ci sub_def)
   1.248 +
   1.249 +  (* Square *)
   1.250 +lemma sqr_ci:"ALL ls. Ipol ls (sqr p) = Ipol ls p * Ipol ls p"
   1.251 +by(induct p, auto simp add: add_ci mkPinj_ci mkPX_ci mul_ci ring_eq_simps power_add)
   1.252 +
   1.253 +
   1.254 +  (* Power *)
   1.255 +lemma even_pow:"even n \<longrightarrow> pow (p, n) = pow (sqr p, n div 2)" by(induct n,auto)
   1.256 +lemma pow_ci: "ALL p. Ipol ls (pow (p, n)) = (Ipol ls p) ^ n"
   1.257 +proof(induct n rule: nat_less_induct)
   1.258 +  case (1 k)
   1.259 +  have two:"2=Suc( Suc 0)" by simp
   1.260 +  from prems show ?case 
   1.261 +  proof(cases k)
   1.262 +    case (Suc l)
   1.263 +    hence KL:"k=Suc l" by simp
   1.264 +    have "even l \<or> odd l" by (simp)
   1.265 +    moreover
   1.266 +    {assume EL:"even l"
   1.267 +      have "Suc l div 2 = l div 2" by (simp add: nat_number even_nat_plus_one_div_two[OF EL])
   1.268 +      moreover
   1.269 +      from KL have"l<k" by simp
   1.270 +      with prems have "ALL p. Ipol ls (pow (p, l)) = Ipol ls p ^ l" by simp
   1.271 +      moreover
   1.272 +      note prems even_nat_plus_one_div_two[OF EL]
   1.273 +      ultimately have ?thesis by (simp add: mul_ci power_Suc even_pow) }
   1.274 +    moreover
   1.275 +    {assume OL:"odd l"
   1.276 +      with prems have "\<lbrakk>\<forall>m<Suc l. \<forall>p. Ipol ls (pow (p, m)) = Ipol ls p ^ m; k = Suc l; odd l\<rbrakk> \<Longrightarrow> \<forall>p. Ipol ls (sqr p) ^ (Suc l div 2) = Ipol ls p ^ Suc l"
   1.277 +      proof(cases l)
   1.278 +	case (Suc w)
   1.279 +	from prems have EW:"even w" by simp
   1.280 +	from two have two_times:"(2 * (w div 2))= w" by (simp only: even_nat_div_two_times_two[OF EW])
   1.281 +	have A:"ALL p. (Ipol ls p * Ipol ls p) = (Ipol ls p) ^ (Suc (Suc 0))" by (simp add: power_Suc)
   1.282 +	from A two[symmetric] have "ALL p.(Ipol ls p * Ipol ls p) = (Ipol ls p) ^ 2" by simp
   1.283 +	with prems show ?thesis by (auto simp add: power_mult[symmetric, of _ 2 _] two_times mul_ci sqr_ci)
   1.284 +      qed(simp)
   1.285 +      with prems have ?thesis by simp }
   1.286 +    ultimately show ?thesis by blast
   1.287 +  qed(simp)
   1.288 +qed
   1.289 +
   1.290 +  (* Normalization preserves semantics  *)
   1.291 +lemma norm_ci:"Ipolex l Pe = Ipol l (norm Pe)"
   1.292 +  by(induct Pe, simp_all add: add_ci sub_ci mul_ci neg_ci pow_ci)
   1.293 +
   1.294 +(* Reflection lemma: Key to the (incomplete) decision procedure *)
   1.295 +lemma norm_eq:
   1.296 +  assumes A:"norm P1  = norm P2" 
   1.297 +  shows "Ipolex l P1 = Ipolex l P2"
   1.298 +proof -
   1.299 +  from A have "Ipol l (norm P1) = Ipol l (norm P2)" by simp
   1.300 +  thus ?thesis by(simp only: norm_ci)
   1.301 +qed
   1.302 +
   1.303 +
   1.304 +    (* Code generation *)
   1.305 +(*
   1.306 +Does not work, since no generic ring operations implementation is there
   1.307 +generate_code ("ring.ML") test = "norm"*)
   1.308 +
   1.309 +
   1.310 + use "comm_ring.ML"
   1.311 +setup "CommRing.setup"
   1.312 +
   1.313 +end
   1.314 \ No newline at end of file
     2.1 --- a/src/HOL/Integ/Presburger.thy	Wed Sep 14 10:24:39 2005 +0200
     2.2 +++ b/src/HOL/Integ/Presburger.thy	Wed Sep 14 17:25:52 2005 +0200
     2.3 @@ -10,7 +10,8 @@
     2.4  
     2.5  theory Presburger
     2.6  imports NatSimprocs SetInterval
     2.7 -uses ("cooper_dec.ML") ("cooper_proof.ML") ("qelim.ML") ("presburger.ML")
     2.8 +uses ("cooper_dec.ML") ("cooper_proof.ML") ("qelim.ML") 
     2.9 +	("reflected_presburger.ML") ("reflected_cooper.ML") ("presburger.ML")
    2.10  begin
    2.11  
    2.12  text {* Theorem for unitifying the coeffitients of @{text x} in an existential formula*}
    2.13 @@ -982,8 +983,10 @@
    2.14    by (simp cong: conj_cong)
    2.15  
    2.16  use "cooper_dec.ML"
    2.17 +use "reflected_presburger.ML" 
    2.18 +use "reflected_cooper.ML"
    2.19  oracle
    2.20 -  presburger_oracle ("term") = CooperDec.presburger_oracle
    2.21 +  presburger_oracle ("term") = ReflectedCooper.presburger_oracle
    2.22  
    2.23  use "cooper_proof.ML"
    2.24  use "qelim.ML"
     3.1 --- a/src/HOL/Integ/cooper_dec.ML	Wed Sep 14 10:24:39 2005 +0200
     3.2 +++ b/src/HOL/Integ/cooper_dec.ML	Wed Sep 14 17:25:52 2005 +0200
     3.3 @@ -44,7 +44,6 @@
     3.4    val evalc : term -> term
     3.5    val cooper_w : string list -> term -> (term option * term)
     3.6    val integer_qelim : Term.term -> Term.term
     3.7 -  val presburger_oracle : theory -> term -> term
     3.8  end;
     3.9  
    3.10  structure  CooperDec : COOPER_DEC =
    3.11 @@ -938,8 +937,4 @@
    3.12  
    3.13  val integer_qelim = simpl o evalc o (lift_qelim linform (cnnf posineq o evalc) cooper is_arith_rel) ; 
    3.14  
    3.15 -fun presburger_oracle thy t =
    3.16 -    if (!quick_and_dirty) 
    3.17 -    then HOLogic.mk_Trueprop (HOLogic.mk_eq(t,integer_qelim t))
    3.18 -    else error "Presburger oracle: not in quick_and_dirty mode"
    3.19  end;
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/HOL/Integ/reflected_cooper.ML	Wed Sep 14 17:25:52 2005 +0200
     4.3 @@ -0,0 +1,124 @@
     4.4 +(* $Id$ *)
     4.5 +(* The oracle for Presburger arithmetic based on the verified Code *)
     4.6 +    (* in HOL/ex/Reflected_Presburger.thy *)
     4.7 +
     4.8 +structure ReflectedCooper =
     4.9 +struct
    4.10 +
    4.11 +open Generated;
    4.12 +(* pseudo reification : term -> intterm *)
    4.13 +
    4.14 +fun i_of_term vs t = 
    4.15 +    case t of
    4.16 +	Free(xn,xT) => (case assoc(vs,t) of 
    4.17 +			   NONE   => error "Variable not found in the list!!"
    4.18 +			 | SOME n => Var n)
    4.19 +      | Const("0",iT) => Cst 0
    4.20 +      | Const("1",iT) => Cst 1
    4.21 +      | Bound i => Var (nat i)
    4.22 +      | Const("uminus",_)$t' => Neg (i_of_term vs t')
    4.23 +      | Const ("op +",_)$t1$t2 => Add (i_of_term vs t1,i_of_term vs t2)
    4.24 +      | Const ("op -",_)$t1$t2 => Sub (i_of_term vs t1,i_of_term vs t2)
    4.25 +      | Const ("op *",_)$t1$t2 => Mult (i_of_term vs t1,i_of_term vs t2)
    4.26 +      | Const ("Numeral.number_of",_)$t' => Cst (HOLogic.dest_binum t')
    4.27 +      | _ => error "i_of_term: unknown term";
    4.28 +	
    4.29 +
    4.30 +(* pseudo reification : term -> QF *)
    4.31 +fun qf_of_term vs t = 
    4.32 +    case t of 
    4.33 +	Const("True",_) => T
    4.34 +      | Const("False",_) => F
    4.35 +      | Const("op <",_)$t1$t2 => Lt (i_of_term vs t1,i_of_term vs t2)
    4.36 +      | Const("op <=",_)$t1$t2 => Le (i_of_term vs t1,i_of_term vs t2)
    4.37 +      | Const ("Divides.op dvd",_)$t1$t2 => 
    4.38 +	Divides(i_of_term vs t1,i_of_term vs t2)
    4.39 +      | Const("op =",eqT)$t1$t2 => 
    4.40 +	if (domain_type eqT = HOLogic.intT)
    4.41 +	then let val i1 = i_of_term vs t1
    4.42 +		 val i2 = i_of_term vs t2
    4.43 +	     in	Eq (i1,i2)
    4.44 +	     end 
    4.45 +	else Equ(qf_of_term vs t1,qf_of_term vs t2)
    4.46 +      | Const("op &",_)$t1$t2 => And(qf_of_term vs t1,qf_of_term vs t2)
    4.47 +      | Const("op |",_)$t1$t2 => Or(qf_of_term vs t1,qf_of_term vs t2)
    4.48 +      | Const("op -->",_)$t1$t2 => Imp(qf_of_term vs t1,qf_of_term vs t2)
    4.49 +      | Const("Not",_)$t' => NOT(qf_of_term vs t')
    4.50 +      | Const("Ex",_)$Abs(xn,xT,p) => 
    4.51 +	QEx(qf_of_term (map (fn(v,n) => (v,n + 1)) vs) p)
    4.52 +      | Const("All",_)$Abs(xn,xT,p) => 
    4.53 +	QAll(qf_of_term (map (fn(v,n) => (v,n + 1)) vs) p)
    4.54 +      | _ => error "qf_of_term : unknown term!";
    4.55 +
    4.56 +(*
    4.57 +fun parse s = term_of (read_cterm (sign_of Main.thy) (s,HOLogic.boolT));
    4.58 +
    4.59 +val t = parse "ALL (i::int) (j::int). i < 8* j --> (i - 1 = j + 3 + 2*j) & (j <= -i + k ) | 4 = i | 5 dvd i";
    4.60 +*)
    4.61 +fun zip [] [] = []
    4.62 +  | zip (x::xs) (y::ys) = (x,y)::(zip xs ys);
    4.63 +
    4.64 +
    4.65 +fun start_vs t =
    4.66 +    let val fs = term_frees t
    4.67 +    in zip fs (map nat (0 upto (length fs - 1)))
    4.68 +    end ;
    4.69 +
    4.70 +(* transform intterm and QF back to terms *)
    4.71 +val iT = HOLogic.intT;
    4.72 +val bT = HOLogic.boolT;
    4.73 +fun myassoc2 l v =
    4.74 +    case l of
    4.75 +	[] => NONE
    4.76 +      | (x,v')::xs => if v = v' then SOME x
    4.77 +		      else myassoc2 xs v;
    4.78 +
    4.79 +fun term_of_i vs t =
    4.80 +    case t of 
    4.81 +	Cst i => CooperDec.mk_numeral i
    4.82 +      | Var n => valOf (myassoc2 vs n)
    4.83 +      | Neg t' => Const("uminus",iT --> iT)$(term_of_i vs t')
    4.84 +      | Add(t1,t2) => Const("op +",[iT,iT] ---> iT)$
    4.85 +			   (term_of_i vs t1)$(term_of_i vs t2)
    4.86 +      | Sub(t1,t2) => Const("op -",[iT,iT] ---> iT)$
    4.87 +			   (term_of_i vs t1)$(term_of_i vs t2)
    4.88 +      | Mult(t1,t2) => Const("op *",[iT,iT] ---> iT)$
    4.89 +			   (term_of_i vs t1)$(term_of_i vs t2);
    4.90 +
    4.91 +fun term_of_qf vs t = 
    4.92 +    case t of 
    4.93 +	T => HOLogic.true_const 
    4.94 +      | F => HOLogic.false_const
    4.95 +      | Lt(t1,t2) => Const("op <",[iT,iT] ---> bT)$
    4.96 +			   (term_of_i vs t1)$(term_of_i vs t2)
    4.97 +      | Le(t1,t2) => Const("op <=",[iT,iT] ---> bT)$
    4.98 +			  (term_of_i vs t1)$(term_of_i vs t2)
    4.99 +      | Gt(t1,t2) => Const("op <",[iT,iT] ---> bT)$
   4.100 +			   (term_of_i vs t2)$(term_of_i vs t1)
   4.101 +      | Ge(t1,t2) => Const("op <=",[iT,iT] ---> bT)$
   4.102 +			  (term_of_i vs t2)$(term_of_i vs t1)
   4.103 +      | Eq(t1,t2) => Const("op =",[iT,iT] ---> bT)$
   4.104 +			   (term_of_i vs t1)$(term_of_i vs t2)
   4.105 +      | Divides(t1,t2) => Const("Divides.op dvd",[iT,iT] ---> bT)$
   4.106 +			       (term_of_i vs t1)$(term_of_i vs t2)
   4.107 +      | NOT t' => HOLogic.Not$(term_of_qf vs t')
   4.108 +      | And(t1,t2) => HOLogic.conj$(term_of_qf vs t1)$(term_of_qf vs t2)
   4.109 +      | Or(t1,t2) => HOLogic.disj$(term_of_qf vs t1)$(term_of_qf vs t2)
   4.110 +      | Imp(t1,t2) => HOLogic.imp$(term_of_qf vs t1)$(term_of_qf vs t2)
   4.111 +      | Equ(t1,t2) => (HOLogic.eq_const bT)$(term_of_qf vs t1)$
   4.112 +					   (term_of_qf vs t2)
   4.113 +      | _ => error "If this is raised, Isabelle/HOL or generate_code is inconsistent!";
   4.114 +
   4.115 +(* The oracle *)
   4.116 + exception COOPER; 
   4.117 +
   4.118 +fun presburger_oracle thy t =
   4.119 +    let val vs = start_vs t
   4.120 +	val result = lift_un (term_of_qf vs) (pa (qf_of_term vs t))
   4.121 +    in 
   4.122 +    case result of 
   4.123 +	None => raise COOPER
   4.124 +      | Some t' => HOLogic.mk_Trueprop (HOLogic.mk_eq(t,t'))
   4.125 +    end ;
   4.126 + 
   4.127 +end;
   4.128 \ No newline at end of file
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/HOL/Integ/reflected_presburger.ML	Wed Sep 14 17:25:52 2005 +0200
     5.3 @@ -0,0 +1,2172 @@
     5.4 +(* $Id$ *)
     5.5 +
     5.6 +    (* Caution: This file should not be modified. *)
     5.7 +    (* It is autmatically generated from HOL/ex/Reflected_Presburger.thy *)
     5.8 +fun nat i = if i < 0 then 0 else i;
     5.9 +structure Generated =
    5.10 +struct
    5.11 +
    5.12 +datatype intterm = Cst of int | Var of int | Neg of intterm
    5.13 +  | Add of intterm * intterm | Sub of intterm * intterm
    5.14 +  | Mult of intterm * intterm;
    5.15 +
    5.16 +datatype QF = Lt of intterm * intterm | Gt of intterm * intterm
    5.17 +  | Le of intterm * intterm | Ge of intterm * intterm | Eq of intterm * intterm
    5.18 +  | Divides of intterm * intterm | T | F | NOT of QF | And of QF * QF
    5.19 +  | Or of QF * QF | Imp of QF * QF | Equ of QF * QF | QAll of QF | QEx of QF;
    5.20 +
    5.21 +datatype 'a option = None | Some of 'a;
    5.22 +
    5.23 +fun lift_un c None = None
    5.24 +  | lift_un c (Some p) = Some (c p);
    5.25 +
    5.26 +fun lift_bin (c, (Some a, Some b)) = Some (c a b)
    5.27 +  | lift_bin (c, (None, y)) = None
    5.28 +  | lift_bin (c, (Some y, None)) = None;
    5.29 +
    5.30 +fun lift_qe qe None = None
    5.31 +  | lift_qe qe (Some p) = qe p;
    5.32 +
    5.33 +fun qelim (qe, QAll p) = lift_un NOT (lift_qe qe (lift_un NOT (qelim (qe, p))))
    5.34 +  | qelim (qe, QEx p) = lift_qe qe (qelim (qe, p))
    5.35 +  | qelim (qe, And (p, q)) =
    5.36 +    lift_bin ((fn x => fn xa => And (x, xa)), (qelim (qe, p), qelim (qe, q)))
    5.37 +  | qelim (qe, Or (p, q)) =
    5.38 +    lift_bin ((fn x => fn xa => Or (x, xa)), (qelim (qe, p), qelim (qe, q)))
    5.39 +  | qelim (qe, Imp (p, q)) =
    5.40 +    lift_bin ((fn x => fn xa => Imp (x, xa)), (qelim (qe, p), qelim (qe, q)))
    5.41 +  | qelim (qe, Equ (p, q)) =
    5.42 +    lift_bin ((fn x => fn xa => Equ (x, xa)), (qelim (qe, p), qelim (qe, q)))
    5.43 +  | qelim (qe, NOT p) = lift_un NOT (qelim (qe, p))
    5.44 +  | qelim (qe, Lt (w, x)) = Some (Lt (w, x))
    5.45 +  | qelim (qe, Gt (y, z)) = Some (Gt (y, z))
    5.46 +  | qelim (qe, Le (aa, ab)) = Some (Le (aa, ab))
    5.47 +  | qelim (qe, Ge (ac, ad)) = Some (Ge (ac, ad))
    5.48 +  | qelim (qe, Eq (ae, af)) = Some (Eq (ae, af))
    5.49 +  | qelim (qe, Divides (ag, ah)) = Some (Divides (ag, ah))
    5.50 +  | qelim (qe, T) = Some T
    5.51 +  | qelim (qe, F) = Some F;
    5.52 +
    5.53 +fun lin_mul (c, Cst i) = Cst (c * i)
    5.54 +  | lin_mul (c, Add (Mult (Cst c', Var n), r)) =
    5.55 +    (if (c = 0) then Cst 0
    5.56 +      else Add (Mult (Cst (c * c'), Var n), lin_mul (c, r)));
    5.57 +
    5.58 +fun op_60_def0 m n = ((m) < (n));
    5.59 +
    5.60 +fun op_60_61_def0 m n = not (op_60_def0 n m);
    5.61 +
    5.62 +fun lin_add (Add (Mult (Cst c1, Var n1), r1), Add (Mult (Cst c2, Var n2), r2)) =
    5.63 +    (if (n1 = n2)
    5.64 +      then let val c = Cst (c1 + c2)
    5.65 +           in (if ((c1 + c2) = 0) then lin_add (r1, r2)
    5.66 +                else Add (Mult (c, Var n1), lin_add (r1, r2)))
    5.67 +           end
    5.68 +      else (if op_60_61_def0 n1 n2
    5.69 +             then Add (Mult (Cst c1, Var n1),
    5.70 +                        lin_add (r1, Add (Mult (Cst c2, Var n2), r2)))
    5.71 +             else Add (Mult (Cst c2, Var n2),
    5.72 +                        lin_add (Add (Mult (Cst c1, Var n1), r1), r2))))
    5.73 +  | lin_add (Add (Mult (Cst c1, Var n1), r1), Cst b) =
    5.74 +    Add (Mult (Cst c1, Var n1), lin_add (r1, Cst b))
    5.75 +  | lin_add (Cst x, Add (Mult (Cst c2, Var n2), r2)) =
    5.76 +    Add (Mult (Cst c2, Var n2), lin_add (Cst x, r2))
    5.77 +  | lin_add (Cst b1, Cst b2) = Cst (b1 + b2);
    5.78 +
    5.79 +fun lin_neg i = lin_mul (~1, i);
    5.80 +
    5.81 +fun linearize (Cst b) = Some (Cst b)
    5.82 +  | linearize (Var n) = Some (Add (Mult (Cst 1, Var n), Cst 0))
    5.83 +  | linearize (Neg i) = lift_un lin_neg (linearize i)
    5.84 +  | linearize (Add (i, j)) =
    5.85 +    lift_bin ((fn x => fn y => lin_add (x, y)), (linearize i, linearize j))
    5.86 +  | linearize (Sub (i, j)) =
    5.87 +    lift_bin
    5.88 +      ((fn x => fn y => lin_add (x, lin_neg y)), (linearize i, linearize j))
    5.89 +  | linearize (Mult (i, j)) =
    5.90 +    (case linearize i of None => None
    5.91 +      | Some x =>
    5.92 +          (case x of
    5.93 +            Cst xa =>
    5.94 +              (case linearize j of None => None
    5.95 +                | Some x => Some (lin_mul (xa, x)))
    5.96 +            | Var xa =>
    5.97 +                (case linearize j of None => None
    5.98 +                  | Some xa =>
    5.99 +                      (case xa of Cst xa => Some (lin_mul (xa, x))
   5.100 +                        | Var xa => None | Neg xa => None | Add (xa, xb) => None
   5.101 +                        | Sub (xa, xb) => None | Mult (xa, xb) => None))
   5.102 +            | Neg xa =>
   5.103 +                (case linearize j of None => None
   5.104 +                  | Some xa =>
   5.105 +                      (case xa of Cst xa => Some (lin_mul (xa, x))
   5.106 +                        | Var xa => None | Neg xa => None | Add (xa, xb) => None
   5.107 +                        | Sub (xa, xb) => None | Mult (xa, xb) => None))
   5.108 +            | Add (xa, xb) =>
   5.109 +                (case linearize j of None => None
   5.110 +                  | Some xa =>
   5.111 +                      (case xa of Cst xa => Some (lin_mul (xa, x))
   5.112 +                        | Var xa => None | Neg xa => None | Add (xa, xb) => None
   5.113 +                        | Sub (xa, xb) => None | Mult (xa, xb) => None))
   5.114 +            | Sub (xa, xb) =>
   5.115 +                (case linearize j of None => None
   5.116 +                  | Some xa =>
   5.117 +                      (case xa of Cst xa => Some (lin_mul (xa, x))
   5.118 +                        | Var xa => None | Neg xa => None | Add (xa, xb) => None
   5.119 +                        | Sub (xa, xb) => None | Mult (xa, xb) => None))
   5.120 +            | Mult (xa, xb) =>
   5.121 +                (case linearize j of None => None
   5.122 +                  | Some xa =>
   5.123 +                      (case xa of Cst xa => Some (lin_mul (xa, x))
   5.124 +                        | Var xa => None | Neg xa => None | Add (xa, xb) => None
   5.125 +                        | Sub (xa, xb) => None | Mult (xa, xb) => None))));
   5.126 +
   5.127 +fun linform (Le (it1, it2)) =
   5.128 +    lift_bin
   5.129 +      ((fn x => fn y => Le (lin_add (x, lin_neg y), Cst 0)),
   5.130 +        (linearize it1, linearize it2))
   5.131 +  | linform (Eq (it1, it2)) =
   5.132 +    lift_bin
   5.133 +      ((fn x => fn y => Eq (lin_add (x, lin_neg y), Cst 0)),
   5.134 +        (linearize it1, linearize it2))
   5.135 +  | linform (Divides (d, t)) =
   5.136 +    (case linearize d of None => None
   5.137 +      | Some x =>
   5.138 +          (case x of
   5.139 +            Cst xa =>
   5.140 +              (if (xa = 0) then None
   5.141 +                else (case linearize t of None => None
   5.142 +                       | Some xa => Some (Divides (x, xa))))
   5.143 +            | Var xa => None | Neg xa => None | Add (xa, xb) => None
   5.144 +            | Sub (xa, xb) => None | Mult (xa, xb) => None))
   5.145 +  | linform T = Some T
   5.146 +  | linform F = Some F
   5.147 +  | linform (NOT p) = lift_un NOT (linform p)
   5.148 +  | linform (And (p, q)) =
   5.149 +    lift_bin ((fn f => fn g => And (f, g)), (linform p, linform q))
   5.150 +  | linform (Or (p, q)) =
   5.151 +    lift_bin ((fn f => fn g => Or (f, g)), (linform p, linform q));
   5.152 +
   5.153 +fun nnf (Lt (it1, it2)) = Le (Sub (it1, it2), Cst (~ 1))
   5.154 +  | nnf (Gt (it1, it2)) = Le (Sub (it2, it1), Cst (~ 1))
   5.155 +  | nnf (Le (it1, it2)) = Le (it1, it2)
   5.156 +  | nnf (Ge (it1, it2)) = Le (it2, it1)
   5.157 +  | nnf (Eq (it1, it2)) = Eq (it2, it1)
   5.158 +  | nnf (Divides (d, t)) = Divides (d, t)
   5.159 +  | nnf T = T
   5.160 +  | nnf F = F
   5.161 +  | nnf (And (p, q)) = And (nnf p, nnf q)
   5.162 +  | nnf (Or (p, q)) = Or (nnf p, nnf q)
   5.163 +  | nnf (Imp (p, q)) = Or (nnf (NOT p), nnf q)
   5.164 +  | nnf (Equ (p, q)) = Or (And (nnf p, nnf q), And (nnf (NOT p), nnf (NOT q)))
   5.165 +  | nnf (NOT (Lt (it1, it2))) = Le (it2, it1)
   5.166 +  | nnf (NOT (Gt (it1, it2))) = Le (it1, it2)
   5.167 +  | nnf (NOT (Le (it1, it2))) = Le (Sub (it2, it1), Cst (~ 1))
   5.168 +  | nnf (NOT (Ge (it1, it2))) = Le (Sub (it1, it2), Cst (~ 1))
   5.169 +  | nnf (NOT (Eq (it1, it2))) = NOT (Eq (it1, it2))
   5.170 +  | nnf (NOT (Divides (d, t))) = NOT (Divides (d, t))
   5.171 +  | nnf (NOT T) = F
   5.172 +  | nnf (NOT F) = T
   5.173 +  | nnf (NOT (NOT p)) = nnf p
   5.174 +  | nnf (NOT (And (p, q))) = Or (nnf (NOT p), nnf (NOT q))
   5.175 +  | nnf (NOT (Or (p, q))) = And (nnf (NOT p), nnf (NOT q))
   5.176 +  | nnf (NOT (Imp (p, q))) = And (nnf p, nnf (NOT q))
   5.177 +  | nnf (NOT (Equ (p, q))) =
   5.178 +    Or (And (nnf p, nnf (NOT q)), And (nnf (NOT p), nnf q));
   5.179 +
   5.180 +fun op_45_def2 z w = (z + ~ w);
   5.181 +
   5.182 +fun op_45_def0 m n = nat (op_45_def2 (m) (n));
   5.183 +
   5.184 +val id_1_def0 : int = (0 + 1);
   5.185 +
   5.186 +fun decrvarsI (Cst i) = Cst i
   5.187 +  | decrvarsI (Var n) = Var (op_45_def0 n id_1_def0)
   5.188 +  | decrvarsI (Neg a) = Neg (decrvarsI a)
   5.189 +  | decrvarsI (Add (a, b)) = Add (decrvarsI a, decrvarsI b)
   5.190 +  | decrvarsI (Sub (a, b)) = Sub (decrvarsI a, decrvarsI b)
   5.191 +  | decrvarsI (Mult (a, b)) = Mult (decrvarsI a, decrvarsI b);
   5.192 +
   5.193 +fun decrvars (Lt (a, b)) = Lt (decrvarsI a, decrvarsI b)
   5.194 +  | decrvars (Gt (a, b)) = Gt (decrvarsI a, decrvarsI b)
   5.195 +  | decrvars (Le (a, b)) = Le (decrvarsI a, decrvarsI b)
   5.196 +  | decrvars (Ge (a, b)) = Ge (decrvarsI a, decrvarsI b)
   5.197 +  | decrvars (Eq (a, b)) = Eq (decrvarsI a, decrvarsI b)
   5.198 +  | decrvars (Divides (a, b)) = Divides (decrvarsI a, decrvarsI b)
   5.199 +  | decrvars T = T
   5.200 +  | decrvars F = F
   5.201 +  | decrvars (NOT p) = NOT (decrvars p)
   5.202 +  | decrvars (And (p, q)) = And (decrvars p, decrvars q)
   5.203 +  | decrvars (Or (p, q)) = Or (decrvars p, decrvars q)
   5.204 +  | decrvars (Imp (p, q)) = Imp (decrvars p, decrvars q)
   5.205 +  | decrvars (Equ (p, q)) = Equ (decrvars p, decrvars q);
   5.206 +
   5.207 +fun op_64 [] ys = ys
   5.208 +  | op_64 (x :: xs) ys = (x :: op_64 xs ys);
   5.209 +
   5.210 +fun map f [] = []
   5.211 +  | map f (x :: xs) = (f x :: map f xs);
   5.212 +
   5.213 +fun iupto (i, j) = (if (j < i) then [] else (i :: iupto ((i + 1), j)));
   5.214 +
   5.215 +fun all_sums (j, []) = []
   5.216 +  | all_sums (j, (i :: is)) =
   5.217 +    op_64 (map (fn x => lin_add (i, Cst x)) (iupto (1, j))) (all_sums (j, is));
   5.218 +
   5.219 +fun split x = (fn p => x (fst p) (snd p));
   5.220 +
   5.221 +fun negateSnd x = split (fn q => fn r => (q, ~ r)) x;
   5.222 +
   5.223 +fun adjust b =
   5.224 +  (fn (q, r) =>
   5.225 +    (if (0 <= op_45_def2 r b) then (((2 * q) + 1), op_45_def2 r b)
   5.226 +      else ((2 * q), r)));
   5.227 +
   5.228 +fun negDivAlg (a, b) =
   5.229 +    (if ((0 <= (a + b)) orelse (b <= 0)) then (~1, (a + b))
   5.230 +      else adjust b (negDivAlg (a, (2 * b))));
   5.231 +
   5.232 +fun posDivAlg (a, b) =
   5.233 +    (if ((a < b) orelse (b <= 0)) then (0, a)
   5.234 +      else adjust b (posDivAlg (a, (2 * b))));
   5.235 +
   5.236 +fun divAlg x =
   5.237 +  split (fn a => fn b =>
   5.238 +          (if (0 <= a)
   5.239 +            then (if (0 <= b) then posDivAlg (a, b)
   5.240 +                   else (if (a = 0) then (0, 0)
   5.241 +                          else negateSnd (negDivAlg (~ a, ~ b))))
   5.242 +            else (if (0 < b) then negDivAlg (a, b)
   5.243 +                   else negateSnd (posDivAlg (~ a, ~ b)))))
   5.244 +    x;
   5.245 +
   5.246 +fun op_mod_def1 a b = snd (divAlg (a, b));
   5.247 +
   5.248 +fun op_dvd m n = (op_mod_def1 n m = 0);
   5.249 +
   5.250 +fun psimpl (Le (l, r)) =
   5.251 +    (case lift_bin
   5.252 +            ((fn x => fn y => lin_add (x, lin_neg y)),
   5.253 +              (linearize l, linearize r)) of
   5.254 +      None => Le (l, r)
   5.255 +      | Some x =>
   5.256 +          (case x of Cst xa => (if (xa <= 0) then T else F)
   5.257 +            | Var xa => Le (x, Cst 0) | Neg xa => Le (x, Cst 0)
   5.258 +            | Add (xa, xb) => Le (x, Cst 0) | Sub (xa, xb) => Le (x, Cst 0)
   5.259 +            | Mult (xa, xb) => Le (x, Cst 0)))
   5.260 +  | psimpl (Eq (l, r)) =
   5.261 +    (case lift_bin
   5.262 +            ((fn x => fn y => lin_add (x, lin_neg y)),
   5.263 +              (linearize l, linearize r)) of
   5.264 +      None => Eq (l, r)
   5.265 +      | Some x =>
   5.266 +          (case x of Cst xa => (if (xa = 0) then T else F)
   5.267 +            | Var xa => Eq (x, Cst 0) | Neg xa => Eq (x, Cst 0)
   5.268 +            | Add (xa, xb) => Eq (x, Cst 0) | Sub (xa, xb) => Eq (x, Cst 0)
   5.269 +            | Mult (xa, xb) => Eq (x, Cst 0)))
   5.270 +  | psimpl (Divides (Cst d, t)) =
   5.271 +    (case linearize t of None => Divides (Cst d, t)
   5.272 +      | Some x =>
   5.273 +          (case x of Cst xa => (if op_dvd d xa then T else F)
   5.274 +            | Var xa => Divides (Cst d, x) | Neg xa => Divides (Cst d, x)
   5.275 +            | Add (xa, xb) => Divides (Cst d, x)
   5.276 +            | Sub (xa, xb) => Divides (Cst d, x)
   5.277 +            | Mult (xa, xb) => Divides (Cst d, x)))
   5.278 +  | psimpl (Equ (p, q)) =
   5.279 +    let val p' = psimpl p; val q' = psimpl q
   5.280 +    in (case p' of
   5.281 +         Lt (x, xa) =>
   5.282 +           (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
   5.283 +             | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
   5.284 +             | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
   5.285 +             | T => p' | F => NOT p' | NOT x => Equ (p', q')
   5.286 +             | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
   5.287 +             | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
   5.288 +             | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
   5.289 +         | Gt (x, xa) =>
   5.290 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
   5.291 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
   5.292 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
   5.293 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
   5.294 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
   5.295 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
   5.296 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
   5.297 +         | Le (x, xa) =>
   5.298 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
   5.299 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
   5.300 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
   5.301 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
   5.302 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
   5.303 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
   5.304 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
   5.305 +         | Ge (x, xa) =>
   5.306 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
   5.307 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
   5.308 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
   5.309 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
   5.310 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
   5.311 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
   5.312 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
   5.313 +         | Eq (x, xa) =>
   5.314 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
   5.315 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
   5.316 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
   5.317 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
   5.318 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
   5.319 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
   5.320 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
   5.321 +         | Divides (x, xa) =>
   5.322 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
   5.323 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
   5.324 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
   5.325 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
   5.326 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
   5.327 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
   5.328 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
   5.329 +         | T => q'
   5.330 +         | F => (case q' of Lt (x, xa) => NOT q' | Gt (x, xa) => NOT q'
   5.331 +                  | Le (x, xa) => NOT q' | Ge (x, xa) => NOT q'
   5.332 +                  | Eq (x, xa) => NOT q' | Divides (x, xa) => NOT q' | T => F
   5.333 +                  | F => T | NOT x => x | And (x, xa) => NOT q'
   5.334 +                  | Or (x, xa) => NOT q' | Imp (x, xa) => NOT q'
   5.335 +                  | Equ (x, xa) => NOT q' | QAll x => NOT q' | QEx x => NOT q')
   5.336 +         | NOT x =>
   5.337 +             (case q' of Lt (xa, xb) => Equ (p', q')
   5.338 +               | Gt (xa, xb) => Equ (p', q') | Le (xa, xb) => Equ (p', q')
   5.339 +               | Ge (xa, xb) => Equ (p', q') | Eq (xa, xb) => Equ (p', q')
   5.340 +               | Divides (xa, xb) => Equ (p', q') | T => p' | F => x
   5.341 +               | NOT xa => Equ (x, xa) | And (xa, xb) => Equ (p', q')
   5.342 +               | Or (xa, xb) => Equ (p', q') | Imp (xa, xb) => Equ (p', q')
   5.343 +               | Equ (xa, xb) => Equ (p', q') | QAll xa => Equ (p', q')
   5.344 +               | QEx xa => Equ (p', q'))
   5.345 +         | And (x, xa) =>
   5.346 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
   5.347 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
   5.348 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
   5.349 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
   5.350 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
   5.351 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
   5.352 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
   5.353 +         | Or (x, xa) =>
   5.354 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
   5.355 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
   5.356 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
   5.357 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
   5.358 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
   5.359 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
   5.360 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
   5.361 +         | Imp (x, xa) =>
   5.362 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
   5.363 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
   5.364 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
   5.365 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
   5.366 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
   5.367 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
   5.368 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
   5.369 +         | Equ (x, xa) =>
   5.370 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
   5.371 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
   5.372 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
   5.373 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
   5.374 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
   5.375 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
   5.376 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
   5.377 +         | QAll x =>
   5.378 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
   5.379 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
   5.380 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
   5.381 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
   5.382 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
   5.383 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
   5.384 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
   5.385 +         | QEx x =>
   5.386 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
   5.387 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
   5.388 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
   5.389 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
   5.390 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
   5.391 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
   5.392 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q')))
   5.393 +    end
   5.394 +  | psimpl (NOT p) =
   5.395 +    let val p' = psimpl p
   5.396 +    in (case p' of Lt (x, xa) => NOT p' | Gt (x, xa) => NOT p'
   5.397 +         | Le (x, xa) => NOT p' | Ge (x, xa) => NOT p' | Eq (x, xa) => NOT p'
   5.398 +         | Divides (x, xa) => NOT p' | T => F | F => T | NOT x => x
   5.399 +         | And (x, xa) => NOT p' | Or (x, xa) => NOT p' | Imp (x, xa) => NOT p'
   5.400 +         | Equ (x, xa) => NOT p' | QAll x => NOT p' | QEx x => NOT p')
   5.401 +    end
   5.402 +  | psimpl (Lt (u, v)) = Lt (u, v)
   5.403 +  | psimpl (Gt (w, x)) = Gt (w, x)
   5.404 +  | psimpl (Ge (aa, ab)) = Ge (aa, ab)
   5.405 +  | psimpl (Divides (Var bp, af)) = Divides (Var bp, af)
   5.406 +  | psimpl (Divides (Neg bq, af)) = Divides (Neg bq, af)
   5.407 +  | psimpl (Divides (Add (br, bs), af)) = Divides (Add (br, bs), af)
   5.408 +  | psimpl (Divides (Sub (bt, bu), af)) = Divides (Sub (bt, bu), af)
   5.409 +  | psimpl (Divides (Mult (bv, bw), af)) = Divides (Mult (bv, bw), af)
   5.410 +  | psimpl T = T
   5.411 +  | psimpl F = F
   5.412 +  | psimpl (QAll ap) = QAll ap
   5.413 +  | psimpl (QEx aq) = QEx aq
   5.414 +  | psimpl (And (p, q)) =
   5.415 +    let val p' = psimpl p
   5.416 +    in (case p' of
   5.417 +         Lt (x, xa) =>
   5.418 +           let val q' = psimpl q
   5.419 +           in (case q' of Lt (x, xa) => And (p', q')
   5.420 +                | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
   5.421 +                | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
   5.422 +                | Divides (x, xa) => And (p', q') | T => p' | F => F
   5.423 +                | NOT x => And (p', q') | And (x, xa) => And (p', q')
   5.424 +                | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
   5.425 +                | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
   5.426 +                | QEx x => And (p', q'))
   5.427 +           end
   5.428 +         | Gt (x, xa) =>
   5.429 +             let val q' = psimpl q
   5.430 +             in (case q' of Lt (x, xa) => And (p', q')
   5.431 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
   5.432 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
   5.433 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
   5.434 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
   5.435 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
   5.436 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
   5.437 +                  | QEx x => And (p', q'))
   5.438 +             end
   5.439 +         | Le (x, xa) =>
   5.440 +             let val q' = psimpl q
   5.441 +             in (case q' of Lt (x, xa) => And (p', q')
   5.442 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
   5.443 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
   5.444 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
   5.445 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
   5.446 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
   5.447 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
   5.448 +                  | QEx x => And (p', q'))
   5.449 +             end
   5.450 +         | Ge (x, xa) =>
   5.451 +             let val q' = psimpl q
   5.452 +             in (case q' of Lt (x, xa) => And (p', q')
   5.453 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
   5.454 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
   5.455 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
   5.456 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
   5.457 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
   5.458 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
   5.459 +                  | QEx x => And (p', q'))
   5.460 +             end
   5.461 +         | Eq (x, xa) =>
   5.462 +             let val q' = psimpl q
   5.463 +             in (case q' of Lt (x, xa) => And (p', q')
   5.464 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
   5.465 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
   5.466 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
   5.467 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
   5.468 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
   5.469 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
   5.470 +                  | QEx x => And (p', q'))
   5.471 +             end
   5.472 +         | Divides (x, xa) =>
   5.473 +             let val q' = psimpl q
   5.474 +             in (case q' of Lt (x, xa) => And (p', q')
   5.475 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
   5.476 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
   5.477 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
   5.478 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
   5.479 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
   5.480 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
   5.481 +                  | QEx x => And (p', q'))
   5.482 +             end
   5.483 +         | T => psimpl q | F => F
   5.484 +         | NOT x =>
   5.485 +             let val q' = psimpl q
   5.486 +             in (case q' of Lt (x, xa) => And (p', q')
   5.487 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
   5.488 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
   5.489 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
   5.490 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
   5.491 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
   5.492 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
   5.493 +                  | QEx x => And (p', q'))
   5.494 +             end
   5.495 +         | And (x, xa) =>
   5.496 +             let val q' = psimpl q
   5.497 +             in (case q' of Lt (x, xa) => And (p', q')
   5.498 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
   5.499 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
   5.500 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
   5.501 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
   5.502 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
   5.503 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
   5.504 +                  | QEx x => And (p', q'))
   5.505 +             end
   5.506 +         | Or (x, xa) =>
   5.507 +             let val q' = psimpl q
   5.508 +             in (case q' of Lt (x, xa) => And (p', q')
   5.509 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
   5.510 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
   5.511 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
   5.512 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
   5.513 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
   5.514 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
   5.515 +                  | QEx x => And (p', q'))
   5.516 +             end
   5.517 +         | Imp (x, xa) =>
   5.518 +             let val q' = psimpl q
   5.519 +             in (case q' of Lt (x, xa) => And (p', q')
   5.520 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
   5.521 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
   5.522 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
   5.523 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
   5.524 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
   5.525 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
   5.526 +                  | QEx x => And (p', q'))
   5.527 +             end
   5.528 +         | Equ (x, xa) =>
   5.529 +             let val q' = psimpl q
   5.530 +             in (case q' of Lt (x, xa) => And (p', q')
   5.531 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
   5.532 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
   5.533 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
   5.534 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
   5.535 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
   5.536 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
   5.537 +                  | QEx x => And (p', q'))
   5.538 +             end
   5.539 +         | QAll x =>
   5.540 +             let val q' = psimpl q
   5.541 +             in (case q' of Lt (x, xa) => And (p', q')
   5.542 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
   5.543 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
   5.544 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
   5.545 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
   5.546 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
   5.547 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
   5.548 +                  | QEx x => And (p', q'))
   5.549 +             end
   5.550 +         | QEx x =>
   5.551 +             let val q' = psimpl q
   5.552 +             in (case q' of Lt (x, xa) => And (p', q')
   5.553 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
   5.554 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
   5.555 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
   5.556 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
   5.557 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
   5.558 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
   5.559 +                  | QEx x => And (p', q'))
   5.560 +             end)
   5.561 +    end
   5.562 +  | psimpl (Or (p, q)) =
   5.563 +    let val p' = psimpl p
   5.564 +    in (case p' of
   5.565 +         Lt (x, xa) =>
   5.566 +           let val q' = psimpl q
   5.567 +           in (case q' of Lt (x, xa) => Or (p', q') | Gt (x, xa) => Or (p', q')
   5.568 +                | Le (x, xa) => Or (p', q') | Ge (x, xa) => Or (p', q')
   5.569 +                | Eq (x, xa) => Or (p', q') | Divides (x, xa) => Or (p', q')
   5.570 +                | T => T | F => p' | NOT x => Or (p', q')
   5.571 +                | And (x, xa) => Or (p', q') | Or (x, xa) => Or (p', q')
   5.572 +                | Imp (x, xa) => Or (p', q') | Equ (x, xa) => Or (p', q')
   5.573 +                | QAll x => Or (p', q') | QEx x => Or (p', q'))
   5.574 +           end
   5.575 +         | Gt (x, xa) =>
   5.576 +             let val q' = psimpl q
   5.577 +             in (case q' of Lt (x, xa) => Or (p', q')
   5.578 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
   5.579 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
   5.580 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
   5.581 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
   5.582 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
   5.583 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
   5.584 +                  | QEx x => Or (p', q'))
   5.585 +             end
   5.586 +         | Le (x, xa) =>
   5.587 +             let val q' = psimpl q
   5.588 +             in (case q' of Lt (x, xa) => Or (p', q')
   5.589 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
   5.590 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
   5.591 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
   5.592 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
   5.593 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
   5.594 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
   5.595 +                  | QEx x => Or (p', q'))
   5.596 +             end
   5.597 +         | Ge (x, xa) =>
   5.598 +             let val q' = psimpl q
   5.599 +             in (case q' of Lt (x, xa) => Or (p', q')
   5.600 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
   5.601 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
   5.602 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
   5.603 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
   5.604 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
   5.605 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
   5.606 +                  | QEx x => Or (p', q'))
   5.607 +             end
   5.608 +         | Eq (x, xa) =>
   5.609 +             let val q' = psimpl q
   5.610 +             in (case q' of Lt (x, xa) => Or (p', q')
   5.611 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
   5.612 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
   5.613 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
   5.614 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
   5.615 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
   5.616 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
   5.617 +                  | QEx x => Or (p', q'))
   5.618 +             end
   5.619 +         | Divides (x, xa) =>
   5.620 +             let val q' = psimpl q
   5.621 +             in (case q' of Lt (x, xa) => Or (p', q')
   5.622 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
   5.623 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
   5.624 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
   5.625 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
   5.626 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
   5.627 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
   5.628 +                  | QEx x => Or (p', q'))
   5.629 +             end
   5.630 +         | T => T | F => psimpl q
   5.631 +         | NOT x =>
   5.632 +             let val q' = psimpl q
   5.633 +             in (case q' of Lt (x, xa) => Or (p', q')
   5.634 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
   5.635 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
   5.636 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
   5.637 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
   5.638 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
   5.639 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
   5.640 +                  | QEx x => Or (p', q'))
   5.641 +             end
   5.642 +         | And (x, xa) =>
   5.643 +             let val q' = psimpl q
   5.644 +             in (case q' of Lt (x, xa) => Or (p', q')
   5.645 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
   5.646 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
   5.647 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
   5.648 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
   5.649 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
   5.650 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
   5.651 +                  | QEx x => Or (p', q'))
   5.652 +             end
   5.653 +         | Or (x, xa) =>
   5.654 +             let val q' = psimpl q
   5.655 +             in (case q' of Lt (x, xa) => Or (p', q')
   5.656 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
   5.657 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
   5.658 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
   5.659 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
   5.660 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
   5.661 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
   5.662 +                  | QEx x => Or (p', q'))
   5.663 +             end
   5.664 +         | Imp (x, xa) =>
   5.665 +             let val q' = psimpl q
   5.666 +             in (case q' of Lt (x, xa) => Or (p', q')
   5.667 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
   5.668 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
   5.669 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
   5.670 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
   5.671 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
   5.672 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
   5.673 +                  | QEx x => Or (p', q'))
   5.674 +             end
   5.675 +         | Equ (x, xa) =>
   5.676 +             let val q' = psimpl q
   5.677 +             in (case q' of Lt (x, xa) => Or (p', q')
   5.678 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
   5.679 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
   5.680 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
   5.681 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
   5.682 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
   5.683 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
   5.684 +                  | QEx x => Or (p', q'))
   5.685 +             end
   5.686 +         | QAll x =>
   5.687 +             let val q' = psimpl q
   5.688 +             in (case q' of Lt (x, xa) => Or (p', q')
   5.689 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
   5.690 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
   5.691 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
   5.692 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
   5.693 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
   5.694 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
   5.695 +                  | QEx x => Or (p', q'))
   5.696 +             end
   5.697 +         | QEx x =>
   5.698 +             let val q' = psimpl q
   5.699 +             in (case q' of Lt (x, xa) => Or (p', q')
   5.700 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
   5.701 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
   5.702 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
   5.703 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
   5.704 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
   5.705 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
   5.706 +                  | QEx x => Or (p', q'))
   5.707 +             end)
   5.708 +    end
   5.709 +  | psimpl (Imp (p, q)) =
   5.710 +    let val p' = psimpl p
   5.711 +    in (case p' of
   5.712 +         Lt (x, xa) =>
   5.713 +           let val q' = psimpl q
   5.714 +           in (case q' of Lt (x, xa) => Imp (p', q')
   5.715 +                | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
   5.716 +                | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
   5.717 +                | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
   5.718 +                | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
   5.719 +                | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
   5.720 +                | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
   5.721 +                | QEx x => Imp (p', q'))
   5.722 +           end
   5.723 +         | Gt (x, xa) =>
   5.724 +             let val q' = psimpl q
   5.725 +             in (case q' of Lt (x, xa) => Imp (p', q')
   5.726 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
   5.727 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
   5.728 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
   5.729 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
   5.730 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
   5.731 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
   5.732 +                  | QEx x => Imp (p', q'))
   5.733 +             end
   5.734 +         | Le (x, xa) =>
   5.735 +             let val q' = psimpl q
   5.736 +             in (case q' of Lt (x, xa) => Imp (p', q')
   5.737 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
   5.738 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
   5.739 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
   5.740 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
   5.741 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
   5.742 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
   5.743 +                  | QEx x => Imp (p', q'))
   5.744 +             end
   5.745 +         | Ge (x, xa) =>
   5.746 +             let val q' = psimpl q
   5.747 +             in (case q' of Lt (x, xa) => Imp (p', q')
   5.748 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
   5.749 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
   5.750 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
   5.751 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
   5.752 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
   5.753 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
   5.754 +                  | QEx x => Imp (p', q'))
   5.755 +             end
   5.756 +         | Eq (x, xa) =>
   5.757 +             let val q' = psimpl q
   5.758 +             in (case q' of Lt (x, xa) => Imp (p', q')
   5.759 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
   5.760 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
   5.761 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
   5.762 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
   5.763 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
   5.764 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
   5.765 +                  | QEx x => Imp (p', q'))
   5.766 +             end
   5.767 +         | Divides (x, xa) =>
   5.768 +             let val q' = psimpl q
   5.769 +             in (case q' of Lt (x, xa) => Imp (p', q')
   5.770 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
   5.771 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
   5.772 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
   5.773 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
   5.774 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
   5.775 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
   5.776 +                  | QEx x => Imp (p', q'))
   5.777 +             end
   5.778 +         | T => psimpl q | F => T
   5.779 +         | NOT x =>
   5.780 +             let val q' = psimpl q
   5.781 +             in (case q' of Lt (xa, xb) => Or (x, q')
   5.782 +                  | Gt (xa, xb) => Or (x, q') | Le (xa, xb) => Or (x, q')
   5.783 +                  | Ge (xa, xb) => Or (x, q') | Eq (xa, xb) => Or (x, q')
   5.784 +                  | Divides (xa, xb) => Or (x, q') | T => T | F => x
   5.785 +                  | NOT xa => Or (x, q') | And (xa, xb) => Or (x, q')
   5.786 +                  | Or (xa, xb) => Or (x, q') | Imp (xa, xb) => Or (x, q')
   5.787 +                  | Equ (xa, xb) => Or (x, q') | QAll xa => Or (x, q')
   5.788 +                  | QEx xa => Or (x, q'))
   5.789 +             end
   5.790 +         | And (x, xa) =>
   5.791 +             let val q' = psimpl q
   5.792 +             in (case q' of Lt (x, xa) => Imp (p', q')
   5.793 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
   5.794 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
   5.795 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
   5.796 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
   5.797 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
   5.798 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
   5.799 +                  | QEx x => Imp (p', q'))
   5.800 +             end
   5.801 +         | Or (x, xa) =>
   5.802 +             let val q' = psimpl q
   5.803 +             in (case q' of Lt (x, xa) => Imp (p', q')
   5.804 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
   5.805 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
   5.806 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
   5.807 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
   5.808 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
   5.809 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
   5.810 +                  | QEx x => Imp (p', q'))
   5.811 +             end
   5.812 +         | Imp (x, xa) =>
   5.813 +             let val q' = psimpl q
   5.814 +             in (case q' of Lt (x, xa) => Imp (p', q')
   5.815 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
   5.816 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
   5.817 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
   5.818 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
   5.819 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
   5.820 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
   5.821 +                  | QEx x => Imp (p', q'))
   5.822 +             end
   5.823 +         | Equ (x, xa) =>
   5.824 +             let val q' = psimpl q
   5.825 +             in (case q' of Lt (x, xa) => Imp (p', q')
   5.826 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
   5.827 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
   5.828 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
   5.829 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
   5.830 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
   5.831 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
   5.832 +                  | QEx x => Imp (p', q'))
   5.833 +             end
   5.834 +         | QAll x =>
   5.835 +             let val q' = psimpl q
   5.836 +             in (case q' of Lt (x, xa) => Imp (p', q')
   5.837 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
   5.838 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
   5.839 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
   5.840 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
   5.841 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
   5.842 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
   5.843 +                  | QEx x => Imp (p', q'))
   5.844 +             end
   5.845 +         | QEx x =>
   5.846 +             let val q' = psimpl q
   5.847 +             in (case q' of Lt (x, xa) => Imp (p', q')
   5.848 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
   5.849 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
   5.850 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
   5.851 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
   5.852 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
   5.853 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
   5.854 +                  | QEx x => Imp (p', q'))
   5.855 +             end)
   5.856 +    end;
   5.857 +
   5.858 +fun subst_it i (Cst b) = Cst b
   5.859 +  | subst_it i (Var n) = (if (n = 0) then i else Var n)
   5.860 +  | subst_it i (Neg it) = Neg (subst_it i it)
   5.861 +  | subst_it i (Add (it1, it2)) = Add (subst_it i it1, subst_it i it2)
   5.862 +  | subst_it i (Sub (it1, it2)) = Sub (subst_it i it1, subst_it i it2)
   5.863 +  | subst_it i (Mult (it1, it2)) = Mult (subst_it i it1, subst_it i it2);
   5.864 +
   5.865 +fun subst_p i (Le (it1, it2)) = Le (subst_it i it1, subst_it i it2)
   5.866 +  | subst_p i (Lt (it1, it2)) = Lt (subst_it i it1, subst_it i it2)
   5.867 +  | subst_p i (Ge (it1, it2)) = Ge (subst_it i it1, subst_it i it2)
   5.868 +  | subst_p i (Gt (it1, it2)) = Gt (subst_it i it1, subst_it i it2)
   5.869 +  | subst_p i (Eq (it1, it2)) = Eq (subst_it i it1, subst_it i it2)
   5.870 +  | subst_p i (Divides (d, t)) = Divides (subst_it i d, subst_it i t)
   5.871 +  | subst_p i T = T
   5.872 +  | subst_p i F = F
   5.873 +  | subst_p i (And (p, q)) = And (subst_p i p, subst_p i q)
   5.874 +  | subst_p i (Or (p, q)) = Or (subst_p i p, subst_p i q)
   5.875 +  | subst_p i (Imp (p, q)) = Imp (subst_p i p, subst_p i q)
   5.876 +  | subst_p i (Equ (p, q)) = Equ (subst_p i p, subst_p i q)
   5.877 +  | subst_p i (NOT p) = NOT (subst_p i p);
   5.878 +
   5.879 +fun explode_disj ([], p) = F
   5.880 +  | explode_disj ((i :: is), p) =
   5.881 +    let val pi = psimpl (subst_p i p)
   5.882 +    in (case pi of
   5.883 +         Lt (x, xa) =>
   5.884 +           let val r = explode_disj (is, p)
   5.885 +           in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
   5.886 +                | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
   5.887 +                | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
   5.888 +                | T => T | F => pi | NOT x => Or (pi, r)
   5.889 +                | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
   5.890 +                | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
   5.891 +                | QAll x => Or (pi, r) | QEx x => Or (pi, r))
   5.892 +           end
   5.893 +         | Gt (x, xa) =>
   5.894 +             let val r = explode_disj (is, p)
   5.895 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
   5.896 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
   5.897 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
   5.898 +                  | T => T | F => pi | NOT x => Or (pi, r)
   5.899 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
   5.900 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
   5.901 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
   5.902 +             end
   5.903 +         | Le (x, xa) =>
   5.904 +             let val r = explode_disj (is, p)
   5.905 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
   5.906 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
   5.907 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
   5.908 +                  | T => T | F => pi | NOT x => Or (pi, r)
   5.909 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
   5.910 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
   5.911 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
   5.912 +             end
   5.913 +         | Ge (x, xa) =>
   5.914 +             let val r = explode_disj (is, p)
   5.915 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
   5.916 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
   5.917 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
   5.918 +                  | T => T | F => pi | NOT x => Or (pi, r)
   5.919 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
   5.920 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
   5.921 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
   5.922 +             end
   5.923 +         | Eq (x, xa) =>
   5.924 +             let val r = explode_disj (is, p)
   5.925 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
   5.926 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
   5.927 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
   5.928 +                  | T => T | F => pi | NOT x => Or (pi, r)
   5.929 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
   5.930 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
   5.931 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
   5.932 +             end
   5.933 +         | Divides (x, xa) =>
   5.934 +             let val r = explode_disj (is, p)
   5.935 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
   5.936 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
   5.937 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
   5.938 +                  | T => T | F => pi | NOT x => Or (pi, r)
   5.939 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
   5.940 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
   5.941 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
   5.942 +             end
   5.943 +         | T => T | F => explode_disj (is, p)
   5.944 +         | NOT x =>
   5.945 +             let val r = explode_disj (is, p)
   5.946 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
   5.947 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
   5.948 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
   5.949 +                  | T => T | F => pi | NOT x => Or (pi, r)
   5.950 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
   5.951 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
   5.952 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
   5.953 +             end
   5.954 +         | And (x, xa) =>
   5.955 +             let val r = explode_disj (is, p)
   5.956 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
   5.957 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
   5.958 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
   5.959 +                  | T => T | F => pi | NOT x => Or (pi, r)
   5.960 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
   5.961 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
   5.962 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
   5.963 +             end
   5.964 +         | Or (x, xa) =>
   5.965 +             let val r = explode_disj (is, p)
   5.966 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
   5.967 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
   5.968 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
   5.969 +                  | T => T | F => pi | NOT x => Or (pi, r)
   5.970 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
   5.971 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
   5.972 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
   5.973 +             end
   5.974 +         | Imp (x, xa) =>
   5.975 +             let val r = explode_disj (is, p)
   5.976 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
   5.977 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
   5.978 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
   5.979 +                  | T => T | F => pi | NOT x => Or (pi, r)
   5.980 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
   5.981 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
   5.982 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
   5.983 +             end
   5.984 +         | Equ (x, xa) =>
   5.985 +             let val r = explode_disj (is, p)
   5.986 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
   5.987 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
   5.988 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
   5.989 +                  | T => T | F => pi | NOT x => Or (pi, r)
   5.990 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
   5.991 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
   5.992 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
   5.993 +             end
   5.994 +         | QAll x =>
   5.995 +             let val r = explode_disj (is, p)
   5.996 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
   5.997 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
   5.998 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
   5.999 +                  | T => T | F => pi | NOT x => Or (pi, r)
  5.1000 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
  5.1001 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
  5.1002 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
  5.1003 +             end
  5.1004 +         | QEx x =>
  5.1005 +             let val r = explode_disj (is, p)
  5.1006 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
  5.1007 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
  5.1008 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
  5.1009 +                  | T => T | F => pi | NOT x => Or (pi, r)
  5.1010 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
  5.1011 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
  5.1012 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
  5.1013 +             end)
  5.1014 +    end;
  5.1015 +
  5.1016 +fun minusinf (And (p, q)) = And (minusinf p, minusinf q)
  5.1017 +  | minusinf (Or (p, q)) = Or (minusinf p, minusinf q)
  5.1018 +  | minusinf (Lt (u, v)) = Lt (u, v)
  5.1019 +  | minusinf (Gt (w, x)) = Gt (w, x)
  5.1020 +  | minusinf (Le (Cst bo, z)) = Le (Cst bo, z)
  5.1021 +  | minusinf (Le (Var bp, z)) = Le (Var bp, z)
  5.1022 +  | minusinf (Le (Neg bq, z)) = Le (Neg bq, z)
  5.1023 +  | minusinf (Le (Add (Cst cg, bs), z)) = Le (Add (Cst cg, bs), z)
  5.1024 +  | minusinf (Le (Add (Var ch, bs), z)) = Le (Add (Var ch, bs), z)
  5.1025 +  | minusinf (Le (Add (Neg ci, bs), z)) = Le (Add (Neg ci, bs), z)
  5.1026 +  | minusinf (Le (Add (Add (cj, ck), bs), z)) = Le (Add (Add (cj, ck), bs), z)
  5.1027 +  | minusinf (Le (Add (Sub (cl, cm), bs), z)) = Le (Add (Sub (cl, cm), bs), z)
  5.1028 +  | minusinf (Le (Add (Mult (Cst cy, Cst dq), bs), z)) =
  5.1029 +    Le (Add (Mult (Cst cy, Cst dq), bs), z)
  5.1030 +  | minusinf (Le (Add (Mult (Cst cy, Var ei), bs), z)) =
  5.1031 +    (if (ei = 0) then (if (cy < 0) then F else T)
  5.1032 +      else Le (Add (Mult (Cst cy, Var (op_45_def0 ei id_1_def0 + 1)), bs), z))
  5.1033 +  | minusinf (Le (Add (Mult (Cst cy, Neg ds), bs), z)) =
  5.1034 +    Le (Add (Mult (Cst cy, Neg ds), bs), z)
  5.1035 +  | minusinf (Le (Add (Mult (Cst cy, Add (dt, du)), bs), z)) =
  5.1036 +    Le (Add (Mult (Cst cy, Add (dt, du)), bs), z)
  5.1037 +  | minusinf (Le (Add (Mult (Cst cy, Sub (dv, dw)), bs), z)) =
  5.1038 +    Le (Add (Mult (Cst cy, Sub (dv, dw)), bs), z)
  5.1039 +  | minusinf (Le (Add (Mult (Cst cy, Mult (dx, dy)), bs), z)) =
  5.1040 +    Le (Add (Mult (Cst cy, Mult (dx, dy)), bs), z)
  5.1041 +  | minusinf (Le (Add (Mult (Var cz, co), bs), z)) =
  5.1042 +    Le (Add (Mult (Var cz, co), bs), z)
  5.1043 +  | minusinf (Le (Add (Mult (Neg da, co), bs), z)) =
  5.1044 +    Le (Add (Mult (Neg da, co), bs), z)
  5.1045 +  | minusinf (Le (Add (Mult (Add (db, dc), co), bs), z)) =
  5.1046 +    Le (Add (Mult (Add (db, dc), co), bs), z)
  5.1047 +  | minusinf (Le (Add (Mult (Sub (dd, de), co), bs), z)) =
  5.1048 +    Le (Add (Mult (Sub (dd, de), co), bs), z)
  5.1049 +  | minusinf (Le (Add (Mult (Mult (df, dg), co), bs), z)) =
  5.1050 +    Le (Add (Mult (Mult (df, dg), co), bs), z)
  5.1051 +  | minusinf (Le (Sub (bt, bu), z)) = Le (Sub (bt, bu), z)
  5.1052 +  | minusinf (Le (Mult (bv, bw), z)) = Le (Mult (bv, bw), z)
  5.1053 +  | minusinf (Ge (aa, ab)) = Ge (aa, ab)
  5.1054 +  | minusinf (Eq (Cst ek, ad)) = Eq (Cst ek, ad)
  5.1055 +  | minusinf (Eq (Var el, ad)) = Eq (Var el, ad)
  5.1056 +  | minusinf (Eq (Neg em, ad)) = Eq (Neg em, ad)
  5.1057 +  | minusinf (Eq (Add (Cst fc, eo), ad)) = Eq (Add (Cst fc, eo), ad)
  5.1058 +  | minusinf (Eq (Add (Var fd, eo), ad)) = Eq (Add (Var fd, eo), ad)
  5.1059 +  | minusinf (Eq (Add (Neg fe, eo), ad)) = Eq (Add (Neg fe, eo), ad)
  5.1060 +  | minusinf (Eq (Add (Add (ff, fg), eo), ad)) = Eq (Add (Add (ff, fg), eo), ad)
  5.1061 +  | minusinf (Eq (Add (Sub (fh, fi), eo), ad)) = Eq (Add (Sub (fh, fi), eo), ad)
  5.1062 +  | minusinf (Eq (Add (Mult (Cst fu, Cst gm), eo), ad)) =
  5.1063 +    Eq (Add (Mult (Cst fu, Cst gm), eo), ad)
  5.1064 +  | minusinf (Eq (Add (Mult (Cst fu, Var he), eo), ad)) =
  5.1065 +    (if (he = 0) then F
  5.1066 +      else Eq (Add (Mult (Cst fu, Var (op_45_def0 he id_1_def0 + 1)), eo), ad))
  5.1067 +  | minusinf (Eq (Add (Mult (Cst fu, Neg go), eo), ad)) =
  5.1068 +    Eq (Add (Mult (Cst fu, Neg go), eo), ad)
  5.1069 +  | minusinf (Eq (Add (Mult (Cst fu, Add (gp, gq)), eo), ad)) =
  5.1070 +    Eq (Add (Mult (Cst fu, Add (gp, gq)), eo), ad)
  5.1071 +  | minusinf (Eq (Add (Mult (Cst fu, Sub (gr, gs)), eo), ad)) =
  5.1072 +    Eq (Add (Mult (Cst fu, Sub (gr, gs)), eo), ad)
  5.1073 +  | minusinf (Eq (Add (Mult (Cst fu, Mult (gt, gu)), eo), ad)) =
  5.1074 +    Eq (Add (Mult (Cst fu, Mult (gt, gu)), eo), ad)
  5.1075 +  | minusinf (Eq (Add (Mult (Var fv, fk), eo), ad)) =
  5.1076 +    Eq (Add (Mult (Var fv, fk), eo), ad)
  5.1077 +  | minusinf (Eq (Add (Mult (Neg fw, fk), eo), ad)) =
  5.1078 +    Eq (Add (Mult (Neg fw, fk), eo), ad)
  5.1079 +  | minusinf (Eq (Add (Mult (Add (fx, fy), fk), eo), ad)) =
  5.1080 +    Eq (Add (Mult (Add (fx, fy), fk), eo), ad)
  5.1081 +  | minusinf (Eq (Add (Mult (Sub (fz, ga), fk), eo), ad)) =
  5.1082 +    Eq (Add (Mult (Sub (fz, ga), fk), eo), ad)
  5.1083 +  | minusinf (Eq (Add (Mult (Mult (gb, gc), fk), eo), ad)) =
  5.1084 +    Eq (Add (Mult (Mult (gb, gc), fk), eo), ad)
  5.1085 +  | minusinf (Eq (Sub (ep, eq), ad)) = Eq (Sub (ep, eq), ad)
  5.1086 +  | minusinf (Eq (Mult (er, es), ad)) = Eq (Mult (er, es), ad)
  5.1087 +  | minusinf (Divides (ae, af)) = Divides (ae, af)
  5.1088 +  | minusinf T = T
  5.1089 +  | minusinf F = F
  5.1090 +  | minusinf (NOT (Lt (hg, hh))) = NOT (Lt (hg, hh))
  5.1091 +  | minusinf (NOT (Gt (hi, hj))) = NOT (Gt (hi, hj))
  5.1092 +  | minusinf (NOT (Le (hk, hl))) = NOT (Le (hk, hl))
  5.1093 +  | minusinf (NOT (Ge (hm, hn))) = NOT (Ge (hm, hn))
  5.1094 +  | minusinf (NOT (Eq (Cst ja, hp))) = NOT (Eq (Cst ja, hp))
  5.1095 +  | minusinf (NOT (Eq (Var jb, hp))) = NOT (Eq (Var jb, hp))
  5.1096 +  | minusinf (NOT (Eq (Neg jc, hp))) = NOT (Eq (Neg jc, hp))
  5.1097 +  | minusinf (NOT (Eq (Add (Cst js, je), hp))) = NOT (Eq (Add (Cst js, je), hp))
  5.1098 +  | minusinf (NOT (Eq (Add (Var jt, je), hp))) = NOT (Eq (Add (Var jt, je), hp))
  5.1099 +  | minusinf (NOT (Eq (Add (Neg ju, je), hp))) = NOT (Eq (Add (Neg ju, je), hp))
  5.1100 +  | minusinf (NOT (Eq (Add (Add (jv, jw), je), hp))) =
  5.1101 +    NOT (Eq (Add (Add (jv, jw), je), hp))
  5.1102 +  | minusinf (NOT (Eq (Add (Sub (jx, jy), je), hp))) =
  5.1103 +    NOT (Eq (Add (Sub (jx, jy), je), hp))
  5.1104 +  | minusinf (NOT (Eq (Add (Mult (Cst kk, Cst lc), je), hp))) =
  5.1105 +    NOT (Eq (Add (Mult (Cst kk, Cst lc), je), hp))
  5.1106 +  | minusinf (NOT (Eq (Add (Mult (Cst kk, Var lu), je), hp))) =
  5.1107 +    (if (lu = 0) then T
  5.1108 +      else NOT (Eq (Add (Mult (Cst kk, Var (op_45_def0 lu id_1_def0 + 1)), je),
  5.1109 +                     hp)))
  5.1110 +  | minusinf (NOT (Eq (Add (Mult (Cst kk, Neg le), je), hp))) =
  5.1111 +    NOT (Eq (Add (Mult (Cst kk, Neg le), je), hp))
  5.1112 +  | minusinf (NOT (Eq (Add (Mult (Cst kk, Add (lf, lg)), je), hp))) =
  5.1113 +    NOT (Eq (Add (Mult (Cst kk, Add (lf, lg)), je), hp))
  5.1114 +  | minusinf (NOT (Eq (Add (Mult (Cst kk, Sub (lh, li)), je), hp))) =
  5.1115 +    NOT (Eq (Add (Mult (Cst kk, Sub (lh, li)), je), hp))
  5.1116 +  | minusinf (NOT (Eq (Add (Mult (Cst kk, Mult (lj, lk)), je), hp))) =
  5.1117 +    NOT (Eq (Add (Mult (Cst kk, Mult (lj, lk)), je), hp))
  5.1118 +  | minusinf (NOT (Eq (Add (Mult (Var kl, ka), je), hp))) =
  5.1119 +    NOT (Eq (Add (Mult (Var kl, ka), je), hp))
  5.1120 +  | minusinf (NOT (Eq (Add (Mult (Neg km, ka), je), hp))) =
  5.1121 +    NOT (Eq (Add (Mult (Neg km, ka), je), hp))
  5.1122 +  | minusinf (NOT (Eq (Add (Mult (Add (kn, ko), ka), je), hp))) =
  5.1123 +    NOT (Eq (Add (Mult (Add (kn, ko), ka), je), hp))
  5.1124 +  | minusinf (NOT (Eq (Add (Mult (Sub (kp, kq), ka), je), hp))) =
  5.1125 +    NOT (Eq (Add (Mult (Sub (kp, kq), ka), je), hp))
  5.1126 +  | minusinf (NOT (Eq (Add (Mult (Mult (kr, ks), ka), je), hp))) =
  5.1127 +    NOT (Eq (Add (Mult (Mult (kr, ks), ka), je), hp))
  5.1128 +  | minusinf (NOT (Eq (Sub (jf, jg), hp))) = NOT (Eq (Sub (jf, jg), hp))
  5.1129 +  | minusinf (NOT (Eq (Mult (jh, ji), hp))) = NOT (Eq (Mult (jh, ji), hp))
  5.1130 +  | minusinf (NOT (Divides (hq, hr))) = NOT (Divides (hq, hr))
  5.1131 +  | minusinf (NOT T) = NOT T
  5.1132 +  | minusinf (NOT F) = NOT F
  5.1133 +  | minusinf (NOT (NOT hs)) = NOT (NOT hs)
  5.1134 +  | minusinf (NOT (And (ht, hu))) = NOT (And (ht, hu))
  5.1135 +  | minusinf (NOT (Or (hv, hw))) = NOT (Or (hv, hw))
  5.1136 +  | minusinf (NOT (Imp (hx, hy))) = NOT (Imp (hx, hy))
  5.1137 +  | minusinf (NOT (Equ (hz, ia))) = NOT (Equ (hz, ia))
  5.1138 +  | minusinf (NOT (QAll ib)) = NOT (QAll ib)
  5.1139 +  | minusinf (NOT (QEx ic)) = NOT (QEx ic)
  5.1140 +  | minusinf (Imp (al, am)) = Imp (al, am)
  5.1141 +  | minusinf (Equ (an, ao)) = Equ (an, ao)
  5.1142 +  | minusinf (QAll ap) = QAll ap
  5.1143 +  | minusinf (QEx aq) = QEx aq;
  5.1144 +
  5.1145 +fun abs i = (if (i < 0) then ~ i else i);
  5.1146 +
  5.1147 +fun op_div_def1 a b = fst (divAlg (a, b));
  5.1148 +
  5.1149 +fun op_mod_def0 m n = nat (op_mod_def1 (m) (n));
  5.1150 +
  5.1151 +fun ngcd (m, n) = (if (n = 0) then m else ngcd (n, op_mod_def0 m n));
  5.1152 +
  5.1153 +fun igcd x = split (fn a => fn b => (ngcd (nat (abs a), nat (abs b)))) x;
  5.1154 +
  5.1155 +fun ilcm a b = op_div_def1 (a * b) (igcd (a, b));
  5.1156 +
  5.1157 +fun divlcm (NOT p) = divlcm p
  5.1158 +  | divlcm (And (p, q)) = ilcm (divlcm p) (divlcm q)
  5.1159 +  | divlcm (Or (p, q)) = ilcm (divlcm p) (divlcm q)
  5.1160 +  | divlcm (Lt (u, v)) = 1
  5.1161 +  | divlcm (Gt (w, x)) = 1
  5.1162 +  | divlcm (Le (y, z)) = 1
  5.1163 +  | divlcm (Ge (aa, ab)) = 1
  5.1164 +  | divlcm (Eq (ac, ad)) = 1
  5.1165 +  | divlcm (Divides (Cst bo, Cst cg)) = 1
  5.1166 +  | divlcm (Divides (Cst bo, Var ch)) = 1
  5.1167 +  | divlcm (Divides (Cst bo, Neg ci)) = 1
  5.1168 +  | divlcm (Divides (Cst bo, Add (Cst cy, ck))) = 1
  5.1169 +  | divlcm (Divides (Cst bo, Add (Var cz, ck))) = 1
  5.1170 +  | divlcm (Divides (Cst bo, Add (Neg da, ck))) = 1
  5.1171 +  | divlcm (Divides (Cst bo, Add (Add (db, dc), ck))) = 1
  5.1172 +  | divlcm (Divides (Cst bo, Add (Sub (dd, de), ck))) = 1
  5.1173 +  | divlcm (Divides (Cst bo, Add (Mult (Cst dq, Cst ei), ck))) = 1
  5.1174 +  | divlcm (Divides (Cst bo, Add (Mult (Cst dq, Var fa), ck))) =
  5.1175 +    (if (fa = 0) then abs bo else 1)
  5.1176 +  | divlcm (Divides (Cst bo, Add (Mult (Cst dq, Neg ek), ck))) = 1
  5.1177 +  | divlcm (Divides (Cst bo, Add (Mult (Cst dq, Add (el, em)), ck))) = 1
  5.1178 +  | divlcm (Divides (Cst bo, Add (Mult (Cst dq, Sub (en, eo)), ck))) = 1
  5.1179 +  | divlcm (Divides (Cst bo, Add (Mult (Cst dq, Mult (ep, eq)), ck))) = 1
  5.1180 +  | divlcm (Divides (Cst bo, Add (Mult (Var dr, dg), ck))) = 1
  5.1181 +  | divlcm (Divides (Cst bo, Add (Mult (Neg ds, dg), ck))) = 1
  5.1182 +  | divlcm (Divides (Cst bo, Add (Mult (Add (dt, du), dg), ck))) = 1
  5.1183 +  | divlcm (Divides (Cst bo, Add (Mult (Sub (dv, dw), dg), ck))) = 1
  5.1184 +  | divlcm (Divides (Cst bo, Add (Mult (Mult (dx, dy), dg), ck))) = 1
  5.1185 +  | divlcm (Divides (Cst bo, Sub (cl, cm))) = 1
  5.1186 +  | divlcm (Divides (Cst bo, Mult (cn, co))) = 1
  5.1187 +  | divlcm (Divides (Var bp, af)) = 1
  5.1188 +  | divlcm (Divides (Neg bq, af)) = 1
  5.1189 +  | divlcm (Divides (Add (br, bs), af)) = 1
  5.1190 +  | divlcm (Divides (Sub (bt, bu), af)) = 1
  5.1191 +  | divlcm (Divides (Mult (bv, bw), af)) = 1
  5.1192 +  | divlcm T = 1
  5.1193 +  | divlcm F = 1
  5.1194 +  | divlcm (Imp (al, am)) = 1
  5.1195 +  | divlcm (Equ (an, ao)) = 1
  5.1196 +  | divlcm (QAll ap) = 1
  5.1197 +  | divlcm (QEx aq) = 1;
  5.1198 +
  5.1199 +fun explode_minf (q, B) =
  5.1200 +    let val d = divlcm q; val pm = minusinf q;
  5.1201 +        val dj1 = explode_disj (map (fn x => Cst x) (iupto (1, d)), pm)
  5.1202 +    in (case dj1 of
  5.1203 +         Lt (x, xa) =>
  5.1204 +           let val dj2 = explode_disj (all_sums (d, B), q)
  5.1205 +           in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
  5.1206 +                | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
  5.1207 +                | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
  5.1208 +                | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
  5.1209 +                | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
  5.1210 +                | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
  5.1211 +                | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
  5.1212 +                | QEx x => Or (dj1, dj2))
  5.1213 +           end
  5.1214 +         | Gt (x, xa) =>
  5.1215 +             let val dj2 = explode_disj (all_sums (d, B), q)
  5.1216 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
  5.1217 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
  5.1218 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
  5.1219 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
  5.1220 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
  5.1221 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
  5.1222 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
  5.1223 +                  | QEx x => Or (dj1, dj2))
  5.1224 +             end
  5.1225 +         | Le (x, xa) =>
  5.1226 +             let val dj2 = explode_disj (all_sums (d, B), q)
  5.1227 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
  5.1228 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
  5.1229 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
  5.1230 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
  5.1231 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
  5.1232 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
  5.1233 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
  5.1234 +                  | QEx x => Or (dj1, dj2))
  5.1235 +             end
  5.1236 +         | Ge (x, xa) =>
  5.1237 +             let val dj2 = explode_disj (all_sums (d, B), q)
  5.1238 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
  5.1239 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
  5.1240 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
  5.1241 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
  5.1242 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
  5.1243 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
  5.1244 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
  5.1245 +                  | QEx x => Or (dj1, dj2))
  5.1246 +             end
  5.1247 +         | Eq (x, xa) =>
  5.1248 +             let val dj2 = explode_disj (all_sums (d, B), q)
  5.1249 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
  5.1250 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
  5.1251 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
  5.1252 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
  5.1253 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
  5.1254 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
  5.1255 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
  5.1256 +                  | QEx x => Or (dj1, dj2))
  5.1257 +             end
  5.1258 +         | Divides (x, xa) =>
  5.1259 +             let val dj2 = explode_disj (all_sums (d, B), q)
  5.1260 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
  5.1261 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
  5.1262 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
  5.1263 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
  5.1264 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
  5.1265 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
  5.1266 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
  5.1267 +                  | QEx x => Or (dj1, dj2))
  5.1268 +             end
  5.1269 +         | T => T | F => explode_disj (all_sums (d, B), q)
  5.1270 +         | NOT x =>
  5.1271 +             let val dj2 = explode_disj (all_sums (d, B), q)
  5.1272 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
  5.1273 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
  5.1274 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
  5.1275 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
  5.1276 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
  5.1277 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
  5.1278 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
  5.1279 +                  | QEx x => Or (dj1, dj2))
  5.1280 +             end
  5.1281 +         | And (x, xa) =>
  5.1282 +             let val dj2 = explode_disj (all_sums (d, B), q)
  5.1283 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
  5.1284 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
  5.1285 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
  5.1286 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
  5.1287 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
  5.1288 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
  5.1289 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
  5.1290 +                  | QEx x => Or (dj1, dj2))
  5.1291 +             end
  5.1292 +         | Or (x, xa) =>
  5.1293 +             let val dj2 = explode_disj (all_sums (d, B), q)
  5.1294 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
  5.1295 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
  5.1296 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
  5.1297 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
  5.1298 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
  5.1299 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
  5.1300 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
  5.1301 +                  | QEx x => Or (dj1, dj2))
  5.1302 +             end
  5.1303 +         | Imp (x, xa) =>
  5.1304 +             let val dj2 = explode_disj (all_sums (d, B), q)
  5.1305 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
  5.1306 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
  5.1307 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
  5.1308 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
  5.1309 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
  5.1310 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
  5.1311 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
  5.1312 +                  | QEx x => Or (dj1, dj2))
  5.1313 +             end
  5.1314 +         | Equ (x, xa) =>
  5.1315 +             let val dj2 = explode_disj (all_sums (d, B), q)
  5.1316 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
  5.1317 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
  5.1318 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
  5.1319 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
  5.1320 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
  5.1321 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
  5.1322 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
  5.1323 +                  | QEx x => Or (dj1, dj2))
  5.1324 +             end
  5.1325 +         | QAll x =>
  5.1326 +             let val dj2 = explode_disj (all_sums (d, B), q)
  5.1327 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
  5.1328 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
  5.1329 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
  5.1330 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
  5.1331 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
  5.1332 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
  5.1333 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
  5.1334 +                  | QEx x => Or (dj1, dj2))
  5.1335 +             end
  5.1336 +         | QEx x =>
  5.1337 +             let val dj2 = explode_disj (all_sums (d, B), q)
  5.1338 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
  5.1339 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
  5.1340 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
  5.1341 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
  5.1342 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
  5.1343 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
  5.1344 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
  5.1345 +                  | QEx x => Or (dj1, dj2))
  5.1346 +             end)
  5.1347 +    end;
  5.1348 +
  5.1349 +fun mirror (And (p, q)) = And (mirror p, mirror q)
  5.1350 +  | mirror (Or (p, q)) = Or (mirror p, mirror q)
  5.1351 +  | mirror (Lt (u, v)) = Lt (u, v)
  5.1352 +  | mirror (Gt (w, x)) = Gt (w, x)
  5.1353 +  | mirror (Le (Cst bp, aa)) = Le (Cst bp, aa)
  5.1354 +  | mirror (Le (Var bq, aa)) = Le (Var bq, aa)
  5.1355 +  | mirror (Le (Neg br, aa)) = Le (Neg br, aa)
  5.1356 +  | mirror (Le (Add (Cst ch, bt), aa)) = Le (Add (Cst ch, bt), aa)
  5.1357 +  | mirror (Le (Add (Var ci, bt), aa)) = Le (Add (Var ci, bt), aa)
  5.1358 +  | mirror (Le (Add (Neg cj, bt), aa)) = Le (Add (Neg cj, bt), aa)
  5.1359 +  | mirror (Le (Add (Add (ck, cl), bt), aa)) = Le (Add (Add (ck, cl), bt), aa)
  5.1360 +  | mirror (Le (Add (Sub (cm, cn), bt), aa)) = Le (Add (Sub (cm, cn), bt), aa)
  5.1361 +  | mirror (Le (Add (Mult (Cst cz, Cst dr), bt), aa)) =
  5.1362 +    Le (Add (Mult (Cst cz, Cst dr), bt), aa)
  5.1363 +  | mirror (Le (Add (Mult (Cst cz, Var ej), bt), aa)) =
  5.1364 +    (if (ej = 0) then Le (Add (Mult (Cst (~ cz), Var 0), bt), aa)
  5.1365 +      else Le (Add (Mult (Cst cz, Var (op_45_def0 ej id_1_def0 + 1)), bt), aa))
  5.1366 +  | mirror (Le (Add (Mult (Cst cz, Neg dt), bt), aa)) =
  5.1367 +    Le (Add (Mult (Cst cz, Neg dt), bt), aa)
  5.1368 +  | mirror (Le (Add (Mult (Cst cz, Add (du, dv)), bt), aa)) =
  5.1369 +    Le (Add (Mult (Cst cz, Add (du, dv)), bt), aa)
  5.1370 +  | mirror (Le (Add (Mult (Cst cz, Sub (dw, dx)), bt), aa)) =
  5.1371 +    Le (Add (Mult (Cst cz, Sub (dw, dx)), bt), aa)
  5.1372 +  | mirror (Le (Add (Mult (Cst cz, Mult (dy, dz)), bt), aa)) =
  5.1373 +    Le (Add (Mult (Cst cz, Mult (dy, dz)), bt), aa)
  5.1374 +  | mirror (Le (Add (Mult (Var da, cp), bt), aa)) =
  5.1375 +    Le (Add (Mult (Var da, cp), bt), aa)
  5.1376 +  | mirror (Le (Add (Mult (Neg db, cp), bt), aa)) =
  5.1377 +    Le (Add (Mult (Neg db, cp), bt), aa)
  5.1378 +  | mirror (Le (Add (Mult (Add (dc, dd), cp), bt), aa)) =
  5.1379 +    Le (Add (Mult (Add (dc, dd), cp), bt), aa)
  5.1380 +  | mirror (Le (Add (Mult (Sub (de, df), cp), bt), aa)) =
  5.1381 +    Le (Add (Mult (Sub (de, df), cp), bt), aa)
  5.1382 +  | mirror (Le (Add (Mult (Mult (dg, dh), cp), bt), aa)) =
  5.1383 +    Le (Add (Mult (Mult (dg, dh), cp), bt), aa)
  5.1384 +  | mirror (Le (Sub (bu, bv), aa)) = Le (Sub (bu, bv), aa)
  5.1385 +  | mirror (Le (Mult (bw, bx), aa)) = Le (Mult (bw, bx), aa)
  5.1386 +  | mirror (Ge (ab, ac)) = Ge (ab, ac)
  5.1387 +  | mirror (Eq (Cst el, ae)) = Eq (Cst el, ae)
  5.1388 +  | mirror (Eq (Var em, ae)) = Eq (Var em, ae)
  5.1389 +  | mirror (Eq (Neg en, ae)) = Eq (Neg en, ae)
  5.1390 +  | mirror (Eq (Add (Cst fd, ep), ae)) = Eq (Add (Cst fd, ep), ae)
  5.1391 +  | mirror (Eq (Add (Var fe, ep), ae)) = Eq (Add (Var fe, ep), ae)
  5.1392 +  | mirror (Eq (Add (Neg ff, ep), ae)) = Eq (Add (Neg ff, ep), ae)
  5.1393 +  | mirror (Eq (Add (Add (fg, fh), ep), ae)) = Eq (Add (Add (fg, fh), ep), ae)
  5.1394 +  | mirror (Eq (Add (Sub (fi, fj), ep), ae)) = Eq (Add (Sub (fi, fj), ep), ae)
  5.1395 +  | mirror (Eq (Add (Mult (Cst fv, Cst gn), ep), ae)) =
  5.1396 +    Eq (Add (Mult (Cst fv, Cst gn), ep), ae)
  5.1397 +  | mirror (Eq (Add (Mult (Cst fv, Var hf), ep), ae)) =
  5.1398 +    (if (hf = 0) then Eq (Add (Mult (Cst (~ fv), Var 0), ep), ae)
  5.1399 +      else Eq (Add (Mult (Cst fv, Var (op_45_def0 hf id_1_def0 + 1)), ep), ae))
  5.1400 +  | mirror (Eq (Add (Mult (Cst fv, Neg gp), ep), ae)) =
  5.1401 +    Eq (Add (Mult (Cst fv, Neg gp), ep), ae)
  5.1402 +  | mirror (Eq (Add (Mult (Cst fv, Add (gq, gr)), ep), ae)) =
  5.1403 +    Eq (Add (Mult (Cst fv, Add (gq, gr)), ep), ae)
  5.1404 +  | mirror (Eq (Add (Mult (Cst fv, Sub (gs, gt)), ep), ae)) =
  5.1405 +    Eq (Add (Mult (Cst fv, Sub (gs, gt)), ep), ae)
  5.1406 +  | mirror (Eq (Add (Mult (Cst fv, Mult (gu, gv)), ep), ae)) =
  5.1407 +    Eq (Add (Mult (Cst fv, Mult (gu, gv)), ep), ae)
  5.1408 +  | mirror (Eq (Add (Mult (Var fw, fl), ep), ae)) =
  5.1409 +    Eq (Add (Mult (Var fw, fl), ep), ae)
  5.1410 +  | mirror (Eq (Add (Mult (Neg fx, fl), ep), ae)) =
  5.1411 +    Eq (Add (Mult (Neg fx, fl), ep), ae)
  5.1412 +  | mirror (Eq (Add (Mult (Add (fy, fz), fl), ep), ae)) =
  5.1413 +    Eq (Add (Mult (Add (fy, fz), fl), ep), ae)
  5.1414 +  | mirror (Eq (Add (Mult (Sub (ga, gb), fl), ep), ae)) =
  5.1415 +    Eq (Add (Mult (Sub (ga, gb), fl), ep), ae)
  5.1416 +  | mirror (Eq (Add (Mult (Mult (gc, gd), fl), ep), ae)) =
  5.1417 +    Eq (Add (Mult (Mult (gc, gd), fl), ep), ae)
  5.1418 +  | mirror (Eq (Sub (eq, er), ae)) = Eq (Sub (eq, er), ae)
  5.1419 +  | mirror (Eq (Mult (es, et), ae)) = Eq (Mult (es, et), ae)
  5.1420 +  | mirror (Divides (Cst hh, Cst hz)) = Divides (Cst hh, Cst hz)
  5.1421 +  | mirror (Divides (Cst hh, Var ia)) = Divides (Cst hh, Var ia)
  5.1422 +  | mirror (Divides (Cst hh, Neg ib)) = Divides (Cst hh, Neg ib)
  5.1423 +  | mirror (Divides (Cst hh, Add (Cst ir, id))) =
  5.1424 +    Divides (Cst hh, Add (Cst ir, id))
  5.1425 +  | mirror (Divides (Cst hh, Add (Var is, id))) =
  5.1426 +    Divides (Cst hh, Add (Var is, id))
  5.1427 +  | mirror (Divides (Cst hh, Add (Neg it, id))) =
  5.1428 +    Divides (Cst hh, Add (Neg it, id))
  5.1429 +  | mirror (Divides (Cst hh, Add (Add (iu, iv), id))) =
  5.1430 +    Divides (Cst hh, Add (Add (iu, iv), id))
  5.1431 +  | mirror (Divides (Cst hh, Add (Sub (iw, ix), id))) =
  5.1432 +    Divides (Cst hh, Add (Sub (iw, ix), id))
  5.1433 +  | mirror (Divides (Cst hh, Add (Mult (Cst jj, Cst kb), id))) =
  5.1434 +    Divides (Cst hh, Add (Mult (Cst jj, Cst kb), id))
  5.1435 +  | mirror (Divides (Cst hh, Add (Mult (Cst jj, Var kt), id))) =
  5.1436 +    (if (kt = 0) then Divides (Cst hh, Add (Mult (Cst (~ jj), Var 0), id))
  5.1437 +      else Divides
  5.1438 +             (Cst hh,
  5.1439 +               Add (Mult (Cst jj, Var (op_45_def0 kt id_1_def0 + 1)), id)))
  5.1440 +  | mirror (Divides (Cst hh, Add (Mult (Cst jj, Neg kd), id))) =
  5.1441 +    Divides (Cst hh, Add (Mult (Cst jj, Neg kd), id))
  5.1442 +  | mirror (Divides (Cst hh, Add (Mult (Cst jj, Add (ke, kf)), id))) =
  5.1443 +    Divides (Cst hh, Add (Mult (Cst jj, Add (ke, kf)), id))
  5.1444 +  | mirror (Divides (Cst hh, Add (Mult (Cst jj, Sub (kg, kh)), id))) =
  5.1445 +    Divides (Cst hh, Add (Mult (Cst jj, Sub (kg, kh)), id))
  5.1446 +  | mirror (Divides (Cst hh, Add (Mult (Cst jj, Mult (ki, kj)), id))) =
  5.1447 +    Divides (Cst hh, Add (Mult (Cst jj, Mult (ki, kj)), id))
  5.1448 +  | mirror (Divides (Cst hh, Add (Mult (Var jk, iz), id))) =
  5.1449 +    Divides (Cst hh, Add (Mult (Var jk, iz), id))
  5.1450 +  | mirror (Divides (Cst hh, Add (Mult (Neg jl, iz), id))) =
  5.1451 +    Divides (Cst hh, Add (Mult (Neg jl, iz), id))
  5.1452 +  | mirror (Divides (Cst hh, Add (Mult (Add (jm, jn), iz), id))) =
  5.1453 +    Divides (Cst hh, Add (Mult (Add (jm, jn), iz), id))
  5.1454 +  | mirror (Divides (Cst hh, Add (Mult (Sub (jo, jp), iz), id))) =
  5.1455 +    Divides (Cst hh, Add (Mult (Sub (jo, jp), iz), id))
  5.1456 +  | mirror (Divides (Cst hh, Add (Mult (Mult (jq, jr), iz), id))) =
  5.1457 +    Divides (Cst hh, Add (Mult (Mult (jq, jr), iz), id))
  5.1458 +  | mirror (Divides (Cst hh, Sub (ie, if'))) = Divides (Cst hh, Sub (ie, if'))
  5.1459 +  | mirror (Divides (Cst hh, Mult (ig, ih))) = Divides (Cst hh, Mult (ig, ih))
  5.1460 +  | mirror (Divides (Var hi, ag)) = Divides (Var hi, ag)
  5.1461 +  | mirror (Divides (Neg hj, ag)) = Divides (Neg hj, ag)
  5.1462 +  | mirror (Divides (Add (hk, hl), ag)) = Divides (Add (hk, hl), ag)
  5.1463 +  | mirror (Divides (Sub (hm, hn), ag)) = Divides (Sub (hm, hn), ag)
  5.1464 +  | mirror (Divides (Mult (ho, hp), ag)) = Divides (Mult (ho, hp), ag)
  5.1465 +  | mirror T = T
  5.1466 +  | mirror F = F
  5.1467 +  | mirror (NOT (Lt (kv, kw))) = NOT (Lt (kv, kw))
  5.1468 +  | mirror (NOT (Gt (kx, ky))) = NOT (Gt (kx, ky))
  5.1469 +  | mirror (NOT (Le (kz, la))) = NOT (Le (kz, la))
  5.1470 +  | mirror (NOT (Ge (lb, lc))) = NOT (Ge (lb, lc))
  5.1471 +  | mirror (NOT (Eq (Cst mp, le))) = NOT (Eq (Cst mp, le))
  5.1472 +  | mirror (NOT (Eq (Var mq, le))) = NOT (Eq (Var mq, le))
  5.1473 +  | mirror (NOT (Eq (Neg mr, le))) = NOT (Eq (Neg mr, le))
  5.1474 +  | mirror (NOT (Eq (Add (Cst nh, mt), le))) = NOT (Eq (Add (Cst nh, mt), le))
  5.1475 +  | mirror (NOT (Eq (Add (Var ni, mt), le))) = NOT (Eq (Add (Var ni, mt), le))
  5.1476 +  | mirror (NOT (Eq (Add (Neg nj, mt), le))) = NOT (Eq (Add (Neg nj, mt), le))
  5.1477 +  | mirror (NOT (Eq (Add (Add (nk, nl), mt), le))) =
  5.1478 +    NOT (Eq (Add (Add (nk, nl), mt), le))
  5.1479 +  | mirror (NOT (Eq (Add (Sub (nm, nn), mt), le))) =
  5.1480 +    NOT (Eq (Add (Sub (nm, nn), mt), le))
  5.1481 +  | mirror (NOT (Eq (Add (Mult (Cst nz, Cst or), mt), le))) =
  5.1482 +    NOT (Eq (Add (Mult (Cst nz, Cst or), mt), le))
  5.1483 +  | mirror (NOT (Eq (Add (Mult (Cst nz, Var pj), mt), le))) =
  5.1484 +    (if (pj = 0) then NOT (Eq (Add (Mult (Cst (~ nz), Var 0), mt), le))
  5.1485 +      else NOT (Eq (Add (Mult (Cst nz, Var (op_45_def0 pj id_1_def0 + 1)), mt),
  5.1486 +                     le)))
  5.1487 +  | mirror (NOT (Eq (Add (Mult (Cst nz, Neg ot), mt), le))) =
  5.1488 +    NOT (Eq (Add (Mult (Cst nz, Neg ot), mt), le))
  5.1489 +  | mirror (NOT (Eq (Add (Mult (Cst nz, Add (ou, ov)), mt), le))) =
  5.1490 +    NOT (Eq (Add (Mult (Cst nz, Add (ou, ov)), mt), le))
  5.1491 +  | mirror (NOT (Eq (Add (Mult (Cst nz, Sub (ow, ox)), mt), le))) =
  5.1492 +    NOT (Eq (Add (Mult (Cst nz, Sub (ow, ox)), mt), le))
  5.1493 +  | mirror (NOT (Eq (Add (Mult (Cst nz, Mult (oy, oz)), mt), le))) =
  5.1494 +    NOT (Eq (Add (Mult (Cst nz, Mult (oy, oz)), mt), le))
  5.1495 +  | mirror (NOT (Eq (Add (Mult (Var oa, np), mt), le))) =
  5.1496 +    NOT (Eq (Add (Mult (Var oa, np), mt), le))
  5.1497 +  | mirror (NOT (Eq (Add (Mult (Neg ob, np), mt), le))) =
  5.1498 +    NOT (Eq (Add (Mult (Neg ob, np), mt), le))
  5.1499 +  | mirror (NOT (Eq (Add (Mult (Add (oc, od), np), mt), le))) =
  5.1500 +    NOT (Eq (Add (Mult (Add (oc, od), np), mt), le))
  5.1501 +  | mirror (NOT (Eq (Add (Mult (Sub (oe, of'), np), mt), le))) =
  5.1502 +    NOT (Eq (Add (Mult (Sub (oe, of'), np), mt), le))
  5.1503 +  | mirror (NOT (Eq (Add (Mult (Mult (og, oh), np), mt), le))) =
  5.1504 +    NOT (Eq (Add (Mult (Mult (og, oh), np), mt), le))
  5.1505 +  | mirror (NOT (Eq (Sub (mu, mv), le))) = NOT (Eq (Sub (mu, mv), le))
  5.1506 +  | mirror (NOT (Eq (Mult (mw, mx), le))) = NOT (Eq (Mult (mw, mx), le))
  5.1507 +  | mirror (NOT (Divides (Cst pl, Cst qd))) = NOT (Divides (Cst pl, Cst qd))
  5.1508 +  | mirror (NOT (Divides (Cst pl, Var qe))) = NOT (Divides (Cst pl, Var qe))
  5.1509 +  | mirror (NOT (Divides (Cst pl, Neg qf))) = NOT (Divides (Cst pl, Neg qf))
  5.1510 +  | mirror (NOT (Divides (Cst pl, Add (Cst qv, qh)))) =
  5.1511 +    NOT (Divides (Cst pl, Add (Cst qv, qh)))
  5.1512 +  | mirror (NOT (Divides (Cst pl, Add (Var qw, qh)))) =
  5.1513 +    NOT (Divides (Cst pl, Add (Var qw, qh)))
  5.1514 +  | mirror (NOT (Divides (Cst pl, Add (Neg qx, qh)))) =
  5.1515 +    NOT (Divides (Cst pl, Add (Neg qx, qh)))
  5.1516 +  | mirror (NOT (Divides (Cst pl, Add (Add (qy, qz), qh)))) =
  5.1517 +    NOT (Divides (Cst pl, Add (Add (qy, qz), qh)))
  5.1518 +  | mirror (NOT (Divides (Cst pl, Add (Sub (ra, rb), qh)))) =
  5.1519 +    NOT (Divides (Cst pl, Add (Sub (ra, rb), qh)))
  5.1520 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Cst rn, Cst sf), qh)))) =
  5.1521 +    NOT (Divides (Cst pl, Add (Mult (Cst rn, Cst sf), qh)))
  5.1522 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Cst rn, Var sx), qh)))) =
  5.1523 +    (if (sx = 0)
  5.1524 +      then NOT (Divides (Cst pl, Add (Mult (Cst (~ rn), Var 0), qh)))
  5.1525 +      else NOT (Divides
  5.1526 +                  (Cst pl,
  5.1527 +                    Add (Mult (Cst rn, Var (op_45_def0 sx id_1_def0 + 1)),
  5.1528 +                          qh))))
  5.1529 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Cst rn, Neg sh), qh)))) =
  5.1530 +    NOT (Divides (Cst pl, Add (Mult (Cst rn, Neg sh), qh)))
  5.1531 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Cst rn, Add (si, sj)), qh)))) =
  5.1532 +    NOT (Divides (Cst pl, Add (Mult (Cst rn, Add (si, sj)), qh)))
  5.1533 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Cst rn, Sub (sk, sl)), qh)))) =
  5.1534 +    NOT (Divides (Cst pl, Add (Mult (Cst rn, Sub (sk, sl)), qh)))
  5.1535 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Cst rn, Mult (sm, sn)), qh)))) =
  5.1536 +    NOT (Divides (Cst pl, Add (Mult (Cst rn, Mult (sm, sn)), qh)))
  5.1537 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Var ro, rd), qh)))) =
  5.1538 +    NOT (Divides (Cst pl, Add (Mult (Var ro, rd), qh)))
  5.1539 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Neg rp, rd), qh)))) =
  5.1540 +    NOT (Divides (Cst pl, Add (Mult (Neg rp, rd), qh)))
  5.1541 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Add (rq, rr), rd), qh)))) =
  5.1542 +    NOT (Divides (Cst pl, Add (Mult (Add (rq, rr), rd), qh)))
  5.1543 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Sub (rs, rt), rd), qh)))) =
  5.1544 +    NOT (Divides (Cst pl, Add (Mult (Sub (rs, rt), rd), qh)))
  5.1545 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Mult (ru, rv), rd), qh)))) =
  5.1546 +    NOT (Divides (Cst pl, Add (Mult (Mult (ru, rv), rd), qh)))
  5.1547 +  | mirror (NOT (Divides (Cst pl, Sub (qi, qj)))) =
  5.1548 +    NOT (Divides (Cst pl, Sub (qi, qj)))
  5.1549 +  | mirror (NOT (Divides (Cst pl, Mult (qk, ql)))) =
  5.1550 +    NOT (Divides (Cst pl, Mult (qk, ql)))
  5.1551 +  | mirror (NOT (Divides (Var pm, lg))) = NOT (Divides (Var pm, lg))
  5.1552 +  | mirror (NOT (Divides (Neg pn, lg))) = NOT (Divides (Neg pn, lg))
  5.1553 +  | mirror (NOT (Divides (Add (po, pp), lg))) = NOT (Divides (Add (po, pp), lg))
  5.1554 +  | mirror (NOT (Divides (Sub (pq, pr), lg))) = NOT (Divides (Sub (pq, pr), lg))
  5.1555 +  | mirror (NOT (Divides (Mult (ps, pt), lg))) =
  5.1556 +    NOT (Divides (Mult (ps, pt), lg))
  5.1557 +  | mirror (NOT T) = NOT T
  5.1558 +  | mirror (NOT F) = NOT F
  5.1559 +  | mirror (NOT (NOT lh)) = NOT (NOT lh)
  5.1560 +  | mirror (NOT (And (li, lj))) = NOT (And (li, lj))
  5.1561 +  | mirror (NOT (Or (lk, ll))) = NOT (Or (lk, ll))
  5.1562 +  | mirror (NOT (Imp (lm, ln))) = NOT (Imp (lm, ln))
  5.1563 +  | mirror (NOT (Equ (lo, lp))) = NOT (Equ (lo, lp))
  5.1564 +  | mirror (NOT (QAll lq)) = NOT (QAll lq)
  5.1565 +  | mirror (NOT (QEx lr)) = NOT (QEx lr)
  5.1566 +  | mirror (Imp (am, an)) = Imp (am, an)
  5.1567 +  | mirror (Equ (ao, ap)) = Equ (ao, ap)
  5.1568 +  | mirror (QAll aq) = QAll aq
  5.1569 +  | mirror (QEx ar) = QEx ar;
  5.1570 +
  5.1571 +fun op_43_def0 m n = nat ((m) + (n));
  5.1572 +
  5.1573 +fun size_def1 [] = 0
  5.1574 +  | size_def1 (a :: list) = op_43_def0 (size_def1 list) (0 + 1);
  5.1575 +
  5.1576 +fun aset (And (p, q)) = op_64 (aset p) (aset q)
  5.1577 +  | aset (Or (p, q)) = op_64 (aset p) (aset q)
  5.1578 +  | aset (Lt (u, v)) = []
  5.1579 +  | aset (Gt (w, x)) = []
  5.1580 +  | aset (Le (Cst bo, z)) = []
  5.1581 +  | aset (Le (Var bp, z)) = []
  5.1582 +  | aset (Le (Neg bq, z)) = []
  5.1583 +  | aset (Le (Add (Cst cg, bs), z)) = []
  5.1584 +  | aset (Le (Add (Var ch, bs), z)) = []
  5.1585 +  | aset (Le (Add (Neg ci, bs), z)) = []
  5.1586 +  | aset (Le (Add (Add (cj, ck), bs), z)) = []
  5.1587 +  | aset (Le (Add (Sub (cl, cm), bs), z)) = []
  5.1588 +  | aset (Le (Add (Mult (Cst cy, Cst dq), bs), z)) = []
  5.1589 +  | aset (Le (Add (Mult (Cst cy, Var ei), bs), z)) =
  5.1590 +    (if (ei = 0)
  5.1591 +      then (if (cy < 0) then [lin_add (bs, Cst 1)]
  5.1592 +             else [lin_neg bs, lin_add (lin_neg bs, Cst 1)])
  5.1593 +      else [])
  5.1594 +  | aset (Le (Add (Mult (Cst cy, Neg ds), bs), z)) = []
  5.1595 +  | aset (Le (Add (Mult (Cst cy, Add (dt, du)), bs), z)) = []
  5.1596 +  | aset (Le (Add (Mult (Cst cy, Sub (dv, dw)), bs), z)) = []
  5.1597 +  | aset (Le (Add (Mult (Cst cy, Mult (dx, dy)), bs), z)) = []
  5.1598 +  | aset (Le (Add (Mult (Var cz, co), bs), z)) = []
  5.1599 +  | aset (Le (Add (Mult (Neg da, co), bs), z)) = []
  5.1600 +  | aset (Le (Add (Mult (Add (db, dc), co), bs), z)) = []
  5.1601 +  | aset (Le (Add (Mult (Sub (dd, de), co), bs), z)) = []
  5.1602 +  | aset (Le (Add (Mult (Mult (df, dg), co), bs), z)) = []
  5.1603 +  | aset (Le (Sub (bt, bu), z)) = []
  5.1604 +  | aset (Le (Mult (bv, bw), z)) = []
  5.1605 +  | aset (Ge (aa, ab)) = []
  5.1606 +  | aset (Eq (Cst ek, ad)) = []
  5.1607 +  | aset (Eq (Var el, ad)) = []
  5.1608 +  | aset (Eq (Neg em, ad)) = []
  5.1609 +  | aset (Eq (Add (Cst fc, eo), ad)) = []
  5.1610 +  | aset (Eq (Add (Var fd, eo), ad)) = []
  5.1611 +  | aset (Eq (Add (Neg fe, eo), ad)) = []
  5.1612 +  | aset (Eq (Add (Add (ff, fg), eo), ad)) = []
  5.1613 +  | aset (Eq (Add (Sub (fh, fi), eo), ad)) = []
  5.1614 +  | aset (Eq (Add (Mult (Cst fu, Cst gm), eo), ad)) = []
  5.1615 +  | aset (Eq (Add (Mult (Cst fu, Var he), eo), ad)) =
  5.1616 +    (if (he = 0)
  5.1617 +      then (if (fu < 0) then [lin_add (eo, Cst 1)]
  5.1618 +             else [lin_add (lin_neg eo, Cst 1)])
  5.1619 +      else [])
  5.1620 +  | aset (Eq (Add (Mult (Cst fu, Neg go), eo), ad)) = []
  5.1621 +  | aset (Eq (Add (Mult (Cst fu, Add (gp, gq)), eo), ad)) = []
  5.1622 +  | aset (Eq (Add (Mult (Cst fu, Sub (gr, gs)), eo), ad)) = []
  5.1623 +  | aset (Eq (Add (Mult (Cst fu, Mult (gt, gu)), eo), ad)) = []
  5.1624 +  | aset (Eq (Add (Mult (Var fv, fk), eo), ad)) = []
  5.1625 +  | aset (Eq (Add (Mult (Neg fw, fk), eo), ad)) = []
  5.1626 +  | aset (Eq (Add (Mult (Add (fx, fy), fk), eo), ad)) = []
  5.1627 +  | aset (Eq (Add (Mult (Sub (fz, ga), fk), eo), ad)) = []
  5.1628 +  | aset (Eq (Add (Mult (Mult (gb, gc), fk), eo), ad)) = []
  5.1629 +  | aset (Eq (Sub (ep, eq), ad)) = []
  5.1630 +  | aset (Eq (Mult (er, es), ad)) = []
  5.1631 +  | aset (Divides (ae, af)) = []
  5.1632 +  | aset T = []
  5.1633 +  | aset F = []
  5.1634 +  | aset (NOT (Lt (hg, hh))) = []
  5.1635 +  | aset (NOT (Gt (hi, hj))) = []
  5.1636 +  | aset (NOT (Le (hk, hl))) = []
  5.1637 +  | aset (NOT (Ge (hm, hn))) = []
  5.1638 +  | aset (NOT (Eq (Cst ja, hp))) = []
  5.1639 +  | aset (NOT (Eq (Var jb, hp))) = []
  5.1640 +  | aset (NOT (Eq (Neg jc, hp))) = []
  5.1641 +  | aset (NOT (Eq (Add (Cst js, je), hp))) = []
  5.1642 +  | aset (NOT (Eq (Add (Var jt, je), hp))) = []
  5.1643 +  | aset (NOT (Eq (Add (Neg ju, je), hp))) = []
  5.1644 +  | aset (NOT (Eq (Add (Add (jv, jw), je), hp))) = []
  5.1645 +  | aset (NOT (Eq (Add (Sub (jx, jy), je), hp))) = []
  5.1646 +  | aset (NOT (Eq (Add (Mult (Cst kk, Cst lc), je), hp))) = []
  5.1647 +  | aset (NOT (Eq (Add (Mult (Cst kk, Var lu), je), hp))) =
  5.1648 +    (if (lu = 0) then (if (kk < 0) then [je] else [lin_neg je]) else [])
  5.1649 +  | aset (NOT (Eq (Add (Mult (Cst kk, Neg le), je), hp))) = []
  5.1650 +  | aset (NOT (Eq (Add (Mult (Cst kk, Add (lf, lg)), je), hp))) = []
  5.1651 +  | aset (NOT (Eq (Add (Mult (Cst kk, Sub (lh, li)), je), hp))) = []
  5.1652 +  | aset (NOT (Eq (Add (Mult (Cst kk, Mult (lj, lk)), je), hp))) = []
  5.1653 +  | aset (NOT (Eq (Add (Mult (Var kl, ka), je), hp))) = []
  5.1654 +  | aset (NOT (Eq (Add (Mult (Neg km, ka), je), hp))) = []
  5.1655 +  | aset (NOT (Eq (Add (Mult (Add (kn, ko), ka), je), hp))) = []
  5.1656 +  | aset (NOT (Eq (Add (Mult (Sub (kp, kq), ka), je), hp))) = []
  5.1657 +  | aset (NOT (Eq (Add (Mult (Mult (kr, ks), ka), je), hp))) = []
  5.1658 +  | aset (NOT (Eq (Sub (jf, jg), hp))) = []
  5.1659 +  | aset (NOT (Eq (Mult (jh, ji), hp))) = []
  5.1660 +  | aset (NOT (Divides (hq, hr))) = []
  5.1661 +  | aset (NOT T) = []
  5.1662 +  | aset (NOT F) = []
  5.1663 +  | aset (NOT (NOT hs)) = []
  5.1664 +  | aset (NOT (And (ht, hu))) = []
  5.1665 +  | aset (NOT (Or (hv, hw))) = []
  5.1666 +  | aset (NOT (Imp (hx, hy))) = []
  5.1667 +  | aset (NOT (Equ (hz, ia))) = []
  5.1668 +  | aset (NOT (QAll ib)) = []
  5.1669 +  | aset (NOT (QEx ic)) = []
  5.1670 +  | aset (Imp (al, am)) = []
  5.1671 +  | aset (Equ (an, ao)) = []
  5.1672 +  | aset (QAll ap) = []
  5.1673 +  | aset (QEx aq) = [];
  5.1674 +
  5.1675 +fun op_mem x [] = false
  5.1676 +  | op_mem x (y :: ys) = (if (y = x) then true else op_mem x ys);
  5.1677 +
  5.1678 +fun list_insert x xs = (if op_mem x xs then xs else (x :: xs));
  5.1679 +
  5.1680 +fun list_set [] = []
  5.1681 +  | list_set (x :: xs) = list_insert x (list_set xs);
  5.1682 +
  5.1683 +fun bset (And (p, q)) = op_64 (bset p) (bset q)
  5.1684 +  | bset (Or (p, q)) = op_64 (bset p) (bset q)
  5.1685 +  | bset (Lt (u, v)) = []
  5.1686 +  | bset (Gt (w, x)) = []
  5.1687 +  | bset (Le (Cst bo, z)) = []
  5.1688 +  | bset (Le (Var bp, z)) = []
  5.1689 +  | bset (Le (Neg bq, z)) = []
  5.1690 +  | bset (Le (Add (Cst cg, bs), z)) = []
  5.1691 +  | bset (Le (Add (Var ch, bs), z)) = []
  5.1692 +  | bset (Le (Add (Neg ci, bs), z)) = []
  5.1693 +  | bset (Le (Add (Add (cj, ck), bs), z)) = []
  5.1694 +  | bset (Le (Add (Sub (cl, cm), bs), z)) = []
  5.1695 +  | bset (Le (Add (Mult (Cst cy, Cst dq), bs), z)) = []
  5.1696 +  | bset (Le (Add (Mult (Cst cy, Var ei), bs), z)) =
  5.1697 +    (if (ei = 0)
  5.1698 +      then (if (cy < 0) then [lin_add (bs, Cst ~1), bs]
  5.1699 +             else [lin_add (lin_neg bs, Cst ~1)])
  5.1700 +      else [])
  5.1701 +  | bset (Le (Add (Mult (Cst cy, Neg ds), bs), z)) = []
  5.1702 +  | bset (Le (Add (Mult (Cst cy, Add (dt, du)), bs), z)) = []
  5.1703 +  | bset (Le (Add (Mult (Cst cy, Sub (dv, dw)), bs), z)) = []
  5.1704 +  | bset (Le (Add (Mult (Cst cy, Mult (dx, dy)), bs), z)) = []
  5.1705 +  | bset (Le (Add (Mult (Var cz, co), bs), z)) = []
  5.1706 +  | bset (Le (Add (Mult (Neg da, co), bs), z)) = []
  5.1707 +  | bset (Le (Add (Mult (Add (db, dc), co), bs), z)) = []
  5.1708 +  | bset (Le (Add (Mult (Sub (dd, de), co), bs), z)) = []
  5.1709 +  | bset (Le (Add (Mult (Mult (df, dg), co), bs), z)) = []
  5.1710 +  | bset (Le (Sub (bt, bu), z)) = []
  5.1711 +  | bset (Le (Mult (bv, bw), z)) = []
  5.1712 +  | bset (Ge (aa, ab)) = []
  5.1713 +  | bset (Eq (Cst ek, ad)) = []
  5.1714 +  | bset (Eq (Var el, ad)) = []
  5.1715 +  | bset (Eq (Neg em, ad)) = []
  5.1716 +  | bset (Eq (Add (Cst fc, eo), ad)) = []
  5.1717 +  | bset (Eq (Add (Var fd, eo), ad)) = []
  5.1718 +  | bset (Eq (Add (Neg fe, eo), ad)) = []
  5.1719 +  | bset (Eq (Add (Add (ff, fg), eo), ad)) = []
  5.1720 +  | bset (Eq (Add (Sub (fh, fi), eo), ad)) = []
  5.1721 +  | bset (Eq (Add (Mult (Cst fu, Cst gm), eo), ad)) = []
  5.1722 +  | bset (Eq (Add (Mult (Cst fu, Var he), eo), ad)) =
  5.1723 +    (if (he = 0)
  5.1724 +      then (if (fu < 0) then [lin_add (eo, Cst ~1)]
  5.1725 +             else [lin_add (lin_neg eo, Cst ~1)])
  5.1726 +      else [])
  5.1727 +  | bset (Eq (Add (Mult (Cst fu, Neg go), eo), ad)) = []
  5.1728 +  | bset (Eq (Add (Mult (Cst fu, Add (gp, gq)), eo), ad)) = []
  5.1729 +  | bset (Eq (Add (Mult (Cst fu, Sub (gr, gs)), eo), ad)) = []
  5.1730 +  | bset (Eq (Add (Mult (Cst fu, Mult (gt, gu)), eo), ad)) = []
  5.1731 +  | bset (Eq (Add (Mult (Var fv, fk), eo), ad)) = []
  5.1732 +  | bset (Eq (Add (Mult (Neg fw, fk), eo), ad)) = []
  5.1733 +  | bset (Eq (Add (Mult (Add (fx, fy), fk), eo), ad)) = []
  5.1734 +  | bset (Eq (Add (Mult (Sub (fz, ga), fk), eo), ad)) = []
  5.1735 +  | bset (Eq (Add (Mult (Mult (gb, gc), fk), eo), ad)) = []
  5.1736 +  | bset (Eq (Sub (ep, eq), ad)) = []
  5.1737 +  | bset (Eq (Mult (er, es), ad)) = []
  5.1738 +  | bset (Divides (ae, af)) = []
  5.1739 +  | bset T = []
  5.1740 +  | bset F = []
  5.1741 +  | bset (NOT (Lt (hg, hh))) = []
  5.1742 +  | bset (NOT (Gt (hi, hj))) = []
  5.1743 +  | bset (NOT (Le (hk, hl))) = []
  5.1744 +  | bset (NOT (Ge (hm, hn))) = []
  5.1745 +  | bset (NOT (Eq (Cst ja, hp))) = []
  5.1746 +  | bset (NOT (Eq (Var jb, hp))) = []
  5.1747 +  | bset (NOT (Eq (Neg jc, hp))) = []
  5.1748 +  | bset (NOT (Eq (Add (Cst js, je), hp))) = []
  5.1749 +  | bset (NOT (Eq (Add (Var jt, je), hp))) = []
  5.1750 +  | bset (NOT (Eq (Add (Neg ju, je), hp))) = []
  5.1751 +  | bset (NOT (Eq (Add (Add (jv, jw), je), hp))) = []
  5.1752 +  | bset (NOT (Eq (Add (Sub (jx, jy), je), hp))) = []
  5.1753 +  | bset (NOT (Eq (Add (Mult (Cst kk, Cst lc), je), hp))) = []
  5.1754 +  | bset (NOT (Eq (Add (Mult (Cst kk, Var lu), je), hp))) =
  5.1755 +    (if (lu = 0) then (if (kk < 0) then [je] else [lin_neg je]) else [])
  5.1756 +  | bset (NOT (Eq (Add (Mult (Cst kk, Neg le), je), hp))) = []
  5.1757 +  | bset (NOT (Eq (Add (Mult (Cst kk, Add (lf, lg)), je), hp))) = []
  5.1758 +  | bset (NOT (Eq (Add (Mult (Cst kk, Sub (lh, li)), je), hp))) = []
  5.1759 +  | bset (NOT (Eq (Add (Mult (Cst kk, Mult (lj, lk)), je), hp))) = []
  5.1760 +  | bset (NOT (Eq (Add (Mult (Var kl, ka), je), hp))) = []
  5.1761 +  | bset (NOT (Eq (Add (Mult (Neg km, ka), je), hp))) = []
  5.1762 +  | bset (NOT (Eq (Add (Mult (Add (kn, ko), ka), je), hp))) = []
  5.1763 +  | bset (NOT (Eq (Add (Mult (Sub (kp, kq), ka), je), hp))) = []
  5.1764 +  | bset (NOT (Eq (Add (Mult (Mult (kr, ks), ka), je), hp))) = []
  5.1765 +  | bset (NOT (Eq (Sub (jf, jg), hp))) = []
  5.1766 +  | bset (NOT (Eq (Mult (jh, ji), hp))) = []
  5.1767 +  | bset (NOT (Divides (hq, hr))) = []
  5.1768 +  | bset (NOT T) = []
  5.1769 +  | bset (NOT F) = []
  5.1770 +  | bset (NOT (NOT hs)) = []
  5.1771 +  | bset (NOT (And (ht, hu))) = []
  5.1772 +  | bset (NOT (Or (hv, hw))) = []
  5.1773 +  | bset (NOT (Imp (hx, hy))) = []
  5.1774 +  | bset (NOT (Equ (hz, ia))) = []
  5.1775 +  | bset (NOT (QAll ib)) = []
  5.1776 +  | bset (NOT (QEx ic)) = []
  5.1777 +  | bset (Imp (al, am)) = []
  5.1778 +  | bset (Equ (an, ao)) = []
  5.1779 +  | bset (QAll ap) = []
  5.1780 +  | bset (QEx aq) = [];
  5.1781 +
  5.1782 +fun adjustcoeff (l, Le (Add (Mult (Cst c, Var 0), r), Cst i)) =
  5.1783 +    (if (c <= 0)
  5.1784 +      then Le (Add (Mult (Cst ~1, Var 0), lin_mul (~ (op_div_def1 l c), r)),
  5.1785 +                Cst 0)
  5.1786 +      else Le (Add (Mult (Cst 1, Var 0), lin_mul (op_div_def1 l c, r)), Cst 0))
  5.1787 +  | adjustcoeff (l, Eq (Add (Mult (Cst c, Var 0), r), Cst i)) =
  5.1788 +    Eq (Add (Mult (Cst 1, Var 0), lin_mul (op_div_def1 l c, r)), Cst 0)
  5.1789 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst c, Var 0), r), Cst i))) =
  5.1790 +    NOT (Eq (Add (Mult (Cst 1, Var 0), lin_mul (op_div_def1 l c, r)), Cst 0))
  5.1791 +  | adjustcoeff (l, And (p, q)) = And (adjustcoeff (l, p), adjustcoeff (l, q))
  5.1792 +  | adjustcoeff (l, Or (p, q)) = Or (adjustcoeff (l, p), adjustcoeff (l, q))
  5.1793 +  | adjustcoeff (l, Lt (w, x)) = Lt (w, x)
  5.1794 +  | adjustcoeff (l, Gt (y, z)) = Gt (y, z)
  5.1795 +  | adjustcoeff (l, Le (Cst bq, ab)) = Le (Cst bq, ab)
  5.1796 +  | adjustcoeff (l, Le (Var br, ab)) = Le (Var br, ab)
  5.1797 +  | adjustcoeff (l, Le (Neg bs, ab)) = Le (Neg bs, ab)
  5.1798 +  | adjustcoeff (l, Le (Add (Cst ci, bu), ab)) = Le (Add (Cst ci, bu), ab)
  5.1799 +  | adjustcoeff (l, Le (Add (Var cj, bu), ab)) = Le (Add (Var cj, bu), ab)
  5.1800 +  | adjustcoeff (l, Le (Add (Neg ck, bu), ab)) = Le (Add (Neg ck, bu), ab)
  5.1801 +  | adjustcoeff (l, Le (Add (Add (cl, cm), bu), ab)) =
  5.1802 +    Le (Add (Add (cl, cm), bu), ab)
  5.1803 +  | adjustcoeff (l, Le (Add (Sub (cn, co), bu), ab)) =
  5.1804 +    Le (Add (Sub (cn, co), bu), ab)
  5.1805 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Cst ds), bu), ab)) =
  5.1806 +    Le (Add (Mult (Cst da, Cst ds), bu), ab)
  5.1807 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Var 0), bu), Var en)) =
  5.1808 +    Le (Add (Mult (Cst da, Var 0), bu), Var en)
  5.1809 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Var 0), bu), Neg eo)) =
  5.1810 +    Le (Add (Mult (Cst da, Var 0), bu), Neg eo)
  5.1811 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Var 0), bu), Add (ep, eq))) =
  5.1812 +    Le (Add (Mult (Cst da, Var 0), bu), Add (ep, eq))
  5.1813 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Var 0), bu), Sub (er, es))) =
  5.1814 +    Le (Add (Mult (Cst da, Var 0), bu), Sub (er, es))
  5.1815 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Var 0), bu), Mult (et, eu))) =
  5.1816 +    Le (Add (Mult (Cst da, Var 0), bu), Mult (et, eu))
  5.1817 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Var ek), bu), ab)) =
  5.1818 +    Le (Add (Mult (Cst da, Var ek), bu), ab)
  5.1819 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Neg du), bu), ab)) =
  5.1820 +    Le (Add (Mult (Cst da, Neg du), bu), ab)
  5.1821 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Add (dv, dw)), bu), ab)) =
  5.1822 +    Le (Add (Mult (Cst da, Add (dv, dw)), bu), ab)
  5.1823 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Sub (dx, dy)), bu), ab)) =
  5.1824 +    Le (Add (Mult (Cst da, Sub (dx, dy)), bu), ab)
  5.1825 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Mult (dz, ea)), bu), ab)) =
  5.1826 +    Le (Add (Mult (Cst da, Mult (dz, ea)), bu), ab)
  5.1827 +  | adjustcoeff (l, Le (Add (Mult (Var db, cq), bu), ab)) =
  5.1828 +    Le (Add (Mult (Var db, cq), bu), ab)
  5.1829 +  | adjustcoeff (l, Le (Add (Mult (Neg dc, cq), bu), ab)) =
  5.1830 +    Le (Add (Mult (Neg dc, cq), bu), ab)
  5.1831 +  | adjustcoeff (l, Le (Add (Mult (Add (dd, de), cq), bu), ab)) =
  5.1832 +    Le (Add (Mult (Add (dd, de), cq), bu), ab)
  5.1833 +  | adjustcoeff (l, Le (Add (Mult (Sub (df, dg), cq), bu), ab)) =
  5.1834 +    Le (Add (Mult (Sub (df, dg), cq), bu), ab)
  5.1835 +  | adjustcoeff (l, Le (Add (Mult (Mult (dh, di), cq), bu), ab)) =
  5.1836 +    Le (Add (Mult (Mult (dh, di), cq), bu), ab)
  5.1837 +  | adjustcoeff (l, Le (Sub (bv, bw), ab)) = Le (Sub (bv, bw), ab)
  5.1838 +  | adjustcoeff (l, Le (Mult (bx, by), ab)) = Le (Mult (bx, by), ab)
  5.1839 +  | adjustcoeff (l, Ge (ac, ad)) = Ge (ac, ad)
  5.1840 +  | adjustcoeff (l, Eq (Cst fe, af)) = Eq (Cst fe, af)
  5.1841 +  | adjustcoeff (l, Eq (Var ff, af)) = Eq (Var ff, af)
  5.1842 +  | adjustcoeff (l, Eq (Neg fg, af)) = Eq (Neg fg, af)
  5.1843 +  | adjustcoeff (l, Eq (Add (Cst fw, fi), af)) = Eq (Add (Cst fw, fi), af)
  5.1844 +  | adjustcoeff (l, Eq (Add (Var fx, fi), af)) = Eq (Add (Var fx, fi), af)
  5.1845 +  | adjustcoeff (l, Eq (Add (Neg fy, fi), af)) = Eq (Add (Neg fy, fi), af)
  5.1846 +  | adjustcoeff (l, Eq (Add (Add (fz, ga), fi), af)) =
  5.1847 +    Eq (Add (Add (fz, ga), fi), af)
  5.1848 +  | adjustcoeff (l, Eq (Add (Sub (gb, gc), fi), af)) =
  5.1849 +    Eq (Add (Sub (gb, gc), fi), af)
  5.1850 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Cst hg), fi), af)) =
  5.1851 +    Eq (Add (Mult (Cst go, Cst hg), fi), af)
  5.1852 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Var 0), fi), Var ib)) =
  5.1853 +    Eq (Add (Mult (Cst go, Var 0), fi), Var ib)
  5.1854 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Var 0), fi), Neg ic)) =
  5.1855 +    Eq (Add (Mult (Cst go, Var 0), fi), Neg ic)
  5.1856 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Var 0), fi), Add (id, ie))) =
  5.1857 +    Eq (Add (Mult (Cst go, Var 0), fi), Add (id, ie))
  5.1858 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Var 0), fi), Sub (if', ig))) =
  5.1859 +    Eq (Add (Mult (Cst go, Var 0), fi), Sub (if', ig))
  5.1860 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Var 0), fi), Mult (ih, ii))) =
  5.1861 +    Eq (Add (Mult (Cst go, Var 0), fi), Mult (ih, ii))
  5.1862 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Var hy), fi), af)) =
  5.1863 +    Eq (Add (Mult (Cst go, Var hy), fi), af)
  5.1864 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Neg hi), fi), af)) =
  5.1865 +    Eq (Add (Mult (Cst go, Neg hi), fi), af)
  5.1866 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Add (hj, hk)), fi), af)) =
  5.1867 +    Eq (Add (Mult (Cst go, Add (hj, hk)), fi), af)
  5.1868 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Sub (hl, hm)), fi), af)) =
  5.1869 +    Eq (Add (Mult (Cst go, Sub (hl, hm)), fi), af)
  5.1870 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Mult (hn, ho)), fi), af)) =
  5.1871 +    Eq (Add (Mult (Cst go, Mult (hn, ho)), fi), af)
  5.1872 +  | adjustcoeff (l, Eq (Add (Mult (Var gp, ge), fi), af)) =
  5.1873 +    Eq (Add (Mult (Var gp, ge), fi), af)
  5.1874 +  | adjustcoeff (l, Eq (Add (Mult (Neg gq, ge), fi), af)) =
  5.1875 +    Eq (Add (Mult (Neg gq, ge), fi), af)
  5.1876 +  | adjustcoeff (l, Eq (Add (Mult (Add (gr, gs), ge), fi), af)) =
  5.1877 +    Eq (Add (Mult (Add (gr, gs), ge), fi), af)
  5.1878 +  | adjustcoeff (l, Eq (Add (Mult (Sub (gt, gu), ge), fi), af)) =
  5.1879 +    Eq (Add (Mult (Sub (gt, gu), ge), fi), af)
  5.1880 +  | adjustcoeff (l, Eq (Add (Mult (Mult (gv, gw), ge), fi), af)) =
  5.1881 +    Eq (Add (Mult (Mult (gv, gw), ge), fi), af)
  5.1882 +  | adjustcoeff (l, Eq (Sub (fj, fk), af)) = Eq (Sub (fj, fk), af)
  5.1883 +  | adjustcoeff (l, Eq (Mult (fl, fm), af)) = Eq (Mult (fl, fm), af)
  5.1884 +  | adjustcoeff (l, Divides (Cst is, Cst jk)) = Divides (Cst is, Cst jk)
  5.1885 +  | adjustcoeff (l, Divides (Cst is, Var jl)) = Divides (Cst is, Var jl)
  5.1886 +  | adjustcoeff (l, Divides (Cst is, Neg jm)) = Divides (Cst is, Neg jm)
  5.1887 +  | adjustcoeff (l, Divides (Cst is, Add (Cst kc, jo))) =
  5.1888 +    Divides (Cst is, Add (Cst kc, jo))
  5.1889 +  | adjustcoeff (l, Divides (Cst is, Add (Var kd, jo))) =
  5.1890 +    Divides (Cst is, Add (Var kd, jo))
  5.1891 +  | adjustcoeff (l, Divides (Cst is, Add (Neg ke, jo))) =
  5.1892 +    Divides (Cst is, Add (Neg ke, jo))
  5.1893 +  | adjustcoeff (l, Divides (Cst is, Add (Add (kf, kg), jo))) =
  5.1894 +    Divides (Cst is, Add (Add (kf, kg), jo))
  5.1895 +  | adjustcoeff (l, Divides (Cst is, Add (Sub (kh, ki), jo))) =
  5.1896 +    Divides (Cst is, Add (Sub (kh, ki), jo))
  5.1897 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Cst ku, Cst lm), jo))) =
  5.1898 +    Divides (Cst is, Add (Mult (Cst ku, Cst lm), jo))
  5.1899 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Cst ku, Var me), jo))) =
  5.1900 +    (if (me = 0)
  5.1901 +      then Divides
  5.1902 +             (Cst (op_div_def1 l ku * is),
  5.1903 +               Add (Mult (Cst 1, Var 0), lin_mul (op_div_def1 l ku, jo)))
  5.1904 +      else Divides
  5.1905 +             (Cst is,
  5.1906 +               Add (Mult (Cst ku, Var (op_45_def0 me id_1_def0 + 1)), jo)))
  5.1907 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Cst ku, Neg lo), jo))) =
  5.1908 +    Divides (Cst is, Add (Mult (Cst ku, Neg lo), jo))
  5.1909 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Cst ku, Add (lp, lq)), jo))) =
  5.1910 +    Divides (Cst is, Add (Mult (Cst ku, Add (lp, lq)), jo))
  5.1911 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Cst ku, Sub (lr, ls)), jo))) =
  5.1912 +    Divides (Cst is, Add (Mult (Cst ku, Sub (lr, ls)), jo))
  5.1913 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Cst ku, Mult (lt, lu)), jo))) =
  5.1914 +    Divides (Cst is, Add (Mult (Cst ku, Mult (lt, lu)), jo))
  5.1915 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Var kv, kk), jo))) =
  5.1916 +    Divides (Cst is, Add (Mult (Var kv, kk), jo))
  5.1917 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Neg kw, kk), jo))) =
  5.1918 +    Divides (Cst is, Add (Mult (Neg kw, kk), jo))
  5.1919 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Add (kx, ky), kk), jo))) =
  5.1920 +    Divides (Cst is, Add (Mult (Add (kx, ky), kk), jo))
  5.1921 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Sub (kz, la), kk), jo))) =
  5.1922 +    Divides (Cst is, Add (Mult (Sub (kz, la), kk), jo))
  5.1923 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Mult (lb, lc), kk), jo))) =
  5.1924 +    Divides (Cst is, Add (Mult (Mult (lb, lc), kk), jo))
  5.1925 +  | adjustcoeff (l, Divides (Cst is, Sub (jp, jq))) =
  5.1926 +    Divides (Cst is, Sub (jp, jq))
  5.1927 +  | adjustcoeff (l, Divides (Cst is, Mult (jr, js))) =
  5.1928 +    Divides (Cst is, Mult (jr, js))
  5.1929 +  | adjustcoeff (l, Divides (Var it, ah)) = Divides (Var it, ah)
  5.1930 +  | adjustcoeff (l, Divides (Neg iu, ah)) = Divides (Neg iu, ah)
  5.1931 +  | adjustcoeff (l, Divides (Add (iv, iw), ah)) = Divides (Add (iv, iw), ah)
  5.1932 +  | adjustcoeff (l, Divides (Sub (ix, iy), ah)) = Divides (Sub (ix, iy), ah)
  5.1933 +  | adjustcoeff (l, Divides (Mult (iz, ja), ah)) = Divides (Mult (iz, ja), ah)
  5.1934 +  | adjustcoeff (l, T) = T
  5.1935 +  | adjustcoeff (l, F) = F
  5.1936 +  | adjustcoeff (l, NOT (Lt (mg, mh))) = NOT (Lt (mg, mh))
  5.1937 +  | adjustcoeff (l, NOT (Gt (mi, mj))) = NOT (Gt (mi, mj))
  5.1938 +  | adjustcoeff (l, NOT (Le (mk, ml))) = NOT (Le (mk, ml))
  5.1939 +  | adjustcoeff (l, NOT (Ge (mm, mn))) = NOT (Ge (mm, mn))
  5.1940 +  | adjustcoeff (l, NOT (Eq (Cst oa, mp))) = NOT (Eq (Cst oa, mp))
  5.1941 +  | adjustcoeff (l, NOT (Eq (Var ob, mp))) = NOT (Eq (Var ob, mp))
  5.1942 +  | adjustcoeff (l, NOT (Eq (Neg oc, mp))) = NOT (Eq (Neg oc, mp))
  5.1943 +  | adjustcoeff (l, NOT (Eq (Add (Cst os, oe), mp))) =
  5.1944 +    NOT (Eq (Add (Cst os, oe), mp))
  5.1945 +  | adjustcoeff (l, NOT (Eq (Add (Var ot, oe), mp))) =
  5.1946 +    NOT (Eq (Add (Var ot, oe), mp))
  5.1947 +  | adjustcoeff (l, NOT (Eq (Add (Neg ou, oe), mp))) =
  5.1948 +    NOT (Eq (Add (Neg ou, oe), mp))
  5.1949 +  | adjustcoeff (l, NOT (Eq (Add (Add (ov, ow), oe), mp))) =
  5.1950 +    NOT (Eq (Add (Add (ov, ow), oe), mp))
  5.1951 +  | adjustcoeff (l, NOT (Eq (Add (Sub (ox, oy), oe), mp))) =
  5.1952 +    NOT (Eq (Add (Sub (ox, oy), oe), mp))
  5.1953 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Cst qc), oe), mp))) =
  5.1954 +    NOT (Eq (Add (Mult (Cst pk, Cst qc), oe), mp))
  5.1955 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Var qx))) =
  5.1956 +    NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Var qx))
  5.1957 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Neg qy))) =
  5.1958 +    NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Neg qy))
  5.1959 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Add (qz, ra)))) =
  5.1960 +    NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Add (qz, ra)))
  5.1961 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Sub (rb, rc)))) =
  5.1962 +    NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Sub (rb, rc)))
  5.1963 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Mult (rd, re)))) =
  5.1964 +    NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Mult (rd, re)))
  5.1965 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Var qu), oe), mp))) =
  5.1966 +    NOT (Eq (Add (Mult (Cst pk, Var qu), oe), mp))
  5.1967 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Neg qe), oe), mp))) =
  5.1968 +    NOT (Eq (Add (Mult (Cst pk, Neg qe), oe), mp))
  5.1969 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Add (qf, qg)), oe), mp))) =
  5.1970 +    NOT (Eq (Add (Mult (Cst pk, Add (qf, qg)), oe), mp))
  5.1971 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Sub (qh, qi)), oe), mp))) =
  5.1972 +    NOT (Eq (Add (Mult (Cst pk, Sub (qh, qi)), oe), mp))
  5.1973 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Mult (qj, qk)), oe), mp))) =
  5.1974 +    NOT (Eq (Add (Mult (Cst pk, Mult (qj, qk)), oe), mp))
  5.1975 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Var pl, pa), oe), mp))) =
  5.1976 +    NOT (Eq (Add (Mult (Var pl, pa), oe), mp))
  5.1977 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Neg pm, pa), oe), mp))) =
  5.1978 +    NOT (Eq (Add (Mult (Neg pm, pa), oe), mp))
  5.1979 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Add (pn, po), pa), oe), mp))) =
  5.1980 +    NOT (Eq (Add (Mult (Add (pn, po), pa), oe), mp))
  5.1981 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Sub (pp, pq), pa), oe), mp))) =
  5.1982 +    NOT (Eq (Add (Mult (Sub (pp, pq), pa), oe), mp))
  5.1983 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Mult (pr, ps), pa), oe), mp))) =
  5.1984 +    NOT (Eq (Add (Mult (Mult (pr, ps), pa), oe), mp))
  5.1985 +  | adjustcoeff (l, NOT (Eq (Sub (of', og), mp))) = NOT (Eq (Sub (of', og), mp))
  5.1986 +  | adjustcoeff (l, NOT (Eq (Mult (oh, oi), mp))) = NOT (Eq (Mult (oh, oi), mp))
  5.1987 +  | adjustcoeff (l, NOT (Divides (Cst ro, Cst sg))) =
  5.1988 +    NOT (Divides (Cst ro, Cst sg))
  5.1989 +  | adjustcoeff (l, NOT (Divides (Cst ro, Var sh))) =
  5.1990 +    NOT (Divides (Cst ro, Var sh))
  5.1991 +  | adjustcoeff (l, NOT (Divides (Cst ro, Neg si))) =
  5.1992 +    NOT (Divides (Cst ro, Neg si))
  5.1993 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Cst sy, sk)))) =
  5.1994 +    NOT (Divides (Cst ro, Add (Cst sy, sk)))
  5.1995 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Var sz, sk)))) =
  5.1996 +    NOT (Divides (Cst ro, Add (Var sz, sk)))
  5.1997 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Neg ta, sk)))) =
  5.1998 +    NOT (Divides (Cst ro, Add (Neg ta, sk)))
  5.1999 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Add (tb, tc), sk)))) =
  5.2000 +    NOT (Divides (Cst ro, Add (Add (tb, tc), sk)))
  5.2001 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Sub (td, te), sk)))) =
  5.2002 +    NOT (Divides (Cst ro, Add (Sub (td, te), sk)))
  5.2003 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Cst tq, Cst ui), sk)))) =
  5.2004 +    NOT (Divides (Cst ro, Add (Mult (Cst tq, Cst ui), sk)))
  5.2005 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Cst tq, Var va), sk)))) =
  5.2006 +    (if (va = 0)
  5.2007 +      then NOT (Divides
  5.2008 +                  (Cst (op_div_def1 l tq * ro),
  5.2009 +                    Add (Mult (Cst 1, Var 0), lin_mul (op_div_def1 l tq, sk))))
  5.2010 +      else NOT (Divides
  5.2011 +                  (Cst ro,
  5.2012 +                    Add (Mult (Cst tq, Var (op_45_def0 va id_1_def0 + 1)),
  5.2013 +                          sk))))
  5.2014 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Cst tq, Neg uk), sk)))) =
  5.2015 +    NOT (Divides (Cst ro, Add (Mult (Cst tq, Neg uk), sk)))
  5.2016 +  | adjustcoeff
  5.2017 +      (l, NOT (Divides (Cst ro, Add (Mult (Cst tq, Add (ul, um)), sk)))) =
  5.2018 +    NOT (Divides (Cst ro, Add (Mult (Cst tq, Add (ul, um)), sk)))
  5.2019 +  | adjustcoeff
  5.2020 +      (l, NOT (Divides (Cst ro, Add (Mult (Cst tq, Sub (un, uo)), sk)))) =
  5.2021 +    NOT (Divides (Cst ro, Add (Mult (Cst tq, Sub (un, uo)), sk)))
  5.2022 +  | adjustcoeff
  5.2023 +      (l, NOT (Divides (Cst ro, Add (Mult (Cst tq, Mult (up, uq)), sk)))) =
  5.2024 +    NOT (Divides (Cst ro, Add (Mult (Cst tq, Mult (up, uq)), sk)))
  5.2025 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Var tr, tg), sk)))) =
  5.2026 +    NOT (Divides (Cst ro, Add (Mult (Var tr, tg), sk)))
  5.2027 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Neg ts, tg), sk)))) =
  5.2028 +    NOT (Divides (Cst ro, Add (Mult (Neg ts, tg), sk)))
  5.2029 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Add (tt, tu), tg), sk)))) =
  5.2030 +    NOT (Divides (Cst ro, Add (Mult (Add (tt, tu), tg), sk)))
  5.2031 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Sub (tv, tw), tg), sk)))) =
  5.2032 +    NOT (Divides (Cst ro, Add (Mult (Sub (tv, tw), tg), sk)))
  5.2033 +  | adjustcoeff
  5.2034 +      (l, NOT (Divides (Cst ro, Add (Mult (Mult (tx, ty), tg), sk)))) =
  5.2035 +    NOT (Divides (Cst ro, Add (Mult (Mult (tx, ty), tg), sk)))
  5.2036 +  | adjustcoeff (l, NOT (Divides (Cst ro, Sub (sl, sm)))) =
  5.2037 +    NOT (Divides (Cst ro, Sub (sl, sm)))
  5.2038 +  | adjustcoeff (l, NOT (Divides (Cst ro, Mult (sn, so)))) =
  5.2039 +    NOT (Divides (Cst ro, Mult (sn, so)))
  5.2040 +  | adjustcoeff (l, NOT (Divides (Var rp, mr))) = NOT (Divides (Var rp, mr))
  5.2041 +  | adjustcoeff (l, NOT (Divides (Neg rq, mr))) = NOT (Divides (Neg rq, mr))
  5.2042 +  | adjustcoeff (l, NOT (Divides (Add (rr, rs), mr))) =
  5.2043 +    NOT (Divides (Add (rr, rs), mr))
  5.2044 +  | adjustcoeff (l, NOT (Divides (Sub (rt, ru), mr))) =
  5.2045 +    NOT (Divides (Sub (rt, ru), mr))
  5.2046 +  | adjustcoeff (l, NOT (Divides (Mult (rv, rw), mr))) =
  5.2047 +    NOT (Divides (Mult (rv, rw), mr))
  5.2048 +  | adjustcoeff (l, NOT T) = NOT T
  5.2049 +  | adjustcoeff (l, NOT F) = NOT F
  5.2050 +  | adjustcoeff (l, NOT (NOT ms)) = NOT (NOT ms)
  5.2051 +  | adjustcoeff (l, NOT (And (mt, mu))) = NOT (And (mt, mu))
  5.2052 +  | adjustcoeff (l, NOT (Or (mv, mw))) = NOT (Or (mv, mw))
  5.2053 +  | adjustcoeff (l, NOT (Imp (mx, my))) = NOT (Imp (mx, my))
  5.2054 +  | adjustcoeff (l, NOT (Equ (mz, na))) = NOT (Equ (mz, na))
  5.2055 +  | adjustcoeff (l, NOT (QAll nb)) = NOT (QAll nb)
  5.2056 +  | adjustcoeff (l, NOT (QEx nc)) = NOT (QEx nc)
  5.2057 +  | adjustcoeff (l, Imp (an, ao)) = Imp (an, ao)
  5.2058 +  | adjustcoeff (l, Equ (ap, aq)) = Equ (ap, aq)
  5.2059 +  | adjustcoeff (l, QAll ar) = QAll ar
  5.2060 +  | adjustcoeff (l, QEx as') = QEx as';
  5.2061 +
  5.2062 +fun formlcm (Le (Add (Mult (Cst c, Var 0), r), Cst i)) = abs c
  5.2063 +  | formlcm (Eq (Add (Mult (Cst c, Var 0), r), Cst i)) = abs c
  5.2064 +  | formlcm (NOT p) = formlcm p
  5.2065 +  | formlcm (And (p, q)) = ilcm (formlcm p) (formlcm q)
  5.2066 +  | formlcm (Or (p, q)) = ilcm (formlcm p) (formlcm q)
  5.2067 +  | formlcm (Lt (u, v)) = 1
  5.2068 +  | formlcm (Gt (w, x)) = 1
  5.2069 +  | formlcm (Le (Cst bo, z)) = 1
  5.2070 +  | formlcm (Le (Var bp, z)) = 1
  5.2071 +  | formlcm (Le (Neg bq, z)) = 1
  5.2072 +  | formlcm (Le (Add (Cst cg, bs), z)) = 1
  5.2073 +  | formlcm (Le (Add (Var ch, bs), z)) = 1
  5.2074 +  | formlcm (Le (Add (Neg ci, bs), z)) = 1
  5.2075 +  | formlcm (Le (Add (Add (cj, ck), bs), z)) = 1
  5.2076 +  | formlcm (Le (Add (Sub (cl, cm), bs), z)) = 1
  5.2077 +  | formlcm (Le (Add (Mult (Cst cy, Cst dq), bs), z)) = 1
  5.2078 +  | formlcm (Le (Add (Mult (Cst cy, Var 0), bs), Var el)) = 1
  5.2079 +  | formlcm (Le (Add (Mult (Cst cy, Var 0), bs), Neg em)) = 1
  5.2080 +  | formlcm (Le (Add (Mult (Cst cy, Var 0), bs), Add (en, eo))) = 1
  5.2081 +  | formlcm (Le (Add (Mult (Cst cy, Var 0), bs), Sub (ep, eq))) = 1
  5.2082 +  | formlcm (Le (Add (Mult (Cst cy, Var 0), bs), Mult (er, es))) = 1
  5.2083 +  | formlcm (Le (Add (Mult (Cst cy, Var ei ), bs), z)) = 1
  5.2084 +  | formlcm (Le (Add (Mult (Cst cy, Neg ds), bs), z)) = 1
  5.2085 +  | formlcm (Le (Add (Mult (Cst cy, Add (dt, du)), bs), z)) = 1
  5.2086 +  | formlcm (Le (Add (Mult (Cst cy, Sub (dv, dw)), bs), z)) = 1
  5.2087 +  | formlcm (Le (Add (Mult (Cst cy, Mult (dx, dy)), bs), z)) = 1
  5.2088 +  | formlcm (Le (Add (Mult (Var cz, co), bs), z)) = 1
  5.2089 +  | formlcm (Le (Add (Mult (Neg da, co), bs), z)) = 1
  5.2090 +  | formlcm (Le (Add (Mult (Add (db, dc), co), bs), z)) = 1
  5.2091 +  | formlcm (Le (Add (Mult (Sub (dd, de), co), bs), z)) = 1
  5.2092 +  | formlcm (Le (Add (Mult (Mult (df, dg), co), bs), z)) = 1
  5.2093 +  | formlcm (Le (Sub (bt, bu), z)) = 1
  5.2094 +  | formlcm (Le (Mult (bv, bw), z)) = 1
  5.2095 +  | formlcm (Ge (aa, ab)) = 1
  5.2096 +  | formlcm (Eq (Cst fc, ad)) = 1
  5.2097 +  | formlcm (Eq (Var fd, ad)) = 1
  5.2098 +  | formlcm (Eq (Neg fe, ad)) = 1
  5.2099 +  | formlcm (Eq (Add (Cst fu, fg), ad)) = 1
  5.2100 +  | formlcm (Eq (Add (Var fv, fg), ad)) = 1
  5.2101 +  | formlcm (Eq (Add (Neg fw, fg), ad)) = 1
  5.2102 +  | formlcm (Eq (Add (Add (fx, fy), fg), ad)) = 1
  5.2103 +  | formlcm (Eq (Add (Sub (fz, ga), fg), ad)) = 1
  5.2104 +  | formlcm (Eq (Add (Mult (Cst gm, Cst he), fg), ad)) = 1
  5.2105 +  | formlcm (Eq (Add (Mult (Cst gm, Var 0), fg), Var hz)) = 1
  5.2106 +  | formlcm (Eq (Add (Mult (Cst gm, Var 0), fg), Neg ia)) = 1
  5.2107 +  | formlcm (Eq (Add (Mult (Cst gm, Var 0), fg), Add (ib, ic))) = 1
  5.2108 +  | formlcm (Eq (Add (Mult (Cst gm, Var 0), fg), Sub (id, ie))) = 1
  5.2109 +  | formlcm (Eq (Add (Mult (Cst gm, Var 0), fg), Mult (if', ig))) = 1
  5.2110 +  | formlcm (Eq (Add (Mult (Cst gm, Var hw), fg), ad)) = 1
  5.2111 +  | formlcm (Eq (Add (Mult (Cst gm, Neg hg), fg), ad)) = 1
  5.2112 +  | formlcm (Eq (Add (Mult (Cst gm, Add (hh, hi)), fg), ad)) = 1
  5.2113 +  | formlcm (Eq (Add (Mult (Cst gm, Sub (hj, hk)), fg), ad)) = 1
  5.2114 +  | formlcm (Eq (Add (Mult (Cst gm, Mult (hl, hm)), fg), ad)) = 1
  5.2115 +  | formlcm (Eq (Add (Mult (Var gn, gc), fg), ad)) = 1
  5.2116 +  | formlcm (Eq (Add (Mult (Neg go, gc), fg), ad)) = 1
  5.2117 +  | formlcm (Eq (Add (Mult (Add (gp, gq), gc), fg), ad)) = 1
  5.2118 +  | formlcm (Eq (Add (Mult (Sub (gr, gs), gc), fg), ad)) = 1
  5.2119 +  | formlcm (Eq (Add (Mult (Mult (gt, gu), gc), fg), ad)) = 1
  5.2120 +  | formlcm (Eq (Sub (fh, fi), ad)) = 1
  5.2121 +  | formlcm (Eq (Mult (fj, fk), ad)) = 1
  5.2122 +  | formlcm (Divides (Cst iq, Cst ji)) = 1
  5.2123 +  | formlcm (Divides (Cst iq, Var jj)) = 1
  5.2124 +  | formlcm (Divides (Cst iq, Neg jk)) = 1
  5.2125 +  | formlcm (Divides (Cst iq, Add (Cst ka, jm))) = 1
  5.2126 +  | formlcm (Divides (Cst iq, Add (Var kb, jm))) = 1
  5.2127 +  | formlcm (Divides (Cst iq, Add (Neg kc, jm))) = 1
  5.2128 +  | formlcm (Divides (Cst iq, Add (Add (kd, ke), jm))) = 1
  5.2129 +  | formlcm (Divides (Cst iq, Add (Sub (kf, kg), jm))) = 1
  5.2130 +  | formlcm (Divides (Cst iq, Add (Mult (Cst ks, Cst lk), jm))) = 1
  5.2131 +  | formlcm (Divides (Cst iq, Add (Mult (Cst ks, Var mc), jm))) =
  5.2132 +    (if (mc = 0) then abs ks else 1)
  5.2133 +  | formlcm (Divides (Cst iq, Add (Mult (Cst ks, Neg lm), jm))) = 1
  5.2134 +  | formlcm (Divides (Cst iq, Add (Mult (Cst ks, Add (ln, lo)), jm))) = 1
  5.2135 +  | formlcm (Divides (Cst iq, Add (Mult (Cst ks, Sub (lp, lq)), jm))) = 1
  5.2136 +  | formlcm (Divides (Cst iq, Add (Mult (Cst ks, Mult (lr, ls)), jm))) = 1
  5.2137 +  | formlcm (Divides (Cst iq, Add (Mult (Var kt, ki), jm))) = 1
  5.2138 +  | formlcm (Divides (Cst iq, Add (Mult (Neg ku, ki), jm))) = 1
  5.2139 +  | formlcm (Divides (Cst iq, Add (Mult (Add (kv, kw), ki), jm))) = 1
  5.2140 +  | formlcm (Divides (Cst iq, Add (Mult (Sub (kx, ky), ki), jm))) = 1
  5.2141 +  | formlcm (Divides (Cst iq, Add (Mult (Mult (kz, la), ki), jm))) = 1
  5.2142 +  | formlcm (Divides (Cst iq, Sub (jn, jo))) = 1
  5.2143 +  | formlcm (Divides (Cst iq, Mult (jp, jq))) = 1
  5.2144 +  | formlcm (Divides (Var ir, af)) = 1
  5.2145 +  | formlcm (Divides (Neg is, af)) = 1
  5.2146 +  | formlcm (Divides (Add (it, iu), af)) = 1
  5.2147 +  | formlcm (Divides (Sub (iv, iw), af)) = 1
  5.2148 +  | formlcm (Divides (Mult (ix, iy), af)) = 1
  5.2149 +  | formlcm T = 1
  5.2150 +  | formlcm F = 1
  5.2151 +  | formlcm (Imp (al, am)) = 1
  5.2152 +  | formlcm (Equ (an, ao)) = 1
  5.2153 +  | formlcm (QAll ap) = 1
  5.2154 +  | formlcm (QEx aq) = 1;
  5.2155 +
  5.2156 +fun unitycoeff p =
  5.2157 +  let val l = formlcm p; val p' = adjustcoeff (l, p)
  5.2158 +  in (if (l = 1) then p'
  5.2159 +       else And (Divides (Cst l, Add (Mult (Cst 1, Var 0), Cst 0)), p'))
  5.2160 +  end;
  5.2161 +
  5.2162 +fun unify p =
  5.2163 +  let val q = unitycoeff p; val B = list_set (bset q); val A = list_set (aset q)
  5.2164 +  in (if op_60_61_def0 (size_def1 B) (size_def1 A) then (q, B)
  5.2165 +       else (mirror q, map lin_neg A))
  5.2166 +  end;
  5.2167 +
  5.2168 +fun cooper p =
  5.2169 +  lift_un (fn q => decrvars (explode_minf (unify q))) (linform (nnf p));
  5.2170 +
  5.2171 +fun pa p = lift_un psimpl (qelim (cooper, p));
  5.2172 +
  5.2173 +val test = pa;
  5.2174 +
  5.2175 +end;
     6.1 --- a/src/HOL/IsaMakefile	Wed Sep 14 10:24:39 2005 +0200
     6.2 +++ b/src/HOL/IsaMakefile	Wed Sep 14 17:25:52 2005 +0200
     6.3 @@ -78,13 +78,15 @@
     6.4    $(SRC)/TFL/casesplit.ML $(SRC)/TFL/dcterm.ML $(SRC)/TFL/post.ML		\
     6.5    $(SRC)/TFL/rules.ML $(SRC)/TFL/tfl.ML $(SRC)/TFL/thms.ML			\
     6.6    $(SRC)/TFL/thry.ML $(SRC)/TFL/usyntax.ML $(SRC)/TFL/utils.ML			\
     6.7 -  Binomial.thy Datatype.ML Datatype.thy Datatype_Universe.thy Divides.thy \
     6.8 +  Binomial.thy Commutative_Ring.thy Datatype.ML Datatype.thy \
     6.9 +  Datatype_Universe.thy Divides.thy \
    6.10    Equiv_Relations.thy Extraction.thy Finite_Set.ML Finite_Set.thy		\
    6.11    FixedPoint.thy Fun.thy HOL.ML HOL.thy Hilbert_Choice.thy Inductive.thy		\
    6.12    Infinite_Set.thy Integ/IntArith.thy Integ/IntDef.thy Integ/IntDiv.thy		\
    6.13    Integ/NatBin.thy Integ/NatSimprocs.thy Integ/Numeral.thy			\
    6.14    Integ/Parity.thy Integ/Presburger.thy Integ/cooper_dec.ML			\
    6.15 -  Integ/cooper_proof.ML Integ/int_arith1.ML Integ/int_factor_simprocs.ML	\
    6.16 +  Integ/cooper_proof.ML Integ/reflected_presburger.ML \
    6.17 +  Integ/reflected_cooper.ML Integ/int_arith1.ML Integ/int_factor_simprocs.ML	\
    6.18    Integ/nat_simprocs.ML Integ/presburger.ML Integ/qelim.ML LOrder.thy		\
    6.19    Lattice_Locales.thy List.ML List.thy Main.ML Main.thy Map.thy		\
    6.20    Nat.ML Nat.thy NatArith.thy OrderedGroup.ML OrderedGroup.thy			\
    6.21 @@ -96,7 +98,7 @@
    6.22    Tools/ATP/recon_order_clauses.ML Tools/ATP/recon_parse.ML			\
    6.23    Tools/ATP/recon_prelim.ML Tools/ATP/recon_transfer_proof.ML			\
    6.24    Tools/ATP/recon_translate_proof.ML Tools/ATP/res_clasimpset.ML		\
    6.25 -  Tools/ATP/watcher.ML 					\
    6.26 +  Tools/ATP/watcher.ML 	Tools/comm_ring.ML				\
    6.27    Tools/datatype_abs_proofs.ML Tools/datatype_aux.ML				\
    6.28    Tools/datatype_codegen.ML Tools/datatype_package.ML				\
    6.29    Tools/datatype_prop.ML Tools/datatype_realizer.ML				\
    6.30 @@ -584,13 +586,15 @@
    6.31  HOL-ex: HOL $(LOG)/HOL-ex.gz
    6.32  
    6.33  $(LOG)/HOL-ex.gz: $(OUT)/HOL ex/Antiquote.thy \
    6.34 -  ex/BT.thy ex/BinEx.thy ex/Higher_Order_Logic.thy \
    6.35 +  ex/BT.thy ex/BinEx.thy ex/Commutative_RingEx.thy \
    6.36 +  ex/Commutative_Ring_Complete.thy ex/Higher_Order_Logic.thy \
    6.37    ex/Hilbert_Classical.thy ex/InSort.thy \
    6.38    ex/InductiveInvariant.thy  ex/InductiveInvariant_examples.thy\
    6.39    ex/Intuitionistic.thy \
    6.40    ex/Lagrange.thy ex/Locales.thy ex/MergeSort.thy \
    6.41    ex/MT.ML ex/MT.thy ex/MonoidGroup.thy ex/Multiquote.thy \
    6.42 -  ex/NatSum.thy ex/PER.thy ex/PresburgerEx.thy ex/Primrec.thy ex/Puzzle.thy \
    6.43 +  ex/NatSum.thy ex/PER.thy ex/PresburgerEx.thy ex/Reflected_Presburger.thy \
    6.44 +  ex/Primrec.thy ex/Puzzle.thy \
    6.45    ex/Qsort.thy ex/Quickcheck_Examples.thy ex/ROOT.ML ex/Recdefs.thy ex/Records.thy \
    6.46    ex/Refute_Examples.thy \
    6.47    ex/StringEx.thy ex/SVC_Oracle.ML ex/SVC_Oracle.thy \
     7.1 --- a/src/HOL/Presburger.thy	Wed Sep 14 10:24:39 2005 +0200
     7.2 +++ b/src/HOL/Presburger.thy	Wed Sep 14 17:25:52 2005 +0200
     7.3 @@ -10,7 +10,8 @@
     7.4  
     7.5  theory Presburger
     7.6  imports NatSimprocs SetInterval
     7.7 -uses ("cooper_dec.ML") ("cooper_proof.ML") ("qelim.ML") ("presburger.ML")
     7.8 +uses ("cooper_dec.ML") ("cooper_proof.ML") ("qelim.ML") 
     7.9 +	("reflected_presburger.ML") ("reflected_cooper.ML") ("presburger.ML")
    7.10  begin
    7.11  
    7.12  text {* Theorem for unitifying the coeffitients of @{text x} in an existential formula*}
    7.13 @@ -982,8 +983,10 @@
    7.14    by (simp cong: conj_cong)
    7.15  
    7.16  use "cooper_dec.ML"
    7.17 +use "reflected_presburger.ML" 
    7.18 +use "reflected_cooper.ML"
    7.19  oracle
    7.20 -  presburger_oracle ("term") = CooperDec.presburger_oracle
    7.21 +  presburger_oracle ("term") = ReflectedCooper.presburger_oracle
    7.22  
    7.23  use "cooper_proof.ML"
    7.24  use "qelim.ML"
     8.1 --- a/src/HOL/Tools/Presburger/cooper_dec.ML	Wed Sep 14 10:24:39 2005 +0200
     8.2 +++ b/src/HOL/Tools/Presburger/cooper_dec.ML	Wed Sep 14 17:25:52 2005 +0200
     8.3 @@ -44,7 +44,6 @@
     8.4    val evalc : term -> term
     8.5    val cooper_w : string list -> term -> (term option * term)
     8.6    val integer_qelim : Term.term -> Term.term
     8.7 -  val presburger_oracle : theory -> term -> term
     8.8  end;
     8.9  
    8.10  structure  CooperDec : COOPER_DEC =
    8.11 @@ -938,8 +937,4 @@
    8.12  
    8.13  val integer_qelim = simpl o evalc o (lift_qelim linform (cnnf posineq o evalc) cooper is_arith_rel) ; 
    8.14  
    8.15 -fun presburger_oracle thy t =
    8.16 -    if (!quick_and_dirty) 
    8.17 -    then HOLogic.mk_Trueprop (HOLogic.mk_eq(t,integer_qelim t))
    8.18 -    else error "Presburger oracle: not in quick_and_dirty mode"
    8.19  end;
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/HOL/Tools/Presburger/reflected_cooper.ML	Wed Sep 14 17:25:52 2005 +0200
     9.3 @@ -0,0 +1,124 @@
     9.4 +(* $Id$ *)
     9.5 +(* The oracle for Presburger arithmetic based on the verified Code *)
     9.6 +    (* in HOL/ex/Reflected_Presburger.thy *)
     9.7 +
     9.8 +structure ReflectedCooper =
     9.9 +struct
    9.10 +
    9.11 +open Generated;
    9.12 +(* pseudo reification : term -> intterm *)
    9.13 +
    9.14 +fun i_of_term vs t = 
    9.15 +    case t of
    9.16 +	Free(xn,xT) => (case assoc(vs,t) of 
    9.17 +			   NONE   => error "Variable not found in the list!!"
    9.18 +			 | SOME n => Var n)
    9.19 +      | Const("0",iT) => Cst 0
    9.20 +      | Const("1",iT) => Cst 1
    9.21 +      | Bound i => Var (nat i)
    9.22 +      | Const("uminus",_)$t' => Neg (i_of_term vs t')
    9.23 +      | Const ("op +",_)$t1$t2 => Add (i_of_term vs t1,i_of_term vs t2)
    9.24 +      | Const ("op -",_)$t1$t2 => Sub (i_of_term vs t1,i_of_term vs t2)
    9.25 +      | Const ("op *",_)$t1$t2 => Mult (i_of_term vs t1,i_of_term vs t2)
    9.26 +      | Const ("Numeral.number_of",_)$t' => Cst (HOLogic.dest_binum t')
    9.27 +      | _ => error "i_of_term: unknown term";
    9.28 +	
    9.29 +
    9.30 +(* pseudo reification : term -> QF *)
    9.31 +fun qf_of_term vs t = 
    9.32 +    case t of 
    9.33 +	Const("True",_) => T
    9.34 +      | Const("False",_) => F
    9.35 +      | Const("op <",_)$t1$t2 => Lt (i_of_term vs t1,i_of_term vs t2)
    9.36 +      | Const("op <=",_)$t1$t2 => Le (i_of_term vs t1,i_of_term vs t2)
    9.37 +      | Const ("Divides.op dvd",_)$t1$t2 => 
    9.38 +	Divides(i_of_term vs t1,i_of_term vs t2)
    9.39 +      | Const("op =",eqT)$t1$t2 => 
    9.40 +	if (domain_type eqT = HOLogic.intT)
    9.41 +	then let val i1 = i_of_term vs t1
    9.42 +		 val i2 = i_of_term vs t2
    9.43 +	     in	Eq (i1,i2)
    9.44 +	     end 
    9.45 +	else Equ(qf_of_term vs t1,qf_of_term vs t2)
    9.46 +      | Const("op &",_)$t1$t2 => And(qf_of_term vs t1,qf_of_term vs t2)
    9.47 +      | Const("op |",_)$t1$t2 => Or(qf_of_term vs t1,qf_of_term vs t2)
    9.48 +      | Const("op -->",_)$t1$t2 => Imp(qf_of_term vs t1,qf_of_term vs t2)
    9.49 +      | Const("Not",_)$t' => NOT(qf_of_term vs t')
    9.50 +      | Const("Ex",_)$Abs(xn,xT,p) => 
    9.51 +	QEx(qf_of_term (map (fn(v,n) => (v,n + 1)) vs) p)
    9.52 +      | Const("All",_)$Abs(xn,xT,p) => 
    9.53 +	QAll(qf_of_term (map (fn(v,n) => (v,n + 1)) vs) p)
    9.54 +      | _ => error "qf_of_term : unknown term!";
    9.55 +
    9.56 +(*
    9.57 +fun parse s = term_of (read_cterm (sign_of Main.thy) (s,HOLogic.boolT));
    9.58 +
    9.59 +val t = parse "ALL (i::int) (j::int). i < 8* j --> (i - 1 = j + 3 + 2*j) & (j <= -i + k ) | 4 = i | 5 dvd i";
    9.60 +*)
    9.61 +fun zip [] [] = []
    9.62 +  | zip (x::xs) (y::ys) = (x,y)::(zip xs ys);
    9.63 +
    9.64 +
    9.65 +fun start_vs t =
    9.66 +    let val fs = term_frees t
    9.67 +    in zip fs (map nat (0 upto (length fs - 1)))
    9.68 +    end ;
    9.69 +
    9.70 +(* transform intterm and QF back to terms *)
    9.71 +val iT = HOLogic.intT;
    9.72 +val bT = HOLogic.boolT;
    9.73 +fun myassoc2 l v =
    9.74 +    case l of
    9.75 +	[] => NONE
    9.76 +      | (x,v')::xs => if v = v' then SOME x
    9.77 +		      else myassoc2 xs v;
    9.78 +
    9.79 +fun term_of_i vs t =
    9.80 +    case t of 
    9.81 +	Cst i => CooperDec.mk_numeral i
    9.82 +      | Var n => valOf (myassoc2 vs n)
    9.83 +      | Neg t' => Const("uminus",iT --> iT)$(term_of_i vs t')
    9.84 +      | Add(t1,t2) => Const("op +",[iT,iT] ---> iT)$
    9.85 +			   (term_of_i vs t1)$(term_of_i vs t2)
    9.86 +      | Sub(t1,t2) => Const("op -",[iT,iT] ---> iT)$
    9.87 +			   (term_of_i vs t1)$(term_of_i vs t2)
    9.88 +      | Mult(t1,t2) => Const("op *",[iT,iT] ---> iT)$
    9.89 +			   (term_of_i vs t1)$(term_of_i vs t2);
    9.90 +
    9.91 +fun term_of_qf vs t = 
    9.92 +    case t of 
    9.93 +	T => HOLogic.true_const 
    9.94 +      | F => HOLogic.false_const
    9.95 +      | Lt(t1,t2) => Const("op <",[iT,iT] ---> bT)$
    9.96 +			   (term_of_i vs t1)$(term_of_i vs t2)
    9.97 +      | Le(t1,t2) => Const("op <=",[iT,iT] ---> bT)$
    9.98 +			  (term_of_i vs t1)$(term_of_i vs t2)
    9.99 +      | Gt(t1,t2) => Const("op <",[iT,iT] ---> bT)$
   9.100 +			   (term_of_i vs t2)$(term_of_i vs t1)
   9.101 +      | Ge(t1,t2) => Const("op <=",[iT,iT] ---> bT)$
   9.102 +			  (term_of_i vs t2)$(term_of_i vs t1)
   9.103 +      | Eq(t1,t2) => Const("op =",[iT,iT] ---> bT)$
   9.104 +			   (term_of_i vs t1)$(term_of_i vs t2)
   9.105 +      | Divides(t1,t2) => Const("Divides.op dvd",[iT,iT] ---> bT)$
   9.106 +			       (term_of_i vs t1)$(term_of_i vs t2)
   9.107 +      | NOT t' => HOLogic.Not$(term_of_qf vs t')
   9.108 +      | And(t1,t2) => HOLogic.conj$(term_of_qf vs t1)$(term_of_qf vs t2)
   9.109 +      | Or(t1,t2) => HOLogic.disj$(term_of_qf vs t1)$(term_of_qf vs t2)
   9.110 +      | Imp(t1,t2) => HOLogic.imp$(term_of_qf vs t1)$(term_of_qf vs t2)
   9.111 +      | Equ(t1,t2) => (HOLogic.eq_const bT)$(term_of_qf vs t1)$
   9.112 +					   (term_of_qf vs t2)
   9.113 +      | _ => error "If this is raised, Isabelle/HOL or generate_code is inconsistent!";
   9.114 +
   9.115 +(* The oracle *)
   9.116 + exception COOPER; 
   9.117 +
   9.118 +fun presburger_oracle thy t =
   9.119 +    let val vs = start_vs t
   9.120 +	val result = lift_un (term_of_qf vs) (pa (qf_of_term vs t))
   9.121 +    in 
   9.122 +    case result of 
   9.123 +	None => raise COOPER
   9.124 +      | Some t' => HOLogic.mk_Trueprop (HOLogic.mk_eq(t,t'))
   9.125 +    end ;
   9.126 + 
   9.127 +end;
   9.128 \ No newline at end of file
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/HOL/Tools/Presburger/reflected_presburger.ML	Wed Sep 14 17:25:52 2005 +0200
    10.3 @@ -0,0 +1,2172 @@
    10.4 +(* $Id$ *)
    10.5 +
    10.6 +    (* Caution: This file should not be modified. *)
    10.7 +    (* It is autmatically generated from HOL/ex/Reflected_Presburger.thy *)
    10.8 +fun nat i = if i < 0 then 0 else i;
    10.9 +structure Generated =
   10.10 +struct
   10.11 +
   10.12 +datatype intterm = Cst of int | Var of int | Neg of intterm
   10.13 +  | Add of intterm * intterm | Sub of intterm * intterm
   10.14 +  | Mult of intterm * intterm;
   10.15 +
   10.16 +datatype QF = Lt of intterm * intterm | Gt of intterm * intterm
   10.17 +  | Le of intterm * intterm | Ge of intterm * intterm | Eq of intterm * intterm
   10.18 +  | Divides of intterm * intterm | T | F | NOT of QF | And of QF * QF
   10.19 +  | Or of QF * QF | Imp of QF * QF | Equ of QF * QF | QAll of QF | QEx of QF;
   10.20 +
   10.21 +datatype 'a option = None | Some of 'a;
   10.22 +
   10.23 +fun lift_un c None = None
   10.24 +  | lift_un c (Some p) = Some (c p);
   10.25 +
   10.26 +fun lift_bin (c, (Some a, Some b)) = Some (c a b)
   10.27 +  | lift_bin (c, (None, y)) = None
   10.28 +  | lift_bin (c, (Some y, None)) = None;
   10.29 +
   10.30 +fun lift_qe qe None = None
   10.31 +  | lift_qe qe (Some p) = qe p;
   10.32 +
   10.33 +fun qelim (qe, QAll p) = lift_un NOT (lift_qe qe (lift_un NOT (qelim (qe, p))))
   10.34 +  | qelim (qe, QEx p) = lift_qe qe (qelim (qe, p))
   10.35 +  | qelim (qe, And (p, q)) =
   10.36 +    lift_bin ((fn x => fn xa => And (x, xa)), (qelim (qe, p), qelim (qe, q)))
   10.37 +  | qelim (qe, Or (p, q)) =
   10.38 +    lift_bin ((fn x => fn xa => Or (x, xa)), (qelim (qe, p), qelim (qe, q)))
   10.39 +  | qelim (qe, Imp (p, q)) =
   10.40 +    lift_bin ((fn x => fn xa => Imp (x, xa)), (qelim (qe, p), qelim (qe, q)))
   10.41 +  | qelim (qe, Equ (p, q)) =
   10.42 +    lift_bin ((fn x => fn xa => Equ (x, xa)), (qelim (qe, p), qelim (qe, q)))
   10.43 +  | qelim (qe, NOT p) = lift_un NOT (qelim (qe, p))
   10.44 +  | qelim (qe, Lt (w, x)) = Some (Lt (w, x))
   10.45 +  | qelim (qe, Gt (y, z)) = Some (Gt (y, z))
   10.46 +  | qelim (qe, Le (aa, ab)) = Some (Le (aa, ab))
   10.47 +  | qelim (qe, Ge (ac, ad)) = Some (Ge (ac, ad))
   10.48 +  | qelim (qe, Eq (ae, af)) = Some (Eq (ae, af))
   10.49 +  | qelim (qe, Divides (ag, ah)) = Some (Divides (ag, ah))
   10.50 +  | qelim (qe, T) = Some T
   10.51 +  | qelim (qe, F) = Some F;
   10.52 +
   10.53 +fun lin_mul (c, Cst i) = Cst (c * i)
   10.54 +  | lin_mul (c, Add (Mult (Cst c', Var n), r)) =
   10.55 +    (if (c = 0) then Cst 0
   10.56 +      else Add (Mult (Cst (c * c'), Var n), lin_mul (c, r)));
   10.57 +
   10.58 +fun op_60_def0 m n = ((m) < (n));
   10.59 +
   10.60 +fun op_60_61_def0 m n = not (op_60_def0 n m);
   10.61 +
   10.62 +fun lin_add (Add (Mult (Cst c1, Var n1), r1), Add (Mult (Cst c2, Var n2), r2)) =
   10.63 +    (if (n1 = n2)
   10.64 +      then let val c = Cst (c1 + c2)
   10.65 +           in (if ((c1 + c2) = 0) then lin_add (r1, r2)
   10.66 +                else Add (Mult (c, Var n1), lin_add (r1, r2)))
   10.67 +           end
   10.68 +      else (if op_60_61_def0 n1 n2
   10.69 +             then Add (Mult (Cst c1, Var n1),
   10.70 +                        lin_add (r1, Add (Mult (Cst c2, Var n2), r2)))
   10.71 +             else Add (Mult (Cst c2, Var n2),
   10.72 +                        lin_add (Add (Mult (Cst c1, Var n1), r1), r2))))
   10.73 +  | lin_add (Add (Mult (Cst c1, Var n1), r1), Cst b) =
   10.74 +    Add (Mult (Cst c1, Var n1), lin_add (r1, Cst b))
   10.75 +  | lin_add (Cst x, Add (Mult (Cst c2, Var n2), r2)) =
   10.76 +    Add (Mult (Cst c2, Var n2), lin_add (Cst x, r2))
   10.77 +  | lin_add (Cst b1, Cst b2) = Cst (b1 + b2);
   10.78 +
   10.79 +fun lin_neg i = lin_mul (~1, i);
   10.80 +
   10.81 +fun linearize (Cst b) = Some (Cst b)
   10.82 +  | linearize (Var n) = Some (Add (Mult (Cst 1, Var n), Cst 0))
   10.83 +  | linearize (Neg i) = lift_un lin_neg (linearize i)
   10.84 +  | linearize (Add (i, j)) =
   10.85 +    lift_bin ((fn x => fn y => lin_add (x, y)), (linearize i, linearize j))
   10.86 +  | linearize (Sub (i, j)) =
   10.87 +    lift_bin
   10.88 +      ((fn x => fn y => lin_add (x, lin_neg y)), (linearize i, linearize j))
   10.89 +  | linearize (Mult (i, j)) =
   10.90 +    (case linearize i of None => None
   10.91 +      | Some x =>
   10.92 +          (case x of
   10.93 +            Cst xa =>
   10.94 +              (case linearize j of None => None
   10.95 +                | Some x => Some (lin_mul (xa, x)))
   10.96 +            | Var xa =>
   10.97 +                (case linearize j of None => None
   10.98 +                  | Some xa =>
   10.99 +                      (case xa of Cst xa => Some (lin_mul (xa, x))
  10.100 +                        | Var xa => None | Neg xa => None | Add (xa, xb) => None
  10.101 +                        | Sub (xa, xb) => None | Mult (xa, xb) => None))
  10.102 +            | Neg xa =>
  10.103 +                (case linearize j of None => None
  10.104 +                  | Some xa =>
  10.105 +                      (case xa of Cst xa => Some (lin_mul (xa, x))
  10.106 +                        | Var xa => None | Neg xa => None | Add (xa, xb) => None
  10.107 +                        | Sub (xa, xb) => None | Mult (xa, xb) => None))
  10.108 +            | Add (xa, xb) =>
  10.109 +                (case linearize j of None => None
  10.110 +                  | Some xa =>
  10.111 +                      (case xa of Cst xa => Some (lin_mul (xa, x))
  10.112 +                        | Var xa => None | Neg xa => None | Add (xa, xb) => None
  10.113 +                        | Sub (xa, xb) => None | Mult (xa, xb) => None))
  10.114 +            | Sub (xa, xb) =>
  10.115 +                (case linearize j of None => None
  10.116 +                  | Some xa =>
  10.117 +                      (case xa of Cst xa => Some (lin_mul (xa, x))
  10.118 +                        | Var xa => None | Neg xa => None | Add (xa, xb) => None
  10.119 +                        | Sub (xa, xb) => None | Mult (xa, xb) => None))
  10.120 +            | Mult (xa, xb) =>
  10.121 +                (case linearize j of None => None
  10.122 +                  | Some xa =>
  10.123 +                      (case xa of Cst xa => Some (lin_mul (xa, x))
  10.124 +                        | Var xa => None | Neg xa => None | Add (xa, xb) => None
  10.125 +                        | Sub (xa, xb) => None | Mult (xa, xb) => None))));
  10.126 +
  10.127 +fun linform (Le (it1, it2)) =
  10.128 +    lift_bin
  10.129 +      ((fn x => fn y => Le (lin_add (x, lin_neg y), Cst 0)),
  10.130 +        (linearize it1, linearize it2))
  10.131 +  | linform (Eq (it1, it2)) =
  10.132 +    lift_bin
  10.133 +      ((fn x => fn y => Eq (lin_add (x, lin_neg y), Cst 0)),
  10.134 +        (linearize it1, linearize it2))
  10.135 +  | linform (Divides (d, t)) =
  10.136 +    (case linearize d of None => None
  10.137 +      | Some x =>
  10.138 +          (case x of
  10.139 +            Cst xa =>
  10.140 +              (if (xa = 0) then None
  10.141 +                else (case linearize t of None => None
  10.142 +                       | Some xa => Some (Divides (x, xa))))
  10.143 +            | Var xa => None | Neg xa => None | Add (xa, xb) => None
  10.144 +            | Sub (xa, xb) => None | Mult (xa, xb) => None))
  10.145 +  | linform T = Some T
  10.146 +  | linform F = Some F
  10.147 +  | linform (NOT p) = lift_un NOT (linform p)
  10.148 +  | linform (And (p, q)) =
  10.149 +    lift_bin ((fn f => fn g => And (f, g)), (linform p, linform q))
  10.150 +  | linform (Or (p, q)) =
  10.151 +    lift_bin ((fn f => fn g => Or (f, g)), (linform p, linform q));
  10.152 +
  10.153 +fun nnf (Lt (it1, it2)) = Le (Sub (it1, it2), Cst (~ 1))
  10.154 +  | nnf (Gt (it1, it2)) = Le (Sub (it2, it1), Cst (~ 1))
  10.155 +  | nnf (Le (it1, it2)) = Le (it1, it2)
  10.156 +  | nnf (Ge (it1, it2)) = Le (it2, it1)
  10.157 +  | nnf (Eq (it1, it2)) = Eq (it2, it1)
  10.158 +  | nnf (Divides (d, t)) = Divides (d, t)
  10.159 +  | nnf T = T
  10.160 +  | nnf F = F
  10.161 +  | nnf (And (p, q)) = And (nnf p, nnf q)
  10.162 +  | nnf (Or (p, q)) = Or (nnf p, nnf q)
  10.163 +  | nnf (Imp (p, q)) = Or (nnf (NOT p), nnf q)
  10.164 +  | nnf (Equ (p, q)) = Or (And (nnf p, nnf q), And (nnf (NOT p), nnf (NOT q)))
  10.165 +  | nnf (NOT (Lt (it1, it2))) = Le (it2, it1)
  10.166 +  | nnf (NOT (Gt (it1, it2))) = Le (it1, it2)
  10.167 +  | nnf (NOT (Le (it1, it2))) = Le (Sub (it2, it1), Cst (~ 1))
  10.168 +  | nnf (NOT (Ge (it1, it2))) = Le (Sub (it1, it2), Cst (~ 1))
  10.169 +  | nnf (NOT (Eq (it1, it2))) = NOT (Eq (it1, it2))
  10.170 +  | nnf (NOT (Divides (d, t))) = NOT (Divides (d, t))
  10.171 +  | nnf (NOT T) = F
  10.172 +  | nnf (NOT F) = T
  10.173 +  | nnf (NOT (NOT p)) = nnf p
  10.174 +  | nnf (NOT (And (p, q))) = Or (nnf (NOT p), nnf (NOT q))
  10.175 +  | nnf (NOT (Or (p, q))) = And (nnf (NOT p), nnf (NOT q))
  10.176 +  | nnf (NOT (Imp (p, q))) = And (nnf p, nnf (NOT q))
  10.177 +  | nnf (NOT (Equ (p, q))) =
  10.178 +    Or (And (nnf p, nnf (NOT q)), And (nnf (NOT p), nnf q));
  10.179 +
  10.180 +fun op_45_def2 z w = (z + ~ w);
  10.181 +
  10.182 +fun op_45_def0 m n = nat (op_45_def2 (m) (n));
  10.183 +
  10.184 +val id_1_def0 : int = (0 + 1);
  10.185 +
  10.186 +fun decrvarsI (Cst i) = Cst i
  10.187 +  | decrvarsI (Var n) = Var (op_45_def0 n id_1_def0)
  10.188 +  | decrvarsI (Neg a) = Neg (decrvarsI a)
  10.189 +  | decrvarsI (Add (a, b)) = Add (decrvarsI a, decrvarsI b)
  10.190 +  | decrvarsI (Sub (a, b)) = Sub (decrvarsI a, decrvarsI b)
  10.191 +  | decrvarsI (Mult (a, b)) = Mult (decrvarsI a, decrvarsI b);
  10.192 +
  10.193 +fun decrvars (Lt (a, b)) = Lt (decrvarsI a, decrvarsI b)
  10.194 +  | decrvars (Gt (a, b)) = Gt (decrvarsI a, decrvarsI b)
  10.195 +  | decrvars (Le (a, b)) = Le (decrvarsI a, decrvarsI b)
  10.196 +  | decrvars (Ge (a, b)) = Ge (decrvarsI a, decrvarsI b)
  10.197 +  | decrvars (Eq (a, b)) = Eq (decrvarsI a, decrvarsI b)
  10.198 +  | decrvars (Divides (a, b)) = Divides (decrvarsI a, decrvarsI b)
  10.199 +  | decrvars T = T
  10.200 +  | decrvars F = F
  10.201 +  | decrvars (NOT p) = NOT (decrvars p)
  10.202 +  | decrvars (And (p, q)) = And (decrvars p, decrvars q)
  10.203 +  | decrvars (Or (p, q)) = Or (decrvars p, decrvars q)
  10.204 +  | decrvars (Imp (p, q)) = Imp (decrvars p, decrvars q)
  10.205 +  | decrvars (Equ (p, q)) = Equ (decrvars p, decrvars q);
  10.206 +
  10.207 +fun op_64 [] ys = ys
  10.208 +  | op_64 (x :: xs) ys = (x :: op_64 xs ys);
  10.209 +
  10.210 +fun map f [] = []
  10.211 +  | map f (x :: xs) = (f x :: map f xs);
  10.212 +
  10.213 +fun iupto (i, j) = (if (j < i) then [] else (i :: iupto ((i + 1), j)));
  10.214 +
  10.215 +fun all_sums (j, []) = []
  10.216 +  | all_sums (j, (i :: is)) =
  10.217 +    op_64 (map (fn x => lin_add (i, Cst x)) (iupto (1, j))) (all_sums (j, is));
  10.218 +
  10.219 +fun split x = (fn p => x (fst p) (snd p));
  10.220 +
  10.221 +fun negateSnd x = split (fn q => fn r => (q, ~ r)) x;
  10.222 +
  10.223 +fun adjust b =
  10.224 +  (fn (q, r) =>
  10.225 +    (if (0 <= op_45_def2 r b) then (((2 * q) + 1), op_45_def2 r b)
  10.226 +      else ((2 * q), r)));
  10.227 +
  10.228 +fun negDivAlg (a, b) =
  10.229 +    (if ((0 <= (a + b)) orelse (b <= 0)) then (~1, (a + b))
  10.230 +      else adjust b (negDivAlg (a, (2 * b))));
  10.231 +
  10.232 +fun posDivAlg (a, b) =
  10.233 +    (if ((a < b) orelse (b <= 0)) then (0, a)
  10.234 +      else adjust b (posDivAlg (a, (2 * b))));
  10.235 +
  10.236 +fun divAlg x =
  10.237 +  split (fn a => fn b =>
  10.238 +          (if (0 <= a)
  10.239 +            then (if (0 <= b) then posDivAlg (a, b)
  10.240 +                   else (if (a = 0) then (0, 0)
  10.241 +                          else negateSnd (negDivAlg (~ a, ~ b))))
  10.242 +            else (if (0 < b) then negDivAlg (a, b)
  10.243 +                   else negateSnd (posDivAlg (~ a, ~ b)))))
  10.244 +    x;
  10.245 +
  10.246 +fun op_mod_def1 a b = snd (divAlg (a, b));
  10.247 +
  10.248 +fun op_dvd m n = (op_mod_def1 n m = 0);
  10.249 +
  10.250 +fun psimpl (Le (l, r)) =
  10.251 +    (case lift_bin
  10.252 +            ((fn x => fn y => lin_add (x, lin_neg y)),
  10.253 +              (linearize l, linearize r)) of
  10.254 +      None => Le (l, r)
  10.255 +      | Some x =>
  10.256 +          (case x of Cst xa => (if (xa <= 0) then T else F)
  10.257 +            | Var xa => Le (x, Cst 0) | Neg xa => Le (x, Cst 0)
  10.258 +            | Add (xa, xb) => Le (x, Cst 0) | Sub (xa, xb) => Le (x, Cst 0)
  10.259 +            | Mult (xa, xb) => Le (x, Cst 0)))
  10.260 +  | psimpl (Eq (l, r)) =
  10.261 +    (case lift_bin
  10.262 +            ((fn x => fn y => lin_add (x, lin_neg y)),
  10.263 +              (linearize l, linearize r)) of
  10.264 +      None => Eq (l, r)
  10.265 +      | Some x =>
  10.266 +          (case x of Cst xa => (if (xa = 0) then T else F)
  10.267 +            | Var xa => Eq (x, Cst 0) | Neg xa => Eq (x, Cst 0)
  10.268 +            | Add (xa, xb) => Eq (x, Cst 0) | Sub (xa, xb) => Eq (x, Cst 0)
  10.269 +            | Mult (xa, xb) => Eq (x, Cst 0)))
  10.270 +  | psimpl (Divides (Cst d, t)) =
  10.271 +    (case linearize t of None => Divides (Cst d, t)
  10.272 +      | Some x =>
  10.273 +          (case x of Cst xa => (if op_dvd d xa then T else F)
  10.274 +            | Var xa => Divides (Cst d, x) | Neg xa => Divides (Cst d, x)
  10.275 +            | Add (xa, xb) => Divides (Cst d, x)
  10.276 +            | Sub (xa, xb) => Divides (Cst d, x)
  10.277 +            | Mult (xa, xb) => Divides (Cst d, x)))
  10.278 +  | psimpl (Equ (p, q)) =
  10.279 +    let val p' = psimpl p; val q' = psimpl q
  10.280 +    in (case p' of
  10.281 +         Lt (x, xa) =>
  10.282 +           (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
  10.283 +             | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
  10.284 +             | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
  10.285 +             | T => p' | F => NOT p' | NOT x => Equ (p', q')
  10.286 +             | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
  10.287 +             | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
  10.288 +             | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
  10.289 +         | Gt (x, xa) =>
  10.290 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
  10.291 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
  10.292 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
  10.293 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
  10.294 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
  10.295 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
  10.296 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
  10.297 +         | Le (x, xa) =>
  10.298 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
  10.299 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
  10.300 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
  10.301 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
  10.302 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
  10.303 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
  10.304 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
  10.305 +         | Ge (x, xa) =>
  10.306 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
  10.307 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
  10.308 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
  10.309 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
  10.310 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
  10.311 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
  10.312 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
  10.313 +         | Eq (x, xa) =>
  10.314 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
  10.315 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
  10.316 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
  10.317 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
  10.318 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
  10.319 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
  10.320 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
  10.321 +         | Divides (x, xa) =>
  10.322 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
  10.323 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
  10.324 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
  10.325 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
  10.326 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
  10.327 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
  10.328 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
  10.329 +         | T => q'
  10.330 +         | F => (case q' of Lt (x, xa) => NOT q' | Gt (x, xa) => NOT q'
  10.331 +                  | Le (x, xa) => NOT q' | Ge (x, xa) => NOT q'
  10.332 +                  | Eq (x, xa) => NOT q' | Divides (x, xa) => NOT q' | T => F
  10.333 +                  | F => T | NOT x => x | And (x, xa) => NOT q'
  10.334 +                  | Or (x, xa) => NOT q' | Imp (x, xa) => NOT q'
  10.335 +                  | Equ (x, xa) => NOT q' | QAll x => NOT q' | QEx x => NOT q')
  10.336 +         | NOT x =>
  10.337 +             (case q' of Lt (xa, xb) => Equ (p', q')
  10.338 +               | Gt (xa, xb) => Equ (p', q') | Le (xa, xb) => Equ (p', q')
  10.339 +               | Ge (xa, xb) => Equ (p', q') | Eq (xa, xb) => Equ (p', q')
  10.340 +               | Divides (xa, xb) => Equ (p', q') | T => p' | F => x
  10.341 +               | NOT xa => Equ (x, xa) | And (xa, xb) => Equ (p', q')
  10.342 +               | Or (xa, xb) => Equ (p', q') | Imp (xa, xb) => Equ (p', q')
  10.343 +               | Equ (xa, xb) => Equ (p', q') | QAll xa => Equ (p', q')
  10.344 +               | QEx xa => Equ (p', q'))
  10.345 +         | And (x, xa) =>
  10.346 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
  10.347 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
  10.348 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
  10.349 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
  10.350 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
  10.351 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
  10.352 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
  10.353 +         | Or (x, xa) =>
  10.354 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
  10.355 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
  10.356 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
  10.357 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
  10.358 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
  10.359 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
  10.360 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
  10.361 +         | Imp (x, xa) =>
  10.362 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
  10.363 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
  10.364 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
  10.365 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
  10.366 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
  10.367 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
  10.368 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
  10.369 +         | Equ (x, xa) =>
  10.370 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
  10.371 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
  10.372 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
  10.373 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
  10.374 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
  10.375 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
  10.376 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
  10.377 +         | QAll x =>
  10.378 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
  10.379 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
  10.380 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
  10.381 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
  10.382 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
  10.383 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
  10.384 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q'))
  10.385 +         | QEx x =>
  10.386 +             (case q' of Lt (x, xa) => Equ (p', q') | Gt (x, xa) => Equ (p', q')
  10.387 +               | Le (x, xa) => Equ (p', q') | Ge (x, xa) => Equ (p', q')
  10.388 +               | Eq (x, xa) => Equ (p', q') | Divides (x, xa) => Equ (p', q')
  10.389 +               | T => p' | F => NOT p' | NOT x => Equ (p', q')
  10.390 +               | And (x, xa) => Equ (p', q') | Or (x, xa) => Equ (p', q')
  10.391 +               | Imp (x, xa) => Equ (p', q') | Equ (x, xa) => Equ (p', q')
  10.392 +               | QAll x => Equ (p', q') | QEx x => Equ (p', q')))
  10.393 +    end
  10.394 +  | psimpl (NOT p) =
  10.395 +    let val p' = psimpl p
  10.396 +    in (case p' of Lt (x, xa) => NOT p' | Gt (x, xa) => NOT p'
  10.397 +         | Le (x, xa) => NOT p' | Ge (x, xa) => NOT p' | Eq (x, xa) => NOT p'
  10.398 +         | Divides (x, xa) => NOT p' | T => F | F => T | NOT x => x
  10.399 +         | And (x, xa) => NOT p' | Or (x, xa) => NOT p' | Imp (x, xa) => NOT p'
  10.400 +         | Equ (x, xa) => NOT p' | QAll x => NOT p' | QEx x => NOT p')
  10.401 +    end
  10.402 +  | psimpl (Lt (u, v)) = Lt (u, v)
  10.403 +  | psimpl (Gt (w, x)) = Gt (w, x)
  10.404 +  | psimpl (Ge (aa, ab)) = Ge (aa, ab)
  10.405 +  | psimpl (Divides (Var bp, af)) = Divides (Var bp, af)
  10.406 +  | psimpl (Divides (Neg bq, af)) = Divides (Neg bq, af)
  10.407 +  | psimpl (Divides (Add (br, bs), af)) = Divides (Add (br, bs), af)
  10.408 +  | psimpl (Divides (Sub (bt, bu), af)) = Divides (Sub (bt, bu), af)
  10.409 +  | psimpl (Divides (Mult (bv, bw), af)) = Divides (Mult (bv, bw), af)
  10.410 +  | psimpl T = T
  10.411 +  | psimpl F = F
  10.412 +  | psimpl (QAll ap) = QAll ap
  10.413 +  | psimpl (QEx aq) = QEx aq
  10.414 +  | psimpl (And (p, q)) =
  10.415 +    let val p' = psimpl p
  10.416 +    in (case p' of
  10.417 +         Lt (x, xa) =>
  10.418 +           let val q' = psimpl q
  10.419 +           in (case q' of Lt (x, xa) => And (p', q')
  10.420 +                | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
  10.421 +                | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
  10.422 +                | Divides (x, xa) => And (p', q') | T => p' | F => F
  10.423 +                | NOT x => And (p', q') | And (x, xa) => And (p', q')
  10.424 +                | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
  10.425 +                | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
  10.426 +                | QEx x => And (p', q'))
  10.427 +           end
  10.428 +         | Gt (x, xa) =>
  10.429 +             let val q' = psimpl q
  10.430 +             in (case q' of Lt (x, xa) => And (p', q')
  10.431 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
  10.432 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
  10.433 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
  10.434 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
  10.435 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
  10.436 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
  10.437 +                  | QEx x => And (p', q'))
  10.438 +             end
  10.439 +         | Le (x, xa) =>
  10.440 +             let val q' = psimpl q
  10.441 +             in (case q' of Lt (x, xa) => And (p', q')
  10.442 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
  10.443 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
  10.444 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
  10.445 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
  10.446 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
  10.447 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
  10.448 +                  | QEx x => And (p', q'))
  10.449 +             end
  10.450 +         | Ge (x, xa) =>
  10.451 +             let val q' = psimpl q
  10.452 +             in (case q' of Lt (x, xa) => And (p', q')
  10.453 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
  10.454 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
  10.455 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
  10.456 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
  10.457 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
  10.458 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
  10.459 +                  | QEx x => And (p', q'))
  10.460 +             end
  10.461 +         | Eq (x, xa) =>
  10.462 +             let val q' = psimpl q
  10.463 +             in (case q' of Lt (x, xa) => And (p', q')
  10.464 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
  10.465 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
  10.466 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
  10.467 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
  10.468 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
  10.469 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
  10.470 +                  | QEx x => And (p', q'))
  10.471 +             end
  10.472 +         | Divides (x, xa) =>
  10.473 +             let val q' = psimpl q
  10.474 +             in (case q' of Lt (x, xa) => And (p', q')
  10.475 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
  10.476 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
  10.477 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
  10.478 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
  10.479 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
  10.480 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
  10.481 +                  | QEx x => And (p', q'))
  10.482 +             end
  10.483 +         | T => psimpl q | F => F
  10.484 +         | NOT x =>
  10.485 +             let val q' = psimpl q
  10.486 +             in (case q' of Lt (x, xa) => And (p', q')
  10.487 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
  10.488 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
  10.489 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
  10.490 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
  10.491 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
  10.492 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
  10.493 +                  | QEx x => And (p', q'))
  10.494 +             end
  10.495 +         | And (x, xa) =>
  10.496 +             let val q' = psimpl q
  10.497 +             in (case q' of Lt (x, xa) => And (p', q')
  10.498 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
  10.499 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
  10.500 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
  10.501 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
  10.502 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
  10.503 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
  10.504 +                  | QEx x => And (p', q'))
  10.505 +             end
  10.506 +         | Or (x, xa) =>
  10.507 +             let val q' = psimpl q
  10.508 +             in (case q' of Lt (x, xa) => And (p', q')
  10.509 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
  10.510 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
  10.511 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
  10.512 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
  10.513 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
  10.514 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
  10.515 +                  | QEx x => And (p', q'))
  10.516 +             end
  10.517 +         | Imp (x, xa) =>
  10.518 +             let val q' = psimpl q
  10.519 +             in (case q' of Lt (x, xa) => And (p', q')
  10.520 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
  10.521 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
  10.522 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
  10.523 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
  10.524 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
  10.525 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
  10.526 +                  | QEx x => And (p', q'))
  10.527 +             end
  10.528 +         | Equ (x, xa) =>
  10.529 +             let val q' = psimpl q
  10.530 +             in (case q' of Lt (x, xa) => And (p', q')
  10.531 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
  10.532 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
  10.533 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
  10.534 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
  10.535 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
  10.536 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
  10.537 +                  | QEx x => And (p', q'))
  10.538 +             end
  10.539 +         | QAll x =>
  10.540 +             let val q' = psimpl q
  10.541 +             in (case q' of Lt (x, xa) => And (p', q')
  10.542 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
  10.543 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
  10.544 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
  10.545 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
  10.546 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
  10.547 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
  10.548 +                  | QEx x => And (p', q'))
  10.549 +             end
  10.550 +         | QEx x =>
  10.551 +             let val q' = psimpl q
  10.552 +             in (case q' of Lt (x, xa) => And (p', q')
  10.553 +                  | Gt (x, xa) => And (p', q') | Le (x, xa) => And (p', q')
  10.554 +                  | Ge (x, xa) => And (p', q') | Eq (x, xa) => And (p', q')
  10.555 +                  | Divides (x, xa) => And (p', q') | T => p' | F => F
  10.556 +                  | NOT x => And (p', q') | And (x, xa) => And (p', q')
  10.557 +                  | Or (x, xa) => And (p', q') | Imp (x, xa) => And (p', q')
  10.558 +                  | Equ (x, xa) => And (p', q') | QAll x => And (p', q')
  10.559 +                  | QEx x => And (p', q'))
  10.560 +             end)
  10.561 +    end
  10.562 +  | psimpl (Or (p, q)) =
  10.563 +    let val p' = psimpl p
  10.564 +    in (case p' of
  10.565 +         Lt (x, xa) =>
  10.566 +           let val q' = psimpl q
  10.567 +           in (case q' of Lt (x, xa) => Or (p', q') | Gt (x, xa) => Or (p', q')
  10.568 +                | Le (x, xa) => Or (p', q') | Ge (x, xa) => Or (p', q')
  10.569 +                | Eq (x, xa) => Or (p', q') | Divides (x, xa) => Or (p', q')
  10.570 +                | T => T | F => p' | NOT x => Or (p', q')
  10.571 +                | And (x, xa) => Or (p', q') | Or (x, xa) => Or (p', q')
  10.572 +                | Imp (x, xa) => Or (p', q') | Equ (x, xa) => Or (p', q')
  10.573 +                | QAll x => Or (p', q') | QEx x => Or (p', q'))
  10.574 +           end
  10.575 +         | Gt (x, xa) =>
  10.576 +             let val q' = psimpl q
  10.577 +             in (case q' of Lt (x, xa) => Or (p', q')
  10.578 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
  10.579 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
  10.580 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
  10.581 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
  10.582 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
  10.583 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
  10.584 +                  | QEx x => Or (p', q'))
  10.585 +             end
  10.586 +         | Le (x, xa) =>
  10.587 +             let val q' = psimpl q
  10.588 +             in (case q' of Lt (x, xa) => Or (p', q')
  10.589 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
  10.590 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
  10.591 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
  10.592 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
  10.593 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
  10.594 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
  10.595 +                  | QEx x => Or (p', q'))
  10.596 +             end
  10.597 +         | Ge (x, xa) =>
  10.598 +             let val q' = psimpl q
  10.599 +             in (case q' of Lt (x, xa) => Or (p', q')
  10.600 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
  10.601 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
  10.602 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
  10.603 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
  10.604 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
  10.605 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
  10.606 +                  | QEx x => Or (p', q'))
  10.607 +             end
  10.608 +         | Eq (x, xa) =>
  10.609 +             let val q' = psimpl q
  10.610 +             in (case q' of Lt (x, xa) => Or (p', q')
  10.611 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
  10.612 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
  10.613 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
  10.614 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
  10.615 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
  10.616 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
  10.617 +                  | QEx x => Or (p', q'))
  10.618 +             end
  10.619 +         | Divides (x, xa) =>
  10.620 +             let val q' = psimpl q
  10.621 +             in (case q' of Lt (x, xa) => Or (p', q')
  10.622 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
  10.623 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
  10.624 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
  10.625 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
  10.626 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
  10.627 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
  10.628 +                  | QEx x => Or (p', q'))
  10.629 +             end
  10.630 +         | T => T | F => psimpl q
  10.631 +         | NOT x =>
  10.632 +             let val q' = psimpl q
  10.633 +             in (case q' of Lt (x, xa) => Or (p', q')
  10.634 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
  10.635 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
  10.636 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
  10.637 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
  10.638 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
  10.639 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
  10.640 +                  | QEx x => Or (p', q'))
  10.641 +             end
  10.642 +         | And (x, xa) =>
  10.643 +             let val q' = psimpl q
  10.644 +             in (case q' of Lt (x, xa) => Or (p', q')
  10.645 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
  10.646 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
  10.647 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
  10.648 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
  10.649 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
  10.650 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
  10.651 +                  | QEx x => Or (p', q'))
  10.652 +             end
  10.653 +         | Or (x, xa) =>
  10.654 +             let val q' = psimpl q
  10.655 +             in (case q' of Lt (x, xa) => Or (p', q')
  10.656 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
  10.657 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
  10.658 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
  10.659 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
  10.660 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
  10.661 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
  10.662 +                  | QEx x => Or (p', q'))
  10.663 +             end
  10.664 +         | Imp (x, xa) =>
  10.665 +             let val q' = psimpl q
  10.666 +             in (case q' of Lt (x, xa) => Or (p', q')
  10.667 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
  10.668 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
  10.669 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
  10.670 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
  10.671 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
  10.672 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
  10.673 +                  | QEx x => Or (p', q'))
  10.674 +             end
  10.675 +         | Equ (x, xa) =>
  10.676 +             let val q' = psimpl q
  10.677 +             in (case q' of Lt (x, xa) => Or (p', q')
  10.678 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
  10.679 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
  10.680 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
  10.681 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
  10.682 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
  10.683 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
  10.684 +                  | QEx x => Or (p', q'))
  10.685 +             end
  10.686 +         | QAll x =>
  10.687 +             let val q' = psimpl q
  10.688 +             in (case q' of Lt (x, xa) => Or (p', q')
  10.689 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
  10.690 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
  10.691 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
  10.692 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
  10.693 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
  10.694 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
  10.695 +                  | QEx x => Or (p', q'))
  10.696 +             end
  10.697 +         | QEx x =>
  10.698 +             let val q' = psimpl q
  10.699 +             in (case q' of Lt (x, xa) => Or (p', q')
  10.700 +                  | Gt (x, xa) => Or (p', q') | Le (x, xa) => Or (p', q')
  10.701 +                  | Ge (x, xa) => Or (p', q') | Eq (x, xa) => Or (p', q')
  10.702 +                  | Divides (x, xa) => Or (p', q') | T => T | F => p'
  10.703 +                  | NOT x => Or (p', q') | And (x, xa) => Or (p', q')
  10.704 +                  | Or (x, xa) => Or (p', q') | Imp (x, xa) => Or (p', q')
  10.705 +                  | Equ (x, xa) => Or (p', q') | QAll x => Or (p', q')
  10.706 +                  | QEx x => Or (p', q'))
  10.707 +             end)
  10.708 +    end
  10.709 +  | psimpl (Imp (p, q)) =
  10.710 +    let val p' = psimpl p
  10.711 +    in (case p' of
  10.712 +         Lt (x, xa) =>
  10.713 +           let val q' = psimpl q
  10.714 +           in (case q' of Lt (x, xa) => Imp (p', q')
  10.715 +                | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
  10.716 +                | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
  10.717 +                | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
  10.718 +                | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
  10.719 +                | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
  10.720 +                | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
  10.721 +                | QEx x => Imp (p', q'))
  10.722 +           end
  10.723 +         | Gt (x, xa) =>
  10.724 +             let val q' = psimpl q
  10.725 +             in (case q' of Lt (x, xa) => Imp (p', q')
  10.726 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
  10.727 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
  10.728 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
  10.729 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
  10.730 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
  10.731 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
  10.732 +                  | QEx x => Imp (p', q'))
  10.733 +             end
  10.734 +         | Le (x, xa) =>
  10.735 +             let val q' = psimpl q
  10.736 +             in (case q' of Lt (x, xa) => Imp (p', q')
  10.737 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
  10.738 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
  10.739 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
  10.740 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
  10.741 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
  10.742 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
  10.743 +                  | QEx x => Imp (p', q'))
  10.744 +             end
  10.745 +         | Ge (x, xa) =>
  10.746 +             let val q' = psimpl q
  10.747 +             in (case q' of Lt (x, xa) => Imp (p', q')
  10.748 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
  10.749 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
  10.750 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
  10.751 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
  10.752 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
  10.753 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
  10.754 +                  | QEx x => Imp (p', q'))
  10.755 +             end
  10.756 +         | Eq (x, xa) =>
  10.757 +             let val q' = psimpl q
  10.758 +             in (case q' of Lt (x, xa) => Imp (p', q')
  10.759 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
  10.760 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
  10.761 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
  10.762 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
  10.763 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
  10.764 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
  10.765 +                  | QEx x => Imp (p', q'))
  10.766 +             end
  10.767 +         | Divides (x, xa) =>
  10.768 +             let val q' = psimpl q
  10.769 +             in (case q' of Lt (x, xa) => Imp (p', q')
  10.770 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
  10.771 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
  10.772 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
  10.773 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
  10.774 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
  10.775 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
  10.776 +                  | QEx x => Imp (p', q'))
  10.777 +             end
  10.778 +         | T => psimpl q | F => T
  10.779 +         | NOT x =>
  10.780 +             let val q' = psimpl q
  10.781 +             in (case q' of Lt (xa, xb) => Or (x, q')
  10.782 +                  | Gt (xa, xb) => Or (x, q') | Le (xa, xb) => Or (x, q')
  10.783 +                  | Ge (xa, xb) => Or (x, q') | Eq (xa, xb) => Or (x, q')
  10.784 +                  | Divides (xa, xb) => Or (x, q') | T => T | F => x
  10.785 +                  | NOT xa => Or (x, q') | And (xa, xb) => Or (x, q')
  10.786 +                  | Or (xa, xb) => Or (x, q') | Imp (xa, xb) => Or (x, q')
  10.787 +                  | Equ (xa, xb) => Or (x, q') | QAll xa => Or (x, q')
  10.788 +                  | QEx xa => Or (x, q'))
  10.789 +             end
  10.790 +         | And (x, xa) =>
  10.791 +             let val q' = psimpl q
  10.792 +             in (case q' of Lt (x, xa) => Imp (p', q')
  10.793 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
  10.794 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
  10.795 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
  10.796 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
  10.797 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
  10.798 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
  10.799 +                  | QEx x => Imp (p', q'))
  10.800 +             end
  10.801 +         | Or (x, xa) =>
  10.802 +             let val q' = psimpl q
  10.803 +             in (case q' of Lt (x, xa) => Imp (p', q')
  10.804 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
  10.805 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
  10.806 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
  10.807 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
  10.808 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
  10.809 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
  10.810 +                  | QEx x => Imp (p', q'))
  10.811 +             end
  10.812 +         | Imp (x, xa) =>
  10.813 +             let val q' = psimpl q
  10.814 +             in (case q' of Lt (x, xa) => Imp (p', q')
  10.815 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
  10.816 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
  10.817 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
  10.818 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
  10.819 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
  10.820 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
  10.821 +                  | QEx x => Imp (p', q'))
  10.822 +             end
  10.823 +         | Equ (x, xa) =>
  10.824 +             let val q' = psimpl q
  10.825 +             in (case q' of Lt (x, xa) => Imp (p', q')
  10.826 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
  10.827 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
  10.828 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
  10.829 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
  10.830 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
  10.831 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
  10.832 +                  | QEx x => Imp (p', q'))
  10.833 +             end
  10.834 +         | QAll x =>
  10.835 +             let val q' = psimpl q
  10.836 +             in (case q' of Lt (x, xa) => Imp (p', q')
  10.837 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
  10.838 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
  10.839 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
  10.840 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
  10.841 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
  10.842 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
  10.843 +                  | QEx x => Imp (p', q'))
  10.844 +             end
  10.845 +         | QEx x =>
  10.846 +             let val q' = psimpl q
  10.847 +             in (case q' of Lt (x, xa) => Imp (p', q')
  10.848 +                  | Gt (x, xa) => Imp (p', q') | Le (x, xa) => Imp (p', q')
  10.849 +                  | Ge (x, xa) => Imp (p', q') | Eq (x, xa) => Imp (p', q')
  10.850 +                  | Divides (x, xa) => Imp (p', q') | T => T | F => NOT p'
  10.851 +                  | NOT x => Imp (p', q') | And (x, xa) => Imp (p', q')
  10.852 +                  | Or (x, xa) => Imp (p', q') | Imp (x, xa) => Imp (p', q')
  10.853 +                  | Equ (x, xa) => Imp (p', q') | QAll x => Imp (p', q')
  10.854 +                  | QEx x => Imp (p', q'))
  10.855 +             end)
  10.856 +    end;
  10.857 +
  10.858 +fun subst_it i (Cst b) = Cst b
  10.859 +  | subst_it i (Var n) = (if (n = 0) then i else Var n)
  10.860 +  | subst_it i (Neg it) = Neg (subst_it i it)
  10.861 +  | subst_it i (Add (it1, it2)) = Add (subst_it i it1, subst_it i it2)
  10.862 +  | subst_it i (Sub (it1, it2)) = Sub (subst_it i it1, subst_it i it2)
  10.863 +  | subst_it i (Mult (it1, it2)) = Mult (subst_it i it1, subst_it i it2);
  10.864 +
  10.865 +fun subst_p i (Le (it1, it2)) = Le (subst_it i it1, subst_it i it2)
  10.866 +  | subst_p i (Lt (it1, it2)) = Lt (subst_it i it1, subst_it i it2)
  10.867 +  | subst_p i (Ge (it1, it2)) = Ge (subst_it i it1, subst_it i it2)
  10.868 +  | subst_p i (Gt (it1, it2)) = Gt (subst_it i it1, subst_it i it2)
  10.869 +  | subst_p i (Eq (it1, it2)) = Eq (subst_it i it1, subst_it i it2)
  10.870 +  | subst_p i (Divides (d, t)) = Divides (subst_it i d, subst_it i t)
  10.871 +  | subst_p i T = T
  10.872 +  | subst_p i F = F
  10.873 +  | subst_p i (And (p, q)) = And (subst_p i p, subst_p i q)
  10.874 +  | subst_p i (Or (p, q)) = Or (subst_p i p, subst_p i q)
  10.875 +  | subst_p i (Imp (p, q)) = Imp (subst_p i p, subst_p i q)
  10.876 +  | subst_p i (Equ (p, q)) = Equ (subst_p i p, subst_p i q)
  10.877 +  | subst_p i (NOT p) = NOT (subst_p i p);
  10.878 +
  10.879 +fun explode_disj ([], p) = F
  10.880 +  | explode_disj ((i :: is), p) =
  10.881 +    let val pi = psimpl (subst_p i p)
  10.882 +    in (case pi of
  10.883 +         Lt (x, xa) =>
  10.884 +           let val r = explode_disj (is, p)
  10.885 +           in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
  10.886 +                | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
  10.887 +                | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
  10.888 +                | T => T | F => pi | NOT x => Or (pi, r)
  10.889 +                | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
  10.890 +                | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
  10.891 +                | QAll x => Or (pi, r) | QEx x => Or (pi, r))
  10.892 +           end
  10.893 +         | Gt (x, xa) =>
  10.894 +             let val r = explode_disj (is, p)
  10.895 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
  10.896 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
  10.897 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
  10.898 +                  | T => T | F => pi | NOT x => Or (pi, r)
  10.899 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
  10.900 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
  10.901 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
  10.902 +             end
  10.903 +         | Le (x, xa) =>
  10.904 +             let val r = explode_disj (is, p)
  10.905 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
  10.906 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
  10.907 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
  10.908 +                  | T => T | F => pi | NOT x => Or (pi, r)
  10.909 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
  10.910 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
  10.911 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
  10.912 +             end
  10.913 +         | Ge (x, xa) =>
  10.914 +             let val r = explode_disj (is, p)
  10.915 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
  10.916 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
  10.917 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
  10.918 +                  | T => T | F => pi | NOT x => Or (pi, r)
  10.919 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
  10.920 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
  10.921 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
  10.922 +             end
  10.923 +         | Eq (x, xa) =>
  10.924 +             let val r = explode_disj (is, p)
  10.925 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
  10.926 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
  10.927 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
  10.928 +                  | T => T | F => pi | NOT x => Or (pi, r)
  10.929 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
  10.930 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
  10.931 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
  10.932 +             end
  10.933 +         | Divides (x, xa) =>
  10.934 +             let val r = explode_disj (is, p)
  10.935 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
  10.936 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
  10.937 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
  10.938 +                  | T => T | F => pi | NOT x => Or (pi, r)
  10.939 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
  10.940 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
  10.941 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
  10.942 +             end
  10.943 +         | T => T | F => explode_disj (is, p)
  10.944 +         | NOT x =>
  10.945 +             let val r = explode_disj (is, p)
  10.946 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
  10.947 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
  10.948 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
  10.949 +                  | T => T | F => pi | NOT x => Or (pi, r)
  10.950 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
  10.951 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
  10.952 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
  10.953 +             end
  10.954 +         | And (x, xa) =>
  10.955 +             let val r = explode_disj (is, p)
  10.956 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
  10.957 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
  10.958 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
  10.959 +                  | T => T | F => pi | NOT x => Or (pi, r)
  10.960 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
  10.961 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
  10.962 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
  10.963 +             end
  10.964 +         | Or (x, xa) =>
  10.965 +             let val r = explode_disj (is, p)
  10.966 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
  10.967 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
  10.968 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
  10.969 +                  | T => T | F => pi | NOT x => Or (pi, r)
  10.970 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
  10.971 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
  10.972 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
  10.973 +             end
  10.974 +         | Imp (x, xa) =>
  10.975 +             let val r = explode_disj (is, p)
  10.976 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
  10.977 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
  10.978 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
  10.979 +                  | T => T | F => pi | NOT x => Or (pi, r)
  10.980 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
  10.981 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
  10.982 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
  10.983 +             end
  10.984 +         | Equ (x, xa) =>
  10.985 +             let val r = explode_disj (is, p)
  10.986 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
  10.987 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
  10.988 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
  10.989 +                  | T => T | F => pi | NOT x => Or (pi, r)
  10.990 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
  10.991 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
  10.992 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
  10.993 +             end
  10.994 +         | QAll x =>
  10.995 +             let val r = explode_disj (is, p)
  10.996 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
  10.997 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
  10.998 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
  10.999 +                  | T => T | F => pi | NOT x => Or (pi, r)
 10.1000 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
 10.1001 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
 10.1002 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
 10.1003 +             end
 10.1004 +         | QEx x =>
 10.1005 +             let val r = explode_disj (is, p)
 10.1006 +             in (case r of Lt (x, xa) => Or (pi, r) | Gt (x, xa) => Or (pi, r)
 10.1007 +                  | Le (x, xa) => Or (pi, r) | Ge (x, xa) => Or (pi, r)
 10.1008 +                  | Eq (x, xa) => Or (pi, r) | Divides (x, xa) => Or (pi, r)
 10.1009 +                  | T => T | F => pi | NOT x => Or (pi, r)
 10.1010 +                  | And (x, xa) => Or (pi, r) | Or (x, xa) => Or (pi, r)
 10.1011 +                  | Imp (x, xa) => Or (pi, r) | Equ (x, xa) => Or (pi, r)
 10.1012 +                  | QAll x => Or (pi, r) | QEx x => Or (pi, r))
 10.1013 +             end)
 10.1014 +    end;
 10.1015 +
 10.1016 +fun minusinf (And (p, q)) = And (minusinf p, minusinf q)
 10.1017 +  | minusinf (Or (p, q)) = Or (minusinf p, minusinf q)
 10.1018 +  | minusinf (Lt (u, v)) = Lt (u, v)
 10.1019 +  | minusinf (Gt (w, x)) = Gt (w, x)
 10.1020 +  | minusinf (Le (Cst bo, z)) = Le (Cst bo, z)
 10.1021 +  | minusinf (Le (Var bp, z)) = Le (Var bp, z)
 10.1022 +  | minusinf (Le (Neg bq, z)) = Le (Neg bq, z)
 10.1023 +  | minusinf (Le (Add (Cst cg, bs), z)) = Le (Add (Cst cg, bs), z)
 10.1024 +  | minusinf (Le (Add (Var ch, bs), z)) = Le (Add (Var ch, bs), z)
 10.1025 +  | minusinf (Le (Add (Neg ci, bs), z)) = Le (Add (Neg ci, bs), z)
 10.1026 +  | minusinf (Le (Add (Add (cj, ck), bs), z)) = Le (Add (Add (cj, ck), bs), z)
 10.1027 +  | minusinf (Le (Add (Sub (cl, cm), bs), z)) = Le (Add (Sub (cl, cm), bs), z)
 10.1028 +  | minusinf (Le (Add (Mult (Cst cy, Cst dq), bs), z)) =
 10.1029 +    Le (Add (Mult (Cst cy, Cst dq), bs), z)
 10.1030 +  | minusinf (Le (Add (Mult (Cst cy, Var ei), bs), z)) =
 10.1031 +    (if (ei = 0) then (if (cy < 0) then F else T)
 10.1032 +      else Le (Add (Mult (Cst cy, Var (op_45_def0 ei id_1_def0 + 1)), bs), z))
 10.1033 +  | minusinf (Le (Add (Mult (Cst cy, Neg ds), bs), z)) =
 10.1034 +    Le (Add (Mult (Cst cy, Neg ds), bs), z)
 10.1035 +  | minusinf (Le (Add (Mult (Cst cy, Add (dt, du)), bs), z)) =
 10.1036 +    Le (Add (Mult (Cst cy, Add (dt, du)), bs), z)
 10.1037 +  | minusinf (Le (Add (Mult (Cst cy, Sub (dv, dw)), bs), z)) =
 10.1038 +    Le (Add (Mult (Cst cy, Sub (dv, dw)), bs), z)
 10.1039 +  | minusinf (Le (Add (Mult (Cst cy, Mult (dx, dy)), bs), z)) =
 10.1040 +    Le (Add (Mult (Cst cy, Mult (dx, dy)), bs), z)
 10.1041 +  | minusinf (Le (Add (Mult (Var cz, co), bs), z)) =
 10.1042 +    Le (Add (Mult (Var cz, co), bs), z)
 10.1043 +  | minusinf (Le (Add (Mult (Neg da, co), bs), z)) =
 10.1044 +    Le (Add (Mult (Neg da, co), bs), z)
 10.1045 +  | minusinf (Le (Add (Mult (Add (db, dc), co), bs), z)) =
 10.1046 +    Le (Add (Mult (Add (db, dc), co), bs), z)
 10.1047 +  | minusinf (Le (Add (Mult (Sub (dd, de), co), bs), z)) =
 10.1048 +    Le (Add (Mult (Sub (dd, de), co), bs), z)
 10.1049 +  | minusinf (Le (Add (Mult (Mult (df, dg), co), bs), z)) =
 10.1050 +    Le (Add (Mult (Mult (df, dg), co), bs), z)
 10.1051 +  | minusinf (Le (Sub (bt, bu), z)) = Le (Sub (bt, bu), z)
 10.1052 +  | minusinf (Le (Mult (bv, bw), z)) = Le (Mult (bv, bw), z)
 10.1053 +  | minusinf (Ge (aa, ab)) = Ge (aa, ab)
 10.1054 +  | minusinf (Eq (Cst ek, ad)) = Eq (Cst ek, ad)
 10.1055 +  | minusinf (Eq (Var el, ad)) = Eq (Var el, ad)
 10.1056 +  | minusinf (Eq (Neg em, ad)) = Eq (Neg em, ad)
 10.1057 +  | minusinf (Eq (Add (Cst fc, eo), ad)) = Eq (Add (Cst fc, eo), ad)
 10.1058 +  | minusinf (Eq (Add (Var fd, eo), ad)) = Eq (Add (Var fd, eo), ad)
 10.1059 +  | minusinf (Eq (Add (Neg fe, eo), ad)) = Eq (Add (Neg fe, eo), ad)
 10.1060 +  | minusinf (Eq (Add (Add (ff, fg), eo), ad)) = Eq (Add (Add (ff, fg), eo), ad)
 10.1061 +  | minusinf (Eq (Add (Sub (fh, fi), eo), ad)) = Eq (Add (Sub (fh, fi), eo), ad)
 10.1062 +  | minusinf (Eq (Add (Mult (Cst fu, Cst gm), eo), ad)) =
 10.1063 +    Eq (Add (Mult (Cst fu, Cst gm), eo), ad)
 10.1064 +  | minusinf (Eq (Add (Mult (Cst fu, Var he), eo), ad)) =
 10.1065 +    (if (he = 0) then F
 10.1066 +      else Eq (Add (Mult (Cst fu, Var (op_45_def0 he id_1_def0 + 1)), eo), ad))
 10.1067 +  | minusinf (Eq (Add (Mult (Cst fu, Neg go), eo), ad)) =
 10.1068 +    Eq (Add (Mult (Cst fu, Neg go), eo), ad)
 10.1069 +  | minusinf (Eq (Add (Mult (Cst fu, Add (gp, gq)), eo), ad)) =
 10.1070 +    Eq (Add (Mult (Cst fu, Add (gp, gq)), eo), ad)
 10.1071 +  | minusinf (Eq (Add (Mult (Cst fu, Sub (gr, gs)), eo), ad)) =
 10.1072 +    Eq (Add (Mult (Cst fu, Sub (gr, gs)), eo), ad)
 10.1073 +  | minusinf (Eq (Add (Mult (Cst fu, Mult (gt, gu)), eo), ad)) =
 10.1074 +    Eq (Add (Mult (Cst fu, Mult (gt, gu)), eo), ad)
 10.1075 +  | minusinf (Eq (Add (Mult (Var fv, fk), eo), ad)) =
 10.1076 +    Eq (Add (Mult (Var fv, fk), eo), ad)
 10.1077 +  | minusinf (Eq (Add (Mult (Neg fw, fk), eo), ad)) =
 10.1078 +    Eq (Add (Mult (Neg fw, fk), eo), ad)
 10.1079 +  | minusinf (Eq (Add (Mult (Add (fx, fy), fk), eo), ad)) =
 10.1080 +    Eq (Add (Mult (Add (fx, fy), fk), eo), ad)
 10.1081 +  | minusinf (Eq (Add (Mult (Sub (fz, ga), fk), eo), ad)) =
 10.1082 +    Eq (Add (Mult (Sub (fz, ga), fk), eo), ad)
 10.1083 +  | minusinf (Eq (Add (Mult (Mult (gb, gc), fk), eo), ad)) =
 10.1084 +    Eq (Add (Mult (Mult (gb, gc), fk), eo), ad)
 10.1085 +  | minusinf (Eq (Sub (ep, eq), ad)) = Eq (Sub (ep, eq), ad)
 10.1086 +  | minusinf (Eq (Mult (er, es), ad)) = Eq (Mult (er, es), ad)
 10.1087 +  | minusinf (Divides (ae, af)) = Divides (ae, af)
 10.1088 +  | minusinf T = T
 10.1089 +  | minusinf F = F
 10.1090 +  | minusinf (NOT (Lt (hg, hh))) = NOT (Lt (hg, hh))
 10.1091 +  | minusinf (NOT (Gt (hi, hj))) = NOT (Gt (hi, hj))
 10.1092 +  | minusinf (NOT (Le (hk, hl))) = NOT (Le (hk, hl))
 10.1093 +  | minusinf (NOT (Ge (hm, hn))) = NOT (Ge (hm, hn))
 10.1094 +  | minusinf (NOT (Eq (Cst ja, hp))) = NOT (Eq (Cst ja, hp))
 10.1095 +  | minusinf (NOT (Eq (Var jb, hp))) = NOT (Eq (Var jb, hp))
 10.1096 +  | minusinf (NOT (Eq (Neg jc, hp))) = NOT (Eq (Neg jc, hp))
 10.1097 +  | minusinf (NOT (Eq (Add (Cst js, je), hp))) = NOT (Eq (Add (Cst js, je), hp))
 10.1098 +  | minusinf (NOT (Eq (Add (Var jt, je), hp))) = NOT (Eq (Add (Var jt, je), hp))
 10.1099 +  | minusinf (NOT (Eq (Add (Neg ju, je), hp))) = NOT (Eq (Add (Neg ju, je), hp))
 10.1100 +  | minusinf (NOT (Eq (Add (Add (jv, jw), je), hp))) =
 10.1101 +    NOT (Eq (Add (Add (jv, jw), je), hp))
 10.1102 +  | minusinf (NOT (Eq (Add (Sub (jx, jy), je), hp))) =
 10.1103 +    NOT (Eq (Add (Sub (jx, jy), je), hp))
 10.1104 +  | minusinf (NOT (Eq (Add (Mult (Cst kk, Cst lc), je), hp))) =
 10.1105 +    NOT (Eq (Add (Mult (Cst kk, Cst lc), je), hp))
 10.1106 +  | minusinf (NOT (Eq (Add (Mult (Cst kk, Var lu), je), hp))) =
 10.1107 +    (if (lu = 0) then T
 10.1108 +      else NOT (Eq (Add (Mult (Cst kk, Var (op_45_def0 lu id_1_def0 + 1)), je),
 10.1109 +                     hp)))
 10.1110 +  | minusinf (NOT (Eq (Add (Mult (Cst kk, Neg le), je), hp))) =
 10.1111 +    NOT (Eq (Add (Mult (Cst kk, Neg le), je), hp))
 10.1112 +  | minusinf (NOT (Eq (Add (Mult (Cst kk, Add (lf, lg)), je), hp))) =
 10.1113 +    NOT (Eq (Add (Mult (Cst kk, Add (lf, lg)), je), hp))
 10.1114 +  | minusinf (NOT (Eq (Add (Mult (Cst kk, Sub (lh, li)), je), hp))) =
 10.1115 +    NOT (Eq (Add (Mult (Cst kk, Sub (lh, li)), je), hp))
 10.1116 +  | minusinf (NOT (Eq (Add (Mult (Cst kk, Mult (lj, lk)), je), hp))) =
 10.1117 +    NOT (Eq (Add (Mult (Cst kk, Mult (lj, lk)), je), hp))
 10.1118 +  | minusinf (NOT (Eq (Add (Mult (Var kl, ka), je), hp))) =
 10.1119 +    NOT (Eq (Add (Mult (Var kl, ka), je), hp))
 10.1120 +  | minusinf (NOT (Eq (Add (Mult (Neg km, ka), je), hp))) =
 10.1121 +    NOT (Eq (Add (Mult (Neg km, ka), je), hp))
 10.1122 +  | minusinf (NOT (Eq (Add (Mult (Add (kn, ko), ka), je), hp))) =
 10.1123 +    NOT (Eq (Add (Mult (Add (kn, ko), ka), je), hp))
 10.1124 +  | minusinf (NOT (Eq (Add (Mult (Sub (kp, kq), ka), je), hp))) =
 10.1125 +    NOT (Eq (Add (Mult (Sub (kp, kq), ka), je), hp))
 10.1126 +  | minusinf (NOT (Eq (Add (Mult (Mult (kr, ks), ka), je), hp))) =
 10.1127 +    NOT (Eq (Add (Mult (Mult (kr, ks), ka), je), hp))
 10.1128 +  | minusinf (NOT (Eq (Sub (jf, jg), hp))) = NOT (Eq (Sub (jf, jg), hp))
 10.1129 +  | minusinf (NOT (Eq (Mult (jh, ji), hp))) = NOT (Eq (Mult (jh, ji), hp))
 10.1130 +  | minusinf (NOT (Divides (hq, hr))) = NOT (Divides (hq, hr))
 10.1131 +  | minusinf (NOT T) = NOT T
 10.1132 +  | minusinf (NOT F) = NOT F
 10.1133 +  | minusinf (NOT (NOT hs)) = NOT (NOT hs)
 10.1134 +  | minusinf (NOT (And (ht, hu))) = NOT (And (ht, hu))
 10.1135 +  | minusinf (NOT (Or (hv, hw))) = NOT (Or (hv, hw))
 10.1136 +  | minusinf (NOT (Imp (hx, hy))) = NOT (Imp (hx, hy))
 10.1137 +  | minusinf (NOT (Equ (hz, ia))) = NOT (Equ (hz, ia))
 10.1138 +  | minusinf (NOT (QAll ib)) = NOT (QAll ib)
 10.1139 +  | minusinf (NOT (QEx ic)) = NOT (QEx ic)
 10.1140 +  | minusinf (Imp (al, am)) = Imp (al, am)
 10.1141 +  | minusinf (Equ (an, ao)) = Equ (an, ao)
 10.1142 +  | minusinf (QAll ap) = QAll ap
 10.1143 +  | minusinf (QEx aq) = QEx aq;
 10.1144 +
 10.1145 +fun abs i = (if (i < 0) then ~ i else i);
 10.1146 +
 10.1147 +fun op_div_def1 a b = fst (divAlg (a, b));
 10.1148 +
 10.1149 +fun op_mod_def0 m n = nat (op_mod_def1 (m) (n));
 10.1150 +
 10.1151 +fun ngcd (m, n) = (if (n = 0) then m else ngcd (n, op_mod_def0 m n));
 10.1152 +
 10.1153 +fun igcd x = split (fn a => fn b => (ngcd (nat (abs a), nat (abs b)))) x;
 10.1154 +
 10.1155 +fun ilcm a b = op_div_def1 (a * b) (igcd (a, b));
 10.1156 +
 10.1157 +fun divlcm (NOT p) = divlcm p
 10.1158 +  | divlcm (And (p, q)) = ilcm (divlcm p) (divlcm q)
 10.1159 +  | divlcm (Or (p, q)) = ilcm (divlcm p) (divlcm q)
 10.1160 +  | divlcm (Lt (u, v)) = 1
 10.1161 +  | divlcm (Gt (w, x)) = 1
 10.1162 +  | divlcm (Le (y, z)) = 1
 10.1163 +  | divlcm (Ge (aa, ab)) = 1
 10.1164 +  | divlcm (Eq (ac, ad)) = 1
 10.1165 +  | divlcm (Divides (Cst bo, Cst cg)) = 1
 10.1166 +  | divlcm (Divides (Cst bo, Var ch)) = 1
 10.1167 +  | divlcm (Divides (Cst bo, Neg ci)) = 1
 10.1168 +  | divlcm (Divides (Cst bo, Add (Cst cy, ck))) = 1
 10.1169 +  | divlcm (Divides (Cst bo, Add (Var cz, ck))) = 1
 10.1170 +  | divlcm (Divides (Cst bo, Add (Neg da, ck))) = 1
 10.1171 +  | divlcm (Divides (Cst bo, Add (Add (db, dc), ck))) = 1
 10.1172 +  | divlcm (Divides (Cst bo, Add (Sub (dd, de), ck))) = 1
 10.1173 +  | divlcm (Divides (Cst bo, Add (Mult (Cst dq, Cst ei), ck))) = 1
 10.1174 +  | divlcm (Divides (Cst bo, Add (Mult (Cst dq, Var fa), ck))) =
 10.1175 +    (if (fa = 0) then abs bo else 1)
 10.1176 +  | divlcm (Divides (Cst bo, Add (Mult (Cst dq, Neg ek), ck))) = 1
 10.1177 +  | divlcm (Divides (Cst bo, Add (Mult (Cst dq, Add (el, em)), ck))) = 1
 10.1178 +  | divlcm (Divides (Cst bo, Add (Mult (Cst dq, Sub (en, eo)), ck))) = 1
 10.1179 +  | divlcm (Divides (Cst bo, Add (Mult (Cst dq, Mult (ep, eq)), ck))) = 1
 10.1180 +  | divlcm (Divides (Cst bo, Add (Mult (Var dr, dg), ck))) = 1
 10.1181 +  | divlcm (Divides (Cst bo, Add (Mult (Neg ds, dg), ck))) = 1
 10.1182 +  | divlcm (Divides (Cst bo, Add (Mult (Add (dt, du), dg), ck))) = 1
 10.1183 +  | divlcm (Divides (Cst bo, Add (Mult (Sub (dv, dw), dg), ck))) = 1
 10.1184 +  | divlcm (Divides (Cst bo, Add (Mult (Mult (dx, dy), dg), ck))) = 1
 10.1185 +  | divlcm (Divides (Cst bo, Sub (cl, cm))) = 1
 10.1186 +  | divlcm (Divides (Cst bo, Mult (cn, co))) = 1
 10.1187 +  | divlcm (Divides (Var bp, af)) = 1
 10.1188 +  | divlcm (Divides (Neg bq, af)) = 1
 10.1189 +  | divlcm (Divides (Add (br, bs), af)) = 1
 10.1190 +  | divlcm (Divides (Sub (bt, bu), af)) = 1
 10.1191 +  | divlcm (Divides (Mult (bv, bw), af)) = 1
 10.1192 +  | divlcm T = 1
 10.1193 +  | divlcm F = 1
 10.1194 +  | divlcm (Imp (al, am)) = 1
 10.1195 +  | divlcm (Equ (an, ao)) = 1
 10.1196 +  | divlcm (QAll ap) = 1
 10.1197 +  | divlcm (QEx aq) = 1;
 10.1198 +
 10.1199 +fun explode_minf (q, B) =
 10.1200 +    let val d = divlcm q; val pm = minusinf q;
 10.1201 +        val dj1 = explode_disj (map (fn x => Cst x) (iupto (1, d)), pm)
 10.1202 +    in (case dj1 of
 10.1203 +         Lt (x, xa) =>
 10.1204 +           let val dj2 = explode_disj (all_sums (d, B), q)
 10.1205 +           in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
 10.1206 +                | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
 10.1207 +                | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
 10.1208 +                | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
 10.1209 +                | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
 10.1210 +                | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
 10.1211 +                | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
 10.1212 +                | QEx x => Or (dj1, dj2))
 10.1213 +           end
 10.1214 +         | Gt (x, xa) =>
 10.1215 +             let val dj2 = explode_disj (all_sums (d, B), q)
 10.1216 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
 10.1217 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
 10.1218 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
 10.1219 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
 10.1220 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
 10.1221 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
 10.1222 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
 10.1223 +                  | QEx x => Or (dj1, dj2))
 10.1224 +             end
 10.1225 +         | Le (x, xa) =>
 10.1226 +             let val dj2 = explode_disj (all_sums (d, B), q)
 10.1227 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
 10.1228 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
 10.1229 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
 10.1230 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
 10.1231 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
 10.1232 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
 10.1233 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
 10.1234 +                  | QEx x => Or (dj1, dj2))
 10.1235 +             end
 10.1236 +         | Ge (x, xa) =>
 10.1237 +             let val dj2 = explode_disj (all_sums (d, B), q)
 10.1238 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
 10.1239 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
 10.1240 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
 10.1241 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
 10.1242 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
 10.1243 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
 10.1244 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
 10.1245 +                  | QEx x => Or (dj1, dj2))
 10.1246 +             end
 10.1247 +         | Eq (x, xa) =>
 10.1248 +             let val dj2 = explode_disj (all_sums (d, B), q)
 10.1249 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
 10.1250 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
 10.1251 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
 10.1252 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
 10.1253 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
 10.1254 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
 10.1255 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
 10.1256 +                  | QEx x => Or (dj1, dj2))
 10.1257 +             end
 10.1258 +         | Divides (x, xa) =>
 10.1259 +             let val dj2 = explode_disj (all_sums (d, B), q)
 10.1260 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
 10.1261 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
 10.1262 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
 10.1263 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
 10.1264 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
 10.1265 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
 10.1266 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
 10.1267 +                  | QEx x => Or (dj1, dj2))
 10.1268 +             end
 10.1269 +         | T => T | F => explode_disj (all_sums (d, B), q)
 10.1270 +         | NOT x =>
 10.1271 +             let val dj2 = explode_disj (all_sums (d, B), q)
 10.1272 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
 10.1273 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
 10.1274 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
 10.1275 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
 10.1276 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
 10.1277 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
 10.1278 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
 10.1279 +                  | QEx x => Or (dj1, dj2))
 10.1280 +             end
 10.1281 +         | And (x, xa) =>
 10.1282 +             let val dj2 = explode_disj (all_sums (d, B), q)
 10.1283 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
 10.1284 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
 10.1285 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
 10.1286 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
 10.1287 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
 10.1288 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
 10.1289 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
 10.1290 +                  | QEx x => Or (dj1, dj2))
 10.1291 +             end
 10.1292 +         | Or (x, xa) =>
 10.1293 +             let val dj2 = explode_disj (all_sums (d, B), q)
 10.1294 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
 10.1295 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
 10.1296 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
 10.1297 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
 10.1298 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
 10.1299 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
 10.1300 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
 10.1301 +                  | QEx x => Or (dj1, dj2))
 10.1302 +             end
 10.1303 +         | Imp (x, xa) =>
 10.1304 +             let val dj2 = explode_disj (all_sums (d, B), q)
 10.1305 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
 10.1306 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
 10.1307 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
 10.1308 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
 10.1309 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
 10.1310 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
 10.1311 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
 10.1312 +                  | QEx x => Or (dj1, dj2))
 10.1313 +             end
 10.1314 +         | Equ (x, xa) =>
 10.1315 +             let val dj2 = explode_disj (all_sums (d, B), q)
 10.1316 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
 10.1317 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
 10.1318 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
 10.1319 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
 10.1320 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
 10.1321 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
 10.1322 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
 10.1323 +                  | QEx x => Or (dj1, dj2))
 10.1324 +             end
 10.1325 +         | QAll x =>
 10.1326 +             let val dj2 = explode_disj (all_sums (d, B), q)
 10.1327 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
 10.1328 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
 10.1329 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
 10.1330 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
 10.1331 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
 10.1332 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
 10.1333 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
 10.1334 +                  | QEx x => Or (dj1, dj2))
 10.1335 +             end
 10.1336 +         | QEx x =>
 10.1337 +             let val dj2 = explode_disj (all_sums (d, B), q)
 10.1338 +             in (case dj2 of Lt (x, xa) => Or (dj1, dj2)
 10.1339 +                  | Gt (x, xa) => Or (dj1, dj2) | Le (x, xa) => Or (dj1, dj2)
 10.1340 +                  | Ge (x, xa) => Or (dj1, dj2) | Eq (x, xa) => Or (dj1, dj2)
 10.1341 +                  | Divides (x, xa) => Or (dj1, dj2) | T => T | F => dj1
 10.1342 +                  | NOT x => Or (dj1, dj2) | And (x, xa) => Or (dj1, dj2)
 10.1343 +                  | Or (x, xa) => Or (dj1, dj2) | Imp (x, xa) => Or (dj1, dj2)
 10.1344 +                  | Equ (x, xa) => Or (dj1, dj2) | QAll x => Or (dj1, dj2)
 10.1345 +                  | QEx x => Or (dj1, dj2))
 10.1346 +             end)
 10.1347 +    end;
 10.1348 +
 10.1349 +fun mirror (And (p, q)) = And (mirror p, mirror q)
 10.1350 +  | mirror (Or (p, q)) = Or (mirror p, mirror q)
 10.1351 +  | mirror (Lt (u, v)) = Lt (u, v)
 10.1352 +  | mirror (Gt (w, x)) = Gt (w, x)
 10.1353 +  | mirror (Le (Cst bp, aa)) = Le (Cst bp, aa)
 10.1354 +  | mirror (Le (Var bq, aa)) = Le (Var bq, aa)
 10.1355 +  | mirror (Le (Neg br, aa)) = Le (Neg br, aa)
 10.1356 +  | mirror (Le (Add (Cst ch, bt), aa)) = Le (Add (Cst ch, bt), aa)
 10.1357 +  | mirror (Le (Add (Var ci, bt), aa)) = Le (Add (Var ci, bt), aa)
 10.1358 +  | mirror (Le (Add (Neg cj, bt), aa)) = Le (Add (Neg cj, bt), aa)
 10.1359 +  | mirror (Le (Add (Add (ck, cl), bt), aa)) = Le (Add (Add (ck, cl), bt), aa)
 10.1360 +  | mirror (Le (Add (Sub (cm, cn), bt), aa)) = Le (Add (Sub (cm, cn), bt), aa)
 10.1361 +  | mirror (Le (Add (Mult (Cst cz, Cst dr), bt), aa)) =
 10.1362 +    Le (Add (Mult (Cst cz, Cst dr), bt), aa)
 10.1363 +  | mirror (Le (Add (Mult (Cst cz, Var ej), bt), aa)) =
 10.1364 +    (if (ej = 0) then Le (Add (Mult (Cst (~ cz), Var 0), bt), aa)
 10.1365 +      else Le (Add (Mult (Cst cz, Var (op_45_def0 ej id_1_def0 + 1)), bt), aa))
 10.1366 +  | mirror (Le (Add (Mult (Cst cz, Neg dt), bt), aa)) =
 10.1367 +    Le (Add (Mult (Cst cz, Neg dt), bt), aa)
 10.1368 +  | mirror (Le (Add (Mult (Cst cz, Add (du, dv)), bt), aa)) =
 10.1369 +    Le (Add (Mult (Cst cz, Add (du, dv)), bt), aa)
 10.1370 +  | mirror (Le (Add (Mult (Cst cz, Sub (dw, dx)), bt), aa)) =
 10.1371 +    Le (Add (Mult (Cst cz, Sub (dw, dx)), bt), aa)
 10.1372 +  | mirror (Le (Add (Mult (Cst cz, Mult (dy, dz)), bt), aa)) =
 10.1373 +    Le (Add (Mult (Cst cz, Mult (dy, dz)), bt), aa)
 10.1374 +  | mirror (Le (Add (Mult (Var da, cp), bt), aa)) =
 10.1375 +    Le (Add (Mult (Var da, cp), bt), aa)
 10.1376 +  | mirror (Le (Add (Mult (Neg db, cp), bt), aa)) =
 10.1377 +    Le (Add (Mult (Neg db, cp), bt), aa)
 10.1378 +  | mirror (Le (Add (Mult (Add (dc, dd), cp), bt), aa)) =
 10.1379 +    Le (Add (Mult (Add (dc, dd), cp), bt), aa)
 10.1380 +  | mirror (Le (Add (Mult (Sub (de, df), cp), bt), aa)) =
 10.1381 +    Le (Add (Mult (Sub (de, df), cp), bt), aa)
 10.1382 +  | mirror (Le (Add (Mult (Mult (dg, dh), cp), bt), aa)) =
 10.1383 +    Le (Add (Mult (Mult (dg, dh), cp), bt), aa)
 10.1384 +  | mirror (Le (Sub (bu, bv), aa)) = Le (Sub (bu, bv), aa)
 10.1385 +  | mirror (Le (Mult (bw, bx), aa)) = Le (Mult (bw, bx), aa)
 10.1386 +  | mirror (Ge (ab, ac)) = Ge (ab, ac)
 10.1387 +  | mirror (Eq (Cst el, ae)) = Eq (Cst el, ae)
 10.1388 +  | mirror (Eq (Var em, ae)) = Eq (Var em, ae)
 10.1389 +  | mirror (Eq (Neg en, ae)) = Eq (Neg en, ae)
 10.1390 +  | mirror (Eq (Add (Cst fd, ep), ae)) = Eq (Add (Cst fd, ep), ae)
 10.1391 +  | mirror (Eq (Add (Var fe, ep), ae)) = Eq (Add (Var fe, ep), ae)
 10.1392 +  | mirror (Eq (Add (Neg ff, ep), ae)) = Eq (Add (Neg ff, ep), ae)
 10.1393 +  | mirror (Eq (Add (Add (fg, fh), ep), ae)) = Eq (Add (Add (fg, fh), ep), ae)
 10.1394 +  | mirror (Eq (Add (Sub (fi, fj), ep), ae)) = Eq (Add (Sub (fi, fj), ep), ae)
 10.1395 +  | mirror (Eq (Add (Mult (Cst fv, Cst gn), ep), ae)) =
 10.1396 +    Eq (Add (Mult (Cst fv, Cst gn), ep), ae)
 10.1397 +  | mirror (Eq (Add (Mult (Cst fv, Var hf), ep), ae)) =
 10.1398 +    (if (hf = 0) then Eq (Add (Mult (Cst (~ fv), Var 0), ep), ae)
 10.1399 +      else Eq (Add (Mult (Cst fv, Var (op_45_def0 hf id_1_def0 + 1)), ep), ae))
 10.1400 +  | mirror (Eq (Add (Mult (Cst fv, Neg gp), ep), ae)) =
 10.1401 +    Eq (Add (Mult (Cst fv, Neg gp), ep), ae)
 10.1402 +  | mirror (Eq (Add (Mult (Cst fv, Add (gq, gr)), ep), ae)) =
 10.1403 +    Eq (Add (Mult (Cst fv, Add (gq, gr)), ep), ae)
 10.1404 +  | mirror (Eq (Add (Mult (Cst fv, Sub (gs, gt)), ep), ae)) =
 10.1405 +    Eq (Add (Mult (Cst fv, Sub (gs, gt)), ep), ae)
 10.1406 +  | mirror (Eq (Add (Mult (Cst fv, Mult (gu, gv)), ep), ae)) =
 10.1407 +    Eq (Add (Mult (Cst fv, Mult (gu, gv)), ep), ae)
 10.1408 +  | mirror (Eq (Add (Mult (Var fw, fl), ep), ae)) =
 10.1409 +    Eq (Add (Mult (Var fw, fl), ep), ae)
 10.1410 +  | mirror (Eq (Add (Mult (Neg fx, fl), ep), ae)) =
 10.1411 +    Eq (Add (Mult (Neg fx, fl), ep), ae)
 10.1412 +  | mirror (Eq (Add (Mult (Add (fy, fz), fl), ep), ae)) =
 10.1413 +    Eq (Add (Mult (Add (fy, fz), fl), ep), ae)
 10.1414 +  | mirror (Eq (Add (Mult (Sub (ga, gb), fl), ep), ae)) =
 10.1415 +    Eq (Add (Mult (Sub (ga, gb), fl), ep), ae)
 10.1416 +  | mirror (Eq (Add (Mult (Mult (gc, gd), fl), ep), ae)) =
 10.1417 +    Eq (Add (Mult (Mult (gc, gd), fl), ep), ae)
 10.1418 +  | mirror (Eq (Sub (eq, er), ae)) = Eq (Sub (eq, er), ae)
 10.1419 +  | mirror (Eq (Mult (es, et), ae)) = Eq (Mult (es, et), ae)
 10.1420 +  | mirror (Divides (Cst hh, Cst hz)) = Divides (Cst hh, Cst hz)
 10.1421 +  | mirror (Divides (Cst hh, Var ia)) = Divides (Cst hh, Var ia)
 10.1422 +  | mirror (Divides (Cst hh, Neg ib)) = Divides (Cst hh, Neg ib)
 10.1423 +  | mirror (Divides (Cst hh, Add (Cst ir, id))) =
 10.1424 +    Divides (Cst hh, Add (Cst ir, id))
 10.1425 +  | mirror (Divides (Cst hh, Add (Var is, id))) =
 10.1426 +    Divides (Cst hh, Add (Var is, id))
 10.1427 +  | mirror (Divides (Cst hh, Add (Neg it, id))) =
 10.1428 +    Divides (Cst hh, Add (Neg it, id))
 10.1429 +  | mirror (Divides (Cst hh, Add (Add (iu, iv), id))) =
 10.1430 +    Divides (Cst hh, Add (Add (iu, iv), id))
 10.1431 +  | mirror (Divides (Cst hh, Add (Sub (iw, ix), id))) =
 10.1432 +    Divides (Cst hh, Add (Sub (iw, ix), id))
 10.1433 +  | mirror (Divides (Cst hh, Add (Mult (Cst jj, Cst kb), id))) =
 10.1434 +    Divides (Cst hh, Add (Mult (Cst jj, Cst kb), id))
 10.1435 +  | mirror (Divides (Cst hh, Add (Mult (Cst jj, Var kt), id))) =
 10.1436 +    (if (kt = 0) then Divides (Cst hh, Add (Mult (Cst (~ jj), Var 0), id))
 10.1437 +      else Divides
 10.1438 +             (Cst hh,
 10.1439 +               Add (Mult (Cst jj, Var (op_45_def0 kt id_1_def0 + 1)), id)))
 10.1440 +  | mirror (Divides (Cst hh, Add (Mult (Cst jj, Neg kd), id))) =
 10.1441 +    Divides (Cst hh, Add (Mult (Cst jj, Neg kd), id))
 10.1442 +  | mirror (Divides (Cst hh, Add (Mult (Cst jj, Add (ke, kf)), id))) =
 10.1443 +    Divides (Cst hh, Add (Mult (Cst jj, Add (ke, kf)), id))
 10.1444 +  | mirror (Divides (Cst hh, Add (Mult (Cst jj, Sub (kg, kh)), id))) =
 10.1445 +    Divides (Cst hh, Add (Mult (Cst jj, Sub (kg, kh)), id))
 10.1446 +  | mirror (Divides (Cst hh, Add (Mult (Cst jj, Mult (ki, kj)), id))) =
 10.1447 +    Divides (Cst hh, Add (Mult (Cst jj, Mult (ki, kj)), id))
 10.1448 +  | mirror (Divides (Cst hh, Add (Mult (Var jk, iz), id))) =
 10.1449 +    Divides (Cst hh, Add (Mult (Var jk, iz), id))
 10.1450 +  | mirror (Divides (Cst hh, Add (Mult (Neg jl, iz), id))) =
 10.1451 +    Divides (Cst hh, Add (Mult (Neg jl, iz), id))
 10.1452 +  | mirror (Divides (Cst hh, Add (Mult (Add (jm, jn), iz), id))) =
 10.1453 +    Divides (Cst hh, Add (Mult (Add (jm, jn), iz), id))
 10.1454 +  | mirror (Divides (Cst hh, Add (Mult (Sub (jo, jp), iz), id))) =
 10.1455 +    Divides (Cst hh, Add (Mult (Sub (jo, jp), iz), id))
 10.1456 +  | mirror (Divides (Cst hh, Add (Mult (Mult (jq, jr), iz), id))) =
 10.1457 +    Divides (Cst hh, Add (Mult (Mult (jq, jr), iz), id))
 10.1458 +  | mirror (Divides (Cst hh, Sub (ie, if'))) = Divides (Cst hh, Sub (ie, if'))
 10.1459 +  | mirror (Divides (Cst hh, Mult (ig, ih))) = Divides (Cst hh, Mult (ig, ih))
 10.1460 +  | mirror (Divides (Var hi, ag)) = Divides (Var hi, ag)
 10.1461 +  | mirror (Divides (Neg hj, ag)) = Divides (Neg hj, ag)
 10.1462 +  | mirror (Divides (Add (hk, hl), ag)) = Divides (Add (hk, hl), ag)
 10.1463 +  | mirror (Divides (Sub (hm, hn), ag)) = Divides (Sub (hm, hn), ag)
 10.1464 +  | mirror (Divides (Mult (ho, hp), ag)) = Divides (Mult (ho, hp), ag)
 10.1465 +  | mirror T = T
 10.1466 +  | mirror F = F
 10.1467 +  | mirror (NOT (Lt (kv, kw))) = NOT (Lt (kv, kw))
 10.1468 +  | mirror (NOT (Gt (kx, ky))) = NOT (Gt (kx, ky))
 10.1469 +  | mirror (NOT (Le (kz, la))) = NOT (Le (kz, la))
 10.1470 +  | mirror (NOT (Ge (lb, lc))) = NOT (Ge (lb, lc))
 10.1471 +  | mirror (NOT (Eq (Cst mp, le))) = NOT (Eq (Cst mp, le))
 10.1472 +  | mirror (NOT (Eq (Var mq, le))) = NOT (Eq (Var mq, le))
 10.1473 +  | mirror (NOT (Eq (Neg mr, le))) = NOT (Eq (Neg mr, le))
 10.1474 +  | mirror (NOT (Eq (Add (Cst nh, mt), le))) = NOT (Eq (Add (Cst nh, mt), le))
 10.1475 +  | mirror (NOT (Eq (Add (Var ni, mt), le))) = NOT (Eq (Add (Var ni, mt), le))
 10.1476 +  | mirror (NOT (Eq (Add (Neg nj, mt), le))) = NOT (Eq (Add (Neg nj, mt), le))
 10.1477 +  | mirror (NOT (Eq (Add (Add (nk, nl), mt), le))) =
 10.1478 +    NOT (Eq (Add (Add (nk, nl), mt), le))
 10.1479 +  | mirror (NOT (Eq (Add (Sub (nm, nn), mt), le))) =
 10.1480 +    NOT (Eq (Add (Sub (nm, nn), mt), le))
 10.1481 +  | mirror (NOT (Eq (Add (Mult (Cst nz, Cst or), mt), le))) =
 10.1482 +    NOT (Eq (Add (Mult (Cst nz, Cst or), mt), le))
 10.1483 +  | mirror (NOT (Eq (Add (Mult (Cst nz, Var pj), mt), le))) =
 10.1484 +    (if (pj = 0) then NOT (Eq (Add (Mult (Cst (~ nz), Var 0), mt), le))
 10.1485 +      else NOT (Eq (Add (Mult (Cst nz, Var (op_45_def0 pj id_1_def0 + 1)), mt),
 10.1486 +                     le)))
 10.1487 +  | mirror (NOT (Eq (Add (Mult (Cst nz, Neg ot), mt), le))) =
 10.1488 +    NOT (Eq (Add (Mult (Cst nz, Neg ot), mt), le))
 10.1489 +  | mirror (NOT (Eq (Add (Mult (Cst nz, Add (ou, ov)), mt), le))) =
 10.1490 +    NOT (Eq (Add (Mult (Cst nz, Add (ou, ov)), mt), le))
 10.1491 +  | mirror (NOT (Eq (Add (Mult (Cst nz, Sub (ow, ox)), mt), le))) =
 10.1492 +    NOT (Eq (Add (Mult (Cst nz, Sub (ow, ox)), mt), le))
 10.1493 +  | mirror (NOT (Eq (Add (Mult (Cst nz, Mult (oy, oz)), mt), le))) =
 10.1494 +    NOT (Eq (Add (Mult (Cst nz, Mult (oy, oz)), mt), le))
 10.1495 +  | mirror (NOT (Eq (Add (Mult (Var oa, np), mt), le))) =
 10.1496 +    NOT (Eq (Add (Mult (Var oa, np), mt), le))
 10.1497 +  | mirror (NOT (Eq (Add (Mult (Neg ob, np), mt), le))) =
 10.1498 +    NOT (Eq (Add (Mult (Neg ob, np), mt), le))
 10.1499 +  | mirror (NOT (Eq (Add (Mult (Add (oc, od), np), mt), le))) =
 10.1500 +    NOT (Eq (Add (Mult (Add (oc, od), np), mt), le))
 10.1501 +  | mirror (NOT (Eq (Add (Mult (Sub (oe, of'), np), mt), le))) =
 10.1502 +    NOT (Eq (Add (Mult (Sub (oe, of'), np), mt), le))
 10.1503 +  | mirror (NOT (Eq (Add (Mult (Mult (og, oh), np), mt), le))) =
 10.1504 +    NOT (Eq (Add (Mult (Mult (og, oh), np), mt), le))
 10.1505 +  | mirror (NOT (Eq (Sub (mu, mv), le))) = NOT (Eq (Sub (mu, mv), le))
 10.1506 +  | mirror (NOT (Eq (Mult (mw, mx), le))) = NOT (Eq (Mult (mw, mx), le))
 10.1507 +  | mirror (NOT (Divides (Cst pl, Cst qd))) = NOT (Divides (Cst pl, Cst qd))
 10.1508 +  | mirror (NOT (Divides (Cst pl, Var qe))) = NOT (Divides (Cst pl, Var qe))
 10.1509 +  | mirror (NOT (Divides (Cst pl, Neg qf))) = NOT (Divides (Cst pl, Neg qf))
 10.1510 +  | mirror (NOT (Divides (Cst pl, Add (Cst qv, qh)))) =
 10.1511 +    NOT (Divides (Cst pl, Add (Cst qv, qh)))
 10.1512 +  | mirror (NOT (Divides (Cst pl, Add (Var qw, qh)))) =
 10.1513 +    NOT (Divides (Cst pl, Add (Var qw, qh)))
 10.1514 +  | mirror (NOT (Divides (Cst pl, Add (Neg qx, qh)))) =
 10.1515 +    NOT (Divides (Cst pl, Add (Neg qx, qh)))
 10.1516 +  | mirror (NOT (Divides (Cst pl, Add (Add (qy, qz), qh)))) =
 10.1517 +    NOT (Divides (Cst pl, Add (Add (qy, qz), qh)))
 10.1518 +  | mirror (NOT (Divides (Cst pl, Add (Sub (ra, rb), qh)))) =
 10.1519 +    NOT (Divides (Cst pl, Add (Sub (ra, rb), qh)))
 10.1520 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Cst rn, Cst sf), qh)))) =
 10.1521 +    NOT (Divides (Cst pl, Add (Mult (Cst rn, Cst sf), qh)))
 10.1522 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Cst rn, Var sx), qh)))) =
 10.1523 +    (if (sx = 0)
 10.1524 +      then NOT (Divides (Cst pl, Add (Mult (Cst (~ rn), Var 0), qh)))
 10.1525 +      else NOT (Divides
 10.1526 +                  (Cst pl,
 10.1527 +                    Add (Mult (Cst rn, Var (op_45_def0 sx id_1_def0 + 1)),
 10.1528 +                          qh))))
 10.1529 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Cst rn, Neg sh), qh)))) =
 10.1530 +    NOT (Divides (Cst pl, Add (Mult (Cst rn, Neg sh), qh)))
 10.1531 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Cst rn, Add (si, sj)), qh)))) =
 10.1532 +    NOT (Divides (Cst pl, Add (Mult (Cst rn, Add (si, sj)), qh)))
 10.1533 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Cst rn, Sub (sk, sl)), qh)))) =
 10.1534 +    NOT (Divides (Cst pl, Add (Mult (Cst rn, Sub (sk, sl)), qh)))
 10.1535 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Cst rn, Mult (sm, sn)), qh)))) =
 10.1536 +    NOT (Divides (Cst pl, Add (Mult (Cst rn, Mult (sm, sn)), qh)))
 10.1537 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Var ro, rd), qh)))) =
 10.1538 +    NOT (Divides (Cst pl, Add (Mult (Var ro, rd), qh)))
 10.1539 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Neg rp, rd), qh)))) =
 10.1540 +    NOT (Divides (Cst pl, Add (Mult (Neg rp, rd), qh)))
 10.1541 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Add (rq, rr), rd), qh)))) =
 10.1542 +    NOT (Divides (Cst pl, Add (Mult (Add (rq, rr), rd), qh)))
 10.1543 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Sub (rs, rt), rd), qh)))) =
 10.1544 +    NOT (Divides (Cst pl, Add (Mult (Sub (rs, rt), rd), qh)))
 10.1545 +  | mirror (NOT (Divides (Cst pl, Add (Mult (Mult (ru, rv), rd), qh)))) =
 10.1546 +    NOT (Divides (Cst pl, Add (Mult (Mult (ru, rv), rd), qh)))
 10.1547 +  | mirror (NOT (Divides (Cst pl, Sub (qi, qj)))) =
 10.1548 +    NOT (Divides (Cst pl, Sub (qi, qj)))
 10.1549 +  | mirror (NOT (Divides (Cst pl, Mult (qk, ql)))) =
 10.1550 +    NOT (Divides (Cst pl, Mult (qk, ql)))
 10.1551 +  | mirror (NOT (Divides (Var pm, lg))) = NOT (Divides (Var pm, lg))
 10.1552 +  | mirror (NOT (Divides (Neg pn, lg))) = NOT (Divides (Neg pn, lg))
 10.1553 +  | mirror (NOT (Divides (Add (po, pp), lg))) = NOT (Divides (Add (po, pp), lg))
 10.1554 +  | mirror (NOT (Divides (Sub (pq, pr), lg))) = NOT (Divides (Sub (pq, pr), lg))
 10.1555 +  | mirror (NOT (Divides (Mult (ps, pt), lg))) =
 10.1556 +    NOT (Divides (Mult (ps, pt), lg))
 10.1557 +  | mirror (NOT T) = NOT T
 10.1558 +  | mirror (NOT F) = NOT F
 10.1559 +  | mirror (NOT (NOT lh)) = NOT (NOT lh)
 10.1560 +  | mirror (NOT (And (li, lj))) = NOT (And (li, lj))
 10.1561 +  | mirror (NOT (Or (lk, ll))) = NOT (Or (lk, ll))
 10.1562 +  | mirror (NOT (Imp (lm, ln))) = NOT (Imp (lm, ln))
 10.1563 +  | mirror (NOT (Equ (lo, lp))) = NOT (Equ (lo, lp))
 10.1564 +  | mirror (NOT (QAll lq)) = NOT (QAll lq)
 10.1565 +  | mirror (NOT (QEx lr)) = NOT (QEx lr)
 10.1566 +  | mirror (Imp (am, an)) = Imp (am, an)
 10.1567 +  | mirror (Equ (ao, ap)) = Equ (ao, ap)
 10.1568 +  | mirror (QAll aq) = QAll aq
 10.1569 +  | mirror (QEx ar) = QEx ar;
 10.1570 +
 10.1571 +fun op_43_def0 m n = nat ((m) + (n));
 10.1572 +
 10.1573 +fun size_def1 [] = 0
 10.1574 +  | size_def1 (a :: list) = op_43_def0 (size_def1 list) (0 + 1);
 10.1575 +
 10.1576 +fun aset (And (p, q)) = op_64 (aset p) (aset q)
 10.1577 +  | aset (Or (p, q)) = op_64 (aset p) (aset q)
 10.1578 +  | aset (Lt (u, v)) = []
 10.1579 +  | aset (Gt (w, x)) = []
 10.1580 +  | aset (Le (Cst bo, z)) = []
 10.1581 +  | aset (Le (Var bp, z)) = []
 10.1582 +  | aset (Le (Neg bq, z)) = []
 10.1583 +  | aset (Le (Add (Cst cg, bs), z)) = []
 10.1584 +  | aset (Le (Add (Var ch, bs), z)) = []
 10.1585 +  | aset (Le (Add (Neg ci, bs), z)) = []
 10.1586 +  | aset (Le (Add (Add (cj, ck), bs), z)) = []
 10.1587 +  | aset (Le (Add (Sub (cl, cm), bs), z)) = []
 10.1588 +  | aset (Le (Add (Mult (Cst cy, Cst dq), bs), z)) = []
 10.1589 +  | aset (Le (Add (Mult (Cst cy, Var ei), bs), z)) =
 10.1590 +    (if (ei = 0)
 10.1591 +      then (if (cy < 0) then [lin_add (bs, Cst 1)]
 10.1592 +             else [lin_neg bs, lin_add (lin_neg bs, Cst 1)])
 10.1593 +      else [])
 10.1594 +  | aset (Le (Add (Mult (Cst cy, Neg ds), bs), z)) = []
 10.1595 +  | aset (Le (Add (Mult (Cst cy, Add (dt, du)), bs), z)) = []
 10.1596 +  | aset (Le (Add (Mult (Cst cy, Sub (dv, dw)), bs), z)) = []
 10.1597 +  | aset (Le (Add (Mult (Cst cy, Mult (dx, dy)), bs), z)) = []
 10.1598 +  | aset (Le (Add (Mult (Var cz, co), bs), z)) = []
 10.1599 +  | aset (Le (Add (Mult (Neg da, co), bs), z)) = []
 10.1600 +  | aset (Le (Add (Mult (Add (db, dc), co), bs), z)) = []
 10.1601 +  | aset (Le (Add (Mult (Sub (dd, de), co), bs), z)) = []
 10.1602 +  | aset (Le (Add (Mult (Mult (df, dg), co), bs), z)) = []
 10.1603 +  | aset (Le (Sub (bt, bu), z)) = []
 10.1604 +  | aset (Le (Mult (bv, bw), z)) = []
 10.1605 +  | aset (Ge (aa, ab)) = []
 10.1606 +  | aset (Eq (Cst ek, ad)) = []
 10.1607 +  | aset (Eq (Var el, ad)) = []
 10.1608 +  | aset (Eq (Neg em, ad)) = []
 10.1609 +  | aset (Eq (Add (Cst fc, eo), ad)) = []
 10.1610 +  | aset (Eq (Add (Var fd, eo), ad)) = []
 10.1611 +  | aset (Eq (Add (Neg fe, eo), ad)) = []
 10.1612 +  | aset (Eq (Add (Add (ff, fg), eo), ad)) = []
 10.1613 +  | aset (Eq (Add (Sub (fh, fi), eo), ad)) = []
 10.1614 +  | aset (Eq (Add (Mult (Cst fu, Cst gm), eo), ad)) = []
 10.1615 +  | aset (Eq (Add (Mult (Cst fu, Var he), eo), ad)) =
 10.1616 +    (if (he = 0)
 10.1617 +      then (if (fu < 0) then [lin_add (eo, Cst 1)]
 10.1618 +             else [lin_add (lin_neg eo, Cst 1)])
 10.1619 +      else [])
 10.1620 +  | aset (Eq (Add (Mult (Cst fu, Neg go), eo), ad)) = []
 10.1621 +  | aset (Eq (Add (Mult (Cst fu, Add (gp, gq)), eo), ad)) = []
 10.1622 +  | aset (Eq (Add (Mult (Cst fu, Sub (gr, gs)), eo), ad)) = []
 10.1623 +  | aset (Eq (Add (Mult (Cst fu, Mult (gt, gu)), eo), ad)) = []
 10.1624 +  | aset (Eq (Add (Mult (Var fv, fk), eo), ad)) = []
 10.1625 +  | aset (Eq (Add (Mult (Neg fw, fk), eo), ad)) = []
 10.1626 +  | aset (Eq (Add (Mult (Add (fx, fy), fk), eo), ad)) = []
 10.1627 +  | aset (Eq (Add (Mult (Sub (fz, ga), fk), eo), ad)) = []
 10.1628 +  | aset (Eq (Add (Mult (Mult (gb, gc), fk), eo), ad)) = []
 10.1629 +  | aset (Eq (Sub (ep, eq), ad)) = []
 10.1630 +  | aset (Eq (Mult (er, es), ad)) = []
 10.1631 +  | aset (Divides (ae, af)) = []
 10.1632 +  | aset T = []
 10.1633 +  | aset F = []
 10.1634 +  | aset (NOT (Lt (hg, hh))) = []
 10.1635 +  | aset (NOT (Gt (hi, hj))) = []
 10.1636 +  | aset (NOT (Le (hk, hl))) = []
 10.1637 +  | aset (NOT (Ge (hm, hn))) = []
 10.1638 +  | aset (NOT (Eq (Cst ja, hp))) = []
 10.1639 +  | aset (NOT (Eq (Var jb, hp))) = []
 10.1640 +  | aset (NOT (Eq (Neg jc, hp))) = []
 10.1641 +  | aset (NOT (Eq (Add (Cst js, je), hp))) = []
 10.1642 +  | aset (NOT (Eq (Add (Var jt, je), hp))) = []
 10.1643 +  | aset (NOT (Eq (Add (Neg ju, je), hp))) = []
 10.1644 +  | aset (NOT (Eq (Add (Add (jv, jw), je), hp))) = []
 10.1645 +  | aset (NOT (Eq (Add (Sub (jx, jy), je), hp))) = []
 10.1646 +  | aset (NOT (Eq (Add (Mult (Cst kk, Cst lc), je), hp))) = []
 10.1647 +  | aset (NOT (Eq (Add (Mult (Cst kk, Var lu), je), hp))) =
 10.1648 +    (if (lu = 0) then (if (kk < 0) then [je] else [lin_neg je]) else [])
 10.1649 +  | aset (NOT (Eq (Add (Mult (Cst kk, Neg le), je), hp))) = []
 10.1650 +  | aset (NOT (Eq (Add (Mult (Cst kk, Add (lf, lg)), je), hp))) = []
 10.1651 +  | aset (NOT (Eq (Add (Mult (Cst kk, Sub (lh, li)), je), hp))) = []
 10.1652 +  | aset (NOT (Eq (Add (Mult (Cst kk, Mult (lj, lk)), je), hp))) = []
 10.1653 +  | aset (NOT (Eq (Add (Mult (Var kl, ka), je), hp))) = []
 10.1654 +  | aset (NOT (Eq (Add (Mult (Neg km, ka), je), hp))) = []
 10.1655 +  | aset (NOT (Eq (Add (Mult (Add (kn, ko), ka), je), hp))) = []
 10.1656 +  | aset (NOT (Eq (Add (Mult (Sub (kp, kq), ka), je), hp))) = []
 10.1657 +  | aset (NOT (Eq (Add (Mult (Mult (kr, ks), ka), je), hp))) = []
 10.1658 +  | aset (NOT (Eq (Sub (jf, jg), hp))) = []
 10.1659 +  | aset (NOT (Eq (Mult (jh, ji), hp))) = []
 10.1660 +  | aset (NOT (Divides (hq, hr))) = []
 10.1661 +  | aset (NOT T) = []
 10.1662 +  | aset (NOT F) = []
 10.1663 +  | aset (NOT (NOT hs)) = []
 10.1664 +  | aset (NOT (And (ht, hu))) = []
 10.1665 +  | aset (NOT (Or (hv, hw))) = []
 10.1666 +  | aset (NOT (Imp (hx, hy))) = []
 10.1667 +  | aset (NOT (Equ (hz, ia))) = []
 10.1668 +  | aset (NOT (QAll ib)) = []
 10.1669 +  | aset (NOT (QEx ic)) = []
 10.1670 +  | aset (Imp (al, am)) = []
 10.1671 +  | aset (Equ (an, ao)) = []
 10.1672 +  | aset (QAll ap) = []
 10.1673 +  | aset (QEx aq) = [];
 10.1674 +
 10.1675 +fun op_mem x [] = false
 10.1676 +  | op_mem x (y :: ys) = (if (y = x) then true else op_mem x ys);
 10.1677 +
 10.1678 +fun list_insert x xs = (if op_mem x xs then xs else (x :: xs));
 10.1679 +
 10.1680 +fun list_set [] = []
 10.1681 +  | list_set (x :: xs) = list_insert x (list_set xs);
 10.1682 +
 10.1683 +fun bset (And (p, q)) = op_64 (bset p) (bset q)
 10.1684 +  | bset (Or (p, q)) = op_64 (bset p) (bset q)
 10.1685 +  | bset (Lt (u, v)) = []
 10.1686 +  | bset (Gt (w, x)) = []
 10.1687 +  | bset (Le (Cst bo, z)) = []
 10.1688 +  | bset (Le (Var bp, z)) = []
 10.1689 +  | bset (Le (Neg bq, z)) = []
 10.1690 +  | bset (Le (Add (Cst cg, bs), z)) = []
 10.1691 +  | bset (Le (Add (Var ch, bs), z)) = []
 10.1692 +  | bset (Le (Add (Neg ci, bs), z)) = []
 10.1693 +  | bset (Le (Add (Add (cj, ck), bs), z)) = []
 10.1694 +  | bset (Le (Add (Sub (cl, cm), bs), z)) = []
 10.1695 +  | bset (Le (Add (Mult (Cst cy, Cst dq), bs), z)) = []
 10.1696 +  | bset (Le (Add (Mult (Cst cy, Var ei), bs), z)) =
 10.1697 +    (if (ei = 0)
 10.1698 +      then (if (cy < 0) then [lin_add (bs, Cst ~1), bs]
 10.1699 +             else [lin_add (lin_neg bs, Cst ~1)])
 10.1700 +      else [])
 10.1701 +  | bset (Le (Add (Mult (Cst cy, Neg ds), bs), z)) = []
 10.1702 +  | bset (Le (Add (Mult (Cst cy, Add (dt, du)), bs), z)) = []
 10.1703 +  | bset (Le (Add (Mult (Cst cy, Sub (dv, dw)), bs), z)) = []
 10.1704 +  | bset (Le (Add (Mult (Cst cy, Mult (dx, dy)), bs), z)) = []
 10.1705 +  | bset (Le (Add (Mult (Var cz, co), bs), z)) = []
 10.1706 +  | bset (Le (Add (Mult (Neg da, co), bs), z)) = []
 10.1707 +  | bset (Le (Add (Mult (Add (db, dc), co), bs), z)) = []
 10.1708 +  | bset (Le (Add (Mult (Sub (dd, de), co), bs), z)) = []
 10.1709 +  | bset (Le (Add (Mult (Mult (df, dg), co), bs), z)) = []
 10.1710 +  | bset (Le (Sub (bt, bu), z)) = []
 10.1711 +  | bset (Le (Mult (bv, bw), z)) = []
 10.1712 +  | bset (Ge (aa, ab)) = []
 10.1713 +  | bset (Eq (Cst ek, ad)) = []
 10.1714 +  | bset (Eq (Var el, ad)) = []
 10.1715 +  | bset (Eq (Neg em, ad)) = []
 10.1716 +  | bset (Eq (Add (Cst fc, eo), ad)) = []
 10.1717 +  | bset (Eq (Add (Var fd, eo), ad)) = []
 10.1718 +  | bset (Eq (Add (Neg fe, eo), ad)) = []
 10.1719 +  | bset (Eq (Add (Add (ff, fg), eo), ad)) = []
 10.1720 +  | bset (Eq (Add (Sub (fh, fi), eo), ad)) = []
 10.1721 +  | bset (Eq (Add (Mult (Cst fu, Cst gm), eo), ad)) = []
 10.1722 +  | bset (Eq (Add (Mult (Cst fu, Var he), eo), ad)) =
 10.1723 +    (if (he = 0)
 10.1724 +      then (if (fu < 0) then [lin_add (eo, Cst ~1)]
 10.1725 +             else [lin_add (lin_neg eo, Cst ~1)])
 10.1726 +      else [])
 10.1727 +  | bset (Eq (Add (Mult (Cst fu, Neg go), eo), ad)) = []
 10.1728 +  | bset (Eq (Add (Mult (Cst fu, Add (gp, gq)), eo), ad)) = []
 10.1729 +  | bset (Eq (Add (Mult (Cst fu, Sub (gr, gs)), eo), ad)) = []
 10.1730 +  | bset (Eq (Add (Mult (Cst fu, Mult (gt, gu)), eo), ad)) = []
 10.1731 +  | bset (Eq (Add (Mult (Var fv, fk), eo), ad)) = []
 10.1732 +  | bset (Eq (Add (Mult (Neg fw, fk), eo), ad)) = []
 10.1733 +  | bset (Eq (Add (Mult (Add (fx, fy), fk), eo), ad)) = []
 10.1734 +  | bset (Eq (Add (Mult (Sub (fz, ga), fk), eo), ad)) = []
 10.1735 +  | bset (Eq (Add (Mult (Mult (gb, gc), fk), eo), ad)) = []
 10.1736 +  | bset (Eq (Sub (ep, eq), ad)) = []
 10.1737 +  | bset (Eq (Mult (er, es), ad)) = []
 10.1738 +  | bset (Divides (ae, af)) = []
 10.1739 +  | bset T = []
 10.1740 +  | bset F = []
 10.1741 +  | bset (NOT (Lt (hg, hh))) = []
 10.1742 +  | bset (NOT (Gt (hi, hj))) = []
 10.1743 +  | bset (NOT (Le (hk, hl))) = []
 10.1744 +  | bset (NOT (Ge (hm, hn))) = []
 10.1745 +  | bset (NOT (Eq (Cst ja, hp))) = []
 10.1746 +  | bset (NOT (Eq (Var jb, hp))) = []
 10.1747 +  | bset (NOT (Eq (Neg jc, hp))) = []
 10.1748 +  | bset (NOT (Eq (Add (Cst js, je), hp))) = []
 10.1749 +  | bset (NOT (Eq (Add (Var jt, je), hp))) = []
 10.1750 +  | bset (NOT (Eq (Add (Neg ju, je), hp))) = []
 10.1751 +  | bset (NOT (Eq (Add (Add (jv, jw), je), hp))) = []
 10.1752 +  | bset (NOT (Eq (Add (Sub (jx, jy), je), hp))) = []
 10.1753 +  | bset (NOT (Eq (Add (Mult (Cst kk, Cst lc), je), hp))) = []
 10.1754 +  | bset (NOT (Eq (Add (Mult (Cst kk, Var lu), je), hp))) =
 10.1755 +    (if (lu = 0) then (if (kk < 0) then [je] else [lin_neg je]) else [])
 10.1756 +  | bset (NOT (Eq (Add (Mult (Cst kk, Neg le), je), hp))) = []
 10.1757 +  | bset (NOT (Eq (Add (Mult (Cst kk, Add (lf, lg)), je), hp))) = []
 10.1758 +  | bset (NOT (Eq (Add (Mult (Cst kk, Sub (lh, li)), je), hp))) = []
 10.1759 +  | bset (NOT (Eq (Add (Mult (Cst kk, Mult (lj, lk)), je), hp))) = []
 10.1760 +  | bset (NOT (Eq (Add (Mult (Var kl, ka), je), hp))) = []
 10.1761 +  | bset (NOT (Eq (Add (Mult (Neg km, ka), je), hp))) = []
 10.1762 +  | bset (NOT (Eq (Add (Mult (Add (kn, ko), ka), je), hp))) = []
 10.1763 +  | bset (NOT (Eq (Add (Mult (Sub (kp, kq), ka), je), hp))) = []
 10.1764 +  | bset (NOT (Eq (Add (Mult (Mult (kr, ks), ka), je), hp))) = []
 10.1765 +  | bset (NOT (Eq (Sub (jf, jg), hp))) = []
 10.1766 +  | bset (NOT (Eq (Mult (jh, ji), hp))) = []
 10.1767 +  | bset (NOT (Divides (hq, hr))) = []
 10.1768 +  | bset (NOT T) = []
 10.1769 +  | bset (NOT F) = []
 10.1770 +  | bset (NOT (NOT hs)) = []
 10.1771 +  | bset (NOT (And (ht, hu))) = []
 10.1772 +  | bset (NOT (Or (hv, hw))) = []
 10.1773 +  | bset (NOT (Imp (hx, hy))) = []
 10.1774 +  | bset (NOT (Equ (hz, ia))) = []
 10.1775 +  | bset (NOT (QAll ib)) = []
 10.1776 +  | bset (NOT (QEx ic)) = []
 10.1777 +  | bset (Imp (al, am)) = []
 10.1778 +  | bset (Equ (an, ao)) = []
 10.1779 +  | bset (QAll ap) = []
 10.1780 +  | bset (QEx aq) = [];
 10.1781 +
 10.1782 +fun adjustcoeff (l, Le (Add (Mult (Cst c, Var 0), r), Cst i)) =
 10.1783 +    (if (c <= 0)
 10.1784 +      then Le (Add (Mult (Cst ~1, Var 0), lin_mul (~ (op_div_def1 l c), r)),
 10.1785 +                Cst 0)
 10.1786 +      else Le (Add (Mult (Cst 1, Var 0), lin_mul (op_div_def1 l c, r)), Cst 0))
 10.1787 +  | adjustcoeff (l, Eq (Add (Mult (Cst c, Var 0), r), Cst i)) =
 10.1788 +    Eq (Add (Mult (Cst 1, Var 0), lin_mul (op_div_def1 l c, r)), Cst 0)
 10.1789 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst c, Var 0), r), Cst i))) =
 10.1790 +    NOT (Eq (Add (Mult (Cst 1, Var 0), lin_mul (op_div_def1 l c, r)), Cst 0))
 10.1791 +  | adjustcoeff (l, And (p, q)) = And (adjustcoeff (l, p), adjustcoeff (l, q))
 10.1792 +  | adjustcoeff (l, Or (p, q)) = Or (adjustcoeff (l, p), adjustcoeff (l, q))
 10.1793 +  | adjustcoeff (l, Lt (w, x)) = Lt (w, x)
 10.1794 +  | adjustcoeff (l, Gt (y, z)) = Gt (y, z)
 10.1795 +  | adjustcoeff (l, Le (Cst bq, ab)) = Le (Cst bq, ab)
 10.1796 +  | adjustcoeff (l, Le (Var br, ab)) = Le (Var br, ab)
 10.1797 +  | adjustcoeff (l, Le (Neg bs, ab)) = Le (Neg bs, ab)
 10.1798 +  | adjustcoeff (l, Le (Add (Cst ci, bu), ab)) = Le (Add (Cst ci, bu), ab)
 10.1799 +  | adjustcoeff (l, Le (Add (Var cj, bu), ab)) = Le (Add (Var cj, bu), ab)
 10.1800 +  | adjustcoeff (l, Le (Add (Neg ck, bu), ab)) = Le (Add (Neg ck, bu), ab)
 10.1801 +  | adjustcoeff (l, Le (Add (Add (cl, cm), bu), ab)) =
 10.1802 +    Le (Add (Add (cl, cm), bu), ab)
 10.1803 +  | adjustcoeff (l, Le (Add (Sub (cn, co), bu), ab)) =
 10.1804 +    Le (Add (Sub (cn, co), bu), ab)
 10.1805 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Cst ds), bu), ab)) =
 10.1806 +    Le (Add (Mult (Cst da, Cst ds), bu), ab)
 10.1807 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Var 0), bu), Var en)) =
 10.1808 +    Le (Add (Mult (Cst da, Var 0), bu), Var en)
 10.1809 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Var 0), bu), Neg eo)) =
 10.1810 +    Le (Add (Mult (Cst da, Var 0), bu), Neg eo)
 10.1811 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Var 0), bu), Add (ep, eq))) =
 10.1812 +    Le (Add (Mult (Cst da, Var 0), bu), Add (ep, eq))
 10.1813 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Var 0), bu), Sub (er, es))) =
 10.1814 +    Le (Add (Mult (Cst da, Var 0), bu), Sub (er, es))
 10.1815 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Var 0), bu), Mult (et, eu))) =
 10.1816 +    Le (Add (Mult (Cst da, Var 0), bu), Mult (et, eu))
 10.1817 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Var ek), bu), ab)) =
 10.1818 +    Le (Add (Mult (Cst da, Var ek), bu), ab)
 10.1819 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Neg du), bu), ab)) =
 10.1820 +    Le (Add (Mult (Cst da, Neg du), bu), ab)
 10.1821 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Add (dv, dw)), bu), ab)) =
 10.1822 +    Le (Add (Mult (Cst da, Add (dv, dw)), bu), ab)
 10.1823 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Sub (dx, dy)), bu), ab)) =
 10.1824 +    Le (Add (Mult (Cst da, Sub (dx, dy)), bu), ab)
 10.1825 +  | adjustcoeff (l, Le (Add (Mult (Cst da, Mult (dz, ea)), bu), ab)) =
 10.1826 +    Le (Add (Mult (Cst da, Mult (dz, ea)), bu), ab)
 10.1827 +  | adjustcoeff (l, Le (Add (Mult (Var db, cq), bu), ab)) =
 10.1828 +    Le (Add (Mult (Var db, cq), bu), ab)
 10.1829 +  | adjustcoeff (l, Le (Add (Mult (Neg dc, cq), bu), ab)) =
 10.1830 +    Le (Add (Mult (Neg dc, cq), bu), ab)
 10.1831 +  | adjustcoeff (l, Le (Add (Mult (Add (dd, de), cq), bu), ab)) =
 10.1832 +    Le (Add (Mult (Add (dd, de), cq), bu), ab)
 10.1833 +  | adjustcoeff (l, Le (Add (Mult (Sub (df, dg), cq), bu), ab)) =
 10.1834 +    Le (Add (Mult (Sub (df, dg), cq), bu), ab)
 10.1835 +  | adjustcoeff (l, Le (Add (Mult (Mult (dh, di), cq), bu), ab)) =
 10.1836 +    Le (Add (Mult (Mult (dh, di), cq), bu), ab)
 10.1837 +  | adjustcoeff (l, Le (Sub (bv, bw), ab)) = Le (Sub (bv, bw), ab)
 10.1838 +  | adjustcoeff (l, Le (Mult (bx, by), ab)) = Le (Mult (bx, by), ab)
 10.1839 +  | adjustcoeff (l, Ge (ac, ad)) = Ge (ac, ad)
 10.1840 +  | adjustcoeff (l, Eq (Cst fe, af)) = Eq (Cst fe, af)
 10.1841 +  | adjustcoeff (l, Eq (Var ff, af)) = Eq (Var ff, af)
 10.1842 +  | adjustcoeff (l, Eq (Neg fg, af)) = Eq (Neg fg, af)
 10.1843 +  | adjustcoeff (l, Eq (Add (Cst fw, fi), af)) = Eq (Add (Cst fw, fi), af)
 10.1844 +  | adjustcoeff (l, Eq (Add (Var fx, fi), af)) = Eq (Add (Var fx, fi), af)
 10.1845 +  | adjustcoeff (l, Eq (Add (Neg fy, fi), af)) = Eq (Add (Neg fy, fi), af)
 10.1846 +  | adjustcoeff (l, Eq (Add (Add (fz, ga), fi), af)) =
 10.1847 +    Eq (Add (Add (fz, ga), fi), af)
 10.1848 +  | adjustcoeff (l, Eq (Add (Sub (gb, gc), fi), af)) =
 10.1849 +    Eq (Add (Sub (gb, gc), fi), af)
 10.1850 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Cst hg), fi), af)) =
 10.1851 +    Eq (Add (Mult (Cst go, Cst hg), fi), af)
 10.1852 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Var 0), fi), Var ib)) =
 10.1853 +    Eq (Add (Mult (Cst go, Var 0), fi), Var ib)
 10.1854 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Var 0), fi), Neg ic)) =
 10.1855 +    Eq (Add (Mult (Cst go, Var 0), fi), Neg ic)
 10.1856 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Var 0), fi), Add (id, ie))) =
 10.1857 +    Eq (Add (Mult (Cst go, Var 0), fi), Add (id, ie))
 10.1858 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Var 0), fi), Sub (if', ig))) =
 10.1859 +    Eq (Add (Mult (Cst go, Var 0), fi), Sub (if', ig))
 10.1860 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Var 0), fi), Mult (ih, ii))) =
 10.1861 +    Eq (Add (Mult (Cst go, Var 0), fi), Mult (ih, ii))
 10.1862 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Var hy), fi), af)) =
 10.1863 +    Eq (Add (Mult (Cst go, Var hy), fi), af)
 10.1864 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Neg hi), fi), af)) =
 10.1865 +    Eq (Add (Mult (Cst go, Neg hi), fi), af)
 10.1866 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Add (hj, hk)), fi), af)) =
 10.1867 +    Eq (Add (Mult (Cst go, Add (hj, hk)), fi), af)
 10.1868 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Sub (hl, hm)), fi), af)) =
 10.1869 +    Eq (Add (Mult (Cst go, Sub (hl, hm)), fi), af)
 10.1870 +  | adjustcoeff (l, Eq (Add (Mult (Cst go, Mult (hn, ho)), fi), af)) =
 10.1871 +    Eq (Add (Mult (Cst go, Mult (hn, ho)), fi), af)
 10.1872 +  | adjustcoeff (l, Eq (Add (Mult (Var gp, ge), fi), af)) =
 10.1873 +    Eq (Add (Mult (Var gp, ge), fi), af)
 10.1874 +  | adjustcoeff (l, Eq (Add (Mult (Neg gq, ge), fi), af)) =
 10.1875 +    Eq (Add (Mult (Neg gq, ge), fi), af)
 10.1876 +  | adjustcoeff (l, Eq (Add (Mult (Add (gr, gs), ge), fi), af)) =
 10.1877 +    Eq (Add (Mult (Add (gr, gs), ge), fi), af)
 10.1878 +  | adjustcoeff (l, Eq (Add (Mult (Sub (gt, gu), ge), fi), af)) =
 10.1879 +    Eq (Add (Mult (Sub (gt, gu), ge), fi), af)
 10.1880 +  | adjustcoeff (l, Eq (Add (Mult (Mult (gv, gw), ge), fi), af)) =
 10.1881 +    Eq (Add (Mult (Mult (gv, gw), ge), fi), af)
 10.1882 +  | adjustcoeff (l, Eq (Sub (fj, fk), af)) = Eq (Sub (fj, fk), af)
 10.1883 +  | adjustcoeff (l, Eq (Mult (fl, fm), af)) = Eq (Mult (fl, fm), af)
 10.1884 +  | adjustcoeff (l, Divides (Cst is, Cst jk)) = Divides (Cst is, Cst jk)
 10.1885 +  | adjustcoeff (l, Divides (Cst is, Var jl)) = Divides (Cst is, Var jl)
 10.1886 +  | adjustcoeff (l, Divides (Cst is, Neg jm)) = Divides (Cst is, Neg jm)
 10.1887 +  | adjustcoeff (l, Divides (Cst is, Add (Cst kc, jo))) =
 10.1888 +    Divides (Cst is, Add (Cst kc, jo))
 10.1889 +  | adjustcoeff (l, Divides (Cst is, Add (Var kd, jo))) =
 10.1890 +    Divides (Cst is, Add (Var kd, jo))
 10.1891 +  | adjustcoeff (l, Divides (Cst is, Add (Neg ke, jo))) =
 10.1892 +    Divides (Cst is, Add (Neg ke, jo))
 10.1893 +  | adjustcoeff (l, Divides (Cst is, Add (Add (kf, kg), jo))) =
 10.1894 +    Divides (Cst is, Add (Add (kf, kg), jo))
 10.1895 +  | adjustcoeff (l, Divides (Cst is, Add (Sub (kh, ki), jo))) =
 10.1896 +    Divides (Cst is, Add (Sub (kh, ki), jo))
 10.1897 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Cst ku, Cst lm), jo))) =
 10.1898 +    Divides (Cst is, Add (Mult (Cst ku, Cst lm), jo))
 10.1899 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Cst ku, Var me), jo))) =
 10.1900 +    (if (me = 0)
 10.1901 +      then Divides
 10.1902 +             (Cst (op_div_def1 l ku * is),
 10.1903 +               Add (Mult (Cst 1, Var 0), lin_mul (op_div_def1 l ku, jo)))
 10.1904 +      else Divides
 10.1905 +             (Cst is,
 10.1906 +               Add (Mult (Cst ku, Var (op_45_def0 me id_1_def0 + 1)), jo)))
 10.1907 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Cst ku, Neg lo), jo))) =
 10.1908 +    Divides (Cst is, Add (Mult (Cst ku, Neg lo), jo))
 10.1909 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Cst ku, Add (lp, lq)), jo))) =
 10.1910 +    Divides (Cst is, Add (Mult (Cst ku, Add (lp, lq)), jo))
 10.1911 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Cst ku, Sub (lr, ls)), jo))) =
 10.1912 +    Divides (Cst is, Add (Mult (Cst ku, Sub (lr, ls)), jo))
 10.1913 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Cst ku, Mult (lt, lu)), jo))) =
 10.1914 +    Divides (Cst is, Add (Mult (Cst ku, Mult (lt, lu)), jo))
 10.1915 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Var kv, kk), jo))) =
 10.1916 +    Divides (Cst is, Add (Mult (Var kv, kk), jo))
 10.1917 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Neg kw, kk), jo))) =
 10.1918 +    Divides (Cst is, Add (Mult (Neg kw, kk), jo))
 10.1919 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Add (kx, ky), kk), jo))) =
 10.1920 +    Divides (Cst is, Add (Mult (Add (kx, ky), kk), jo))
 10.1921 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Sub (kz, la), kk), jo))) =
 10.1922 +    Divides (Cst is, Add (Mult (Sub (kz, la), kk), jo))
 10.1923 +  | adjustcoeff (l, Divides (Cst is, Add (Mult (Mult (lb, lc), kk), jo))) =
 10.1924 +    Divides (Cst is, Add (Mult (Mult (lb, lc), kk), jo))
 10.1925 +  | adjustcoeff (l, Divides (Cst is, Sub (jp, jq))) =
 10.1926 +    Divides (Cst is, Sub (jp, jq))
 10.1927 +  | adjustcoeff (l, Divides (Cst is, Mult (jr, js))) =
 10.1928 +    Divides (Cst is, Mult (jr, js))
 10.1929 +  | adjustcoeff (l, Divides (Var it, ah)) = Divides (Var it, ah)
 10.1930 +  | adjustcoeff (l, Divides (Neg iu, ah)) = Divides (Neg iu, ah)
 10.1931 +  | adjustcoeff (l, Divides (Add (iv, iw), ah)) = Divides (Add (iv, iw), ah)
 10.1932 +  | adjustcoeff (l, Divides (Sub (ix, iy), ah)) = Divides (Sub (ix, iy), ah)
 10.1933 +  | adjustcoeff (l, Divides (Mult (iz, ja), ah)) = Divides (Mult (iz, ja), ah)
 10.1934 +  | adjustcoeff (l, T) = T
 10.1935 +  | adjustcoeff (l, F) = F
 10.1936 +  | adjustcoeff (l, NOT (Lt (mg, mh))) = NOT (Lt (mg, mh))
 10.1937 +  | adjustcoeff (l, NOT (Gt (mi, mj))) = NOT (Gt (mi, mj))
 10.1938 +  | adjustcoeff (l, NOT (Le (mk, ml))) = NOT (Le (mk, ml))
 10.1939 +  | adjustcoeff (l, NOT (Ge (mm, mn))) = NOT (Ge (mm, mn))
 10.1940 +  | adjustcoeff (l, NOT (Eq (Cst oa, mp))) = NOT (Eq (Cst oa, mp))
 10.1941 +  | adjustcoeff (l, NOT (Eq (Var ob, mp))) = NOT (Eq (Var ob, mp))
 10.1942 +  | adjustcoeff (l, NOT (Eq (Neg oc, mp))) = NOT (Eq (Neg oc, mp))
 10.1943 +  | adjustcoeff (l, NOT (Eq (Add (Cst os, oe), mp))) =
 10.1944 +    NOT (Eq (Add (Cst os, oe), mp))
 10.1945 +  | adjustcoeff (l, NOT (Eq (Add (Var ot, oe), mp))) =
 10.1946 +    NOT (Eq (Add (Var ot, oe), mp))
 10.1947 +  | adjustcoeff (l, NOT (Eq (Add (Neg ou, oe), mp))) =
 10.1948 +    NOT (Eq (Add (Neg ou, oe), mp))
 10.1949 +  | adjustcoeff (l, NOT (Eq (Add (Add (ov, ow), oe), mp))) =
 10.1950 +    NOT (Eq (Add (Add (ov, ow), oe), mp))
 10.1951 +  | adjustcoeff (l, NOT (Eq (Add (Sub (ox, oy), oe), mp))) =
 10.1952 +    NOT (Eq (Add (Sub (ox, oy), oe), mp))
 10.1953 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Cst qc), oe), mp))) =
 10.1954 +    NOT (Eq (Add (Mult (Cst pk, Cst qc), oe), mp))
 10.1955 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Var qx))) =
 10.1956 +    NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Var qx))
 10.1957 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Neg qy))) =
 10.1958 +    NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Neg qy))
 10.1959 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Add (qz, ra)))) =
 10.1960 +    NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Add (qz, ra)))
 10.1961 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Sub (rb, rc)))) =
 10.1962 +    NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Sub (rb, rc)))
 10.1963 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Mult (rd, re)))) =
 10.1964 +    NOT (Eq (Add (Mult (Cst pk, Var 0), oe), Mult (rd, re)))
 10.1965 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Var qu), oe), mp))) =
 10.1966 +    NOT (Eq (Add (Mult (Cst pk, Var qu), oe), mp))
 10.1967 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Neg qe), oe), mp))) =
 10.1968 +    NOT (Eq (Add (Mult (Cst pk, Neg qe), oe), mp))
 10.1969 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Add (qf, qg)), oe), mp))) =
 10.1970 +    NOT (Eq (Add (Mult (Cst pk, Add (qf, qg)), oe), mp))
 10.1971 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Sub (qh, qi)), oe), mp))) =
 10.1972 +    NOT (Eq (Add (Mult (Cst pk, Sub (qh, qi)), oe), mp))
 10.1973 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Cst pk, Mult (qj, qk)), oe), mp))) =
 10.1974 +    NOT (Eq (Add (Mult (Cst pk, Mult (qj, qk)), oe), mp))
 10.1975 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Var pl, pa), oe), mp))) =
 10.1976 +    NOT (Eq (Add (Mult (Var pl, pa), oe), mp))
 10.1977 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Neg pm, pa), oe), mp))) =
 10.1978 +    NOT (Eq (Add (Mult (Neg pm, pa), oe), mp))
 10.1979 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Add (pn, po), pa), oe), mp))) =
 10.1980 +    NOT (Eq (Add (Mult (Add (pn, po), pa), oe), mp))
 10.1981 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Sub (pp, pq), pa), oe), mp))) =
 10.1982 +    NOT (Eq (Add (Mult (Sub (pp, pq), pa), oe), mp))
 10.1983 +  | adjustcoeff (l, NOT (Eq (Add (Mult (Mult (pr, ps), pa), oe), mp))) =
 10.1984 +    NOT (Eq (Add (Mult (Mult (pr, ps), pa), oe), mp))
 10.1985 +  | adjustcoeff (l, NOT (Eq (Sub (of', og), mp))) = NOT (Eq (Sub (of', og), mp))
 10.1986 +  | adjustcoeff (l, NOT (Eq (Mult (oh, oi), mp))) = NOT (Eq (Mult (oh, oi), mp))
 10.1987 +  | adjustcoeff (l, NOT (Divides (Cst ro, Cst sg))) =
 10.1988 +    NOT (Divides (Cst ro, Cst sg))
 10.1989 +  | adjustcoeff (l, NOT (Divides (Cst ro, Var sh))) =
 10.1990 +    NOT (Divides (Cst ro, Var sh))
 10.1991 +  | adjustcoeff (l, NOT (Divides (Cst ro, Neg si))) =
 10.1992 +    NOT (Divides (Cst ro, Neg si))
 10.1993 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Cst sy, sk)))) =
 10.1994 +    NOT (Divides (Cst ro, Add (Cst sy, sk)))
 10.1995 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Var sz, sk)))) =
 10.1996 +    NOT (Divides (Cst ro, Add (Var sz, sk)))
 10.1997 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Neg ta, sk)))) =
 10.1998 +    NOT (Divides (Cst ro, Add (Neg ta, sk)))
 10.1999 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Add (tb, tc), sk)))) =
 10.2000 +    NOT (Divides (Cst ro, Add (Add (tb, tc), sk)))
 10.2001 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Sub (td, te), sk)))) =
 10.2002 +    NOT (Divides (Cst ro, Add (Sub (td, te), sk)))
 10.2003 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Cst tq, Cst ui), sk)))) =
 10.2004 +    NOT (Divides (Cst ro, Add (Mult (Cst tq, Cst ui), sk)))
 10.2005 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Cst tq, Var va), sk)))) =
 10.2006 +    (if (va = 0)
 10.2007 +      then NOT (Divides
 10.2008 +                  (Cst (op_div_def1 l tq * ro),
 10.2009 +                    Add (Mult (Cst 1, Var 0), lin_mul (op_div_def1 l tq, sk))))
 10.2010 +      else NOT (Divides
 10.2011 +                  (Cst ro,
 10.2012 +                    Add (Mult (Cst tq, Var (op_45_def0 va id_1_def0 + 1)),
 10.2013 +                          sk))))
 10.2014 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Cst tq, Neg uk), sk)))) =
 10.2015 +    NOT (Divides (Cst ro, Add (Mult (Cst tq, Neg uk), sk)))
 10.2016 +  | adjustcoeff
 10.2017 +      (l, NOT (Divides (Cst ro, Add (Mult (Cst tq, Add (ul, um)), sk)))) =
 10.2018 +    NOT (Divides (Cst ro, Add (Mult (Cst tq, Add (ul, um)), sk)))
 10.2019 +  | adjustcoeff
 10.2020 +      (l, NOT (Divides (Cst ro, Add (Mult (Cst tq, Sub (un, uo)), sk)))) =
 10.2021 +    NOT (Divides (Cst ro, Add (Mult (Cst tq, Sub (un, uo)), sk)))
 10.2022 +  | adjustcoeff
 10.2023 +      (l, NOT (Divides (Cst ro, Add (Mult (Cst tq, Mult (up, uq)), sk)))) =
 10.2024 +    NOT (Divides (Cst ro, Add (Mult (Cst tq, Mult (up, uq)), sk)))
 10.2025 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Var tr, tg), sk)))) =
 10.2026 +    NOT (Divides (Cst ro, Add (Mult (Var tr, tg), sk)))
 10.2027 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Neg ts, tg), sk)))) =
 10.2028 +    NOT (Divides (Cst ro, Add (Mult (Neg ts, tg), sk)))
 10.2029 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Add (tt, tu), tg), sk)))) =
 10.2030 +    NOT (Divides (Cst ro, Add (Mult (Add (tt, tu), tg), sk)))
 10.2031 +  | adjustcoeff (l, NOT (Divides (Cst ro, Add (Mult (Sub (tv, tw), tg), sk)))) =
 10.2032 +    NOT (Divides (Cst ro, Add (Mult (Sub (tv, tw), tg), sk)))
 10.2033 +  | adjustcoeff
 10.2034 +      (l, NOT (Divides (Cst ro, Add (Mult (Mult (tx, ty), tg), sk)))) =
 10.2035 +    NOT (Divides (Cst ro, Add (Mult (Mult (tx, ty), tg), sk)))
 10.2036 +  | adjustcoeff (l, NOT (Divides (Cst ro, Sub (sl, sm)))) =
 10.2037 +    NOT (Divides (Cst ro, Sub (sl, sm)))
 10.2038 +  | adjustcoeff (l, NOT (Divides (Cst ro, Mult (sn, so)))) =
 10.2039 +    NOT (Divides (Cst ro, Mult (sn, so)))
 10.2040 +  | adjustcoeff (l, NOT (Divides (Var rp, mr))) = NOT (Divides (Var rp, mr))
 10.2041 +  | adjustcoeff (l, NOT (Divides (Neg rq, mr))) = NOT (Divides (Neg rq, mr))
 10.2042 +  | adjustcoeff (l, NOT (Divides (Add (rr, rs), mr))) =
 10.2043 +    NOT (Divides (Add (rr, rs), mr))
 10.2044 +  | adjustcoeff (l, NOT (Divides (Sub (rt, ru), mr))) =
 10.2045 +    NOT (Divides (Sub (rt, ru), mr))
 10.2046 +  | adjustcoeff (l, NOT (Divides (Mult (rv, rw), mr))) =
 10.2047 +    NOT (Divides (Mult (rv, rw), mr))
 10.2048 +  | adjustcoeff (l, NOT T) = NOT T
 10.2049 +  | adjustcoeff (l, NOT F) = NOT F
 10.2050 +  | adjustcoeff (l, NOT (NOT ms)) = NOT (NOT ms)
 10.2051 +  | adjustcoeff (l, NOT (And (mt, mu))) = NOT (And (mt, mu))
 10.2052 +  | adjustcoeff (l, NOT (Or (mv, mw))) = NOT (Or (mv, mw))
 10.2053 +  | adjustcoeff (l, NOT (Imp (mx, my))) = NOT (Imp (mx, my))
 10.2054 +  | adjustcoeff (l, NOT (Equ (mz, na))) = NOT (Equ (mz, na))
 10.2055 +  | adjustcoeff (l, NOT (QAll nb)) = NOT (QAll nb)
 10.2056 +  | adjustcoeff (l, NOT (QEx nc)) = NOT (QEx nc)
 10.2057 +  | adjustcoeff (l, Imp (an, ao)) = Imp (an, ao)
 10.2058 +  | adjustcoeff (l, Equ (ap, aq)) = Equ (ap, aq)
 10.2059 +  | adjustcoeff (l, QAll ar) = QAll ar
 10.2060 +  | adjustcoeff (l, QEx as') = QEx as';
 10.2061 +
 10.2062 +fun formlcm (Le (Add (Mult (Cst c, Var 0), r), Cst i)) = abs c
 10.2063 +  | formlcm (Eq (Add (Mult (Cst c, Var 0), r), Cst i)) = abs c
 10.2064 +  | formlcm (NOT p) = formlcm p
 10.2065 +  | formlcm (And (p, q)) = ilcm (formlcm p) (formlcm q)
 10.2066 +  | formlcm (Or (p, q)) = ilcm (formlcm p) (formlcm q)
 10.2067 +  | formlcm (Lt (u, v)) = 1
 10.2068 +  | formlcm (Gt (w, x)) = 1
 10.2069 +  | formlcm (Le (Cst bo, z)) = 1
 10.2070 +  | formlcm (Le (Var bp, z)) = 1
 10.2071 +  | formlcm (Le (Neg bq, z)) = 1
 10.2072 +  | formlcm (Le (Add (Cst cg, bs), z)) = 1
 10.2073 +  | formlcm (Le (Add (Var ch, bs), z)) = 1
 10.2074 +  | formlcm (Le (Add (Neg ci, bs), z)) = 1
 10.2075 +  | formlcm (Le (Add (Add (cj, ck), bs), z)) = 1
 10.2076 +  | formlcm (Le (Add (Sub (cl, cm), bs), z)) = 1
 10.2077 +  | formlcm (Le (Add (Mult (Cst cy, Cst dq), bs), z)) = 1
 10.2078 +  | formlcm (Le (Add (Mult (Cst cy, Var 0), bs), Var el)) = 1
 10.2079 +  | formlcm (Le (Add (Mult (Cst cy, Var 0), bs), Neg em)) = 1
 10.2080 +  | formlcm (Le (Add (Mult (Cst cy, Var 0), bs), Add (en, eo))) = 1
 10.2081 +  | formlcm (Le (Add (Mult (Cst cy, Var 0), bs), Sub (ep, eq))) = 1
 10.2082 +  | formlcm (Le (Add (Mult (Cst cy, Var 0), bs), Mult (er, es))) = 1
 10.2083 +  | formlcm (Le (Add (Mult (Cst cy, Var ei ), bs), z)) = 1
 10.2084 +  | formlcm (Le (Add (Mult (Cst cy, Neg ds), bs), z)) = 1
 10.2085 +  | formlcm (Le (Add (Mult (Cst cy, Add (dt, du)), bs), z)) = 1
 10.2086 +  | formlcm (Le (Add (Mult (Cst cy, Sub (dv, dw)), bs), z)) = 1
 10.2087 +  | formlcm (Le (Add (Mult (Cst cy, Mult (dx, dy)), bs), z)) = 1
 10.2088 +  | formlcm (Le (Add (Mult (Var cz, co), bs), z)) = 1
 10.2089 +  | formlcm (Le (Add (Mult (Neg da, co), bs), z)) = 1
 10.2090 +  | formlcm (Le (Add (Mult (Add (db, dc), co), bs), z)) = 1
 10.2091 +  | formlcm (Le (Add (Mult (Sub (dd, de), co), bs), z)) = 1
 10.2092 +  | formlcm (Le (Add (Mult (Mult (df, dg), co), bs), z)) = 1
 10.2093 +  | formlcm (Le (Sub (bt, bu), z)) = 1
 10.2094 +  | formlcm (Le (Mult (bv, bw), z)) = 1
 10.2095 +  | formlcm (Ge (aa, ab)) = 1
 10.2096 +  | formlcm (Eq (Cst fc, ad)) = 1
 10.2097 +  | formlcm (Eq (Var fd, ad)) = 1
 10.2098 +  | formlcm (Eq (Neg fe, ad)) = 1
 10.2099 +  | formlcm (Eq (Add (Cst fu, fg), ad)) = 1
 10.2100 +  | formlcm (Eq (Add (Var fv, fg), ad)) = 1
 10.2101 +  | formlcm (Eq (Add (Neg fw, fg), ad)) = 1
 10.2102 +  | formlcm (Eq (Add (Add (fx, fy), fg), ad)) = 1
 10.2103 +  | formlcm (Eq (Add (Sub (fz, ga), fg), ad)) = 1
 10.2104 +  | formlcm (Eq (Add (Mult (Cst gm, Cst he), fg), ad)) = 1
 10.2105 +  | formlcm (Eq (Add (Mult (Cst gm, Var 0), fg), Var hz)) = 1
 10.2106 +  | formlcm (Eq (Add (Mult (Cst gm, Var 0), fg), Neg ia)) = 1
 10.2107 +  | formlcm (Eq (Add (Mult (Cst gm, Var 0), fg), Add (ib, ic))) = 1
 10.2108 +  | formlcm (Eq (Add (Mult (Cst gm, Var 0), fg), Sub (id, ie))) = 1
 10.2109 +  | formlcm (Eq (Add (Mult (Cst gm, Var 0), fg), Mult (if', ig))) = 1
 10.2110 +  | formlcm (Eq (Add (Mult (Cst gm, Var hw), fg), ad)) = 1
 10.2111 +  | formlcm (Eq (Add (Mult (Cst gm, Neg hg), fg), ad)) = 1
 10.2112 +  | formlcm (Eq (Add (Mult (Cst gm, Add (hh, hi)), fg), ad)) = 1
 10.2113 +  | formlcm (Eq (Add (Mult (Cst gm, Sub (hj, hk)), fg), ad)) = 1
 10.2114 +  | formlcm (Eq (Add (Mult (Cst gm, Mult (hl, hm)), fg), ad)) = 1
 10.2115 +  | formlcm (Eq (Add (Mult (Var gn, gc), fg), ad)) = 1
 10.2116 +  | formlcm (Eq (Add (Mult (Neg go, gc), fg), ad)) = 1
 10.2117 +  | formlcm (Eq (Add (Mult (Add (gp, gq), gc), fg), ad)) = 1
 10.2118 +  | formlcm (Eq (Add (Mult (Sub (gr, gs), gc), fg), ad)) = 1
 10.2119 +  | formlcm (Eq (Add (Mult (Mult (gt, gu), gc), fg), ad)) = 1
 10.2120 +  | formlcm (Eq (Sub (fh, fi), ad)) = 1
 10.2121 +  | formlcm (Eq (Mult (fj, fk), ad)) = 1
 10.2122 +  | formlcm (Divides (Cst iq, Cst ji)) = 1
 10.2123 +  | formlcm (Divides (Cst iq, Var jj)) = 1
 10.2124 +  | formlcm (Divides (Cst iq, Neg jk)) = 1
 10.2125 +  | formlcm (Divides (Cst iq, Add (Cst ka, jm))) = 1
 10.2126 +  | formlcm (Divides (Cst iq, Add (Var kb, jm))) = 1
 10.2127 +  | formlcm (Divides (Cst iq, Add (Neg kc, jm))) = 1
 10.2128 +  | formlcm (Divides (Cst iq, Add (Add (kd, ke), jm))) = 1
 10.2129 +  | formlcm (Divides (Cst iq, Add (Sub (kf, kg), jm))) = 1
 10.2130 +  | formlcm (Divides (Cst iq, Add (Mult (Cst ks, Cst lk), jm))) = 1
 10.2131 +  | formlcm (Divides (Cst iq, Add (Mult (Cst ks, Var mc), jm))) =
 10.2132 +    (if (mc = 0) then abs ks else 1)
 10.2133 +  | formlcm (Divides (Cst iq, Add (Mult (Cst ks, Neg lm), jm))) = 1
 10.2134 +  | formlcm (Divides (Cst iq, Add (Mult (Cst ks, Add (ln, lo)), jm))) = 1
 10.2135 +  | formlcm (Divides (Cst iq, Add (Mult (Cst ks, Sub (lp, lq)), jm))) = 1
 10.2136 +  | formlcm (Divides (Cst iq, Add (Mult (Cst ks, Mult (lr, ls)), jm))) = 1
 10.2137 +  | formlcm (Divides (Cst iq, Add (Mult (Var kt, ki), jm))) = 1
 10.2138 +  | formlcm (Divides (Cst iq, Add (Mult (Neg ku, ki), jm))) = 1
 10.2139 +  | formlcm (Divides (Cst iq, Add (Mult (Add (kv, kw), ki), jm))) = 1
 10.2140 +  | formlcm (Divides (Cst iq, Add (Mult (Sub (kx, ky), ki), jm))) = 1
 10.2141 +  | formlcm (Divides (Cst iq, Add (Mult (Mult (kz, la), ki), jm))) = 1
 10.2142 +  | formlcm (Divides (Cst iq, Sub (jn, jo))) = 1
 10.2143 +  | formlcm (Divides (Cst iq, Mult (jp, jq))) = 1
 10.2144 +  | formlcm (Divides (Var ir, af)) = 1
 10.2145 +  | formlcm (Divides (Neg is, af)) = 1
 10.2146 +  | formlcm (Divides (Add (it, iu), af)) = 1
 10.2147 +  | formlcm (Divides (Sub (iv, iw), af)) = 1
 10.2148 +  | formlcm (Divides (Mult (ix, iy), af)) = 1
 10.2149 +  | formlcm T = 1
 10.2150 +  | formlcm F = 1
 10.2151 +  | formlcm (Imp (al, am)) = 1
 10.2152 +  | formlcm (Equ (an, ao)) = 1
 10.2153 +  | formlcm (QAll ap) = 1
 10.2154 +  | formlcm (QEx aq) = 1;
 10.2155 +
 10.2156 +fun unitycoeff p =
 10.2157 +  let val l = formlcm p; val p' = adjustcoeff (l, p)
 10.2158 +  in (if (l = 1) then p'
 10.2159 +       else And (Divides (Cst l, Add (Mult (Cst 1, Var 0), Cst 0)), p'))
 10.2160 +  end;
 10.2161 +
 10.2162 +fun unify p =
 10.2163 +  let val q = unitycoeff p; val B = list_set (bset q); val A = list_set (aset q)
 10.2164 +  in (if op_60_61_def0 (size_def1 B) (size_def1 A) then (q, B)
 10.2165 +       else (mirror q, map lin_neg A))
 10.2166 +  end;
 10.2167 +
 10.2168 +fun cooper p =
 10.2169 +  lift_un (fn q => decrvars (explode_minf (unify q))) (linform (nnf p));
 10.2170 +
 10.2171 +fun pa p = lift_un psimpl (qelim (cooper, p));
 10.2172 +
 10.2173 +val test = pa;
 10.2174 +
 10.2175 +end;
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/HOL/Tools/comm_ring.ML	Wed Sep 14 17:25:52 2005 +0200
    11.3 @@ -0,0 +1,134 @@
    11.4 +(*  ID:         $Id$
    11.5 +    Author:     Amine Chaieb
    11.6 +
    11.7 +	     Tactic for solving equalities over commutative rings *)
    11.8 +signature CRING =
    11.9 +sig
   11.10 +    val cring_tac : int -> tactic
   11.11 +    val cring_method: int -> Proof.method
   11.12 +    val setup : (theory -> theory) list
   11.13 +end
   11.14 +structure CommRing :CRING = 
   11.15 +struct
   11.16 +
   11.17 +(* The Cring exception for erronous uses of cring_tac *)
   11.18 +exception CRing of string;
   11.19 +
   11.20 +(* Zero and One of the commutative ring *)
   11.21 +fun cring_zero T = Const("0",T);
   11.22 +fun cring_one T = Const("1",T);
   11.23 +
   11.24 +(* reification functions *)
   11.25 +(* add two polynom expressions *)
   11.26 +fun polT t = Type ("Commutative_Ring.pol",[t]);
   11.27 +fun  polexT t = Type("Commutative_Ring.polex",[t]);
   11.28 +val nT = HOLogic.natT;
   11.29 +fun listT T = Type ("List.list",[T]);
   11.30 +
   11.31 +(* Reification of the constructors *)
   11.32 +(* Nat*)
   11.33 +val succ = Const("Suc",nT --> nT);
   11.34 +val zero = Const("0",nT);
   11.35 +val one = Const("1",nT);
   11.36 +
   11.37 +(* Lists *)
   11.38 +fun reif_list T [] = Const("List.list.Nil",listT T)
   11.39 +  | reif_list T (x::xs) = Const("List.list.Cons",[T,listT T] ---> listT T)
   11.40 +			     $x$(reif_list T xs);
   11.41 +
   11.42 +(* pol*)
   11.43 +fun pol_Pc t = Const("Commutative_Ring.pol.Pc",t --> polT t);
   11.44 +fun pol_Pinj t = Const("Commutative_Ring.pol.Pinj",[nT,polT t] ---> polT t);
   11.45 +fun pol_PX t = Const("Commutative_Ring.pol.PX",[polT t, nT, polT t] ---> polT t);
   11.46 +
   11.47 +(* polex *)
   11.48 +fun polex_add t = Const("Commutative_Ring.polex.Add",[polexT t,polexT t] ---> polexT t);
   11.49 +fun polex_sub t = Const("Commutative_Ring.polex.Sub",[polexT t,polexT t] ---> polexT t);
   11.50 +fun polex_mul t = Const("Commutative_Ring.polex.Mul",[polexT t,polexT t] ---> polexT t);
   11.51 +fun polex_neg t = Const("Commutative_Ring.polex.Neg",polexT t --> polexT t);
   11.52 +fun polex_pol t = Const("Commutative_Ring.polex.Pol",polT t --> polexT t);
   11.53 +fun polex_pow t = Const("Commutative_Ring.polex.Pow",[polexT t, nT] ---> polexT t);
   11.54 +(* reification of natural numbers *)
   11.55 +fun reif_nat n = 
   11.56 +    if n>0 then succ$(reif_nat (n-1))
   11.57 +    else if n=0 then zero
   11.58 +    else raise CRing "ring_tac: reif_nat negative n";
   11.59 +
   11.60 +(* reification of polynoms : primitive cring expressions *)
   11.61 +fun reif_pol T vs t =
   11.62 +    case t of
   11.63 +       Free(_,_) =>
   11.64 +	let val i = find_index_eq t vs 
   11.65 +	in if i = 0 
   11.66 +	   then (pol_PX T)$((pol_Pc T)$ (cring_one T))
   11.67 +			  $one$((pol_Pc T)$(cring_zero T)) 
   11.68 +	   else (pol_Pinj T)$(reif_nat i)$
   11.69 +			    ((pol_PX T)$((pol_Pc T)$ (cring_one T))
   11.70 +				       $one$
   11.71 +				       ((pol_Pc T)$(cring_zero T)))
   11.72 +	end 
   11.73 +      | _ => (pol_Pc T)$ t;
   11.74 +
   11.75 +
   11.76 +(* reification of polynom expressions *)
   11.77 +fun reif_polex T vs t =
   11.78 +    case t of
   11.79 +	Const("op +",_)$a$b => (polex_add T) 
   11.80 +				   $ (reif_polex T vs a)$(reif_polex T vs b)
   11.81 +      |	Const("op -",_)$a$b => (polex_sub T) 
   11.82 +				   $ (reif_polex T vs a)$(reif_polex T vs b)
   11.83 +      | Const("op *",_)$a$b => 	(polex_mul T) 
   11.84 +				    $ (reif_polex T vs a)$ (reif_polex T vs b)
   11.85 +      | Const("uminus",_)$a => (polex_neg T) 
   11.86 +				   $ (reif_polex T vs a)
   11.87 +      | (Const("Nat.power",_)$a$n) => (polex_pow T) $ (reif_polex T vs a) $ n
   11.88 +
   11.89 +      | _ => (polex_pol T) $ (reif_pol T vs t);
   11.90 +
   11.91 +(* reification of the equation *)
   11.92 +val cr_sort = Sign.read_sort (the_context ()) "{comm_ring,recpower}";
   11.93 +fun reif_eq sg (eq as Const("op =",Type("fun",a::_))$lhs$rhs) = 
   11.94 +    if Sign.of_sort (the_context()) (a,cr_sort)
   11.95 +    then 
   11.96 +	let val fs = term_frees eq
   11.97 +	    val cvs = cterm_of sg (reif_list a fs)
   11.98 +	    val clhs = cterm_of sg (reif_polex a fs lhs)
   11.99 +	    val crhs = cterm_of sg (reif_polex a fs rhs)
  11.100 +	    val ca = ctyp_of sg a
  11.101 +	in (ca,cvs,clhs, crhs)
  11.102 +	end
  11.103 +    else raise CRing "reif_eq: not an equation over comm_ring + recpower"
  11.104 +  | reif_eq sg _ = raise CRing "reif_eq: not an equation";
  11.105 +
  11.106 +(*The cring tactic  *)
  11.107 +(* Attention: You have to make sure that no t^0 is in the goal!! *)
  11.108 +(* Use simply rewriting t^0 = 1 *)
  11.109 +val cring_ss = simpset_of (the_context())
  11.110 +			   addsimps 
  11.111 +			   (map thm ["mkPX_def", "mkPinj_def","sub_def",
  11.112 +				     "power_add","even_def","pow_if"])
  11.113 +			   addsimps [sym OF [thm "power_add"]];
  11.114 +
  11.115 +val norm_eq = thm "norm_eq"
  11.116 +fun comm_ring_tac i =(fn st => 
  11.117 +    let
  11.118 +	val g = BasisLibrary.List.nth (prems_of st, i - 1)
  11.119 +	val sg = sign_of_thm st
  11.120 +	val (ca,cvs,clhs,crhs) = reif_eq sg (HOLogic.dest_Trueprop g)
  11.121 +	val norm_eq_th = simplify cring_ss 
  11.122 +			(instantiate' [SOME ca] [SOME clhs, SOME crhs, SOME cvs] 
  11.123 +						norm_eq)
  11.124 +    in ((cut_rules_tac [norm_eq_th] i) 
  11.125 +	    THEN (simp_tac cring_ss i) 
  11.126 +	    THEN (simp_tac cring_ss i)) st
  11.127 +    end);
  11.128 +
  11.129 +fun cring_method i = Method.METHOD (fn facts =>
  11.130 +  Method.insert_tac facts 1 THEN comm_ring_tac i);
  11.131 +
  11.132 +val setup =
  11.133 +  [Method.add_method ("comm_ring",
  11.134 +     Method.no_args (cring_method 1),
  11.135 +     "reflective decision procedure for equalities over commutative rings")];
  11.136 +
  11.137 +end;
  11.138 \ No newline at end of file
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/HOL/ex/Commutative_RingEx.thy	Wed Sep 14 17:25:52 2005 +0200
    12.3 @@ -0,0 +1,47 @@
    12.4 + (* $Id$ *)
    12.5 +theory Commutative_RingEx
    12.6 +imports Main
    12.7 +begin
    12.8 +
    12.9 +  (* Some examples demonstrating the comm_ring method *)
   12.10 +
   12.11 +lemma "4*(x::int)^5*y^3*x^2*3 + x*z + 3^5 = 12*x^7*y^3 + z*x + 243"
   12.12 +by comm_ring
   12.13 +
   12.14 +lemma "((x::int) + y)^2  = x^2 + y^2 + 2*x*y"
   12.15 +by comm_ring
   12.16 +
   12.17 +lemma "((x::int) + y)^3  = x^3 + y^3 + 3*x^2*y + 3*y^2*x"
   12.18 +by comm_ring
   12.19 +
   12.20 +lemma "((x::int) - y)^3  = x^3 + 3*x*y^2 + (-3)*y*x^2 - y^3"
   12.21 +by comm_ring
   12.22 +
   12.23 +lemma "((x::int) - y)^2  = x^2 + y^2 - 2*x*y"
   12.24 +by comm_ring
   12.25 +
   12.26 +lemma " ((a::int) + b + c)^2 = a^2 + b^2 + c^2 + 2*a*b + 2*b*c + 2*a*c"
   12.27 +by comm_ring
   12.28 +
   12.29 +lemma "((a::int) - b - c)^2 = a^2 + b^2 + c^2 - 2*a*b + 2*b*c - 2*a*c"
   12.30 +by comm_ring
   12.31 +
   12.32 +lemma "(a::int)*b + a*c = a*(b+c)"
   12.33 +by comm_ring
   12.34 +
   12.35 +lemma "(a::int)^2 - b^2 = (a - b) * (a + b)"
   12.36 +by comm_ring
   12.37 +
   12.38 +lemma "(a::int)^3 - b^3 = (a - b) * (a^2 + a*b + b^2)"
   12.39 +by comm_ring
   12.40 +
   12.41 +lemma "(a::int)^3 + b^3 = (a + b) * (a^2 - a*b + b^2)"
   12.42 +by comm_ring
   12.43 +
   12.44 +lemma "(a::int)^4 - b^4 = (a - b) * (a + b)*(a^2 + b^2)"
   12.45 +by comm_ring
   12.46 +
   12.47 +lemma "(a::int)^10 - b^10 = (a - b) * (a^9 + a^8*b + a^7*b^2 + a^6*b^3 + a^5*b^4 + a^4*b^5 + a^3*b^6 + a^2*b^7 + a*b^8 + b^9 )"
   12.48 +by comm_ring
   12.49 +
   12.50 +end
   12.51 \ No newline at end of file
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/HOL/ex/Commutative_Ring_Complete.thy	Wed Sep 14 17:25:52 2005 +0200
    13.3 @@ -0,0 +1,384 @@
    13.4 +(*  ID:         $Id$
    13.5 +    Author:     Bernhard Haeupler
    13.6 +
    13.7 +  This theory is about the relative completeness of the tactic 
    13.8 +  As long as the reified atomic polynomials of type 'a pol 
    13.9 +  are in normal form, the cring method is complete *)	
   13.10 +
   13.11 +theory Commutative_Ring_Complete
   13.12 +imports Main
   13.13 +begin
   13.14 +	
   13.15 +  (* Fromalization of normal form *)
   13.16 +consts isnorm :: "('a::{comm_ring,recpower}) pol \<Rightarrow> bool"
   13.17 +recdef isnorm "measure size"
   13.18 +  "isnorm (Pc c) = True"
   13.19 +  "isnorm (Pinj i (Pc c)) = False"
   13.20 +  "isnorm (Pinj i (Pinj j Q)) = False"
   13.21 +  "isnorm (Pinj 0 P) = False"
   13.22 +  "isnorm (Pinj i (PX Q1 j Q2)) = isnorm (PX Q1 j Q2)"
   13.23 +  "isnorm (PX P 0 Q) = False"
   13.24 +  "isnorm (PX (Pc c) i Q) = (c \<noteq> 0 & isnorm Q)"
   13.25 +  "isnorm (PX (PX P1 j (Pc c)) i Q) = (c\<noteq>0 \<and> isnorm(PX P1 j (Pc c))\<and>isnorm Q)"
   13.26 +  "isnorm (PX P i Q) = (isnorm P \<and> isnorm Q)"
   13.27 +
   13.28 +(* Some helpful lemmas *)
   13.29 +lemma norm_Pinj_0_False:"isnorm (Pinj 0 P) = False"
   13.30 +by(cases P, auto)
   13.31 +
   13.32 +lemma norm_PX_0_False:"isnorm (PX (Pc 0) i Q) = False"
   13.33 +by(cases i, auto)
   13.34 +
   13.35 +lemma norm_Pinj:"isnorm (Pinj i Q) \<Longrightarrow> isnorm Q"
   13.36 +by(cases i,simp add: norm_Pinj_0_False norm_PX_0_False,cases Q) auto
   13.37 +
   13.38 +lemma norm_PX2:"isnorm (PX P i Q) \<Longrightarrow> isnorm Q"
   13.39 +by(cases i, auto, cases P, auto, case_tac pol2, auto)
   13.40 +
   13.41 +lemma norm_PX1:"isnorm (PX P i Q) \<Longrightarrow> isnorm P"
   13.42 +by(cases i, auto, cases P, auto, case_tac pol2, auto)
   13.43 +
   13.44 +lemma mkPinj_cn:"\<lbrakk>y~=0; isnorm Q\<rbrakk> \<Longrightarrow> isnorm (mkPinj y Q)" 
   13.45 +apply(auto simp add: mkPinj_def norm_Pinj_0_False split: pol.split)
   13.46 +apply(case_tac nat, auto simp add: norm_Pinj_0_False)
   13.47 +by(case_tac pol, auto) (case_tac y, auto)
   13.48 +
   13.49 +lemma norm_PXtrans: 
   13.50 +  assumes A:"isnorm (PX P x Q)" and "isnorm Q2" 
   13.51 +  shows "isnorm (PX P x Q2)"
   13.52 +proof(cases P)
   13.53 +  case (PX p1 y p2) from prems show ?thesis by(cases x, auto, cases p2, auto)
   13.54 +next
   13.55 +  case Pc from prems show ?thesis by(cases x, auto)
   13.56 +next
   13.57 +  case Pinj from prems show ?thesis by(cases x, auto)
   13.58 +qed
   13.59 + 
   13.60 +
   13.61 +lemma norm_PXtrans2: assumes A:"isnorm (PX P x Q)" and "isnorm Q2" shows "isnorm (PX P (Suc (n+x)) Q2)"
   13.62 +proof(cases P)
   13.63 +  case (PX p1 y p2)
   13.64 +  from prems show ?thesis by(cases x, auto, cases p2, auto)
   13.65 +next
   13.66 +  case Pc
   13.67 +  from prems show ?thesis by(cases x, auto)
   13.68 +next
   13.69 +  case Pinj
   13.70 +  from prems show ?thesis by(cases x, auto)
   13.71 +qed
   13.72 +
   13.73 +    (* mkPX conserves normalizedness (_cn)*)
   13.74 +lemma mkPX_cn: 
   13.75 +  assumes "x \<noteq> 0" and "isnorm P" and "isnorm Q" 
   13.76 +  shows "isnorm (mkPX P x Q)"
   13.77 +proof(cases P)
   13.78 +  case (Pc c)
   13.79 +  from prems show ?thesis by (cases x) (auto simp add: mkPinj_cn mkPX_def)
   13.80 +next
   13.81 +  case (Pinj i Q)
   13.82 +  from prems show ?thesis by (cases x) (auto simp add: mkPinj_cn mkPX_def)
   13.83 +next
   13.84 +  case (PX P1 y P2)
   13.85 +  from prems have Y0:"y>0" by(cases y, auto)
   13.86 +  from prems have "isnorm P1" "isnorm P2" by (auto simp add: norm_PX1[of P1 y P2] norm_PX2[of P1 y P2])
   13.87 +  with prems Y0 show ?thesis by (cases x, auto simp add: mkPX_def norm_PXtrans2[of P1 y _ Q _], cases P2, auto)
   13.88 +qed
   13.89 +
   13.90 +    (* add conserves normalizedness *)
   13.91 +lemma add_cn:"\<lbrakk>isnorm P; (isnorm Q)\<rbrakk> \<Longrightarrow> isnorm (add (P, Q))"
   13.92 +proof(induct P Q rule: add.induct)
   13.93 +  case (2 c i P2) thus ?case by (cases P2, simp_all, cases i, simp_all)
   13.94 +next
   13.95 +  case (3 i P2 c) thus ?case by (cases P2, simp_all, cases i, simp_all)
   13.96 +next
   13.97 +  case (4 c P2 i Q2)
   13.98 +  from prems have "isnorm P2" "isnorm Q2" by (auto simp only: norm_PX1[of P2 i Q2] norm_PX2[of P2 i Q2])
   13.99 +  with prems show ?case by(cases i, simp, cases P2, auto, case_tac pol2, auto)
  13.100 +next
  13.101 +  case (5 P2 i Q2 c)
  13.102 +  from prems have "isnorm P2" "isnorm Q2" by (auto simp only: norm_PX1[of P2 i Q2] norm_PX2[of P2 i Q2])
  13.103 +  with prems show ?case by(cases i, simp, cases P2, auto, case_tac pol2, auto)
  13.104 +next
  13.105 +  case (6 x P2 y Q2)
  13.106 +  from prems have Y0:"y>0" by (cases y, auto simp add: norm_Pinj_0_False) 
  13.107 +  from prems have X0:"x>0" by (cases x, auto simp add: norm_Pinj_0_False) 
  13.108 +  have "x < y \<or> x = y \<or> x > y" by arith
  13.109 +  moreover
  13.110 +  { assume "x<y" hence "EX d. y=d+x" by arith
  13.111 +    then obtain d where "y=d+x"..
  13.112 +    moreover
  13.113 +    note prems X0
  13.114 +    moreover
  13.115 +    from prems have "isnorm P2" "isnorm Q2" by (auto simp add: norm_Pinj[of _ P2] norm_Pinj[of _ Q2])
  13.116 +    moreover
  13.117 +    with prems have "isnorm (Pinj d Q2)" by (cases d, simp, cases Q2, auto)
  13.118 +    ultimately have ?case by (simp add: mkPinj_cn)}
  13.119 +  moreover
  13.120 +  { assume "x=y"
  13.121 +    moreover
  13.122 +    from prems have "isnorm P2" "isnorm Q2" by(auto simp add: norm_Pinj[of _ P2] norm_Pinj[of _ Q2])
  13.123 +    moreover
  13.124 +    note prems Y0
  13.125 +    moreover
  13.126 +    ultimately have ?case by (simp add: mkPinj_cn) }
  13.127 +  moreover
  13.128 +  { assume "x>y" hence "EX d. x=d+y" by arith
  13.129 +    then obtain d where "x=d+y"..
  13.130 +    moreover
  13.131 +    note prems Y0
  13.132 +    moreover
  13.133 +    from prems have "isnorm P2" "isnorm Q2" by (auto simp add: norm_Pinj[of _ P2] norm_Pinj[of _ Q2])
  13.134 +    moreover
  13.135 +    with prems have "isnorm (Pinj d P2)" by (cases d, simp, cases P2, auto)
  13.136 +    ultimately have ?case by (simp add: mkPinj_cn)}
  13.137 +  ultimately show ?case by blast
  13.138 +next
  13.139 +  case (7 x P2 Q2 y R)
  13.140 +  have "x=0 \<or> (x = 1) \<or> (x > 1)" by arith
  13.141 +  moreover
  13.142 +  { assume "x=0" with prems have ?case by (auto simp add: norm_Pinj_0_False)}
  13.143 +  moreover
  13.144 +  { assume "x=1"
  13.145 +    from prems have "isnorm R" "isnorm P2" by (auto simp add: norm_Pinj[of _ P2] norm_PX2[of Q2 y R])
  13.146 +    with prems have "isnorm (add (R, P2))" by simp
  13.147 +    with prems have ?case by (simp add: norm_PXtrans[of Q2 y _]) }
  13.148 +  moreover
  13.149 +  { assume "x > 1" hence "EX d. x=Suc (Suc d)" by arith
  13.150 +    then obtain d where X:"x=Suc (Suc d)" ..
  13.151 +    from prems have NR:"isnorm R" "isnorm P2" by (auto simp add: norm_Pinj[of _ P2] norm_PX2[of Q2 y R])
  13.152 +    with prems have "isnorm (Pinj (x - 1) P2)" by(cases P2, auto)
  13.153 +    with prems NR have "isnorm( add (R, Pinj (x - 1) P2))" "isnorm(PX Q2 y R)" by simp
  13.154 +    with X have ?case by (simp add: norm_PXtrans[of Q2 y _]) }
  13.155 +  ultimately show ?case by blast
  13.156 +next
  13.157 +  case (8 Q2 y R x P2)
  13.158 +  have "x=0 \<or> (x = 1) \<or> (x > 1)" by arith
  13.159 +  moreover
  13.160 +  { assume "x=0" with prems have ?case by (auto simp add: norm_Pinj_0_False)}
  13.161 +  moreover
  13.162 +  { assume "x=1"
  13.163 +    from prems have "isnorm R" "isnorm P2" by (auto simp add: norm_Pinj[of _ P2] norm_PX2[of Q2 y R])
  13.164 +    with prems have "isnorm (add (R, P2))" by simp
  13.165 +    with prems have ?case by (simp add: norm_PXtrans[of Q2 y _]) }
  13.166 +  moreover
  13.167 +  { assume "x > 1" hence "EX d. x=Suc (Suc d)" by arith
  13.168 +    then obtain d where X:"x=Suc (Suc d)" ..
  13.169 +    from prems have NR:"isnorm R" "isnorm P2" by (auto simp add: norm_Pinj[of _ P2] norm_PX2[of Q2 y R])
  13.170 +    with prems have "isnorm (Pinj (x - 1) P2)" by(cases P2, auto)
  13.171 +    with prems NR have "isnorm( add (R, Pinj (x - 1) P2))" "isnorm(PX Q2 y R)" by simp
  13.172 +    with X have ?case by (simp add: norm_PXtrans[of Q2 y _]) }
  13.173 +  ultimately show ?case by blast
  13.174 +next
  13.175 +  case (9 P1 x P2 Q1 y Q2)
  13.176 +  from prems have Y0:"y>0" by(cases y, auto)
  13.177 +  from prems have X0:"x>0" by(cases x, auto)
  13.178 +  from prems have NP1:"isnorm P1" and NP2:"isnorm P2" by (auto simp add: norm_PX1[of P1 _ P2] norm_PX2[of P1 _ P2])
  13.179 +  from prems have NQ1:"isnorm Q1" and NQ2:"isnorm Q2" by (auto simp add: norm_PX1[of Q1 _ Q2] norm_PX2[of Q1 _ Q2])
  13.180 +  have "y < x \<or> x = y \<or> x < y" by arith
  13.181 +  moreover
  13.182 +  {assume sm1:"y < x" hence "EX d. x=d+y" by arith
  13.183 +    then obtain d where sm2:"x=d+y"..
  13.184 +    note prems NQ1 NP1 NP2 NQ2 sm1 sm2
  13.185 +    moreover
  13.186 +    have "isnorm (PX P1 d (Pc 0))" 
  13.187 +    proof(cases P1)
  13.188 +      case (PX p1 y p2)
  13.189 +      with prems show ?thesis by(cases d, simp,cases p2, auto)
  13.190 +    next case Pc   from prems show ?thesis by(cases d, auto)
  13.191 +    next case Pinj from prems show ?thesis by(cases d, auto)
  13.192 +    qed
  13.193 +    ultimately have "isnorm (add (P2, Q2))" "isnorm (add (PX P1 (x - y) (Pc 0), Q1))" by auto
  13.194 +    with Y0 sm1 sm2 have ?case by (simp add: mkPX_cn)}
  13.195 +  moreover
  13.196 +  {assume "x=y"
  13.197 +    from prems NP1 NP2 NQ1 NQ2 have "isnorm (add (P2, Q2))" "isnorm (add (P1, Q1))" by auto
  13.198 +    with Y0 prems have ?case by (simp add: mkPX_cn) }
  13.199 +  moreover
  13.200 +  {assume sm1:"x<y" hence "EX d. y=d+x" by arith
  13.201 +    then obtain d where sm2:"y=d+x"..
  13.202 +    note prems NQ1 NP1 NP2 NQ2 sm1 sm2
  13.203 +    moreover
  13.204 +    have "isnorm (PX Q1 d (Pc 0))" 
  13.205 +    proof(cases Q1)
  13.206 +      case (PX p1 y p2)
  13.207 +      with prems show ?thesis by(cases d, simp,cases p2, auto)
  13.208 +    next case Pc   from prems show ?thesis by(cases d, auto)
  13.209 +    next case Pinj from prems show ?thesis by(cases d, auto)
  13.210 +    qed
  13.211 +    ultimately have "isnorm (add (P2, Q2))" "isnorm (add (PX Q1 (y - x) (Pc 0), P1))" by auto
  13.212 +    with X0 sm1 sm2 have ?case by (simp add: mkPX_cn)}
  13.213 +  ultimately show ?case by blast
  13.214 +qed(simp)
  13.215 +
  13.216 +    (* mul concerves normalizedness *)
  13.217 +lemma mul_cn :"\<lbrakk>isnorm P; (isnorm Q)\<rbrakk> \<Longrightarrow> isnorm (mul (P, Q))"
  13.218 +proof(induct P Q rule: mul.induct)
  13.219 +  case (2 c i P2) thus ?case 
  13.220 +    by (cases P2, simp_all) (cases "i",simp_all add: mkPinj_cn)
  13.221 +next
  13.222 +  case (3 i P2 c) thus ?case 
  13.223 +    by (cases P2, simp_all) (cases "i",simp_all add: mkPinj_cn)
  13.224 +next
  13.225 +  case (4 c P2 i Q2)
  13.226 +  from prems have "isnorm P2" "isnorm Q2" by (auto simp only: norm_PX1[of P2 i Q2] norm_PX2[of P2 i Q2])
  13.227 +  with prems show ?case 
  13.228 +    by - (case_tac "c=0",simp_all,case_tac "i=0",simp_all add: mkPX_cn)
  13.229 +next
  13.230 +  case (5 P2 i Q2 c)
  13.231 +  from prems have "isnorm P2" "isnorm Q2" by (auto simp only: norm_PX1[of P2 i Q2] norm_PX2[of P2 i Q2])
  13.232 +  with prems show ?case
  13.233 +    by - (case_tac "c=0",simp_all,case_tac "i=0",simp_all add: mkPX_cn)
  13.234 +next
  13.235 +  case (6 x P2 y Q2)
  13.236 +  have "x < y \<or> x = y \<or> x > y" by arith
  13.237 +  moreover
  13.238 +  { assume "x<y" hence "EX d. y=d+x" by arith
  13.239 +    then obtain d where "y=d+x"..
  13.240 +    moreover
  13.241 +    note prems
  13.242 +    moreover
  13.243 +    from prems have "x>0" by (cases x, auto simp add: norm_Pinj_0_False) 
  13.244 +    moreover
  13.245 +    from prems have "isnorm P2" "isnorm Q2" by (auto simp add: norm_Pinj[of _ P2] norm_Pinj[of _ Q2])
  13.246 +    moreover
  13.247 +    with prems have "isnorm (Pinj d Q2)" by (cases d, simp, cases Q2, auto) 
  13.248 +    ultimately have ?case by (simp add: mkPinj_cn)}
  13.249 +  moreover
  13.250 +  { assume "x=y"
  13.251 +    moreover
  13.252 +    from prems have "isnorm P2" "isnorm Q2" by(auto simp add: norm_Pinj[of _ P2] norm_Pinj[of _ Q2])
  13.253 +    moreover
  13.254 +    with prems have "y>0" by (cases y, auto simp add: norm_Pinj_0_False)
  13.255 +    moreover
  13.256 +    note prems
  13.257 +    moreover
  13.258 +    ultimately have ?case by (simp add: mkPinj_cn) }
  13.259 +  moreover
  13.260 +  { assume "x>y" hence "EX d. x=d+y" by arith
  13.261 +    then obtain d where "x=d+y"..
  13.262 +    moreover
  13.263 +    note prems
  13.264 +    moreover
  13.265 +    from prems have "y>0" by (cases y, auto simp add: norm_Pinj_0_False) 
  13.266 +    moreover
  13.267 +    from prems have "isnorm P2" "isnorm Q2" by (auto simp add: norm_Pinj[of _ P2] norm_Pinj[of _ Q2])
  13.268 +    moreover
  13.269 +    with prems have "isnorm (Pinj d P2)"  by (cases d, simp, cases P2, auto)
  13.270 +    ultimately have ?case by (simp add: mkPinj_cn) }
  13.271 +  ultimately show ?case by blast
  13.272 +next
  13.273 +  case (7 x P2 Q2 y R)
  13.274 +  from prems have Y0:"y>0" by(cases y, auto)
  13.275 +  have "x=0 \<or> (x = 1) \<or> (x > 1)" by arith
  13.276 +  moreover
  13.277 +  { assume "x=0" with prems have ?case by (auto simp add: norm_Pinj_0_False)}
  13.278 +  moreover
  13.279 +  { assume "x=1"
  13.280 +    from prems have "isnorm R" "isnorm P2" by (auto simp add: norm_Pinj[of _ P2] norm_PX2[of Q2 y R])
  13.281 +    with prems have "isnorm (mul (R, P2))" "isnorm Q2" by (auto simp add: norm_PX1[of Q2 y R])
  13.282 +    with Y0 prems have ?case by (simp add: mkPX_cn)}
  13.283 +  moreover
  13.284 +  { assume "x > 1" hence "EX d. x=Suc (Suc d)" by arith
  13.285 +    then obtain d where X:"x=Suc (Suc d)" ..
  13.286 +    from prems have NR:"isnorm R" "isnorm Q2" by (auto simp add: norm_PX2[of Q2 y R] norm_PX1[of Q2 y R])
  13.287 +    moreover
  13.288 +    from prems have "isnorm (Pinj (x - 1) P2)" by(cases P2, auto)
  13.289 +    moreover
  13.290 +    from prems have "isnorm (Pinj x P2)" by(cases P2, auto)
  13.291 +    moreover
  13.292 +    note prems
  13.293 +    ultimately have "isnorm (mul (R, Pinj (x - 1) P2))" "isnorm (mul (Pinj x P2, Q2))" by auto
  13.294 +    with Y0 X have ?case by (simp add: mkPX_cn)}
  13.295 +  ultimately show ?case by blast
  13.296 +next
  13.297 +  case (8 Q2 y R x P2)
  13.298 +  from prems have Y0:"y>0" by(cases y, auto)
  13.299 +  have "x=0 \<or> (x = 1) \<or> (x > 1)" by arith
  13.300 +  moreover
  13.301 +  { assume "x=0" with prems have ?case by (auto simp add: norm_Pinj_0_False)}
  13.302 +  moreover
  13.303 +  { assume "x=1"
  13.304 +    from prems have "isnorm R" "isnorm P2" by (auto simp add: norm_Pinj[of _ P2] norm_PX2[of Q2 y R])
  13.305 +    with prems have "isnorm (mul (R, P2))" "isnorm Q2" by (auto simp add: norm_PX1[of Q2 y R])
  13.306 +    with Y0 prems have ?case by (simp add: mkPX_cn) }
  13.307 +  moreover
  13.308 +  { assume "x > 1" hence "EX d. x=Suc (Suc d)" by arith
  13.309 +    then obtain d where X:"x=Suc (Suc d)" ..
  13.310 +    from prems have NR:"isnorm R" "isnorm Q2" by (auto simp add: norm_PX2[of Q2 y R] norm_PX1[of Q2 y R])
  13.311 +    moreover
  13.312 +    from prems have "isnorm (Pinj (x - 1) P2)" by(cases P2, auto)
  13.313 +    moreover
  13.314 +    from prems have "isnorm (Pinj x P2)" by(cases P2, auto)
  13.315 +    moreover
  13.316 +    note prems
  13.317 +    ultimately have "isnorm (mul (R, Pinj (x - 1) P2))" "isnorm (mul (Pinj x P2, Q2))" by auto
  13.318 +    with Y0 X have ?case by (simp add: mkPX_cn) }
  13.319 +  ultimately show ?case by blast
  13.320 +next
  13.321 +  case (9 P1 x P2 Q1 y Q2)
  13.322 +  from prems have X0:"x>0" by(cases x, auto)
  13.323 +  from prems have Y0:"y>0" by(cases y, auto)
  13.324 +  note prems
  13.325 +  moreover
  13.326 +  from prems have "isnorm P1" "isnorm P2" by (auto simp add: norm_PX1[of P1 x P2] norm_PX2[of P1 x P2])
  13.327 +  moreover 
  13.328 +  from prems have "isnorm Q1" "isnorm Q2" by (auto simp add: norm_PX1[of Q1 y Q2] norm_PX2[of Q1 y Q2])
  13.329 +  ultimately have "isnorm (mul (P1, Q1))" "isnorm (mul (P2, Q2))" "isnorm (mul (P1, mkPinj 1 Q2))" "isnorm (mul (Q1, mkPinj 1 P2))" 
  13.330 +    by (auto simp add: mkPinj_cn)
  13.331 +  with prems X0 Y0 have "isnorm (mkPX (mul (P1, Q1)) (x + y) (mul (P2, Q2)))" "isnorm (mkPX (mul (P1, mkPinj (Suc 0) Q2)) x (Pc 0))"  
  13.332 +    "isnorm (mkPX (mul (Q1, mkPinj (Suc 0) P2)) y (Pc 0))" 
  13.333 +    by (auto simp add: mkPX_cn)
  13.334 +  thus ?case by (simp add: add_cn)
  13.335 +qed(simp)
  13.336 +
  13.337 +    (* neg conserves normalizedness *)
  13.338 +lemma neg_cn: "isnorm P \<Longrightarrow> isnorm (neg P)"
  13.339 +proof(induct P rule: neg.induct)
  13.340 +  case (Pinj i P2)
  13.341 +  from prems have "isnorm P2" by (simp add: norm_Pinj[of i P2])
  13.342 +  with prems show ?case by(cases P2, auto, cases i, auto)
  13.343 +next
  13.344 +  case (PX P1 x P2)
  13.345 +  from prems have "isnorm P2" "isnorm P1" by (auto simp add: norm_PX1[of P1 x P2] norm_PX2[of P1 x P2])
  13.346 +  with prems show ?case
  13.347 +  proof(cases P1)
  13.348 +    case (PX p1 y p2)
  13.349 +    with prems show ?thesis by(cases x, auto, cases p2, auto)
  13.350 +  next
  13.351 +    case Pinj
  13.352 +    with prems show ?thesis by(cases x, auto)
  13.353 +  qed(cases x, auto)
  13.354 +qed(simp)
  13.355 +
  13.356 +    (* sub conserves normalizedness *)
  13.357 +lemma sub_cn:"\<lbrakk>isnorm p; isnorm q\<rbrakk> \<Longrightarrow> isnorm (sub p q)"
  13.358 +by (simp add: sub_def add_cn neg_cn)
  13.359 +
  13.360 +  (* sqr conserves normalizizedness *)
  13.361 +lemma sqr_cn:"isnorm P \<Longrightarrow> isnorm (sqr P)"
  13.362 +proof(induct P)
  13.363 +  case (Pinj i Q)
  13.364 +  from prems show ?case by(cases Q, auto simp add: mkPX_cn mkPinj_cn, cases i, auto simp add: mkPX_cn mkPinj_cn)
  13.365 +next 
  13.366 +  case (PX P1 x P2)
  13.367 +  from prems have "x+x~=0" "isnorm P2" "isnorm P1" by (cases x,  auto simp add: norm_PX1[of P1 x P2] norm_PX2[of P1 x P2])
  13.368 +  with prems have "isnorm (mkPX (mul (mul (Pc ((1\<Colon>'a) + (1\<Colon>'a)), P1), mkPinj (Suc 0) P2)) x (Pc (0\<Colon>'a)))"
  13.369 +              and "isnorm (mkPX (sqr P1) (x + x) (sqr P2))" by( auto simp add: add_cn mkPX_cn mkPinj_cn mul_cn)
  13.370 +  thus ?case by( auto simp add: add_cn mkPX_cn mkPinj_cn mul_cn)
  13.371 +qed(simp)
  13.372 +
  13.373 +
  13.374 +    (* pow conserves normalizedness  *)
  13.375 +lemma pow_cn:"!! P. \<lbrakk>isnorm P\<rbrakk> \<Longrightarrow> isnorm (pow (P, n))"
  13.376 +proof(induct n rule: nat_less_induct)
  13.377 +  case (1 k)
  13.378 +  show ?case 
  13.379 +  proof(cases "k=0")
  13.380 +    case False
  13.381 +    hence K2:"k div 2 < k" by (cases k, auto)
  13.382 +    from prems have "isnorm (sqr P)" by (simp add: sqr_cn)
  13.383 +    with prems K2 show ?thesis by(simp add: allE[of _ "(k div 2)" _] allE[of _ "(sqr P)" _], cases k, auto simp add: mul_cn)
  13.384 +  qed(simp)
  13.385 +qed
  13.386 +
  13.387 +end
  13.388 \ No newline at end of file
    14.1 --- a/src/HOL/ex/ROOT.ML	Wed Sep 14 10:24:39 2005 +0200
    14.2 +++ b/src/HOL/ex/ROOT.ML	Wed Sep 14 17:25:52 2005 +0200
    14.3 @@ -25,6 +25,7 @@
    14.4  time_use_thy "CTL";
    14.5  time_use_thy "mesontest2";
    14.6  time_use_thy "PresburgerEx";
    14.7 +time_use_thy "Reflected_Presburger";
    14.8  time_use_thy "BT";
    14.9  time_use_thy "InSort";
   14.10  time_use_thy "Qsort";
   14.11 @@ -33,6 +34,8 @@
   14.12  
   14.13  
   14.14  time_use_thy "Lagrange";
   14.15 +time_use_thy "Commutative_RingEx";
   14.16 +time_use_thy "Commutative_Ring_Complete";
   14.17  
   14.18  time_use_thy "set";
   14.19  time_use_thy "MT";
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/src/HOL/ex/Reflected_Presburger.thy	Wed Sep 14 17:25:52 2005 +0200
    15.3 @@ -0,0 +1,5726 @@
    15.4 +(* A formalization of quantifier elimination for Presburger arithmetic*)
    15.5 +(* based on a generic quantifier elimination algorithm and 
    15.6 +   cooper's methos to eliminate on \<exists> *)
    15.7 +
    15.8 +theory Reflected_Presburger
    15.9 +imports Main
   15.10 +uses ("rcooper.ML") ("rpresbtac.ML")
   15.11 +begin
   15.12 +
   15.13 +(* Shadow syntax for integer terms *)
   15.14 +datatype intterm =
   15.15 +    Cst int
   15.16 +  | Var nat
   15.17 +  | Neg intterm
   15.18 +  | Add intterm intterm 
   15.19 +  | Sub intterm intterm
   15.20 +  | Mult intterm intterm
   15.21 +
   15.22 +(* interpretatation of intterms , takes bound variables and free variables *)
   15.23 +consts I_intterm :: "int list \<Rightarrow> intterm \<Rightarrow> int"
   15.24 +primrec 
   15.25 +"I_intterm ats (Cst b) = b"
   15.26 +"I_intterm ats (Var n) = (ats!n)"
   15.27 +"I_intterm ats (Neg it) = -(I_intterm ats it)"
   15.28 +"I_intterm ats (Add it1 it2) = (I_intterm ats it1) + (I_intterm ats it2)" 
   15.29 +"I_intterm ats (Sub it1 it2) = (I_intterm ats it1) - (I_intterm ats it2)"
   15.30 +"I_intterm ats (Mult it1 it2) = (I_intterm ats it1) * (I_intterm ats it2)"
   15.31 +
   15.32 +(*Shadow syntax for Presburger formulae *)
   15.33 +datatype QF = 
   15.34 +   Lt intterm intterm
   15.35 +  |Gt intterm intterm
   15.36 +  |Le intterm intterm
   15.37 +  |Ge intterm intterm
   15.38 +  |Eq intterm intterm
   15.39 +  |Divides intterm intterm
   15.40 +  |T
   15.41 +  |F
   15.42 +  |NOT QF
   15.43 +  |And QF QF
   15.44 +  |Or QF QF
   15.45 +  |Imp QF QF
   15.46 +  |Equ QF QF
   15.47 +  |QAll QF
   15.48 +  |QEx QF
   15.49 +
   15.50 +(* Interpretation of Presburger  formulae *)
   15.51 +consts qinterp :: "int list \<Rightarrow> QF \<Rightarrow> bool"
   15.52 +primrec
   15.53 +"qinterp ats (Lt it1 it2) = (I_intterm ats it1 < I_intterm ats it2)"
   15.54 +"qinterp ats (Gt it1 it2) = (I_intterm ats it1 > I_intterm ats it2)"
   15.55 +"qinterp ats (Le it1 it2) = (I_intterm ats it1 \<le> I_intterm ats it2)"
   15.56 +"qinterp ats (Ge it1 it2) = (I_intterm ats it1 \<ge> I_intterm ats it2)"
   15.57 +"qinterp ats (Divides it1 it2) = (I_intterm ats it1 dvd I_intterm ats it2)"
   15.58 +"qinterp ats (Eq it1 it2) = (I_intterm ats it1 = I_intterm ats it2)"
   15.59 +"qinterp ats T = True"
   15.60 +"qinterp ats F = False"
   15.61 +"qinterp ats (NOT p) = (\<not>(qinterp ats p))"
   15.62 +"qinterp ats (And p q) = (qinterp ats p \<and> qinterp ats q)"
   15.63 +"qinterp ats (Or p q) = (qinterp ats p \<or> qinterp ats q)"
   15.64 +"qinterp ats (Imp p q) = (qinterp ats p \<longrightarrow> qinterp ats q)"
   15.65 +"qinterp ats (Equ p q) = (qinterp ats p = qinterp ats q)"
   15.66 +"qinterp ats (QAll p) = (\<forall>x. qinterp (x#ats) p)"
   15.67 +"qinterp ats (QEx p) = (\<exists>x. qinterp (x#ats) p)"
   15.68 +
   15.69 +(* quantifier elimination based on qe, quantifier elimination for an
   15.70 +   existential formula, with quantifier free body 
   15.71 +   Since quantifier elimination for one formula is allowed to fail, 
   15.72 +   the reult is of type QF option *)
   15.73 +
   15.74 +consts lift_bin:: "('a \<Rightarrow> 'a \<Rightarrow> 'b) \<times> 'a option \<times> 'a option \<Rightarrow> 'b option"
   15.75 +recdef lift_bin "measure (\<lambda>(c,a,b). size a)"
   15.76 +"lift_bin (c,Some a,Some b) = Some (c a b)"
   15.77 +"lift_bin (c,x, y)  = None"
   15.78 +
   15.79 +lemma lift_bin_Some:
   15.80 +  assumes ls: "lift_bin (c,x,y) = Some t"
   15.81 +  shows "(\<exists>a. x = Some a) \<and> (\<exists>b. y = Some b)"
   15.82 +  using ls 
   15.83 +  by (cases "x", auto) (cases "y", auto)+
   15.84 +
   15.85 +consts lift_un:: "('a \<Rightarrow> 'b) \<Rightarrow> 'a option \<Rightarrow> 'b option"
   15.86 +primrec
   15.87 +"lift_un c None = None"
   15.88 +"lift_un c (Some p) = Some (c p)"
   15.89 +
   15.90 +consts lift_qe:: "('a \<Rightarrow> 'b option) \<Rightarrow> 'a option \<Rightarrow> 'b option"
   15.91 +primrec
   15.92 +"lift_qe qe None = None"
   15.93 +"lift_qe qe (Some p) = qe p"
   15.94 +
   15.95 +(* generic quantifier elimination *)
   15.96 +consts qelim :: "(QF \<Rightarrow> QF option) \<times> QF \<Rightarrow> QF option"
   15.97 +recdef qelim "measure (\<lambda>(qe,p). size p)"
   15.98 +"qelim (qe, (QAll p)) = lift_un NOT (lift_qe qe (lift_un NOT (qelim (qe ,p))))"
   15.99 +"qelim (qe, (QEx p)) = lift_qe qe (qelim (qe,p))"
  15.100 +"qelim (qe, (And p q)) = lift_bin (And, (qelim (qe, p)), (qelim (qe, q)))"
  15.101 +"qelim (qe, (Or p q)) = lift_bin (Or, (qelim (qe, p)), (qelim (qe, q)))"
  15.102 +"qelim (qe, (Imp p q)) = lift_bin (Imp, (qelim (qe, p)), (qelim (qe, q)))"
  15.103 +"qelim (qe, (Equ p q)) = lift_bin (Equ, (qelim (qe, p)), (qelim (qe, q)))"
  15.104 +"qelim (qe,NOT p) = lift_un NOT (qelim (qe,p))"
  15.105 +"qelim (qe, p) = Some p"
  15.106 +
  15.107 +(* quantifier free-ness *)
  15.108 +consts isqfree :: "QF \<Rightarrow> bool"
  15.109 +recdef isqfree "measure size"
  15.110 +"isqfree (QAll p) = False"
  15.111 +"isqfree (QEx p) = False"
  15.112 +"isqfree (And p q) = (isqfree p \<and> isqfree q)"
  15.113 +"isqfree (Or p q) = (isqfree p \<and> isqfree q)"
  15.114 +"isqfree (Imp p q) = (isqfree p \<and> isqfree q)"
  15.115 +"isqfree (Equ p q) = (isqfree p \<and> isqfree q)"
  15.116 +"isqfree (NOT p) = isqfree p"
  15.117 +"isqfree p = True"
  15.118 +
  15.119 +(* qelim lifts quantifierfreeness*)
  15.120 +lemma qelim_qfree: 
  15.121 +  assumes qeqf: "(\<And> q q'. \<lbrakk>isqfree q ; qe q = Some q'\<rbrakk> \<Longrightarrow>  isqfree q')"
  15.122 +  shows qff:"\<And> p'. qelim (qe, p) = Some p' \<Longrightarrow> isqfree p'"
  15.123 +  using qeqf
  15.124 +proof (induct p)
  15.125 +  case (Lt a b)
  15.126 +  have "qelim (qe, Lt a b) = Some (Lt a b)" by simp
  15.127 +  moreover have "qelim (qe,Lt a b) = Some p'" . 
  15.128 +  ultimately have "p' = Lt a b" by simp
  15.129 +  moreover have "isqfree (Lt a b)" by simp
  15.130 +  ultimately 
  15.131 +  show ?case  by simp
  15.132 +next  
  15.133 +  case (Gt a b)
  15.134 +  have "qelim (qe, Gt a b) = Some (Gt a b)" by simp
  15.135 +  moreover have "qelim (qe,Gt a b) = Some p'" . 
  15.136 +  ultimately have "p' = Gt a b" by simp
  15.137 +  moreover have "isqfree (Gt a b)" by simp
  15.138 +  ultimately 
  15.139 +  show ?case  by simp
  15.140 +next  
  15.141 +  case (Le a b)
  15.142 +  have "qelim (qe, Le a b) = Some (Le a b)" by simp
  15.143 +  moreover have "qelim (qe,Le a b) = Some p'" . 
  15.144 +  ultimately have "p' = Le a b" by simp
  15.145 +  moreover have "isqfree (Le a b)" by simp
  15.146 +  ultimately 
  15.147 +  show ?case  by simp
  15.148 +next  
  15.149 +  case (Ge a b)
  15.150 +  have "qelim (qe, Ge a b) = Some (Ge a b)" by simp
  15.151 +  moreover have "qelim (qe,Ge a b) = Some p'" . 
  15.152 +  ultimately have "p' = Ge a b" by simp
  15.153 +  moreover have "isqfree (Ge a b)" by simp
  15.154 +  ultimately 
  15.155 +  show ?case  by simp
  15.156 +next  
  15.157 +  case (Eq a b)
  15.158 +  have "qelim (qe, Eq a b) = Some (Eq a b)" by simp
  15.159 +  moreover have "qelim (qe,Eq a b) = Some p'" . 
  15.160 +  ultimately have "p' = Eq a b" by simp
  15.161 +  moreover have "isqfree (Eq a b)" by simp
  15.162 +  ultimately 
  15.163 +  show ?case  by simp
  15.164 +next  
  15.165 +  case (Divides a b)
  15.166 +  have "qelim (qe, Divides a b) = Some (Divides a b)" by simp
  15.167 +  moreover have "qelim (qe,Divides a b) = Some p'" . 
  15.168 +  ultimately have "p' = Divides a b" by simp
  15.169 +  moreover have "isqfree (Divides a b)" by simp
  15.170 +  ultimately 
  15.171 +  show ?case  by simp
  15.172 +next  
  15.173 +  case T 
  15.174 +  have "qelim(qe,T) = Some T" by simp
  15.175 +  moreover have "qelim(qe,T) = Some p'" .
  15.176 +  ultimately have "p' = T" by simp
  15.177 +  moreover have "isqfree T" by simp
  15.178 +  ultimately show ?case by simp
  15.179 +next  
  15.180 +  case F
  15.181 +  have "qelim(qe,F) = Some F" by simp
  15.182 +  moreover have "qelim(qe,F) = Some p'" .
  15.183 +  ultimately have "p' = F" by simp
  15.184 +  moreover have "isqfree F" by simp
  15.185 +  ultimately show ?case by simp
  15.186 +next  
  15.187 +  case (NOT p)
  15.188 +  from "NOT.prems" have "\<exists> p1. qelim(qe,p) = Some p1"
  15.189 +    by  (cases "qelim(qe,p)") simp_all
  15.190 +  then obtain "p1" where p1_def: "qelim(qe,p) = Some p1" by blast
  15.191 +  from "NOT.prems" have "\<And>q q'. \<lbrakk>isqfree q; qe q = Some q'\<rbrakk> \<Longrightarrow> isqfree q'" 
  15.192 +    by blast
  15.193 +  with "NOT.hyps" p1_def have p1qf: "isqfree p1" by blast
  15.194 +  then have "p' = NOT p1" using "NOT.prems" p1_def
  15.195 +    by (cases "qelim(qe,NOT p)") simp_all
  15.196 +  then show ?case using p1qf by simp
  15.197 +next  
  15.198 +  case (And p q) 
  15.199 +  from "And.prems" have p1q1: "(\<exists>p1. qelim(qe,p) = Some p1) \<and> 
  15.200 +    (\<exists>q1. qelim(qe,q) = Some q1)" using lift_bin_Some[where c="And"] by simp
  15.201 +  from p1q1 obtain "p1" and "q1" 
  15.202 +    where p1_def: "qelim(qe,p) = Some p1" 
  15.203 +    and q1_def: "qelim(qe,q) = Some q1" by blast
  15.204 +  from prems have qf1:"isqfree p1"
  15.205 +    using p1_def by blast
  15.206 +  from prems have qf2:"isqfree q1"
  15.207 +    using q1_def by blast
  15.208 +  from "And.prems" have "qelim(qe,And p q) = Some p'" by blast
  15.209 +  then have "p' = And p1 q1" using p1_def q1_def by simp
  15.210 +  then 
  15.211 +  show ?case using qf1 qf2 by simp
  15.212 +next  
  15.213 +  case (Or p q)
  15.214 +  from "Or.prems" have p1q1: "(\<exists>p1. qelim(qe,p) = Some p1) \<and> 
  15.215 +    (\<exists>q1. qelim(qe,q) = Some q1)" using lift_bin_Some[where c="Or"] by simp
  15.216 +  from p1q1 obtain "p1" and "q1" 
  15.217 +    where p1_def: "qelim(qe,p) = Some p1" 
  15.218 +    and q1_def: "qelim(qe,q) = Some q1" by blast
  15.219 +  from prems have qf1:"isqfree p1"
  15.220 +    using p1_def by blast
  15.221 +  from prems have qf2:"isqfree q1"
  15.222 +    using q1_def by blast
  15.223 +  from "Or.prems" have "qelim(qe,Or p q) = Some p'" by blast
  15.224 +  then have "p' = Or p1 q1" using p1_def q1_def by simp
  15.225 +  then 
  15.226 +  show ?case using qf1 qf2 by simp
  15.227 +next  
  15.228 +  case (Imp p q)
  15.229 +  from "Imp.prems" have p1q1: "(\<exists>p1. qelim(qe,p) = Some p1) \<and> 
  15.230 +    (\<exists>q1. qelim(qe,q) = Some q1)" using lift_bin_Some[where c="Imp"] by simp
  15.231 +  from p1q1 obtain "p1" and "q1" 
  15.232 +    where p1_def: "qelim(qe,p) = Some p1" 
  15.233 +    and q1_def: "qelim(qe,q) = Some q1" by blast
  15.234 +  from prems have qf1:"isqfree p1"
  15.235 +    using p1_def by blast
  15.236 +  from prems have qf2:"isqfree q1"
  15.237 +    using q1_def by blast
  15.238 +  from "Imp.prems" have "qelim(qe,Imp p q) = Some p'" by blast
  15.239 +  then have "p' = Imp p1 q1" using p1_def q1_def by simp
  15.240 +  then 
  15.241 +  show ?case using qf1 qf2 by simp
  15.242 +next  
  15.243 +  case (Equ p q)
  15.244 +  from "Equ.prems" have p1q1: "(\<exists>p1. qelim(qe,p) = Some p1) \<and> 
  15.245 +    (\<exists>q1. qelim(qe,q) = Some q1)" using lift_bin_Some[where c="Equ"] by simp
  15.246 +  from p1q1 obtain "p1" and "q1" 
  15.247 +    where p1_def: "qelim(qe,p) = Some p1" 
  15.248 +    and q1_def: "qelim(qe,q) = Some q1" by blast
  15.249 +  from prems have qf1:"isqfree p1"
  15.250 +    using p1_def by blast
  15.251 +  from prems have qf2:"isqfree q1"
  15.252 +    using q1_def by blast
  15.253 +  from "Equ.prems" have "qelim(qe,Equ p q) = Some p'" by blast
  15.254 +  then have "p' = Equ p1 q1" using p1_def q1_def by simp
  15.255 +  then 
  15.256 +  show ?case using qf1 qf2 by simp
  15.257 +next 
  15.258 +  case (QEx p)
  15.259 +  from "QEx.prems" have "\<exists> p1. qelim(qe,p) = Some p1"
  15.260 +    by  (cases "qelim(qe,p)") simp_all
  15.261 +  then obtain "p1" where p1_def: "qelim(qe,p) = Some p1" by blast
  15.262 +  from "QEx.prems" have "\<And>q q'. \<lbrakk>isqfree q; qe q = Some q'\<rbrakk> \<Longrightarrow> isqfree q'" 
  15.263 +    by blast
  15.264 +  with "QEx.hyps" p1_def have p1qf: "isqfree p1" by blast
  15.265 +  from "QEx.prems" have "qe p1 = Some p'" using p1_def by simp
  15.266 +  with "QEx.prems" show ?case  using p1qf 
  15.267 +    by simp
  15.268 +next 
  15.269 +  case (QAll p) 
  15.270 +  from "QAll.prems"
  15.271 +  have "\<exists> p1. lift_qe qe (lift_un NOT (qelim (qe ,p))) = Some p1" 
  15.272 +    by (cases "lift_qe qe (lift_un NOT (qelim (qe ,p)))") simp_all
  15.273 +  then obtain "p1" where 
  15.274 +    p1_def:"lift_qe qe (lift_un NOT (qelim (qe ,p))) = Some p1" by blast
  15.275 +  then have "\<exists> p2. lift_un NOT (qelim (qe ,p)) = Some p2"
  15.276 +    by (cases "qelim (qe ,p)") simp_all
  15.277 +  then obtain "p2" 
  15.278 +    where p2_def:"lift_un NOT (qelim (qe ,p)) = Some p2" by blast
  15.279 +  then have "\<exists> p3. qelim(qe,p) = Some p3" by (cases "qelim(qe,p)") simp_all
  15.280 +  then obtain "p3" where p3_def: "qelim(qe,p) = Some p3" by blast
  15.281 +  with prems have qf3: "isqfree p3" by blast
  15.282 +  have p2_def2: "p2 = NOT p3" using p2_def p3_def by simp
  15.283 +  then have qf2: "isqfree p2" using qf3 by simp
  15.284 +  have p1_edf2: "qe p2 = Some p1" using p1_def p2_def by simp
  15.285 +  with "QAll.prems" have qf1: "isqfree p1" using qf2 by blast
  15.286 +  from "QAll.prems" have "p' = NOT p1" using p1_def by simp
  15.287 +  with qf1 show ?case by simp
  15.288 +qed
  15.289 +
  15.290 +(* qelim lifts semantical equivalence *)
  15.291 +lemma qelim_corr: 
  15.292 +  assumes qecorr: "(\<And> q q' ats. \<lbrakk>isqfree q ; qe q = Some q'\<rbrakk> \<Longrightarrow>  (qinterp ats (QEx q)) = (qinterp ats q'))"
  15.293 +  and qeqf: "(\<And> q q'. \<lbrakk>isqfree q ; qe q = Some q'\<rbrakk> \<Longrightarrow>  isqfree q')"
  15.294 +  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')")
  15.295 +  using qeqf qecorr
  15.296 +proof (induct p)
  15.297 +  case (NOT f)  
  15.298 +  from "NOT.prems" have "\<exists>f'. ?Qe f f' " by (cases "qelim(qe,f)") simp_all
  15.299 +  then obtain "f'" where df': "?Qe f f'" by blast
  15.300 +  with prems have feqf': "?F ats f = ?F ats f'" by blast
  15.301 +  from "NOT.prems" df' have "p' = NOT f'" by simp
  15.302 +  with feqf' show ?case by simp
  15.303 +
  15.304 +next
  15.305 +  case (And f g) 
  15.306 +  from "And.prems" have f1g1: "(\<exists>f1. qelim(qe,f) = Some f1) \<and> 
  15.307 +    (\<exists>g1. qelim(qe,g) = Some g1)" using lift_bin_Some[where c="And"] by simp
  15.308 +  from f1g1 obtain "f1" and "g1" 
  15.309 +    where f1_def: "qelim(qe, f) = Some f1" 
  15.310 +    and g1_def: "qelim(qe,g) = Some g1" by blast
  15.311 +  from prems f1_def have feqf1: "?F ats f = ?F ats f1" by blast
  15.312 +  from prems g1_def have geqg1: "?F ats g = ?F ats g1" by blast
  15.313 +  from "And.prems" f1_def g1_def have "p' = And f1 g1" by simp
  15.314 +  with feqf1 geqg1 show ?case by simp
  15.315 +
  15.316 +next
  15.317 +  case (Or f g) 
  15.318 +  from "Or.prems" have f1g1: "(\<exists>f1. qelim(qe,f) = Some f1) \<and> 
  15.319 +    (\<exists>g1. qelim(qe,g) = Some g1)" using lift_bin_Some[where c="Or"] by simp
  15.320 +  from f1g1 obtain "f1" and "g1" 
  15.321 +    where f1_def: "qelim(qe, f) = Some f1" 
  15.322 +    and g1_def: "qelim(qe,g) = Some g1" by blast
  15.323 +  from prems f1_def have feqf1: "?F ats f = ?F ats  f1" by blast
  15.324 +  from prems g1_def have geqg1: "?F ats g = ?F ats g1" by blast
  15.325 +  from "Or.prems" f1_def g1_def have "p' = Or f1 g1" by simp
  15.326 +  with feqf1 geqg1 show ?case by simp
  15.327 +next
  15.328 +  case (Imp f g)
  15.329 +  from "Imp.prems" have f1g1: "(\<exists>f1. qelim(qe,f) = Some f1) \<and> 
  15.330 +    (\<exists>g1. qelim(qe,g) = Some g1)" using lift_bin_Some[where c="Imp"] by simp
  15.331 +  from f1g1 obtain "f1" and "g1" 
  15.332 +    where f1_def: "qelim(qe, f) = Some f1" 
  15.333 +    and g1_def: "qelim(qe,g) = Some g1" by blast
  15.334 +  from prems f1_def have feqf1: "?F ats f = ?F ats f1" by blast
  15.335 +  from prems g1_def have geqg1: "?F ats g = ?F ats g1" by blast
  15.336 +  from "Imp.prems" f1_def g1_def have "p' = Imp f1 g1" by simp
  15.337 +  with feqf1 geqg1 show ?case by simp
  15.338 +next
  15.339 +  case (Equ f g)
  15.340 +  from "Equ.prems" have f1g1: "(\<exists>f1. qelim(qe,f) = Some f1) \<and> 
  15.341 +    (\<exists>g1. qelim(qe,g) = Some g1)" using lift_bin_Some[where c="Equ"] by simp
  15.342 +  from f1g1 obtain "f1" and "g1" 
  15.343 +    where f1_def: "qelim(qe, f) = Some f1" 
  15.344 +    and g1_def: "qelim(qe,g) = Some g1" by blast
  15.345 +  from prems f1_def have feqf1: "?F ats f = ?F ats f1" by blast
  15.346 +  from prems g1_def have geqg1: "?F ats g = ?F ats g1" by blast
  15.347 +  from "Equ.prems" f1_def g1_def have "p' = Equ f1 g1" by simp
  15.348 +  with feqf1 geqg1 show ?case by simp
  15.349 +next
  15.350 +  case (QEx f) 
  15.351 +    from "QEx.prems" have "\<exists> f1. ?Qe f f1"
  15.352 +    by  (cases "qelim(qe,f)") simp_all
  15.353 +  then obtain "f1" where f1_def: "qelim(qe,f) = Some f1" by blast
  15.354 +  from prems have qf1:"isqfree f1" using qelim_qfree by blast
  15.355 +  from prems have feqf1: "\<forall> ats. qinterp ats f = qinterp ats f1"
  15.356 +    using f1_def qf1 by blast
  15.357 +  then  have "?F ats (QEx f) = ?F ats (QEx f1)" 
  15.358 +    by simp 
  15.359 +  from prems have "qelim (qe,QEx f) = Some p'" by blast
  15.360 +  then  have "\<exists> f'. qe f1 = Some f'" using f1_def by simp
  15.361 +  then obtain "f'" where fdef': "qe f1 = Some f'" by blast
  15.362 +  with prems have exf1: "?F ats (QEx f1) = ?F ats f'" using qf1 by blast
  15.363 +  have fp: "?Qe (QEx f) f'" using f1_def fdef' by simp
  15.364 +  from prems have "?Qe (QEx f) p'" by blast 
  15.365 +  then have "p' = f'" using fp by simp
  15.366 +  then show ?case using feqf1 exf1 by simp
  15.367 +next
  15.368 +  case (QAll f)
  15.369 +  from "QAll.prems"
  15.370 +  have "\<exists> f0. lift_un NOT (lift_qe qe (lift_un NOT (qelim (qe ,f)))) = 
  15.371 +    Some f0"
  15.372 +    by (cases "lift_un NOT (lift_qe qe (lift_un NOT (qelim (qe ,f))))") 
  15.373 +      simp_all
  15.374 +  then obtain "f0" 
  15.375 +    where f0_def: "lift_un NOT (lift_qe qe (lift_un NOT (qelim (qe ,f)))) = 
  15.376 +    Some f0" by blast
  15.377 +  then have "\<exists> f1. lift_qe qe (lift_un NOT (qelim (qe ,f))) = Some f1" 
  15.378 +    by (cases "lift_qe qe (lift_un NOT (qelim (qe ,f)))") simp_all
  15.379 +  then obtain "f1" where 
  15.380 +    f1_def:"lift_qe qe (lift_un NOT (qelim (qe ,f))) = Some f1" by blast
  15.381 +  then have "\<exists> f2. lift_un NOT (qelim (qe ,f)) = Some f2"
  15.382 +    by (cases "qelim (qe ,f)") simp_all
  15.383 +  then obtain "f2" 
  15.384 +    where f2_def:"lift_un NOT (qelim (qe ,f)) = Some f2" by blast
  15.385 +  then have "\<exists> f3. qelim(qe,f) = Some f3" by (cases "qelim(qe,f)") simp_all
  15.386 +  then obtain "f3" where f3_def: "qelim(qe,f) = Some f3" by blast
  15.387 +  from prems have qf3:"isqfree f3" using qelim_qfree by blast
  15.388 +  from prems have feqf3: "\<forall> ats. qinterp ats f = qinterp ats f3"
  15.389 +    using f3_def qf3 by blast
  15.390 +  have f23:"f2 = NOT f3" using f2_def f3_def by simp
  15.391 +  then have feqf2: "\<forall> ats. qinterp ats f = qinterp ats (NOT f2)"
  15.392 +    using feqf3 by simp
  15.393 +  have qf2: "isqfree f2" using f23 qf3 by simp
  15.394 +  have "qe f2 = Some f1" using f1_def f2_def f23 by simp
  15.395 +  with prems have exf2eqf1: "?F ats (QEx f2) = ?F ats f1" using qf2 by blast
  15.396 +  have "f0 = NOT f1" using f0_def f1_def by simp
  15.397 +  then have f0eqf1: "?F ats f0 = ?F ats (NOT f1)" by simp
  15.398 +  from prems have "qelim (qe, QAll f) = Some p'" by blast
  15.399 +  then have f0eqp': "p' = f0" using f0_def by simp
  15.400 +  have "?F ats (QAll f) = (\<forall>x. ?F (x#ats) f)" by simp
  15.401 +  also have "\<dots> = (\<not> (\<exists> x. ?F (x#ats) (NOT f)))" by simp
  15.402 +  also have "\<dots> = (\<not> (\<exists> x. ?F (x#ats) (NOT (NOT f2))))" using feqf2
  15.403 +    by auto
  15.404 +  also have "\<dots> = (\<not> (\<exists> x. ?F (x#ats) f2))" by simp
  15.405 +  also have "\<dots> = (\<not> (?F ats f1))" using exf2eqf1 by simp
  15.406 +  finally show ?case using f0eqp' f0eqf1 by simp
  15.407 +qed simp_all
  15.408 +
  15.409 +(* Cooper's algorithm *)
  15.410 +
  15.411 +
  15.412 +(* Transform an intform into NNF *)
  15.413 +consts lgth :: "QF \<Rightarrow> nat"
  15.414 +       nnf :: "QF \<Rightarrow> QF"    
  15.415 +primrec
  15.416 +"lgth (Lt it1 it2) = 1"
  15.417 +"lgth (Gt it1 it2) = 1"
  15.418 +"lgth (Le it1 it2) = 1"
  15.419 +"lgth (Ge it1 it2) = 1"
  15.420 +"lgth (Eq it1 it2) = 1"
  15.421 +"lgth (Divides it1 it2) = 1"
  15.422 +"lgth T = 1"
  15.423 +"lgth F = 1"
  15.424 +"lgth (NOT p) = 1 + lgth p"
  15.425 +"lgth (And p q) = 1 + lgth p + lgth q"
  15.426 +"lgth (Or p q) = 1 + lgth p + lgth q"
  15.427 +"lgth (Imp p q) = 1 + lgth p + lgth q"
  15.428 +"lgth (Equ p q) = 1 + lgth p + lgth q" 
  15.429 +"lgth (QAll p) = 1 + lgth p" 
  15.430 +"lgth (QEx p) = 1 + lgth p" 
  15.431 +
  15.432 +lemma [simp] :"0 < lgth q"
  15.433 +apply (induct_tac q)
  15.434 +apply(auto)
  15.435 +done
  15.436 +
  15.437 +(* NNF *)
  15.438 +recdef nnf "measure (\<lambda>p. lgth p)"
  15.439 +  "nnf (Lt it1 it2) = Le (Sub it1 it2) (Cst (- 1))"
  15.440 +  "nnf (Gt it1 it2) = Le (Sub it2 it1) (Cst (- 1))"
  15.441 +  "nnf (Le it1 it2) = Le it1 it2 "
  15.442 +  "nnf (Ge it1 it2) = Le it2 it1"
  15.443 +  "nnf (Eq it1 it2) = Eq it2 it1"
  15.444 +  "nnf (Divides d t) = Divides d t"
  15.445 +  "nnf T = T"
  15.446 +  "nnf F = F"
  15.447 +  "nnf (And p q) = And (nnf p) (nnf q)"
  15.448 +  "nnf (Or p q) = Or (nnf p) (nnf q)"
  15.449 +  "nnf (Imp p q) = Or (nnf (NOT p)) (nnf q)"
  15.450 +  "nnf (Equ p q) = Or (And (nnf p) (nnf q)) 
  15.451 +  (And (nnf (NOT p)) (nnf (NOT q)))"
  15.452 +  "nnf (NOT (Lt it1 it2)) = (Le it2 it1)"
  15.453 +  "nnf (NOT (Gt it1 it2))  = (Le it1 it2)"
  15.454 +  "nnf (NOT (Le it1 it2)) = (Le (Sub it2 it1) (Cst (- 1)))"
  15.455 +  "nnf (NOT (Ge it1 it2)) = (Le (Sub it1 it2) (Cst (- 1)))"
  15.456 +  "nnf (NOT (Eq it1 it2)) = (NOT (Eq it1 it2))"
  15.457 +  "nnf (NOT (Divides d t)) = (NOT (Divides d t))"
  15.458 +  "nnf (NOT T) = F"
  15.459 +  "nnf (NOT F) = T"
  15.460 +  "nnf (NOT (NOT p)) = (nnf p)"
  15.461 +  "nnf (NOT (And p q)) = (Or (nnf (NOT p)) (nnf (NOT q)))"
  15.462 +  "nnf (NOT (Or p q)) = (And (nnf (NOT p)) (nnf (NOT q)))"
  15.463 +  "nnf (NOT (Imp p q)) = (And (nnf p) (nnf (NOT q)))"
  15.464 +  "nnf (NOT (Equ p q)) = (Or (And (nnf p) (nnf (NOT q))) (And (nnf (NOT p)) (nnf q)))"
  15.465 +
  15.466 +consts isnnf :: "QF \<Rightarrow> bool"
  15.467 +recdef isnnf "measure (\<lambda>p. lgth p)"
  15.468 +  "isnnf (Le it1 it2) = True"
  15.469 +  "isnnf (Eq it1 it2) = True"
  15.470 +  "isnnf (Divides d t) = True"
  15.471 +  "isnnf T = True"
  15.472 +  "isnnf F = True"
  15.473 +  "isnnf (And p q) = (isnnf p \<and> isnnf q)"
  15.474 +  "isnnf (Or p q) = (isnnf p \<and> isnnf q)"
  15.475 +  "isnnf (NOT (Divides d t)) = True" 
  15.476 +  "isnnf (NOT (Eq it1 it2)) = True" 
  15.477 +  "isnnf p = False"
  15.478 +
  15.479 +(* nnf preserves semantics *)
  15.480 +lemma nnf_corr: "isqfree p \<Longrightarrow> qinterp ats p = qinterp ats (nnf p)"
  15.481 +by (induct p rule: nnf.induct,simp_all) 
  15.482 +(arith, arith, arith, arith, arith, arith, arith, arith, arith, blast)
  15.483 +
  15.484 +
  15.485 +(* the result of nnf is in NNF *)
  15.486 +lemma nnf_isnnf : "isqfree p \<Longrightarrow> isnnf (nnf p)"
  15.487 +by (induct p rule: nnf.induct, auto)
  15.488 +
  15.489 +lemma nnf_isqfree: "isnnf p \<Longrightarrow> isqfree p"
  15.490 +by (induct p rule: isnnf.induct) auto
  15.491 +
  15.492 +(* nnf preserves quantifier freeness *)
  15.493 +lemma nnf_qfree: "isqfree p \<Longrightarrow> isqfree(nnf p)"
  15.494 +  using nnf_isqfree nnf_isnnf by simp
  15.495 +
  15.496 +(* Linearization and normalization of formulae *)
  15.497 +(* Definition of linearity of an intterm *)
  15.498 +
  15.499 +consts islinintterm :: "intterm \<Rightarrow> bool"
  15.500 +recdef islinintterm "measure size"
  15.501 +"islinintterm (Cst i) = True"
  15.502 +"islinintterm (Add (Mult (Cst i) (Var n)) (Cst i')) = (i \<noteq> 0)"
  15.503 +"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))"
  15.504 +"islinintterm i = False"
  15.505 +
  15.506 +(* subterms of linear terms are linear *)
  15.507 +lemma islinintterm_subt:
  15.508 +  assumes lr: "islinintterm (Add (Mult (Cst i) (Var n)) r)"
  15.509 +  shows "islinintterm r"
  15.510 +using lr
  15.511 +by (induct r rule: islinintterm.induct) auto
  15.512 +
  15.513 +(* c \<noteq> 0 for linear term c.n + r*)
  15.514 +lemma islinintterm_cnz:
  15.515 +  assumes lr: "islinintterm (Add (Mult (Cst i) (Var n)) r)"
  15.516 +  shows "i \<noteq> 0"
  15.517 +using lr
  15.518 +by (induct r rule: islinintterm.induct) auto
  15.519 +
  15.520 +lemma islininttermc0r: "islinintterm (Add (Mult (Cst c) (Var n)) r) \<Longrightarrow> (c \<noteq> 0 \<and> islinintterm r)"
  15.521 +by (induct r rule: islinintterm.induct, simp_all)
  15.522 +
  15.523 +(* An alternative linearity definition *)
  15.524 +consts islintn :: "(nat \<times> intterm) \<Rightarrow> bool"
  15.525 +recdef islintn "measure (\<lambda> (n,t). (size t))"
  15.526 +"islintn (n0, Cst i) = True"
  15.527 +"islintn (n0, Add (Mult (Cst i) (Var n)) r) = (i \<noteq> 0 \<and> n0 \<le> n \<and> islintn (n+1,r))"
  15.528 +"islintn (n0, t) = False"
  15.529 +
  15.530 +constdefs islint :: "intterm \<Rightarrow> bool"
  15.531 +  "islint t \<equiv> islintn(0,t)"
  15.532 +
  15.533 +(* And the equivalence to the first definition *)
  15.534 +lemma islinintterm_eq_islint: "islinintterm t = islint t"
  15.535 +  using islint_def
  15.536 +by (induct t rule: islinintterm.induct) auto
  15.537 +
  15.538 +(* monotony *)
  15.539 +lemma islintn_mon:
  15.540 +  assumes lin: "islintn (n,t)"
  15.541 +  and mgen: "m \<le> n"
  15.542 +  shows "islintn(m,t)"
  15.543 +  using lin mgen 
  15.544 +by (induct t rule: islintn.induct) auto
  15.545 +
  15.546 +lemma islintn_subt:
  15.547 +  assumes lint: "islintn(n,Add (Mult (Cst i) (Var m)) r)"
  15.548 +  shows "islintn (m+1,r)"
  15.549 +using lint
  15.550 +by auto
  15.551 +
  15.552 +(* List indexin for n > 0 *)
  15.553 +lemma nth_pos: "0 < n \<longrightarrow> (x#xs) ! n = (y#xs) ! n"
  15.554 +using Nat.gr0_conv_Suc 
  15.555 +by clarsimp 
  15.556 +
  15.557 +lemma nth_pos2: "0 < n \<Longrightarrow> (x#xs) ! n = xs ! (n - 1)"
  15.558 +using Nat.gr0_conv_Suc
  15.559 +by clarsimp
  15.560 +
  15.561 +lemma intterm_novar0: 
  15.562 +  assumes lin: "islinintterm (Add (Mult (Cst i) (Var n)) r)"
  15.563 +  shows "I_intterm (x#ats) r = I_intterm (y#ats) r"
  15.564 +using lin
  15.565 +by (induct r rule: islinintterm.induct) (simp_all add: nth_pos2)
  15.566 +(* a simple version of a general theorem: Interpretation doese not depend 
  15.567 +   on the first variable if it doese not occur in the term *)
  15.568 +
  15.569 +lemma linterm_novar0:
  15.570 +  assumes lin: "islintn (n,t)"
  15.571 +  and npos: "0 < n"
  15.572 +  shows "I_intterm (x#ats) t = I_intterm (y#ats) t"
  15.573 +using lin npos
  15.574 +by (induct n t rule: islintn.induct) (simp_all add: nth_pos2)
  15.575 +
  15.576 +(* Periodicity of dvd *)
  15.577 +lemma dvd_period:
  15.578 +  assumes advdd: "(a::int) dvd d"
  15.579 +  shows "(a dvd (x + t)) = (a dvd ((x+ c*d) + t))"
  15.580 +using advdd  
  15.581 +proof-
  15.582 +  from advdd  have "\<forall>x.\<forall>k. (((a::int) dvd (x + t)) = (a dvd
  15.583 + (x+k*d + t)))" by (rule dvd_modd_pinf)
  15.584 +  then show ?thesis by simp
  15.585 +qed
  15.586 +
  15.587 +(* lin_ad adds two linear terms*)
  15.588 +consts lin_add :: "intterm \<times> intterm \<Rightarrow> intterm"
  15.589 +recdef lin_add "measure (\<lambda>(x,y). ((size x) + (size y)))"
  15.590 +"lin_add (Add (Mult (Cst c1) (Var n1)) (r1),Add (Mult (Cst c2) (Var n2)) (r2)) =
  15.591 +  (if n1=n2 then 
  15.592 +  (let c = Cst (c1 + c2) 
  15.593 +   in (if c1+c2=0 then lin_add(r1,r2) else Add (Mult c (Var n1)) (lin_add (r1,r2))))
  15.594 +  else if n1 \<le> n2 then (Add (Mult (Cst c1) (Var n1)) (lin_add (r1,Add (Mult (Cst c2) (Var n2)) (r2)))) 
  15.595 +  else (Add (Mult (Cst c2) (Var n2)) (lin_add (Add (Mult (Cst c1) (Var n1)) r1,r2))))"
  15.596 +"lin_add (Add (Mult (Cst c1) (Var n1)) (r1),Cst b) = 
  15.597 +  (Add (Mult (Cst c1) (Var n1)) (lin_add (r1, Cst b)))"  
  15.598 +"lin_add (Cst x,Add (Mult (Cst c2) (Var n2)) (r2)) = 
  15.599 +  Add (Mult (Cst c2) (Var n2)) (lin_add (Cst x,r2))" 
  15.600 +"lin_add (Cst b1, Cst b2) = Cst (b1+b2)"
  15.601 +
  15.602 +lemma lin_add_cst_corr: 
  15.603 +  assumes blin : "islintn(n0,b)"
  15.604 +  shows "I_intterm ats (lin_add (Cst a,b)) = (I_intterm ats (Add (Cst a) b))"
  15.605 +using blin
  15.606 +by (induct n0 b rule: islintn.induct) auto
  15.607 +
  15.608 +lemma lin_add_cst_corr2: 
  15.609 +  assumes blin : "islintn(n0,b)"
  15.610 +  shows "I_intterm ats (lin_add (b,Cst a)) = (I_intterm ats (Add b (Cst a)))"
  15.611 +using blin
  15.612 +by (induct n0 b rule: islintn.induct) auto
  15.613 +
  15.614 +lemma lin_add_corrh: "\<And> n01 n02. \<lbrakk> islintn (n01,a) ; islintn (n02,b)\<rbrakk> 
  15.615 +  \<Longrightarrow> I_intterm ats (lin_add(a,b)) = I_intterm ats (Add a b)"
  15.616 +proof(induct a b rule: lin_add.induct)
  15.617 +  case (58 i n r j m s) 
  15.618 +  have "(n = m \<and> i+j = 0) \<or> (n = m \<and> i+j \<noteq> 0) \<or> n < m \<or> m < n " by arith
  15.619 +  moreover
  15.620 +  {assume "n=m\<and>i+j=0" hence ?case using prems by (auto simp add: sym[OF zadd_zmult_distrib]) }
  15.621 +  moreover
  15.622 +  {assume "n=m\<and>i+j\<noteq>0" hence ?case using prems by (auto simp add: Let_def zadd_zmult_distrib)}
  15.623 +  moreover
  15.624 +  {assume "n < m" hence ?case using prems by auto }
  15.625 +  moreover
  15.626 +  {assume "n > m" hence ?case using prems by auto }
  15.627 +  ultimately show ?case by blast
  15.628 +qed (auto simp add: lin_add_cst_corr lin_add_cst_corr2 Let_def)
  15.629 +
  15.630 +(* lin_add has the semantics of Add*)
  15.631 +lemma lin_add_corr:
  15.632 +  assumes lina: "islinintterm a"
  15.633 +  and linb: "islinintterm b"
  15.634 +  shows "I_intterm ats (lin_add (a,b)) = (I_intterm ats (Add a b))"
  15.635 +using lina linb islinintterm_eq_islint islint_def lin_add_corrh
  15.636 +by blast
  15.637 +
  15.638 +lemma lin_add_cst_lint:
  15.639 +  assumes lin: "islintn (n0,b)"
  15.640 +  shows "islintn (n0, lin_add (Cst i, b))"
  15.641 +using lin
  15.642 +by (induct n0 b rule: islintn.induct) auto
  15.643 +
  15.644 +lemma lin_add_cst_lint2:
  15.645 +  assumes lin: "islintn (n0,b)"
  15.646 +  shows "islintn (n0, lin_add (b,Cst i))"
  15.647 +using lin
  15.648 +by (induct n0 b rule: islintn.induct) auto
  15.649 +
  15.650 +(* lin_add preserves linearity..*)
  15.651 +lemma lin_add_lint: "\<And> n0 n01 n02. \<lbrakk> islintn (n01,a) ; islintn (n02,b); n0 \<le>  min n01 n02 \<rbrakk> 
  15.652 +  \<Longrightarrow> islintn (n0, lin_add (a,b))"
  15.653 +proof (induct a b rule: lin_add.induct)
  15.654 +  case (58 i n r j m s)
  15.655 +  have "(n =m \<and> i + j = 0) \<or> (n = m \<and> i+j \<noteq> 0) \<or> n <m \<or> m < n" by arith
  15.656 +  moreover 
  15.657 +  { assume "n = m"
  15.658 +      and  "i+j = 0"
  15.659 +    hence ?case using "58" islintn_mon[where m = "n01" and n = "Suc m"]
  15.660 +      islintn_mon[where m = "n02" and n = "Suc m"] by auto }
  15.661 +  moreover 
  15.662 +  { assume  "n = m"
  15.663 +      and "i+j \<noteq> 0"
  15.664 +    hence ?case using "58" islintn_mon[where m = "n01" and n = "Suc m"]
  15.665 +      islintn_mon[where m = "n02" and n = "Suc m"] by (auto simp add: Let_def) }
  15.666 +  moreover
  15.667 +  { assume "n < m" hence ?case using 58 by force }
  15.668 +moreover
  15.669 +  { assume "m < n"
  15.670 +    hence ?case using 58 
  15.671 +      apply (auto simp add: Let_def) 
  15.672 +      apply (erule allE[where x = "Suc m" ] )
  15.673 +      by (erule allE[where x = "Suc m" ] ) simp }
  15.674 +  ultimately show ?case by blast
  15.675 +qed(simp_all add: Let_def lin_add_cst_lint lin_add_cst_lint2)
  15.676 +
  15.677 +lemma lin_add_lin:
  15.678 +  assumes lina: "islinintterm a"
  15.679 +  and linb: "islinintterm b"
  15.680 +  shows "islinintterm (lin_add (a,b))"
  15.681 +using islinintterm_eq_islint islint_def lin_add_lint lina linb by auto
  15.682 +
  15.683 +(* lin_mul multiplies a linear term by a constant *)
  15.684 +consts lin_mul :: "int \<times> intterm \<Rightarrow> intterm"
  15.685 +recdef lin_mul "measure (\<lambda>(c,t). size t)"
  15.686 +"lin_mul (c,Cst i) = (Cst (c*i))"
  15.687 +"lin_mul (c,Add (Mult (Cst c') (Var n)) r)  = 
  15.688 +  (if c = 0 then (Cst 0) else
  15.689 +  (Add (Mult (Cst (c*c')) (Var n)) (lin_mul (c,r))))"
  15.690 +
  15.691 +lemma zmult_zadd_distrib[simp]: "(a::int) * (b+c) = a*b + a*c"
  15.692 +proof-
  15.693 +  have "a*(b+c) = (b+c)*a" by simp
  15.694 +  moreover have "(b+c)*a = b*a + c*a" by (simp add: zadd_zmult_distrib)
  15.695 +  ultimately show ?thesis by simp
  15.696 +qed
  15.697 +
  15.698 +(* lin_mul has the semantics of Mult *)
  15.699 +lemma lin_mul_corr: 
  15.700 +  assumes lint: "islinintterm  t"
  15.701 +  shows "I_intterm ats (lin_mul (c,t)) = I_intterm ats (Mult (Cst c) t)"
  15.702 +using lint
  15.703 +proof (induct c t rule: lin_mul.induct)
  15.704 +  case (21 c c' n r)
  15.705 +  have "islinintterm (Add (Mult (Cst c') (Var n)) r)" .
  15.706 +  then have "islinintterm r" 
  15.707 +    by (rule islinintterm_subt[of "c'" "n" "r"])
  15.708 +  then show ?case  using "21.hyps" "21.prems" by simp
  15.709 +qed(auto)
  15.710 +
  15.711 +(* lin_mul preserves linearity *)
  15.712 +lemma lin_mul_lin:
  15.713 +  assumes lint: "islinintterm t"
  15.714 +  shows "islinintterm (lin_mul(c,t))"
  15.715 +using lint
  15.716 +by (induct t rule: islinintterm.induct) auto
  15.717 +
  15.718 +lemma lin_mul0:
  15.719 +  assumes lint: "islinintterm t"
  15.720 +  shows "lin_mul(0,t) = Cst 0"
  15.721 +  using lint
  15.722 +  by (induct t rule: islinintterm.induct) auto
  15.723 +
  15.724 +lemma lin_mul_lintn:
  15.725 +  "\<And> m. islintn(m,t) \<Longrightarrow> islintn(m,lin_mul(l,t))"
  15.726 +  by (induct l t rule: lin_mul.induct) simp_all
  15.727 +
  15.728 +(* lin_neg neagtes a linear term *)
  15.729 +constdefs lin_neg :: "intterm \<Rightarrow> intterm"
  15.730 +"lin_neg i == lin_mul ((-1::int),i)"
  15.731 +
  15.732 +(* lin_neg has the semantics of Neg *)
  15.733 +lemma lin_neg_corr:
  15.734 +  assumes lint: "islinintterm  t"
  15.735 +  shows "I_intterm ats (lin_neg t) = I_intterm ats (Neg t)"
  15.736 +  using lint lin_mul_corr
  15.737 +  by (simp add: lin_neg_def lin_mul_corr)
  15.738 +
  15.739 +(* lin_neg preserves linearity *)
  15.740 +lemma lin_neg_lin:
  15.741 +  assumes lint: "islinintterm  t"
  15.742 +  shows "islinintterm (lin_neg t)"
  15.743 +using lint
  15.744 +by (simp add: lin_mul_lin lin_neg_def)
  15.745 +
  15.746 +(* Some properties about lin_add and lin-neg should be moved above *)
  15.747 +
  15.748 +lemma lin_neg_idemp: 
  15.749 +  assumes lini: "islinintterm i"
  15.750 +  shows "lin_neg (lin_neg i) = i"
  15.751 +using lini
  15.752 +by (induct i rule: islinintterm.induct) (auto simp add: lin_neg_def)
  15.753 +
  15.754 +lemma lin_neg_lin_add_distrib:
  15.755 +  assumes lina : "islinintterm a"
  15.756 +  and linb :"islinintterm b"
  15.757 +  shows "lin_neg (lin_add(a,b)) = lin_add (lin_neg a, lin_neg b)"
  15.758 +using lina linb
  15.759 +proof (induct a b rule: lin_add.induct)
  15.760 +  case (58 c1 n1 r1 c2 n2 r2)
  15.761 +  from prems have lincnr1:"islinintterm (Add (Mult (Cst c1) (Var n1)) r1)" by simp
  15.762 +  have linr1: "islinintterm r1" by (rule islinintterm_subt[OF lincnr1])
  15.763 +  from prems have lincnr2: "islinintterm (Add (Mult (Cst c2) (Var n2)) r2)" by simp
  15.764 +  have linr2: "islinintterm r2" by (rule islinintterm_subt[OF lincnr2])
  15.765 +  have "n1 = n2 \<or> n1 < n2 \<or> n1 > n2" by arith
  15.766 +  show ?case using prems linr1 linr2 by (simp_all add: lin_neg_def Let_def)
  15.767 +next
  15.768 +  case (59 c n r b) 
  15.769 +  from prems have lincnr: "islinintterm (Add (Mult (Cst c) (Var n)) r)" by simp
  15.770 +  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  15.771 +  show ?case using prems linr by (simp add: lin_neg_def Let_def)
  15.772 +next
  15.773 +  case (60 b c n r)
  15.774 +  from prems have lincnr: "islinintterm (Add (Mult (Cst c) (Var n)) r)" by simp
  15.775 +  have linr: "islinintterm r" by (rule islinintterm_subt[OF lincnr])
  15.776 +  show ?case  using prems linr by (simp add: lin_neg_def Let_def)
  15.777 +qed (simp_all add: lin_neg_def)
  15.778 +
  15.779 +(* linearize tries to linearize a term *)
  15.780 +consts linearize :: "intterm \<Rightarrow> intterm option"
  15.781 +recdef linearize "measure (\<lambda>t. size t)"
  15.782 +"linearize (Cst b) = Some (Cst b)"
  15.783 +"linearize (Var n) = Some (Add (Mult (Cst 1) (Var n)) (Cst 0))"
  15.784 +"linearize (Neg i) = lift_un lin_neg (linearize i)"
  15.785 + "linearize (Add i j) = lift_bin(\<lambda> x. \<lambda> y. lin_add(x,y), linearize i, linearize j)"
  15.786 +"linearize (Sub i j) = 
  15.787 +  lift_bin(\<lambda> x. \<lambda> y. lin_add(x,lin_neg y), linearize i, linearize j)"
  15.788 +"linearize (Mult i j) = 
  15.789 +  (case linearize i of
  15.790 +  None \<Rightarrow> None
  15.791 +  | Some li \<Rightarrow> (case li of 
  15.792 +     Cst b \<Rightarrow> (case linearize j of
  15.793 +      None \<Rightarrow> None
  15.794 +     | (Some lj) \<Rightarrow> Some (lin_mul(b,lj)))
  15.795 +  | _ \<Rightarrow> (case linearize j of
  15.796 +      None \<Rightarrow> None
  15.797 +    | (Some lj) \<Rightarrow> (case lj of 
  15.798 +        Cst b \<Rightarrow> Some (lin_mul (b,li))
  15.799 +      | _ \<Rightarrow> None))))"
  15.800 +
  15.801 +lemma linearize_linear1:
  15.802 +  assumes lin: "linearize t \<noteq> None"
  15.803 +  shows "islinintterm (the (linearize t))"
  15.804 +using lin
  15.805 +proof (induct t rule: linearize.induct)
  15.806 +  case (1 b) show ?case by simp  
  15.807 +next 
  15.808 +  case (2 n) show ?case by simp 
  15.809 +next 
  15.810 +  case (3 i) show ?case 
  15.811 +    proof-
  15.812 +    have "(linearize i = None) \<or> (\<exists>li. linearize i = Some li)" by auto
  15.813 +    moreover 
  15.814 +    { assume "linearize i = None" with prems have ?thesis by auto}
  15.815 +    moreover 
  15.816 +    { assume lini: "\<exists>li. linearize i = Some li"
  15.817 +      from lini obtain "li" where  "linearize i = Some li" by blast
  15.818 +      have linli: "islinintterm li" by (simp!)
  15.819 +      moreover have "linearize (Neg i) = Some (lin_neg li)" using prems by simp
  15.820 +      moreover from linli have "islinintterm(lin_neg li)" by (simp add: lin_neg_lin)
  15.821 +      ultimately have ?thesis by simp
  15.822 +    }
  15.823 +    ultimately show ?thesis by blast
  15.824 +  qed
  15.825 +next 
  15.826 +  case (4 i j) show ?case 
  15.827 +    proof-
  15.828 +    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 
  15.829 +    moreover 
  15.830 +    {
  15.831 +      assume nlini: "linearize i = None"
  15.832 +      from nlini have "linearize (Add i j) = None" 
  15.833 +	by (simp add: Let_def measure_def inv_image_def) then have ?thesis using prems by auto}
  15.834 +    moreover 
  15.835 +    { assume nlinj: "linearize j = None"
  15.836 +	and lini: "\<exists> li. linearize i = Some li"
  15.837 +      from nlinj lini have "linearize (Add i j) = None" 
  15.838 +	by (simp add: Let_def measure_def inv_image_def, auto) with prems  have ?thesis by auto}
  15.839 +    moreover 
  15.840 +    { assume lini: "\<exists>li. linearize i = Some li"
  15.841 +	and linj: "\<exists>lj. linearize j = Some lj"
  15.842 +      from lini obtain "li" where  "linearize i = Some li" by blast
  15.843 +      have linli: "islinintterm li" by (simp!)
  15.844 +      from linj obtain "lj" where  "linearize j = Some lj" by blast
  15.845 +      have linlj: "islinintterm lj" by (simp!)
  15.846 +      moreover from lini linj have "linearize (Add i j) = Some (lin_add (li,lj))" 
  15.847 +	by (simp add: measure_def inv_image_def, auto!)
  15.848 +      moreover from linli linlj have "islinintterm(lin_add (li,lj))" by (simp add: lin_add_lin)
  15.849 +      ultimately have ?thesis by simp  }
  15.850 +    ultimately show ?thesis by blast
  15.851 +  qed
  15.852 +next 
  15.853 +  case (5 i j)show ?case 
  15.854 +    proof-
  15.855 +    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 
  15.856 +    moreover 
  15.857 +    {
  15.858 +      assume nlini: "linearize i = None"
  15.859 +      from nlini have "linearize (Sub i j) = None" by (simp add: Let_def measure_def inv_image_def) then have ?thesis by (auto!)
  15.860 +    }
  15.861 +    moreover 
  15.862 +    {
  15.863 +      assume lini: "\<exists> li. linearize i = Some li"
  15.864 +	and nlinj: "linearize j = None"
  15.865 +      from nlinj lini have "linearize (Sub i j) = None" 
  15.866 +	by (simp add: Let_def measure_def inv_image_def, auto) then have ?thesis by (auto!)
  15.867 +    }
  15.868 +    moreover 
  15.869 +    {
  15.870 +      assume lini: "\<exists>li. linearize i = Some li"
  15.871 +	and linj: "\<exists>lj. linearize j = Some lj"
  15.872 +      from lini obtain "li" where  "linearize i = Some li" by blast
  15.873 +      have linli: "islinintterm li" by (simp!)
  15.874 +      from linj obtain "lj" where  "linearize j = Some lj" by blast
  15.875 +      have linlj: "islinintterm lj" by (simp!)
  15.876 +      moreover from lini linj have "linearize (Sub i j) = Some (lin_add (li,lin_neg lj))" 
  15.877 +	by (simp add: measure_def inv_image_def, auto!)
  15.878 +      moreover from linli linlj have "islinintterm(lin_add (li,lin_neg lj))" by (simp add: lin_add_lin lin_neg_lin)
  15.879 +      ultimately have ?thesis by simp
  15.880 +    }
  15.881 +    ultimately show ?thesis by blast
  15.882 +  qed
  15.883 +next
  15.884 +  case (6 i j)show ?case 
  15.885 +    proof-
  15.886 +      have cses: "(linearize i = None) \<or> 
  15.887 +	((\<exists> li. linearize i = Some li) \<and> linearize j = None) \<or> 
  15.888 +	((\<exists> li. linearize i = Some li) \<and> (\<exists> bj. linearize j = Some (Cst bj)))
  15.889 +	\<or> ((\<exists> bi. linearize i = Some (Cst bi)) \<and> (\<exists> lj. linearize j = Some lj))
  15.890 +	\<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 
  15.891 +    moreover 
  15.892 +    {
  15.893 +      assume nlini: "linearize i = None"
  15.894 +      from nlini have "linearize (Mult i j) = None" 
  15.895 +	by (simp add: Let_def measure_def inv_image_def)  
  15.896 +      with prems have ?thesis by auto }
  15.897 +    moreover 
  15.898 +    {  assume lini: "\<exists> li. linearize i = Some li"
  15.899 +	and nlinj: "linearize j = None"
  15.900 +      from lini obtain "li" where "linearize i = Some li" by blast 
  15.901 +      moreover from nlinj lini have "linearize (Mult i j) = None"
  15.902 +	using prems
  15.903 +	by (cases li ) (auto simp add: Let_def measure_def inv_image_def)
  15.904 +      with prems have ?thesis by auto}
  15.905 +    moreover 
  15.906 +    { assume lini: "\<exists>li. linearize i = Some li"
  15.907 +	and linj: "\<exists>bj. linearize j = Some (Cst bj)"
  15.908 +      from lini obtain "li" where  li_def: "linearize i = Some li" by blast
  15.909 +      from prems have linli: "islinintterm li" by simp
  15.910 +      moreover 
  15.911 +      from linj  obtain "bj" where  bj_def: "linearize j = Some (Cst bj)" by blast
  15.912 +      have linlj: "islinintterm (Cst bj)" by simp 
  15.913 +      moreover from lini linj prems 
  15.914 +      have "linearize (Mult i j) = Some (lin_mul (bj,li))"
  15.915 +	by (cases li) (auto simp add: measure_def inv_image_def)
  15.916 +      moreover from linli linlj have "islinintterm(lin_mul (bj,li))" by (simp add: lin_mul_lin)
  15.917 +      ultimately have ?thesis by simp  }
  15.918 +    moreover 
  15.919 +    { assume lini: "\<exists>bi. linearize i = Some (Cst bi)"
  15.920 +	and linj: "\<exists>lj. linearize j = Some lj"
  15.921 +      from lini obtain "bi" where  "linearize i = Some (Cst bi)" by blast
  15.922 +      from prems have linli: "islinintterm (Cst bi)" by simp
  15.923 +      moreover 
  15.924 +      from linj  obtain "lj" where  "linearize j = Some lj" by blast
  15.925 +      from prems have linlj: "islinintterm lj" by simp
  15.926 +      moreover from lini linj prems have "linearize (Mult i j) = Some (lin_mul (bi,lj))" 
  15.927 +	by (simp add: measure_def inv_image_def) 
  15.928 +      moreover from linli linlj have "islinintterm(lin_mul (bi,lj))" by (simp add: lin_mul_lin)
  15.929 +      ultimately have ?thesis by simp }
  15.930 +    moreover 
  15.931 +    { assume linc: "\<exists> li. linearize i = Some li \<and> \<not> (\<exists> bi. li = Cst bi)"
  15.932 +	and ljnc: "\<exists> lj. linearize j = Some lj \<and> \<not> (\<exists> bj. lj = Cst bj)"
  15.933 +      from linc obtain "li" where "linearize i = Some li \<and> \<not> (\<exists> bi. li = Cst bi)" by blast
  15.934 +      moreover 
  15.935 +      from ljnc obtain "lj" where "linearize j = Some lj \<and> \<not> (\<exists> bj. lj = Cst bj)" by blast
  15.936 +      ultimately have "linearize (Mult i j) = None"
  15.937 +	by (cases li, auto simp add: measure_def inv_image_def) (cases lj, auto)+
  15.938 +      with prems have ?thesis by simp }
  15.939 +    ultimately show ?thesis by blast
  15.940 +  qed
  15.941 +qed  
  15.942 +
  15.943 +(* the result of linearize, when successful, is a linear term*)
  15.944 +lemma linearize_linear: "\<And> t'. linearize t = Some t' \<Longrightarrow> islinintterm t'"
  15.945 +proof-
  15.946 +  fix t'
  15.947 +  assume lint: "linearize t = Some t'"
  15.948 +  from lint have lt: "linearize t \<noteq> None" by auto
  15.949 +  then have "islinintterm (the (linearize t))" by (rule_tac  linearize_linear1[OF lt])
  15.950 +  with lint show "islinintterm t'" by simp
  15.951 +qed
  15.952 +
  15.953 +lemma linearize_corr1: 
  15.954 +  assumes lin: "linearize t \<noteq> None"
  15.955 +  shows "I_intterm ats t = I_intterm ats (the (linearize t))"
  15.956 +using lin
  15.957 +proof (induct t rule: linearize.induct)
  15.958 +  case (3 i) show ?case 
  15.959 +    proof-
  15.960 +    have "(linearize i = None) \<or> (\<exists>li. linearize i = Some li)" by auto
  15.961 +    moreover 
  15.962 +    {
  15.963 +      assume "linearize i = None"
  15.964 +      have ?thesis using prems by simp
  15.965 +    }
  15.966 +    moreover 
  15.967 +    {
  15.968 +      assume lini: "\<exists>li. linearize i = Some li"
  15.969 +      from lini have lini2: "linearize i \<noteq> None" by simp
  15.970 +      from lini obtain "li" where  "linearize i = Some li" by blast
  15.971 +      from lini2 lini have "islinintterm (the (linearize i))"
  15.972 +	by (simp add: linearize_linear1[OF lini2])
  15.973 +      then have linli: "islinintterm li" using prems by simp
  15.974 +      have ieqli: "I_intterm ats i = I_intterm ats li" using prems by simp
  15.975 +      moreover have "linearize (Neg i) = Some (lin_neg li)" using prems by simp
  15.976 +      moreover from ieqli linli have "I_intterm ats (Neg i) = I_intterm ats (lin_neg li)" by (simp add: lin_neg_corr[OF linli])
  15.977 +      ultimately have ?thesis using prems by (simp add: lin_neg_corr)
  15.978 +    }
  15.979 +    ultimately show ?thesis by blast
  15.980 +  qed
  15.981 +next 
  15.982 +  case (4 i j) show ?case 
  15.983 +    proof-
  15.984 +    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 
  15.985 +    moreover 
  15.986 +    {
  15.987 +      assume nlini: "linearize i = None"
  15.988 +      from nlini have "linearize (Add i j) = None" by (simp add: Let_def measure_def inv_image_def) then have ?thesis using prems by auto
  15.989 +    }
  15.990 +    moreover 
  15.991 +    {
  15.992 +      assume nlinj: "linearize j = None"
  15.993 +	and lini: "\<exists> li. linearize i = Some li"
  15.994 +      from nlinj lini have "linearize (Add i j) = None" 
  15.995 +	by (simp add: Let_def measure_def inv_image_def, auto) 
  15.996 +      then have ?thesis using prems by auto
  15.997 +    }
  15.998 +    moreover 
  15.999 +    {
 15.1000 +      assume lini: "\<exists>li. linearize i = Some li"
 15.1001 +	and linj: "\<exists>lj. linearize j = Some lj"
 15.1002 +      from lini have lini2: "linearize i \<noteq> None" by simp
 15.1003 +      from linj have linj2: "linearize j \<noteq> None" by simp
 15.1004 +      from lini obtain "li" where  "linearize i = Some li" by blast
 15.1005 +      from lini2 have "islinintterm (the (linearize i))" by (simp add: linearize_linear1)
 15.1006 +      then have linli: "islinintterm li" using prems by simp
 15.1007 +      from linj obtain "lj" where  "linearize j = Some lj" by blast
 15.1008 +      from linj2 have "islinintterm (the (linearize j))" by (simp add: linearize_linear1)
 15.1009 +      then have linlj: "islinintterm lj" using prems by simp
 15.1010 +      moreover from lini linj have "linearize (Add i j) = Some (lin_add (li,lj))"
 15.1011 +	using prems by (simp add: measure_def inv_image_def)
 15.1012 +      moreover from linli linlj have "I_intterm ats (lin_add (li,lj)) = I_intterm ats (Add li lj)" by (simp add: lin_add_corr)
 15.1013 +      ultimately have ?thesis using prems by simp
 15.1014 +    }
 15.1015 +    ultimately show ?thesis by blast
 15.1016 +  qed
 15.1017 +next 
 15.1018 +  case (5 i j)show ?case 
 15.1019 +    proof-
 15.1020 +    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 
 15.1021 +    moreover 
 15.1022 +    {
 15.1023 +      assume nlini: "linearize i = None"
 15.1024 +      from nlini have "linearize (Sub i j) = None" by (simp add: Let_def measure_def inv_image_def) then have ?thesis using prems by auto
 15.1025 +    }
 15.1026 +    moreover 
 15.1027 +    {
 15.1028 +      assume lini: "\<exists> li. linearize i = Some li"
 15.1029 +	and nlinj: "linearize j = None"
 15.1030 +      from nlinj lini have "linearize (Sub i j) = None" 
 15.1031 +	by (simp add: Let_def measure_def inv_image_def, auto) with prems have ?thesis by auto
 15.1032 +    }
 15.1033 +    moreover 
 15.1034 +    {
 15.1035 +      assume lini: "\<exists>li. linearize i = Some li"
 15.1036 +	and linj: "\<exists>lj. linearize j = Some lj"
 15.1037 +      from lini have lini2: "linearize i \<noteq> None" by simp
 15.1038 +      from linj have linj2: "linearize j \<noteq> None" by simp
 15.1039 +      from lini obtain "li" where  "linearize i = Some li" by blast
 15.1040 +      from lini2 have "islinintterm (the (linearize i))" by (simp add: linearize_linear1)
 15.1041 +      with prems have linli: "islinintterm li" by simp
 15.1042 +      from linj obtain "lj" where  "linearize j = Some lj" by blast
 15.1043 +      from linj2 have "islinintterm (the (linearize j))" by (simp add: linearize_linear1)
 15.1044 +      with prems have linlj: "islinintterm lj" by simp
 15.1045 +      moreover from prems have "linearize (Sub i j) = Some (lin_add (li,lin_neg lj))" 
 15.1046 +	by (simp add: measure_def inv_image_def)
 15.1047 +      moreover from linlj have linnlj:"islinintterm (lin_neg lj)" by (simp add: lin_neg_lin)
 15.1048 +      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])
 15.1049 +      moreover from linli linlj linnlj have "I_intterm ats (Add li (lin_neg lj)) = I_intterm ats (Sub li lj)" 
 15.1050 +	by (simp add: lin_neg_corr)
 15.1051 +      ultimately have ?thesis using prems by simp    
 15.1052 +    }
 15.1053 +    ultimately show ?thesis by blast
 15.1054 +  qed
 15.1055 +next
 15.1056 +  case (6 i j)show ?case 
 15.1057 +    proof-
 15.1058 +      have cses: "(linearize i = None) \<or> 
 15.1059 +	((\<exists> li. linearize i = Some li) \<and> linearize j = None) \<or> 
 15.1060 +	((\<exists> li. linearize i = Some li) \<and> (\<exists> bj. linearize j = Some (Cst bj)))
 15.1061 +	\<or> ((\<exists> bi. linearize i = Some (Cst bi)) \<and> (\<exists> lj. linearize j = Some lj))
 15.1062 +	\<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 
 15.1063 +    moreover 
 15.1064 +    {
 15.1065 +      assume nlini: "linearize i = None"
 15.1066 +      from nlini have "linearize (Mult i j) = None" by (simp add: Let_def measure_def inv_image_def) with prems  have ?thesis by auto
 15.1067 +    }
 15.1068 +    moreover 
 15.1069 +    {
 15.1070 +      assume lini: "\<exists> li. linearize i = Some li"
 15.1071 +	and nlinj: "linearize j = None"
 15.1072 +
 15.1073 +      from lini obtain "li" where "linearize i = Some li" by blast 
 15.1074 +      moreover from prems have "linearize (Mult i j) = None" 
 15.1075 +	by (cases li) (simp_all add: Let_def measure_def inv_image_def)
 15.1076 +      with prems have ?thesis by auto
 15.1077 +    }
 15.1078 +    moreover 
 15.1079 +    {
 15.1080 +      assume lini: "\<exists>li. linearize i = Some li"
 15.1081 +	and linj: "\<exists>bj. linearize j = Some (Cst bj)"
 15.1082 +      from lini have lini2: "linearize i \<noteq> None" by simp
 15.1083 +      from linj have linj2: "linearize j \<noteq> None" by auto
 15.1084 +      from lini obtain "li" where  "linearize i = Some li" by blast
 15.1085 +      from lini2 have "islinintterm (the (linearize i))" by (simp add: linearize_linear1)
 15.1086 +      with prems  have linli: "islinintterm li" by simp
 15.1087 +      moreover 
 15.1088 +      from linj  obtain "bj" where  "linearize j = Some (Cst bj)" by blast
 15.1089 +      have linlj: "islinintterm (Cst bj)" by simp
 15.1090 +      moreover from prems have "linearize (Mult i j) = Some (lin_mul (bj,li))"
 15.1091 + 	by (cases li) (auto simp add: measure_def inv_image_def) 
 15.1092 +      then have lm1: "I_intterm ats (the(linearize (Mult i j))) = I_intterm ats (lin_mul (bj,li))" by simp
 15.1093 +      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)
 15.1094 +      with prems 
 15.1095 +      have "I_intterm ats (lin_mul(bj,li)) = I_intterm ats (Mult li (the (linearize j)))" 
 15.1096 +	by auto
 15.1097 +      moreover have "I_intterm ats (Mult li (the (linearize j))) = I_intterm ats (Mult i (the (linearize j)))" using prems  by simp
 15.1098 +      moreover have "I_intterm ats i = I_intterm ats (the (linearize i))"  
 15.1099 +	using lini2 lini "6.hyps" by simp
 15.1100 +	moreover have "I_intterm ats j = I_intterm ats (the (linearize j))"
 15.1101 +	  using prems by (cases li) (auto simp add: measure_def inv_image_def)
 15.1102 +      ultimately have ?thesis by auto }
 15.1103 +    moreover 
 15.1104 +    { assume lini: "\<exists>bi. linearize i = Some (Cst bi)"
 15.1105 +	and linj: "\<exists>lj. linearize j = Some lj"
 15.1106 +      from lini have lini2 : "linearize i \<noteq> None" by auto
 15.1107 +      from linj have linj2 : "linearize j \<noteq> None" by auto      
 15.1108 +      from lini obtain "bi" where  "linearize i = Some (Cst bi)" by blast
 15.1109 +      have linli: "islinintterm (Cst bi)" using prems by simp
 15.1110 +      moreover 
 15.1111 +      from linj  obtain "lj" where  "linearize j = Some lj" by blast
 15.1112 +      from linj2 have "islinintterm (the (linearize j))" by (simp add: linearize_linear1) 
 15.1113 +      then have linlj: "islinintterm lj" by (simp!)
 15.1114 +      moreover from linli lini linj have "linearize (Mult i j) = Some (lin_mul (bi,lj))" 	apply (simp add: measure_def inv_image_def) 
 15.1115 +	apply auto by (case_tac "li::intterm",auto!)
 15.1116 +      then have lm1: "I_intterm ats (the(linearize (Mult i j))) = I_intterm ats (lin_mul (bi,lj))" by simp
 15.1117 +      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)
 15.1118 +      then have "I_intterm ats (lin_mul(bi,lj)) = I_intterm ats (Mult (the (linearize i)) lj)" by (auto!)
 15.1119 +      moreover have "I_intterm ats (Mult (the (linearize i)) lj) = I_intterm ats (Mult (the (linearize i)) j)" using lini lini2  by (simp!)
 15.1120 +      moreover have "I_intterm ats i = I_intterm ats (the (linearize i))"  
 15.1121 +	using lini2 lini "6.hyps" by simp
 15.1122 +	moreover have "I_intterm ats j = I_intterm ats (the (linearize j))"
 15.1123 +	  using linj linj2 lini lini2 linli linlj "6.hyps" by (auto!)
 15.1124 +
 15.1125 +      ultimately have ?thesis by auto }
 15.1126 +    moreover 
 15.1127 +    { assume linc: "\<exists> li. linearize i = Some li \<and> \<not> (\<exists> bi. li = Cst bi)"
 15.1128 +	and ljnc: "\<exists> lj. linearize j = Some lj \<and> \<not> (\<exists> bj. lj = Cst bj)"
 15.1129 +      from linc obtain "li" where "\<exists> li. linearize i = Some li \<and> \<not> (\<exists> bi. li = Cst bi)" by blast
 15.1130 +      moreover 
 15.1131 +      from ljnc obtain "lj" where "\<exists> lj. linearize j = Some lj \<and> \<not> (\<exists> bj. lj = Cst bj)" by blast
 15.1132 +      ultimately have "linearize (Mult i j) = None"
 15.1133 +	apply (simp add: measure_def inv_image_def)
 15.1134 +	apply (case_tac "linearize i", auto)
 15.1135 +	apply (case_tac a)
 15.1136 +	apply (auto!)
 15.1137 +	by (case_tac "lj",auto)+
 15.1138 +      then have ?thesis by (simp!) }
 15.1139 +    ultimately show ?thesis by blast
 15.1140 +  qed
 15.1141 +qed  simp_all
 15.1142 +
 15.1143 +
 15.1144 +(* linearize, when successfull, preserves semantics *)
 15.1145 +lemma linearize_corr: "\<And> t'. linearize t = Some t' \<Longrightarrow> I_intterm ats t = I_intterm ats t' "
 15.1146 +proof-
 15.1147 +  fix t'
 15.1148 +  assume lint: "linearize t = Some t'"
 15.1149 +  show  "I_intterm ats t = I_intterm ats t'"
 15.1150 +  proof-
 15.1151 +    from lint have lt: "linearize t \<noteq> None" by simp 
 15.1152 +    then have "I_intterm ats t = I_intterm ats (the (linearize t))" 
 15.1153 +      by (rule_tac linearize_corr1[OF lt])
 15.1154 +    with lint show ?thesis by simp
 15.1155 +  qed
 15.1156 +qed
 15.1157 +
 15.1158 +(* tries to linearize a formula *)
 15.1159 +consts linform :: "QF \<Rightarrow> QF option"
 15.1160 +primrec
 15.1161 +"linform (Le it1 it2) =  
 15.1162 +  lift_bin(\<lambda>x. \<lambda>y. Le (lin_add(x,lin_neg y)) (Cst 0),linearize it1, linearize it2)"
 15.1163 +"linform (Eq it1 it2) =  
 15.1164 +  lift_bin(\<lambda>x. \<lambda>y. Eq (lin_add(x,lin_neg y)) (Cst 0),linearize it1, linearize it2)"
 15.1165 +"linform (Divides d t) =  
 15.1166 +  (case linearize d of
 15.1167 +    None \<Rightarrow> None
 15.1168 +   | Some ld \<Rightarrow> (case ld of
 15.1169 +          Cst b \<Rightarrow> 
 15.1170 +               (if (b=0) then None
 15.1171 +               else 
 15.1172 +                (case linearize t of 
 15.1173 +                 None \<Rightarrow> None
 15.1174 +               | Some lt \<Rightarrow> Some (Divides ld lt)))
 15.1175 +         | _ \<Rightarrow> None))"
 15.1176 +"linform  T = Some T"
 15.1177 +"linform  F = Some F"
 15.1178 +"linform (NOT p) = lift_un NOT (linform p)"
 15.1179 +"linform (And p q)= lift_bin(\<lambda>f. \<lambda>g. And f g, linform p, linform q)"
 15.1180 +"linform (Or p q) = lift_bin(\<lambda>f. \<lambda>g. Or f g, linform p, linform q)"
 15.1181 +
 15.1182 +(* linearity of formulae *)
 15.1183 +consts islinform :: "QF \<Rightarrow> bool"
 15.1184 +recdef islinform "measure size"
 15.1185 +"islinform (Le it (Cst i)) = (i=0 \<and> islinintterm it )"
 15.1186 +"islinform (Eq it (Cst i)) = (i=0 \<and> islinintterm it)"
 15.1187 +"islinform (Divides (Cst d) t) = (d \<noteq> 0 \<and> islinintterm t)"
 15.1188 +"islinform  T = True"
 15.1189 +"islinform  F = True"
 15.1190 +"islinform (NOT (Divides (Cst d) t)) = (d \<noteq> 0 \<and> islinintterm t)"
 15.1191 +"islinform (NOT (Eq it (Cst i))) = (i=0 \<and> islinintterm it)"
 15.1192 +"islinform (And p q)= ((islinform p) \<and> (islinform q))"
 15.1193 +"islinform (Or p q) = ((islinform p) \<and> (islinform q))"
 15.1194 +"islinform p = False"
 15.1195 +
 15.1196 +(* linform preserves nnf, if successful *)
 15.1197 +lemma linform_nnf: 
 15.1198 +  assumes nnfp: "isnnf p" 
 15.1199 +  shows "\<And> p'. \<lbrakk>linform p = Some p'\<rbrakk> \<Longrightarrow> isnnf p'"
 15.1200 +using nnfp
 15.1201 +proof (induct p rule: isnnf.induct, simp_all)
 15.1202 +  case (goal1 a b p')
 15.1203 +  show ?case 
 15.1204 +    using prems 
 15.1205 +    by (cases "linearize a", auto) (cases "linearize b", auto)
 15.1206 +next 
 15.1207 +  case (goal2 a b p')
 15.1208 +  show ?case 
 15.1209 +    using prems 
 15.1210 +    by (cases "linearize a", auto) (cases "linearize b", auto)
 15.1211 +next 
 15.1212 +  case (goal3 d t p')
 15.1213 +  show ?case 
 15.1214 +    using prems
 15.1215 +    apply (cases "linearize d", auto)
 15.1216 +    apply (case_tac "a",auto)
 15.1217 +    apply (case_tac "int=0",auto)
 15.1218 +    by (cases "linearize t",auto)
 15.1219 +next
 15.1220 +  case (goal4 f g p') show ?case 
 15.1221 +    using prems
 15.1222 +    by (cases "linform f", auto) (cases "linform g", auto)
 15.1223 +next
 15.1224 +  case (goal5 f g p') show ?case 
 15.1225 +    using prems
 15.1226 +    by (cases "linform f", auto) (cases "linform g", auto)
 15.1227 +next
 15.1228 +  case (goal6 d t p') show ?case 
 15.1229 +    using prems
 15.1230 +    apply (cases "linearize d", auto)
 15.1231 +    apply (case_tac "a", auto)
 15.1232 +    apply (case_tac "int = 0",auto)
 15.1233 +    by (cases "linearize t", auto)
 15.1234 +next 
 15.1235 +  case (goal7 a b p')
 15.1236 +  show ?case 
 15.1237 +    using prems 
 15.1238 +    by (cases "linearize a", auto) (cases "linearize b", auto)
 15.1239 +
 15.1240 +
 15.1241 +qed
 15.1242 +
 15.1243 +
 15.1244 +lemma linform_corr: "\<And> lp. \<lbrakk> isnnf p ; linform p = Some lp \<rbrakk> \<Longrightarrow> 
 15.1245 +                     (qinterp ats p = qinterp ats lp)"
 15.1246 +proof (induct p rule: linform.induct)
 15.1247 +  case (Le x y)
 15.1248 +  show ?case
 15.1249 +    using "Le.prems"
 15.1250 +  proof-
 15.1251 +    have "(\<exists> lx ly. linearize x = Some lx \<and> linearize y = Some ly) \<or> 
 15.1252 +      (linearize x = None) \<or> (linearize y = None)"by auto
 15.1253 +    moreover 
 15.1254 +    {
 15.1255 +      assume linxy: "\<exists> lx ly. linearize x = Some lx \<and> linearize y = Some ly"
 15.1256 +      from linxy obtain "lx" "ly" 
 15.1257 +	where lxly:"linearize x = Some lx \<and> linearize y = Some ly" by blast
 15.1258 +      then 
 15.1259 +      have lxeqx: "I_intterm ats x = I_intterm ats lx" 
 15.1260 +	by (simp add: linearize_corr)
 15.1261 +      from lxly have lxlin: "islinintterm lx" 
 15.1262 +	by (auto simp add: linearize_linear)
 15.1263 +      from lxly have lyeqy: "I_intterm ats y = I_intterm ats ly"
 15.1264 +	by (simp add: linearize_corr)
 15.1265 +      from lxly have lylin: "islinintterm ly" 
 15.1266 +	by (auto simp add: linearize_linear)
 15.1267 +      from "prems"
 15.1268 +      have lpeqle: "lp =  (Le (lin_add(lx,lin_neg ly)) (Cst 0))"
 15.1269 +	by auto
 15.1270 +      moreover
 15.1271 +      have lin1: "islinintterm (Cst 1)" by simp
 15.1272 +      then
 15.1273 +      have ?thesis  
 15.1274 +	using lxlin lylin lin1 lin_add_lin lin_neg_lin "prems" lxly lpeqle
 15.1275 +	by (simp add: lin_add_corr lin_neg_corr lxeqx lyeqy)
 15.1276 +      
 15.1277 +    }
 15.1278 +    
 15.1279 +    moreover
 15.1280 +    {
 15.1281 +      assume "linearize x = None"
 15.1282 +      have ?thesis using "prems" by simp
 15.1283 +    }
 15.1284 +    
 15.1285 +    moreover
 15.1286 +    {
 15.1287 +      assume "linearize y = None"
 15.1288 +      then have ?thesis using "prems"
 15.1289 +	by (case_tac "linearize x", auto)
 15.1290 +    }
 15.1291 +    ultimately show ?thesis by blast
 15.1292 +  qed
 15.1293 +  
 15.1294 +next 
 15.1295 +  case (Eq x y)
 15.1296 +  show ?case
 15.1297 +    using "Eq.prems"
 15.1298 +  proof-
 15.1299 +    have "(\<exists> lx ly. linearize x = Some lx \<and> linearize y = Some ly) \<or> 
 15.1300 +      (linearize x = None) \<or> (linearize y = None)"by auto
 15.1301 +    moreover 
 15.1302 +    {
 15.1303 +      assume linxy: "\<exists> lx ly. linearize x = Some lx \<and> linearize y = Some ly"
 15.1304 +      from linxy obtain "lx" "ly" 
 15.1305 +	where lxly:"linearize x = Some lx \<and> linearize y = Some ly" by blast
 15.1306 +      then 
 15.1307 +      have lxeqx: "I_intterm ats x = I_intterm ats lx" 
 15.1308 +	by (simp add: linearize_corr)
 15.1309 +      from lxly have lxlin: "islinintterm lx" 
 15.1310 +	by (auto simp add: linearize_linear)
 15.1311 +      from lxly have lyeqy: "I_intterm ats y = I_intterm ats ly"
 15.1312 +	by (simp add: linearize_corr)
 15.1313 +      from lxly have lylin: "islinintterm ly" 
 15.1314 +	by (auto simp add: linearize_linear)
 15.1315 +      from "prems"
 15.1316 +      have lpeqle: "lp =  (Eq (lin_add(lx,lin_neg ly)) (Cst 0))"
 15.1317 +	by auto
 15.1318 +      moreover
 15.1319 +      have lin1: "islinintterm (Cst 1)" by simp
 15.1320 +      then
 15.1321 +      have ?thesis  
 15.1322 +	using lxlin lylin lin1 lin_add_lin lin_neg_lin "prems" lxly lpeqle
 15.1323 +	by (simp add: lin_add_corr lin_neg_corr lxeqx lyeqy)
 15.1324 +      
 15.1325 +    }
 15.1326 +    
 15.1327 +    moreover
 15.1328 +    {
 15.1329 +      assume "linearize x = None"
 15.1330 +      have ?thesis using "prems" by simp
 15.1331 +    }
 15.1332 +    
 15.1333 +    moreover
 15.1334 +    {
 15.1335 +      assume "linearize y = None"
 15.1336 +      then have ?thesis using "prems"
 15.1337 +	by (case_tac "linearize x", auto)
 15.1338 +    }
 15.1339 +    ultimately show ?thesis by blast
 15.1340 +  qed
 15.1341 +  
 15.1342 +next 
 15.1343 +  case (Divides d t)
 15.1344 +  show ?case
 15.1345 +    using "Divides.prems"
 15.1346 +    apply (case_tac "linearize d",auto)
 15.1347 +    apply (case_tac a, auto)
 15.1348 +    apply (case_tac "int = 0", auto)
 15.1349 +    apply (case_tac "linearize t", auto)
 15.1350 +    apply (simp add: linearize_corr)
 15.1351 +    apply (case_tac a, auto)
 15.1352 +    apply (case_tac "int = 0", auto)
 15.1353 +    by (case_tac "linearize t", auto simp add: linearize_corr)
 15.1354 +next
 15.1355 +  case (NOT f) show ?case
 15.1356 +    using "prems"
 15.1357 +  proof-
 15.1358 +    have "(\<exists> lf. linform f = Some lf) \<or> (linform f = None)" by auto
 15.1359 +    moreover 
 15.1360 +    {
 15.1361 +      assume linf: "\<exists> lf. linform f = Some lf"
 15.1362 +      from prems have "isnnf (NOT f)" by simp
 15.1363 +      then have fnnf: "isnnf f" by (cases f) auto
 15.1364 +      from linf obtain "lf" where lf: "linform f = Some lf" by blast
 15.1365 +      then have "lp = NOT lf" using "prems" by auto
 15.1366 +      with "NOT.prems" "NOT.hyps" lf fnnf
 15.1367 +      have ?case by simp
 15.1368 +    }
 15.1369 +    moreover 
 15.1370 +    {
 15.1371 +      assume "linform f = None"
 15.1372 +      then 
 15.1373 +      have "linform (NOT f) = None" by simp
 15.1374 +      then 
 15.1375 +      have ?thesis  using "NOT.prems" by simp
 15.1376 +    }
 15.1377 +    ultimately show ?thesis by blast
 15.1378 +  qed
 15.1379 +next
 15.1380 +  case (Or f g) 
 15.1381 +  show ?case using "Or.hyps"
 15.1382 +  proof -
 15.1383 +    have "((\<exists> lf. linform f = Some lf ) \<and> (\<exists> lg. linform g = Some lg)) \<or> 
 15.1384 +      (linform f = None) \<or> (linform g = None)" by auto
 15.1385 +    moreover
 15.1386 +    {
 15.1387 +      assume linf: "\<exists> lf. linform f = Some lf"
 15.1388 +	and ling: "\<exists> lg. linform g = Some lg"
 15.1389 +      from linf obtain "lf" where lf: "linform f = Some lf" by blast
 15.1390 +      from ling obtain "lg" where lg: "linform g = Some lg" by blast
 15.1391 +      from lf lg have "linform (Or f g) = Some (Or lf lg)" by simp
 15.1392 +      then have "lp = Or lf lg" using lf lg "prems"  by simp
 15.1393 +      with lf lg "prems" have ?thesis by simp
 15.1394 +    }
 15.1395 +    moreover
 15.1396 +    {
 15.1397 +      assume "linform f = None"
 15.1398 +      then have ?thesis using "Or.prems"  by auto
 15.1399 +    }
 15.1400 +    moreover
 15.1401 +    {
 15.1402 +      assume "linform g = None"
 15.1403 +      then have ?thesis using "Or.prems"  by (case_tac "linform f", auto)
 15.1404 +      
 15.1405 +    }
 15.1406 +    ultimately show ?thesis by blast
 15.1407 +  qed
 15.1408 +next
 15.1409 +  case (And f g)