src/HOL/Tools/Presburger/cooper_dec.ML
changeset 16398 7f0faa30f602
parent 16389 48832eba5b1e
child 16837 416e86088931
equal deleted inserted replaced
16397:c047008f88d4 16398:7f0faa30f602
   245 (* Find the LCM of the coefficients of x.                                    *) 
   245 (* Find the LCM of the coefficients of x.                                    *) 
   246 (* ------------------------------------------------------------------------- *) 
   246 (* ------------------------------------------------------------------------- *) 
   247 (*gcd calculates gcd (a,b) and helps lcm_num calculating lcm (a,b)*) 
   247 (*gcd calculates gcd (a,b) and helps lcm_num calculating lcm (a,b)*) 
   248  
   248  
   249 (*BEWARE: replaces Library.gcd!! There is also Library.lcm!*)
   249 (*BEWARE: replaces Library.gcd!! There is also Library.lcm!*)
   250 fun gcd a b = if a=0 then b else gcd (b mod a) a ; 
   250 fun gcd (a:IntInf.int) b = if a=0 then b else gcd (b mod a) a ; 
   251 fun lcm_num a b = (abs a*b) div (gcd (abs a) (abs b)); 
   251 fun lcm_num a b = (abs a*b) div (gcd (abs a) (abs b)); 
   252  
   252  
   253 fun formlcm x fm = case fm of 
   253 fun formlcm x fm = case fm of 
   254     (Const (p,_)$ _ $(Const ("op +", _)$(Const ("op *",_)$ c $ y ) $z ) ) =>  if 
   254     (Const (p,_)$ _ $(Const ("op +", _)$(Const ("op *",_)$ c $ y ) $z ) ) =>  if 
   255     (is_arith_rel fm) andalso (x = y) then  (abs(dest_numeral c)) else 1 
   255     (is_arith_rel fm) andalso (x = y) then  (abs(dest_numeral c)) else 1 
   453     |_  => foldr (fn(k,r) => r andalso (k mod dn = 0)) true ts
   453     |_  => foldr (fn(k,r) => r andalso (k mod dn = 0)) true ts
   454    end;
   454    end;
   455 
   455 
   456 
   456 
   457 val operations = 
   457 val operations = 
   458   [("op =",op=), ("op <",Int.<), ("op >",Int.>), ("op <=",Int.<=) , 
   458   [("op =",op=), ("op <",IntInf.<), ("op >",IntInf.>), ("op <=",IntInf.<=) , 
   459    ("op >=",Int.>=), 
   459    ("op >=",IntInf.>=), 
   460    ("Divides.op dvd",fn (x,y) =>((y mod x) = 0))]; 
   460    ("Divides.op dvd",fn (x,y) =>((IntInf.mod(y, x)) = 0))]; 
   461  
   461  
   462 fun applyoperation (SOME f) (a,b) = f (a, b) 
   462 fun applyoperation (SOME f) (a,b) = f (a, b) 
   463     |applyoperation _ (_, _) = false; 
   463     |applyoperation _ (_, _) = false; 
   464  
   464  
   465 (*Evaluation of constant atomic formulas*) 
   465 (*Evaluation of constant atomic formulas*) 
   677     |mk_uni_int T (node $ rest) = (mk_uni_int T node) $ (mk_uni_int T rest )  
   677     |mk_uni_int T (node $ rest) = (mk_uni_int T node) $ (mk_uni_int T rest )  
   678     |mk_uni_int T (Abs(AV,AT,p)) = Abs(AV,AT,mk_uni_int T p) 
   678     |mk_uni_int T (Abs(AV,AT,p)) = Abs(AV,AT,mk_uni_int T p) 
   679     |mk_uni_int T tm = tm; 
   679     |mk_uni_int T tm = tm; 
   680  
   680  
   681 
   681 
   682 (* Minusinfinity Version*) 
   682 (* Minusinfinity Version*)    
       
   683 fun myupto (m:IntInf.int) n = if m > n then [] else m::(myupto (m+1) n)
       
   684 
   683 fun coopermi vars1 fm = 
   685 fun coopermi vars1 fm = 
   684   case fm of 
   686   case fm of 
   685    Const ("Ex",_) $ Abs(x0,T,p0) => 
   687    Const ("Ex",_) $ Abs(x0,T,p0) => 
   686    let 
   688    let 
   687     val (xn,p1) = variant_abs (x0,T,p0) 
   689     val (xn,p1) = variant_abs (x0,T,p0) 
   688     val x = Free (xn,T)  
   690     val x = Free (xn,T)  
   689     val vars = (xn::vars1) 
   691     val vars = (xn::vars1) 
   690     val p = unitycoeff x  (posineq (simpl p1))
   692     val p = unitycoeff x  (posineq (simpl p1))
   691     val p_inf = simpl (minusinf x p) 
   693     val p_inf = simpl (minusinf x p) 
   692     val bset = bset x p 
   694     val bset = bset x p 
   693     val js = 1 upto divlcm x p  
   695     val js = myupto 1 (divlcm x p)
   694     fun p_element j b = linrep vars x (linear_add vars b (mk_numeral j)) p  
   696     fun p_element j b = linrep vars x (linear_add vars b (mk_numeral j)) p  
   695     fun stage j = list_disj (linrep vars x (mk_numeral j) p_inf :: map (p_element j) bset)  
   697     fun stage j = list_disj (linrep vars x (mk_numeral j) p_inf :: map (p_element j) bset)  
   696    in (list_disj (map stage js))
   698    in (list_disj (map stage js))
   697     end 
   699     end 
   698   | _ => error "cooper: not an existential formula"; 
   700   | _ => error "cooper: not an existential formula"; 
   707     val x = Free (xn,T)
   709     val x = Free (xn,T)
   708     val vars = (xn::vars1)
   710     val vars = (xn::vars1)
   709     val p = unitycoeff x  (posineq (simpl p1))
   711     val p = unitycoeff x  (posineq (simpl p1))
   710     val p_inf = simpl (plusinf x p)
   712     val p_inf = simpl (plusinf x p)
   711     val aset = aset x p
   713     val aset = aset x p
   712     val js = 1 upto divlcm x p
   714     val js = myupto 1 (divlcm x p)
   713     fun p_element j a = linrep vars x (linear_sub vars a (mk_numeral j)) p
   715     fun p_element j a = linrep vars x (linear_sub vars a (mk_numeral j)) p
   714     fun stage j = list_disj (linrep vars x (mk_numeral j) p_inf :: map (p_element j) aset)
   716     fun stage j = list_disj (linrep vars x (mk_numeral j) p_inf :: map (p_element j) aset)
   715    in (list_disj (map stage js))
   717    in (list_disj (map stage js))
   716    end
   718    end
   717   | _ => error "cooper: not an existential formula";
   719   | _ => error "cooper: not an existential formula";
   745       Const("True",_) => (SOME n,HOLogic.true_const)
   747       Const("True",_) => (SOME n,HOLogic.true_const)
   746       |F' => let val (rw,rf) = h nl 
   748       |F' => let val (rw,rf) = h nl 
   747              in (rw,HOLogic.mk_disj(F',rf)) 
   749              in (rw,HOLogic.mk_disj(F',rf)) 
   748 	     end)
   750 	     end)
   749     val f = if b then linear_add else linear_sub
   751     val f = if b then linear_add else linear_sub
   750     val p_elements = foldr (fn (i,l) => l union (map (fn e => f [] e (mk_numeral i)) st)) [] (1 upto d)
   752     val p_elements = foldr (fn (i,l) => l union (map (fn e => f [] e (mk_numeral i)) st)) [] (myupto 1 d)
   751     in h p_elements
   753     in h p_elements
   752     end;
   754     end;
   753 
   755 
   754 fun withness d b st vars x p = case (inf_w b d vars x p) of 
   756 fun withness d b st vars x p = case (inf_w b d vars x p) of 
   755    (SOME n,_) => (SOME n,HOLogic.true_const)
   757    (SOME n,_) => (SOME n,HOLogic.true_const)
   773     val vars = (xn::vars1)
   775     val vars = (xn::vars1)
   774 (*     val p = unitycoeff x  (posineq (simpl p1)) *)
   776 (*     val p = unitycoeff x  (posineq (simpl p1)) *)
   775     val p = unitycoeff x  p1 
   777     val p = unitycoeff x  p1 
   776     val ast = aset x p
   778     val ast = aset x p
   777     val bst = bset x p
   779     val bst = bset x p
   778     val js = 1 upto divlcm x p
   780     val js = myupto 1 (divlcm x p)
   779     val (p_inf,f,S ) = 
   781     val (p_inf,f,S ) = 
   780     if (length bst) <= (length ast) 
   782     if (length bst) <= (length ast) 
   781      then (simpl (minusinf x p),linear_add,bst)
   783      then (simpl (minusinf x p),linear_add,bst)
   782      else (simpl (plusinf x p), linear_sub,ast)
   784      else (simpl (plusinf x p), linear_sub,ast)
   783     fun p_element j a = linrep vars x (f vars a (mk_numeral j)) p
   785     fun p_element j a = linrep vars x (f vars a (mk_numeral j)) p