src/Tools/isac/Knowledge/Rational.thy
branchisac-update-Isa09-2
changeset 38014 3e11e3c2dc42
parent 38006 16d56796f5a0
child 38015 67ba02dffacc
equal deleted inserted replaced
38013:e4f42a63d665 38014:3e11e3c2dc42
  1322     checks the order of the operators .*)
  1322     checks the order of the operators .*)
  1323 fun test_polynomial (Const ("uminus",_) $ Free (str,_)) _ = true (*WN.13.3.03*)
  1323 fun test_polynomial (Const ("uminus",_) $ Free (str,_)) _ = true (*WN.13.3.03*)
  1324   | test_polynomial (t as Free(str,_)) v = true
  1324   | test_polynomial (t as Free(str,_)) v = true
  1325   | test_polynomial (t as Const ("op *",_) $ t1 $ t2) v = if v="^" then false
  1325   | test_polynomial (t as Const ("op *",_) $ t1 $ t2) v = if v="^" then false
  1326 						     else (test_polynomial t1 "*") andalso (test_polynomial t2 "*")
  1326 						     else (test_polynomial t1 "*") andalso (test_polynomial t2 "*")
  1327   | test_polynomial (t as Const ("op +",_) $ t1 $ t2) v = if v="*" orelse v="^" then false 
  1327   | test_polynomial (t as Const ("Groups.plus_class.plus",_) $ t1 $ t2) v = if v="*" orelse v="^" then false 
  1328 							  else (test_polynomial t1 " ") andalso (test_polynomial t2 " ")
  1328 							  else (test_polynomial t1 " ") andalso (test_polynomial t2 " ")
  1329   | test_polynomial (t as Const ("Atools.pow",_) $ t1 $ t2) v = (test_polynomial t1 "^") andalso (test_polynomial t2 "^")
  1329   | test_polynomial (t as Const ("Atools.pow",_) $ t1 $ t2) v = (test_polynomial t1 "^") andalso (test_polynomial t2 "^")
  1330   | test_polynomial _ v = false;  
  1330   | test_polynomial _ v = false;  
  1331 
  1331 
  1332 (*. tests if a term is a polynomial .*)  
  1332 (*. tests if a term is a polynomial .*)  
  1335 (*. help function for is_expanded 
  1335 (*. help function for is_expanded 
  1336     checks the order of the operators .*)
  1336     checks the order of the operators .*)
  1337 fun test_exp (t as Free(str,_)) v = true 
  1337 fun test_exp (t as Free(str,_)) v = true 
  1338   | test_exp (t as Const ("op *",_) $ t1 $ t2) v = if v="^" then false
  1338   | test_exp (t as Const ("op *",_) $ t1 $ t2) v = if v="^" then false
  1339 						     else (test_exp t1 "*") andalso (test_exp t2 "*")
  1339 						     else (test_exp t1 "*") andalso (test_exp t2 "*")
  1340   | test_exp (t as Const ("op +",_) $ t1 $ t2) v = if v="*" orelse v="^" then false 
  1340   | test_exp (t as Const ("Groups.plus_class.plus",_) $ t1 $ t2) v = if v="*" orelse v="^" then false 
  1341 							  else (test_exp t1 " ") andalso (test_exp t2 " ") 
  1341 							  else (test_exp t1 " ") andalso (test_exp t2 " ") 
  1342   | test_exp (t as Const ("op -",_) $ t1 $ t2) v = if v="*" orelse v="^" then false 
  1342   | test_exp (t as Const ("Groups.minus_class.minus",_) $ t1 $ t2) v = if v="*" orelse v="^" then false 
  1343 							  else (test_exp t1 " ") andalso (test_exp t2 " ")
  1343 							  else (test_exp t1 " ") andalso (test_exp t2 " ")
  1344   | test_exp (t as Const ("Atools.pow",_) $ t1 $ t2) v = (test_exp t1 "^") andalso (test_exp t2 "^")
  1344   | test_exp (t as Const ("Atools.pow",_) $ t1 $ t2) v = (test_exp t1 "^") andalso (test_exp t2 "^")
  1345   | test_exp  _ v = false;
  1345   | test_exp  _ v = false;
  1346 
  1346 
  1347 
  1347 
  1427 	      SOME [(1,rev(!vl))] handle _ => NONE
  1427 	      SOME [(1,rev(!vl))] handle _ => NONE
  1428 	      )
  1428 	      )
  1429      else raise error ("RATIONALS_TERM2COEF_EXCEPTION 1: Invalid term")
  1429      else raise error ("RATIONALS_TERM2COEF_EXCEPTION 1: Invalid term")
  1430 	 )
  1430 	 )
  1431     end
  1431     end
  1432   | term2coef' (Const ("op +",_) $ t1 $ t2) v :mv_poly option= 
  1432   | term2coef' (Const ("Groups.plus_class.plus",_) $ t1 $ t2) v :mv_poly option= 
  1433     (
  1433     (
  1434      SOME ((the(term2coef' t1 v)) @ (the(term2coef' t2 v))) handle _ => NONE
  1434      SOME ((the(term2coef' t1 v)) @ (the(term2coef' t2 v))) handle _ => NONE
  1435 	 )
  1435 	 )
  1436   | term2coef' (Const ("op -",_) $ t1 $ t2) v :mv_poly option= 
  1436   | term2coef' (Const ("Groups.minus_class.minus",_) $ t1 $ t2) v :mv_poly option= 
  1437     (
  1437     (
  1438      SOME ((the(term2coef' t1 v)) @ mv_skalar_mul((the(term2coef' t2 v)),1)) handle _ => NONE
  1438      SOME ((the(term2coef' t1 v)) @ mv_skalar_mul((the(term2coef' t2 v)),1)) handle _ => NONE
  1439 	 )
  1439 	 )
  1440   | term2coef' (term) v = raise error ("RATIONALS_TERM2COEF_EXCEPTION 2: Invalid term");
  1440   | term2coef' (term) v = raise error ("RATIONALS_TERM2COEF_EXCEPTION 2: Invalid term");
  1441 
  1441 
  1542 	      SOME [(1,rev(!vl))] handle _ => NONE
  1542 	      SOME [(1,rev(!vl))] handle _ => NONE
  1543 	      )
  1543 	      )
  1544      else raise error ("RATIONALS_TERM2POLY_EXCEPTION 1: Invalid term")
  1544      else raise error ("RATIONALS_TERM2POLY_EXCEPTION 1: Invalid term")
  1545 	 )
  1545 	 )
  1546     end
  1546     end
  1547   | term2poly' (Const ("op +",_) $ t1 $ t2) v :mv_poly option = 
  1547   | term2poly' (Const ("Groups.plus_class.plus",_) $ t1 $ t2) v :mv_poly option = 
  1548     (
  1548     (
  1549      SOME ((the(term2poly' t1 v)) @ (the(term2poly' t2 v))) handle _ => NONE
  1549      SOME ((the(term2poly' t1 v)) @ (the(term2poly' t2 v))) handle _ => NONE
  1550 	 )
  1550 	 )
  1551   | term2poly' (Const ("op -",_) $ t1 $ t2) v :mv_poly option = 
  1551   | term2poly' (Const ("Groups.minus_class.minus",_) $ t1 $ t2) v :mv_poly option = 
  1552     (
  1552     (
  1553      SOME ((the(term2poly' t1 v)) @ mv_skalar_mul((the(term2poly' t2 v)),~1)) handle _ => NONE
  1553      SOME ((the(term2poly' t1 v)) @ mv_skalar_mul((the(term2poly' t2 v)),~1)) handle _ => NONE
  1554 	 )
  1554 	 )
  1555   | term2poly' (term) v = raise error ("RATIONALS_TERM2POLY_EXCEPTION 2: Invalid term");
  1555   | term2poly' (term) v = raise error ("RATIONALS_TERM2POLY_EXCEPTION 2: Invalid term");
  1556 
  1556 
  1672     
  1672     
  1673 (*. converts the internal polynomial representation into an Isabelle term.*)
  1673 (*. converts the internal polynomial representation into an Isabelle term.*)
  1674 fun poly2term' ([] : mv_poly, vs) = Free(str_of_int 0, HOLogic.realT)  
  1674 fun poly2term' ([] : mv_poly, vs) = Free(str_of_int 0, HOLogic.realT)  
  1675   | poly2term' ([(c, e) : mv_monom], vs) = monom2term ((c, e), vs)
  1675   | poly2term' ([(c, e) : mv_monom], vs) = monom2term ((c, e), vs)
  1676   | poly2term' ((c, e) :: ces, vs) =  
  1676   | poly2term' ((c, e) :: ces, vs) =  
  1677     Const("op +", [HOLogic.realT, HOLogic.realT] ---> HOLogic.realT) $
  1677     Const("Groups.plus_class.plus", [HOLogic.realT, HOLogic.realT] ---> HOLogic.realT) $
  1678          poly2term (ces, vs) $ monom2term ((c, e), vs)
  1678          poly2term (ces, vs) $ monom2term ((c, e), vs)
  1679 and poly2term (xs, vs) = poly2term' (rev (sort (mv_geq LEX_) (xs)), vs);
  1679 and poly2term (xs, vs) = poly2term' (rev (sort (mv_geq LEX_) (xs)), vs);
  1680 
  1680 
  1681 
  1681 
  1682 (*. converts a monom into term representation .*)
  1682 (*. converts a monom into term representation .*)
  1707 (*. converts the expanded polynomial representation into the term representation .*)
  1707 (*. converts the expanded polynomial representation into the term representation .*)
  1708 fun exp2term' ([]:mv_poly,vars) =  Free(str_of_int 0,HOLogic.realT)  
  1708 fun exp2term' ([]:mv_poly,vars) =  Free(str_of_int 0,HOLogic.realT)  
  1709   | exp2term' ([(c,e)],vars) =     monom2term((c,e),vars) 			     
  1709   | exp2term' ([(c,e)],vars) =     monom2term((c,e),vars) 			     
  1710   | exp2term' ((c1,e1)::others,vars) =  
  1710   | exp2term' ((c1,e1)::others,vars) =  
  1711     if c1<0 then 	
  1711     if c1<0 then 	
  1712 	Const("op -",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $
  1712 	Const("Groups.minus_class.minus",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $
  1713 	exp2term'(others,vars) $
  1713 	exp2term'(others,vars) $
  1714 	( 
  1714 	( 
  1715 	 monom2term2((c1,e1),vars)
  1715 	 monom2term2((c1,e1),vars)
  1716 	 ) 
  1716 	 ) 
  1717     else
  1717     else
  1718 	Const("op +",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $
  1718 	Const("Groups.plus_class.plus",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $
  1719 	exp2term'(others,vars) $
  1719 	exp2term'(others,vars) $
  1720 	( 
  1720 	( 
  1721 	 monom2term2((c1,e1),vars)
  1721 	 monom2term2((c1,e1),vars)
  1722 	 );
  1722 	 );
  1723 	
  1723 	
  1741 	SOME (poly2term (the (expanded2poly t vars), vars))
  1741 	SOME (poly2term (the (expanded2poly t vars), vars))
  1742     end) handle _ => NONE;
  1742     end) handle _ => NONE;
  1743 
  1743 
  1744 
  1744 
  1745 (*. calculates the greatest common divisor of numerator and denominator and seperates it from each .*)
  1745 (*. calculates the greatest common divisor of numerator and denominator and seperates it from each .*)
  1746 fun step_cancel (t as Const ("HOL.divide",_) $ p1 $ p2) = 
  1746 fun step_cancel (t as Const ("Rings.inverse_class.divide",_) $ p1 $ p2) = 
  1747     let
  1747     let
  1748 	val p1' = Unsynchronized.ref [];
  1748 	val p1' = Unsynchronized.ref [];
  1749 	val p2' = Unsynchronized.ref [];
  1749 	val p2' = Unsynchronized.ref [];
  1750 	val p3  = Unsynchronized.ref []
  1750 	val p3  = Unsynchronized.ref []
  1751 	val vars = rev(get_vars(p1) union get_vars(p2));
  1751 	val vars = rev(get_vars(p1) union get_vars(p2));
  1754          p1':= sort (mv_geq LEX_) (the (term2poly p1 vars ));
  1754          p1':= sort (mv_geq LEX_) (the (term2poly p1 vars ));
  1755        	 p2':= sort (mv_geq LEX_) (the (term2poly p2 vars ));
  1755        	 p2':= sort (mv_geq LEX_) (the (term2poly p2 vars ));
  1756 	 p3:= sort (mv_geq LEX_) (mv_gcd (!p1') (!p2'));
  1756 	 p3:= sort (mv_geq LEX_) (mv_gcd (!p1') (!p2'));
  1757 	 if (!p3)=[(1,mv_null2(vars))] then 
  1757 	 if (!p3)=[(1,mv_null2(vars))] then 
  1758 	     (
  1758 	     (
  1759 	      Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ p1 $ p2
  1759 	      Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ p1 $ p2
  1760 	      )
  1760 	      )
  1761 	 else
  1761 	 else
  1762 	     (
  1762 	     (
  1763 
  1763 
  1764 	      p1':=sort (mv_geq LEX_) (#1(mv_division((!p1'),(!p3),LEX_)));
  1764 	      p1':=sort (mv_geq LEX_) (#1(mv_division((!p1'),(!p3),LEX_)));
  1765 	      p2':=sort (mv_geq LEX_) (#1(mv_division((!p2'),(!p3),LEX_)));
  1765 	      p2':=sort (mv_geq LEX_) (#1(mv_division((!p2'),(!p3),LEX_)));
  1766 	      
  1766 	      
  1767 	      if #1(hd(sort (mv_geq LEX_) (!p2'))) (*mv_lc2(!p2',LEX_)*)>0 then
  1767 	      if #1(hd(sort (mv_geq LEX_) (!p2'))) (*mv_lc2(!p2',LEX_)*)>0 then
  1768 	      (
  1768 	      (
  1769 	       Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1769 	       Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1770 	       $ 
  1770 	       $ 
  1771 	       (
  1771 	       (
  1772 		Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  1772 		Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  1773 		poly2term(!p1',vars) $ 
  1773 		poly2term(!p1',vars) $ 
  1774 		poly2term(!p3,vars) 
  1774 		poly2term(!p3,vars) 
  1784 	      (
  1784 	      (
  1785 	       p1':=mv_skalar_mul(!p1',~1);
  1785 	       p1':=mv_skalar_mul(!p1',~1);
  1786 	       p2':=mv_skalar_mul(!p2',~1);
  1786 	       p2':=mv_skalar_mul(!p2',~1);
  1787 	       p3:=mv_skalar_mul(!p3,~1);
  1787 	       p3:=mv_skalar_mul(!p3,~1);
  1788 	       (
  1788 	       (
  1789 		Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1789 		Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1790 		$ 
  1790 		$ 
  1791 		(
  1791 		(
  1792 		 Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  1792 		 Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  1793 		 poly2term(!p1',vars) $ 
  1793 		 poly2term(!p1',vars) $ 
  1794 		 poly2term(!p3,vars) 
  1794 		 poly2term(!p3,vars) 
  1806     end
  1806     end
  1807 | step_cancel _ = raise error ("RATIONALS_STEP_CANCEL_EXCEPTION: Invalid fraction"); 
  1807 | step_cancel _ = raise error ("RATIONALS_STEP_CANCEL_EXCEPTION: Invalid fraction"); 
  1808 
  1808 
  1809 
  1809 
  1810 (*. same as step_cancel, this time for expanded forms (input+output) .*)
  1810 (*. same as step_cancel, this time for expanded forms (input+output) .*)
  1811 fun step_cancel_expanded (t as Const ("HOL.divide",_) $ p1 $ p2) = 
  1811 fun step_cancel_expanded (t as Const ("Rings.inverse_class.divide",_) $ p1 $ p2) = 
  1812     let
  1812     let
  1813 	val p1' = Unsynchronized.ref [];
  1813 	val p1' = Unsynchronized.ref [];
  1814 	val p2' = Unsynchronized.ref [];
  1814 	val p2' = Unsynchronized.ref [];
  1815 	val p3  = Unsynchronized.ref []
  1815 	val p3  = Unsynchronized.ref []
  1816 	val vars = rev(get_vars(p1) union get_vars(p2));
  1816 	val vars = rev(get_vars(p1) union get_vars(p2));
  1819          p1':= sort (mv_geq LEX_) (the (expanded2poly p1 vars ));
  1819          p1':= sort (mv_geq LEX_) (the (expanded2poly p1 vars ));
  1820        	 p2':= sort (mv_geq LEX_) (the (expanded2poly p2 vars ));
  1820        	 p2':= sort (mv_geq LEX_) (the (expanded2poly p2 vars ));
  1821 	 p3:= sort (mv_geq LEX_) (mv_gcd (!p1') (!p2'));
  1821 	 p3:= sort (mv_geq LEX_) (mv_gcd (!p1') (!p2'));
  1822 	 if (!p3)=[(1,mv_null2(vars))] then 
  1822 	 if (!p3)=[(1,mv_null2(vars))] then 
  1823 	     (
  1823 	     (
  1824 	      Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ p1 $ p2
  1824 	      Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ p1 $ p2
  1825 	      )
  1825 	      )
  1826 	 else
  1826 	 else
  1827 	     (
  1827 	     (
  1828 
  1828 
  1829 	      p1':=sort (mv_geq LEX_) (#1(mv_division((!p1'),(!p3),LEX_)));
  1829 	      p1':=sort (mv_geq LEX_) (#1(mv_division((!p1'),(!p3),LEX_)));
  1830 	      p2':=sort (mv_geq LEX_) (#1(mv_division((!p2'),(!p3),LEX_)));
  1830 	      p2':=sort (mv_geq LEX_) (#1(mv_division((!p2'),(!p3),LEX_)));
  1831 	      
  1831 	      
  1832 	      if #1(hd(sort (mv_geq LEX_) (!p2')))(* mv_lc2(!p2',LEX_)*)>0 then
  1832 	      if #1(hd(sort (mv_geq LEX_) (!p2')))(* mv_lc2(!p2',LEX_)*)>0 then
  1833 	      (
  1833 	      (
  1834 	       Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1834 	       Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1835 	       $ 
  1835 	       $ 
  1836 	       (
  1836 	       (
  1837 		Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  1837 		Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  1838 		poly2expanded(!p1',vars) $ 
  1838 		poly2expanded(!p1',vars) $ 
  1839 		poly2expanded(!p3,vars) 
  1839 		poly2expanded(!p3,vars) 
  1849 	      (
  1849 	      (
  1850 	       p1':=mv_skalar_mul(!p1',~1);
  1850 	       p1':=mv_skalar_mul(!p1',~1);
  1851 	       p2':=mv_skalar_mul(!p2',~1);
  1851 	       p2':=mv_skalar_mul(!p2',~1);
  1852 	       p3:=mv_skalar_mul(!p3,~1);
  1852 	       p3:=mv_skalar_mul(!p3,~1);
  1853 	       (
  1853 	       (
  1854 		Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1854 		Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1855 		$ 
  1855 		$ 
  1856 		(
  1856 		(
  1857 		 Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  1857 		 Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  1858 		 poly2expanded(!p1',vars) $ 
  1858 		 poly2expanded(!p1',vars) $ 
  1859 		 poly2expanded(!p3,vars) 
  1859 		 poly2expanded(!p3,vars) 
  1870 	     )
  1870 	     )
  1871     end
  1871     end
  1872 | step_cancel_expanded _ = raise error ("RATIONALS_STEP_CANCEL_EXCEPTION: Invalid fraction"); 
  1872 | step_cancel_expanded _ = raise error ("RATIONALS_STEP_CANCEL_EXCEPTION: Invalid fraction"); 
  1873 
  1873 
  1874 (*. calculates the greatest common divisor of numerator and denominator and divides each through it .*)
  1874 (*. calculates the greatest common divisor of numerator and denominator and divides each through it .*)
  1875 fun direct_cancel (t as Const ("HOL.divide",_) $ p1 $ p2) = 
  1875 fun direct_cancel (t as Const ("Rings.inverse_class.divide",_) $ p1 $ p2) = 
  1876     let
  1876     let
  1877 	val p1' = Unsynchronized.ref [];
  1877 	val p1' = Unsynchronized.ref [];
  1878 	val p2' = Unsynchronized.ref [];
  1878 	val p2' = Unsynchronized.ref [];
  1879 	val p3  = Unsynchronized.ref []
  1879 	val p3  = Unsynchronized.ref []
  1880 	val vars = rev(get_vars(p1) union get_vars(p2));
  1880 	val vars = rev(get_vars(p1) union get_vars(p2));
  1884 	 p2':=sort (mv_geq LEX_) (mv_shorten((the (term2poly p2 vars )),LEX_));	 
  1884 	 p2':=sort (mv_geq LEX_) (mv_shorten((the (term2poly p2 vars )),LEX_));	 
  1885 	 p3 :=sort (mv_geq LEX_) (mv_gcd (!p1') (!p2'));
  1885 	 p3 :=sort (mv_geq LEX_) (mv_gcd (!p1') (!p2'));
  1886 
  1886 
  1887 	 if (!p3)=[(1,mv_null2(vars))] then 
  1887 	 if (!p3)=[(1,mv_null2(vars))] then 
  1888 	     (
  1888 	     (
  1889 	      (Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ p1 $ p2,[])
  1889 	      (Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ p1 $ p2,[])
  1890 	      )
  1890 	      )
  1891 	 else
  1891 	 else
  1892 	     (
  1892 	     (
  1893 	      p1':=sort (mv_geq LEX_) (#1(mv_division((!p1'),(!p3),LEX_)));
  1893 	      p1':=sort (mv_geq LEX_) (#1(mv_division((!p1'),(!p3),LEX_)));
  1894 	      p2':=sort (mv_geq LEX_) (#1(mv_division((!p2'),(!p3),LEX_)));
  1894 	      p2':=sort (mv_geq LEX_) (#1(mv_division((!p2'),(!p3),LEX_)));
  1895 	      if #1(hd(sort (mv_geq LEX_) (!p2'))) (*mv_lc2(!p2',LEX_)*)>0 then	      
  1895 	      if #1(hd(sort (mv_geq LEX_) (!p2'))) (*mv_lc2(!p2',LEX_)*)>0 then	      
  1896 	      (
  1896 	      (
  1897 	       (
  1897 	       (
  1898 		Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1898 		Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1899 		$ 
  1899 		$ 
  1900 		(
  1900 		(
  1901 		 poly2term((!p1'),vars)
  1901 		 poly2term((!p1'),vars)
  1902 		 ) 
  1902 		 ) 
  1903 		$ 
  1903 		$ 
  1924 		  (
  1924 		  (
  1925 		   p1':=mv_skalar_mul(!p1',~1);
  1925 		   p1':=mv_skalar_mul(!p1',~1);
  1926 		   p2':=mv_skalar_mul(!p2',~1);
  1926 		   p2':=mv_skalar_mul(!p2',~1);
  1927 		   if length(!p3)> 2*(count_neg(!p3)) then () else p3 :=mv_skalar_mul(!p3,~1); 
  1927 		   if length(!p3)> 2*(count_neg(!p3)) then () else p3 :=mv_skalar_mul(!p3,~1); 
  1928 		       (
  1928 		       (
  1929 			Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1929 			Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1930 			$ 
  1930 			$ 
  1931 			(
  1931 			(
  1932 			 poly2term((!p1'),vars)
  1932 			 poly2term((!p1'),vars)
  1933 			 ) 
  1933 			 ) 
  1934 			$ 
  1934 			$ 
  1955 	     )
  1955 	     )
  1956     end
  1956     end
  1957   | direct_cancel _ = raise error ("RATIONALS_DIRECT_CANCEL_EXCEPTION: Invalid fraction"); 
  1957   | direct_cancel _ = raise error ("RATIONALS_DIRECT_CANCEL_EXCEPTION: Invalid fraction"); 
  1958 
  1958 
  1959 (*. same es direct_cancel, this time for expanded forms (input+output).*) 
  1959 (*. same es direct_cancel, this time for expanded forms (input+output).*) 
  1960 fun direct_cancel_expanded (t as Const ("HOL.divide",_) $ p1 $ p2) =  
  1960 fun direct_cancel_expanded (t as Const ("Rings.inverse_class.divide",_) $ p1 $ p2) =  
  1961     let
  1961     let
  1962 	val p1' = Unsynchronized.ref [];
  1962 	val p1' = Unsynchronized.ref [];
  1963 	val p2' = Unsynchronized.ref [];
  1963 	val p2' = Unsynchronized.ref [];
  1964 	val p3  = Unsynchronized.ref []
  1964 	val p3  = Unsynchronized.ref []
  1965 	val vars = rev(get_vars(p1) union get_vars(p2));
  1965 	val vars = rev(get_vars(p1) union get_vars(p2));
  1969 	 p2':=sort (mv_geq LEX_) (mv_shorten((the (expanded2poly p2 vars )),LEX_));	 
  1969 	 p2':=sort (mv_geq LEX_) (mv_shorten((the (expanded2poly p2 vars )),LEX_));	 
  1970 	 p3 :=sort (mv_geq LEX_) (mv_gcd (!p1') (!p2'));
  1970 	 p3 :=sort (mv_geq LEX_) (mv_gcd (!p1') (!p2'));
  1971 
  1971 
  1972 	 if (!p3)=[(1,mv_null2(vars))] then 
  1972 	 if (!p3)=[(1,mv_null2(vars))] then 
  1973 	     (
  1973 	     (
  1974 	      (Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ p1 $ p2,[])
  1974 	      (Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ p1 $ p2,[])
  1975 	      )
  1975 	      )
  1976 	 else
  1976 	 else
  1977 	     (
  1977 	     (
  1978 	      p1':=sort (mv_geq LEX_) (#1(mv_division((!p1'),(!p3),LEX_)));
  1978 	      p1':=sort (mv_geq LEX_) (#1(mv_division((!p1'),(!p3),LEX_)));
  1979 	      p2':=sort (mv_geq LEX_) (#1(mv_division((!p2'),(!p3),LEX_)));
  1979 	      p2':=sort (mv_geq LEX_) (#1(mv_division((!p2'),(!p3),LEX_)));
  1980 	      if #1(hd(sort (mv_geq LEX_) (!p2'))) (*mv_lc2(!p2',LEX_)*)>0 then	      
  1980 	      if #1(hd(sort (mv_geq LEX_) (!p2'))) (*mv_lc2(!p2',LEX_)*)>0 then	      
  1981 	      (
  1981 	      (
  1982 	       (
  1982 	       (
  1983 		Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1983 		Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  1984 		$ 
  1984 		$ 
  1985 		(
  1985 		(
  1986 		 poly2expanded((!p1'),vars)
  1986 		 poly2expanded((!p1'),vars)
  1987 		 ) 
  1987 		 ) 
  1988 		$ 
  1988 		$ 
  2009 		  (
  2009 		  (
  2010 		   p1':=mv_skalar_mul(!p1',~1);
  2010 		   p1':=mv_skalar_mul(!p1',~1);
  2011 		   p2':=mv_skalar_mul(!p2',~1);
  2011 		   p2':=mv_skalar_mul(!p2',~1);
  2012 		   if length(!p3)> 2*(count_neg(!p3)) then () else p3 :=mv_skalar_mul(!p3,~1); 
  2012 		   if length(!p3)> 2*(count_neg(!p3)) then () else p3 :=mv_skalar_mul(!p3,~1); 
  2013 		       (
  2013 		       (
  2014 			Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2014 			Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2015 			$ 
  2015 			$ 
  2016 			(
  2016 			(
  2017 			 poly2expanded((!p1'),vars)
  2017 			 poly2expanded((!p1'),vars)
  2018 			 ) 
  2018 			 ) 
  2019 			$ 
  2019 			$ 
  2041     end
  2041     end
  2042   | direct_cancel_expanded _ = raise error ("RATIONALS_DIRECT_CANCEL_EXCEPTION: Invalid fraction"); 
  2042   | direct_cancel_expanded _ = raise error ("RATIONALS_DIRECT_CANCEL_EXCEPTION: Invalid fraction"); 
  2043 
  2043 
  2044 
  2044 
  2045 (*. adds two fractions .*)
  2045 (*. adds two fractions .*)
  2046 fun add_fract ((Const("HOL.divide",_) $ t11 $ t12),(Const("HOL.divide",_) $ t21 $ t22)) =
  2046 fun add_fract ((Const("Rings.inverse_class.divide",_) $ t11 $ t12),(Const("Rings.inverse_class.divide",_) $ t21 $ t22)) =
  2047     let
  2047     let
  2048 	val vars=get_vars(t11) union get_vars(t12) union get_vars(t21) union get_vars(t22);
  2048 	val vars=get_vars(t11) union get_vars(t12) union get_vars(t21) union get_vars(t22);
  2049 	val t11'= Unsynchronized.ref  (the(term2poly t11 vars));
  2049 	val t11'= Unsynchronized.ref  (the(term2poly t11 vars));
  2050 val _= writeln"### add_fract: done t11"
  2050 val _= writeln"### add_fract: done t11"
  2051 	val t12'= Unsynchronized.ref  (the(term2poly t12 vars));
  2051 	val t12'= Unsynchronized.ref  (the(term2poly t12 vars));
  2072 				       mv_mul(!t21',!m2,LEX_),
  2072 				       mv_mul(!t21',!m2,LEX_),
  2073 				       LEX_),
  2073 				       LEX_),
  2074 				LEX_));
  2074 				LEX_));
  2075 writeln"### add_fract: done sort mv_add";
  2075 writeln"### add_fract: done sort mv_add";
  2076 	 (
  2076 	 (
  2077 	  Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2077 	  Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2078 	  $ 
  2078 	  $ 
  2079 	  (
  2079 	  (
  2080 	   poly2term((!nom),vars)
  2080 	   poly2term((!nom),vars)
  2081 	   ) 
  2081 	   ) 
  2082 	  $ 
  2082 	  $ 
  2087 	 )	     
  2087 	 )	     
  2088     end 
  2088     end 
  2089   | add_fract (_,_) = raise error ("RATIONALS_ADD_FRACTION_EXCEPTION: Invalid add_fraction call");
  2089   | add_fract (_,_) = raise error ("RATIONALS_ADD_FRACTION_EXCEPTION: Invalid add_fraction call");
  2090 
  2090 
  2091 (*. adds two expanded fractions .*)
  2091 (*. adds two expanded fractions .*)
  2092 fun add_fract_exp ((Const("HOL.divide",_) $ t11 $ t12),(Const("HOL.divide",_) $ t21 $ t22)) =
  2092 fun add_fract_exp ((Const("Rings.inverse_class.divide",_) $ t11 $ t12),(Const("Rings.inverse_class.divide",_) $ t21 $ t22)) =
  2093     let
  2093     let
  2094 	val vars=get_vars(t11) union get_vars(t12) union get_vars(t21) union get_vars(t22);
  2094 	val vars=get_vars(t11) union get_vars(t12) union get_vars(t21) union get_vars(t22);
  2095 	val t11'= Unsynchronized.ref  (the(expanded2poly t11 vars));
  2095 	val t11'= Unsynchronized.ref  (the(expanded2poly t11 vars));
  2096 	val t12'= Unsynchronized.ref  (the(expanded2poly t12 vars));
  2096 	val t12'= Unsynchronized.ref  (the(expanded2poly t12 vars));
  2097 	val t21'= Unsynchronized.ref  (the(expanded2poly t21 vars));
  2097 	val t21'= Unsynchronized.ref  (the(expanded2poly t21 vars));
  2106 	 den :=sort (mv_geq LEX_) (mv_lcm (!t12') (!t22'));
  2106 	 den :=sort (mv_geq LEX_) (mv_lcm (!t12') (!t22'));
  2107 	 m1  :=sort (mv_geq LEX_) (#1(mv_division(!den,!t12',LEX_)));
  2107 	 m1  :=sort (mv_geq LEX_) (#1(mv_division(!den,!t12',LEX_)));
  2108 	 m2  :=sort (mv_geq LEX_) (#1(mv_division(!den,!t22',LEX_)));
  2108 	 m2  :=sort (mv_geq LEX_) (#1(mv_division(!den,!t22',LEX_)));
  2109 	 nom :=sort (mv_geq LEX_) (mv_shorten(mv_add(mv_mul(!t11',!m1,LEX_),mv_mul(!t21',!m2,LEX_),LEX_),LEX_));
  2109 	 nom :=sort (mv_geq LEX_) (mv_shorten(mv_add(mv_mul(!t11',!m1,LEX_),mv_mul(!t21',!m2,LEX_),LEX_),LEX_));
  2110 	 (
  2110 	 (
  2111 	  Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2111 	  Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2112 	  $ 
  2112 	  $ 
  2113 	  (
  2113 	  (
  2114 	   poly2expanded((!nom),vars)
  2114 	   poly2expanded((!nom),vars)
  2115 	   ) 
  2115 	   ) 
  2116 	  $ 
  2116 	  $ 
  2164 fun calc_lcm ([x],var)= (x,var) 
  2164 fun calc_lcm ([x],var)= (x,var) 
  2165   | calc_lcm ((x::xs),var) = (mv_lcm x (#1(calc_lcm (xs,var))),var);
  2165   | calc_lcm ((x::xs),var) = (mv_lcm x (#1(calc_lcm (xs,var))),var);
  2166 
  2166 
  2167 (*. converts a list of terms to a list of mv_poly .*)
  2167 (*. converts a list of terms to a list of mv_poly .*)
  2168 fun t2d([],_)=[] 
  2168 fun t2d([],_)=[] 
  2169   | t2d((t as (Const("HOL.divide",_) $ p1 $ p2))::xs,vars)= (the(term2poly p2 vars)) :: t2d(xs,vars); 
  2169   | t2d((t as (Const("Rings.inverse_class.divide",_) $ p1 $ p2))::xs,vars)= (the(term2poly p2 vars)) :: t2d(xs,vars); 
  2170 
  2170 
  2171 (*. same as t2d, this time for expanded forms .*)
  2171 (*. same as t2d, this time for expanded forms .*)
  2172 fun t2d_exp([],_)=[]  
  2172 fun t2d_exp([],_)=[]  
  2173   | t2d_exp((t as (Const("HOL.divide",_) $ p1 $ p2))::xs,vars)= (the(expanded2poly p2 vars)) :: t2d_exp(xs,vars);
  2173   | t2d_exp((t as (Const("Rings.inverse_class.divide",_) $ p1 $ p2))::xs,vars)= (the(expanded2poly p2 vars)) :: t2d_exp(xs,vars);
  2174 
  2174 
  2175 (*. converts a list of fract terms to a list of their denominators .*)
  2175 (*. converts a list of fract terms to a list of their denominators .*)
  2176 fun termlist2denominators [] = ([],[])
  2176 fun termlist2denominators [] = ([],[])
  2177   | termlist2denominators xs = 
  2177   | termlist2denominators xs = 
  2178     let	
  2178     let	
  2181     in
  2181     in
  2182 	var:=[];
  2182 	var:=[];
  2183 	while length(!xxs)>0 do
  2183 	while length(!xxs)>0 do
  2184 	    (
  2184 	    (
  2185 	     let 
  2185 	     let 
  2186 		 val (t as Const ("HOL.divide",_) $ p1x $ p2x)=hd(!xxs);
  2186 		 val (t as Const ("Rings.inverse_class.divide",_) $ p1x $ p2x)=hd(!xxs);
  2187 	     in
  2187 	     in
  2188 		 (
  2188 		 (
  2189 		  xxs:=tl(!xxs);
  2189 		  xxs:=tl(!xxs);
  2190 		  var:=((get_vars(p2x)) union (get_vars(p1x)) union (!var))
  2190 		  var:=((get_vars(p2x)) union (get_vars(p1x)) union (!var))
  2191 		  )
  2191 		  )
  2198 fun calc_lcm ([x],var)= (x,var) 
  2198 fun calc_lcm ([x],var)= (x,var) 
  2199   | calc_lcm ((x::xs),var) = (mv_lcm x (#1(calc_lcm (xs,var))),var);
  2199   | calc_lcm ((x::xs),var) = (mv_lcm x (#1(calc_lcm (xs,var))),var);
  2200 
  2200 
  2201 (*. converts a list of terms to a list of mv_poly .*)
  2201 (*. converts a list of terms to a list of mv_poly .*)
  2202 fun t2d([],_)=[] 
  2202 fun t2d([],_)=[] 
  2203   | t2d((t as (Const("HOL.divide",_) $ p1 $ p2))::xs,vars)= (the(term2poly p2 vars)) :: t2d(xs,vars); 
  2203   | t2d((t as (Const("Rings.inverse_class.divide",_) $ p1 $ p2))::xs,vars)= (the(term2poly p2 vars)) :: t2d(xs,vars); 
  2204 
  2204 
  2205 (*. same as t2d, this time for expanded forms .*)
  2205 (*. same as t2d, this time for expanded forms .*)
  2206 fun t2d_exp([],_)=[]  
  2206 fun t2d_exp([],_)=[]  
  2207   | t2d_exp((t as (Const("HOL.divide",_) $ p1 $ p2))::xs,vars)= (the(expanded2poly p2 vars)) :: t2d_exp(xs,vars);
  2207   | t2d_exp((t as (Const("Rings.inverse_class.divide",_) $ p1 $ p2))::xs,vars)= (the(expanded2poly p2 vars)) :: t2d_exp(xs,vars);
  2208 
  2208 
  2209 (*. converts a list of fract terms to a list of their denominators .*)
  2209 (*. converts a list of fract terms to a list of their denominators .*)
  2210 fun termlist2denominators [] = ([],[])
  2210 fun termlist2denominators [] = ([],[])
  2211   | termlist2denominators xs = 
  2211   | termlist2denominators xs = 
  2212     let	
  2212     let	
  2215     in
  2215     in
  2216 	var:=[];
  2216 	var:=[];
  2217 	while length(!xxs)>0 do
  2217 	while length(!xxs)>0 do
  2218 	    (
  2218 	    (
  2219 	     let 
  2219 	     let 
  2220 		 val (t as Const ("HOL.divide",_) $ p1x $ p2x)=hd(!xxs);
  2220 		 val (t as Const ("Rings.inverse_class.divide",_) $ p1x $ p2x)=hd(!xxs);
  2221 	     in
  2221 	     in
  2222 		 (
  2222 		 (
  2223 		  xxs:=tl(!xxs);
  2223 		  xxs:=tl(!xxs);
  2224 		  var:=((get_vars(p2x)) union (get_vars(p1x)) union (!var))
  2224 		  var:=((get_vars(p2x)) union (get_vars(p1x)) union (!var))
  2225 		  )
  2225 		  )
  2237     in
  2237     in
  2238 	var:=[];
  2238 	var:=[];
  2239 	while length(!xxs)>0 do
  2239 	while length(!xxs)>0 do
  2240 	    (
  2240 	    (
  2241 	     let 
  2241 	     let 
  2242 		 val (t as Const ("HOL.divide",_) $ p1x $ p2x)=hd(!xxs);
  2242 		 val (t as Const ("Rings.inverse_class.divide",_) $ p1x $ p2x)=hd(!xxs);
  2243 	     in
  2243 	     in
  2244 		 (
  2244 		 (
  2245 		  xxs:=tl(!xxs);
  2245 		  xxs:=tl(!xxs);
  2246 		  var:=((get_vars(p2x)) union (get_vars(p1x)) union (!var))
  2246 		  var:=((get_vars(p2x)) union (get_vars(p1x)) union (!var))
  2247 		  )
  2247 		  )
  2251     end;
  2251     end;
  2252 
  2252 
  2253 (*. reduces all fractions to the least common denominator .*)
  2253 (*. reduces all fractions to the least common denominator .*)
  2254 fun com_den(x::xs,denom,den,var)=
  2254 fun com_den(x::xs,denom,den,var)=
  2255     let 
  2255     let 
  2256 	val (t as Const ("HOL.divide",_) $ p1' $ p2')=x;
  2256 	val (t as Const ("Rings.inverse_class.divide",_) $ p1' $ p2')=x;
  2257 	val p2= sort (mv_geq LEX_) (the(term2poly p2' var));
  2257 	val p2= sort (mv_geq LEX_) (the(term2poly p2' var));
  2258 	val p3= #1(mv_division(denom,p2,LEX_));
  2258 	val p3= #1(mv_division(denom,p2,LEX_));
  2259 	val p1var=get_vars(p1');
  2259 	val p1var=get_vars(p1');
  2260     in     
  2260     in     
  2261 	if length(xs)>0 then 
  2261 	if length(xs)>0 then 
  2262 	    if p3=[(1,mv_null2(var))] then
  2262 	    if p3=[(1,mv_null2(var))] then
  2263 		(
  2263 		(
  2264 		 Const ("op +",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT)
  2264 		 Const ("Groups.plus_class.plus",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT)
  2265 		 $ 
  2265 		 $ 
  2266 		 (
  2266 		 (
  2267 		  Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2267 		  Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2268 		  $ 
  2268 		  $ 
  2269 		  poly2term(the (term2poly p1' p1var),p1var)
  2269 		  poly2term(the (term2poly p1' p1var),p1var)
  2270 		  $ 
  2270 		  $ 
  2271 		  den	
  2271 		  den	
  2272 		  )    
  2272 		  )    
  2275 		,
  2275 		,
  2276 		[]
  2276 		[]
  2277 		)
  2277 		)
  2278 	    else
  2278 	    else
  2279 		(
  2279 		(
  2280 		 Const ("op +",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2280 		 Const ("Groups.plus_class.plus",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2281 		 $ 
  2281 		 $ 
  2282 		 (
  2282 		 (
  2283 		  Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2283 		  Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2284 		  $ 
  2284 		  $ 
  2285 		  (
  2285 		  (
  2286 		   Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2286 		   Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2287 		   poly2term(the (term2poly p1' p1var),p1var) $ 
  2287 		   poly2term(the (term2poly p1' p1var),p1var) $ 
  2288 		   poly2term(p3,var)
  2288 		   poly2term(p3,var)
  2299 		)
  2299 		)
  2300 	else
  2300 	else
  2301 	    if p3=[(1,mv_null2(var))] then
  2301 	    if p3=[(1,mv_null2(var))] then
  2302 		(
  2302 		(
  2303 		 (
  2303 		 (
  2304 		  Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2304 		  Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2305 		  $ 
  2305 		  $ 
  2306 		  poly2term(the (term2poly p1' p1var),p1var)
  2306 		  poly2term(the (term2poly p1' p1var),p1var)
  2307 		  $ 
  2307 		  $ 
  2308 		  den	
  2308 		  den	
  2309 		  )
  2309 		  )
  2310 		 ,
  2310 		 ,
  2311 		 []
  2311 		 []
  2312 		 )
  2312 		 )
  2313 	     else
  2313 	     else
  2314 		 (
  2314 		 (
  2315 		  Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2315 		  Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2316 		  $ 
  2316 		  $ 
  2317 		  (
  2317 		  (
  2318 		   Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2318 		   Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2319 		   poly2term(the (term2poly p1' p1var),p1var) $ 
  2319 		   poly2term(the (term2poly p1' p1var),p1var) $ 
  2320 		   poly2term(p3,var)
  2320 		   poly2term(p3,var)
  2327     end;
  2327     end;
  2328 
  2328 
  2329 (*. same as com_den, this time for expanded forms .*)
  2329 (*. same as com_den, this time for expanded forms .*)
  2330 fun com_den_exp(x::xs,denom,den,var)=
  2330 fun com_den_exp(x::xs,denom,den,var)=
  2331     let 
  2331     let 
  2332 	val (t as Const ("HOL.divide",_) $ p1' $ p2')=x;
  2332 	val (t as Const ("Rings.inverse_class.divide",_) $ p1' $ p2')=x;
  2333 	val p2= sort (mv_geq LEX_) (the(expanded2poly p2' var));
  2333 	val p2= sort (mv_geq LEX_) (the(expanded2poly p2' var));
  2334 	val p3= #1(mv_division(denom,p2,LEX_));
  2334 	val p3= #1(mv_division(denom,p2,LEX_));
  2335 	val p1var=get_vars(p1');
  2335 	val p1var=get_vars(p1');
  2336     in     
  2336     in     
  2337 	if length(xs)>0 then 
  2337 	if length(xs)>0 then 
  2338 	    if p3=[(1,mv_null2(var))] then
  2338 	    if p3=[(1,mv_null2(var))] then
  2339 		(
  2339 		(
  2340 		 Const ("op +",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT)
  2340 		 Const ("Groups.plus_class.plus",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT)
  2341 		 $ 
  2341 		 $ 
  2342 		 (
  2342 		 (
  2343 		  Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2343 		  Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2344 		  $ 
  2344 		  $ 
  2345 		  poly2expanded(the(expanded2poly p1' p1var),p1var)
  2345 		  poly2expanded(the(expanded2poly p1' p1var),p1var)
  2346 		  $ 
  2346 		  $ 
  2347 		  den	
  2347 		  den	
  2348 		  )    
  2348 		  )    
  2351 		,
  2351 		,
  2352 		[]
  2352 		[]
  2353 		)
  2353 		)
  2354 	    else
  2354 	    else
  2355 		(
  2355 		(
  2356 		 Const ("op +",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2356 		 Const ("Groups.plus_class.plus",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2357 		 $ 
  2357 		 $ 
  2358 		 (
  2358 		 (
  2359 		  Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2359 		  Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2360 		  $ 
  2360 		  $ 
  2361 		  (
  2361 		  (
  2362 		   Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2362 		   Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2363 		   poly2expanded(the(expanded2poly p1' p1var),p1var) $ 
  2363 		   poly2expanded(the(expanded2poly p1' p1var),p1var) $ 
  2364 		   poly2expanded(p3,var)
  2364 		   poly2expanded(p3,var)
  2375 		)
  2375 		)
  2376 	else
  2376 	else
  2377 	    if p3=[(1,mv_null2(var))] then
  2377 	    if p3=[(1,mv_null2(var))] then
  2378 		(
  2378 		(
  2379 		 (
  2379 		 (
  2380 		  Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2380 		  Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2381 		  $ 
  2381 		  $ 
  2382 		  poly2expanded(the(expanded2poly p1' p1var),p1var)
  2382 		  poly2expanded(the(expanded2poly p1' p1var),p1var)
  2383 		  $ 
  2383 		  $ 
  2384 		  den	
  2384 		  den	
  2385 		  )
  2385 		  )
  2386 		 ,
  2386 		 ,
  2387 		 []
  2387 		 []
  2388 		 )
  2388 		 )
  2389 	     else
  2389 	     else
  2390 		 (
  2390 		 (
  2391 		  Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2391 		  Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) 
  2392 		  $ 
  2392 		  $ 
  2393 		  (
  2393 		  (
  2394 		   Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2394 		   Const ("op *",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2395 		   poly2expanded(the(expanded2poly p1' p1var),p1var) $ 
  2395 		   poly2expanded(the(expanded2poly p1' p1var),p1var) $ 
  2396 		   poly2expanded(p3,var)
  2396 		   poly2expanded(p3,var)
  2405 (* wird aktuell nicht mehr gebraucht, bei rückänderung schon 
  2405 (* wird aktuell nicht mehr gebraucht, bei rückänderung schon 
  2406 -------------------------------------------------------------
  2406 -------------------------------------------------------------
  2407 (* WN0210???SK brauch ma des überhaupt *)
  2407 (* WN0210???SK brauch ma des überhaupt *)
  2408 fun com_den2(x::xs,denom,den,var)=
  2408 fun com_den2(x::xs,denom,den,var)=
  2409     let 
  2409     let 
  2410 	val (t as Const ("HOL.divide",_) $ p1' $ p2')=x;
  2410 	val (t as Const ("Rings.inverse_class.divide",_) $ p1' $ p2')=x;
  2411 	val p2= sort (mv_geq LEX_) (the(term2poly p2' var));
  2411 	val p2= sort (mv_geq LEX_) (the(term2poly p2' var));
  2412 	val p3= #1(mv_division(denom,p2,LEX_));
  2412 	val p3= #1(mv_division(denom,p2,LEX_));
  2413 	val p1var=get_vars(p1');
  2413 	val p1var=get_vars(p1');
  2414     in     
  2414     in     
  2415 	if length(xs)>0 then 
  2415 	if length(xs)>0 then 
  2416 	    if p3=[(1,mv_null2(var))] then
  2416 	    if p3=[(1,mv_null2(var))] then
  2417 		(
  2417 		(
  2418 		 Const ("op +",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2418 		 Const ("Groups.plus_class.plus",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2419 		 poly2term(the(term2poly p1' p1var),p1var) $ 
  2419 		 poly2term(the(term2poly p1' p1var),p1var) $ 
  2420 		 com_den2(xs,denom,den,var)
  2420 		 com_den2(xs,denom,den,var)
  2421 		)
  2421 		)
  2422 	    else
  2422 	    else
  2423 		(
  2423 		(
  2424 		 Const ("op +",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2424 		 Const ("Groups.plus_class.plus",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2425 		 (
  2425 		 (
  2426 		   let 
  2426 		   let 
  2427 		       val p3'=poly2term(p3,var);
  2427 		       val p3'=poly2term(p3,var);
  2428 		       val vars= (((map free2str) o vars) p1') union (((map free2str) o vars) p3');
  2428 		       val vars= (((map free2str) o vars) p1') union (((map free2str) o vars) p3');
  2429 		   in
  2429 		   in
  2449     end;
  2449     end;
  2450 
  2450 
  2451 (* WN0210???SK brauch ma des überhaupt *)
  2451 (* WN0210???SK brauch ma des überhaupt *)
  2452 fun com_den_exp2(x::xs,denom,den,var)=
  2452 fun com_den_exp2(x::xs,denom,den,var)=
  2453     let 
  2453     let 
  2454 	val (t as Const ("HOL.divide",_) $ p1' $ p2')=x;
  2454 	val (t as Const ("Rings.inverse_class.divide",_) $ p1' $ p2')=x;
  2455 	val p2= sort (mv_geq LEX_) (the(expanded2poly p2' var));
  2455 	val p2= sort (mv_geq LEX_) (the(expanded2poly p2' var));
  2456 	val p3= #1(mv_division(denom,p2,LEX_));
  2456 	val p3= #1(mv_division(denom,p2,LEX_));
  2457 	val p1var=get_vars p1';
  2457 	val p1var=get_vars p1';
  2458     in     
  2458     in     
  2459 	if length(xs)>0 then 
  2459 	if length(xs)>0 then 
  2460 	    if p3=[(1,mv_null2(var))] then
  2460 	    if p3=[(1,mv_null2(var))] then
  2461 		(
  2461 		(
  2462 		 Const ("op +",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2462 		 Const ("Groups.plus_class.plus",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2463 		 poly2expanded(the (expanded2poly p1' p1var),p1var) $ 
  2463 		 poly2expanded(the (expanded2poly p1' p1var),p1var) $ 
  2464 		 com_den_exp2(xs,denom,den,var)
  2464 		 com_den_exp2(xs,denom,den,var)
  2465 		)
  2465 		)
  2466 	    else
  2466 	    else
  2467 		(
  2467 		(
  2468 		 Const ("op +",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2468 		 Const ("Groups.plus_class.plus",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2469 		 (
  2469 		 (
  2470 		   let 
  2470 		   let 
  2471 		       val p3'=poly2expanded(p3,var);
  2471 		       val p3'=poly2expanded(p3,var);
  2472 		       val vars= (((map free2str) o vars) p1') union (((map free2str) o vars) p3');
  2472 		       val vars= (((map free2str) o vars) p1') union (((map free2str) o vars) p3');
  2473 		   in
  2473 		   in
  2642         val den_list=termlist2denominators (xs); (* list of denominators *)
  2642         val den_list=termlist2denominators (xs); (* list of denominators *)
  2643 	val (denom,var)=calc_lcm(den_list);      (* common denominator *)
  2643 	val (denom,var)=calc_lcm(den_list);      (* common denominator *)
  2644 	val den=factorize_den(#1(den_list),denom,var);  (* faktorisierter Nenner !!! *)
  2644 	val den=factorize_den(#1(den_list),denom,var);  (* faktorisierter Nenner !!! *)
  2645     in
  2645     in
  2646 	(
  2646 	(
  2647 	 Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2647 	 Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2648 	 com_den2(xs,denom, poly2term(denom,var)(*den*),var) $
  2648 	 com_den2(xs,denom, poly2term(denom,var)(*den*),var) $
  2649 	 poly2term(denom,var)
  2649 	 poly2term(denom,var)
  2650 	,
  2650 	,
  2651 	[]
  2651 	[]
  2652 	)
  2652 	)
  2660         val den_list=termlist2denominators_exp (xs); (* list of denominators *)
  2660         val den_list=termlist2denominators_exp (xs); (* list of denominators *)
  2661 	val (denom,var)=calc_lcm(den_list);      (* common denominator *)
  2661 	val (denom,var)=calc_lcm(den_list);      (* common denominator *)
  2662 	val den=factorize_den_exp(#1(den_list),denom,var);  (* faktorisierter Nenner !!! *)
  2662 	val den=factorize_den_exp(#1(den_list),denom,var);  (* faktorisierter Nenner !!! *)
  2663     in
  2663     in
  2664 	(
  2664 	(
  2665 	 Const ("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2665 	 Const ("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2666 	 com_den_exp2(xs,denom, poly2term(denom,var)(*den*),var) $
  2666 	 com_den_exp2(xs,denom, poly2term(denom,var)(*den*),var) $
  2667 	 poly2expanded(denom,var)
  2667 	 poly2expanded(denom,var)
  2668 	,
  2668 	,
  2669 	[]
  2669 	[]
  2670 	)
  2670 	)
  2671     end;
  2671     end;
  2672 ---------------------------------------------- *)
  2672 ---------------------------------------------- *)
  2673 
  2673 
  2674 
  2674 
  2675 (*. converts a term, which contains severel terms seperated by +, into a list of these terms .*)
  2675 (*. converts a term, which contains severel terms seperated by +, into a list of these terms .*)
  2676 fun term2list (t as (Const("HOL.divide",_) $ _ $ _)) = [t]
  2676 fun term2list (t as (Const("Rings.inverse_class.divide",_) $ _ $ _)) = [t]
  2677   | term2list (t as (Const("Atools.pow",_) $ _ $ _)) = 
  2677   | term2list (t as (Const("Atools.pow",_) $ _ $ _)) = 
  2678     [Const("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2678     [Const("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2679 	  t $ Free("1",HOLogic.realT)
  2679 	  t $ Free("1",HOLogic.realT)
  2680      ]
  2680      ]
  2681   | term2list (t as (Free(_,_))) = 
  2681   | term2list (t as (Free(_,_))) = 
  2682     [Const("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2682     [Const("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2683 	  t $  Free("1",HOLogic.realT)
  2683 	  t $  Free("1",HOLogic.realT)
  2684      ]
  2684      ]
  2685   | term2list (t as (Const("op *",_) $ _ $ _)) = 
  2685   | term2list (t as (Const("op *",_) $ _ $ _)) = 
  2686     [Const("HOL.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2686     [Const("Rings.inverse_class.divide",[HOLogic.realT,HOLogic.realT]--->HOLogic.realT) $ 
  2687 	  t $ Free("1",HOLogic.realT)
  2687 	  t $ Free("1",HOLogic.realT)
  2688      ]
  2688      ]
  2689   | term2list (Const("op +",_) $ t1 $ t2) = term2list(t1) @ term2list(t2)
  2689   | term2list (Const("Groups.plus_class.plus",_) $ t1 $ t2) = term2list(t1) @ term2list(t2)
  2690   | term2list (Const("op -",_) $ t1 $ t2) = 
  2690   | term2list (Const("Groups.minus_class.minus",_) $ t1 $ t2) = 
  2691     raise error ("RATIONALS_TERM2LIST_EXCEPTION: - not implemented yet")
  2691     raise error ("RATIONALS_TERM2LIST_EXCEPTION: - not implemented yet")
  2692   | term2list _ = raise error ("RATIONALS_TERM2LIST_EXCEPTION: invalid term");
  2692   | term2list _ = raise error ("RATIONALS_TERM2LIST_EXCEPTION: invalid term");
  2693 
  2693 
  2694 (*.factors out the gcd of nominator and denominator:
  2694 (*.factors out the gcd of nominator and denominator:
  2695    a/b = (a' * gcd)/(b' * gcd),  a,b,gcd  are poly[2].*)
  2695    a/b = (a' * gcd)/(b' * gcd),  a,b,gcd  are poly[2].*)
  2778     merge_rls "calculate_Rational"
  2778     merge_rls "calculate_Rational"
  2779 	(Rls {id = "divide", preconds = [], rew_ord = ("dummy_ord",dummy_ord), 
  2779 	(Rls {id = "divide", preconds = [], rew_ord = ("dummy_ord",dummy_ord), 
  2780 	      erls = calc_rat_erls, srls = Erls, (*asm_thm = [],*) 
  2780 	      erls = calc_rat_erls, srls = Erls, (*asm_thm = [],*) 
  2781 	      calc = [], 
  2781 	      calc = [], 
  2782 	      rules = 
  2782 	      rules = 
  2783 	      [Calc ("HOL.divide"  ,eval_cancel "#divide_e"),
  2783 	      [Calc ("Rings.inverse_class.divide"  ,eval_cancel "#divide_e"),
  2784 	       
  2784 	       
  2785 	       Thm ("minus_divide_left",
  2785 	       Thm ("minus_divide_left",
  2786 		    num_str (@{thm minus_divide_left} RS @{thm sym})),
  2786 		    num_str (@{thm minus_divide_left} RS @{thm sym})),
  2787 	       (*SYM - ?x / ?y = - (?x / ?y)  may come from subst*)
  2787 	       (*SYM - ?x / ?y = - (?x / ?y)  may come from subst*)
  2788 	       
  2788 	       
  2999 val cancel_p =
  2999 val cancel_p =
  3000     Rrls {id = "cancel_p", prepat=[],
  3000     Rrls {id = "cancel_p", prepat=[],
  3001 	  rew_ord=("ord_make_polynomial",
  3001 	  rew_ord=("ord_make_polynomial",
  3002 		   ord_make_polynomial false thy),
  3002 		   ord_make_polynomial false thy),
  3003 	  erls = rational_erls,
  3003 	  erls = rational_erls,
  3004 	  calc = [("PLUS"    ,("op +"        ,eval_binop "#add_")),
  3004 	  calc = [("PLUS"    ,("Groups.plus_class.plus"        ,eval_binop "#add_")),
  3005 		  ("TIMES"   ,("op *"        ,eval_binop "#mult_")),
  3005 		  ("TIMES"   ,("op *"        ,eval_binop "#mult_")),
  3006 		  ("DIVIDE" ,("HOL.divide"  ,eval_cancel "#divide_e")),
  3006 		  ("DIVIDE" ,("Rings.inverse_class.divide"  ,eval_cancel "#divide_e")),
  3007 		  ("POWER"  ,("Atools.pow"  ,eval_binop "#power_"))],
  3007 		  ("POWER"  ,("Atools.pow"  ,eval_binop "#power_"))],
  3008 	  (*asm_thm=[("real_mult_div_cancel2","")],*)
  3008 	  (*asm_thm=[("real_mult_div_cancel2","")],*)
  3009 	  scr=Rfuns {init_state  = init_state thy Atools_erls ro,
  3009 	  scr=Rfuns {init_state  = init_state thy Atools_erls ro,
  3010 		     normal_form = cancel_p_ thy,
  3010 		     normal_form = cancel_p_ thy,
  3011 		     locate_rule = locate_rule thy Atools_erls ro,
  3011 		     locate_rule = locate_rule thy Atools_erls ro,
  3081 val cancel = 
  3081 val cancel = 
  3082     Rrls {id = "cancel", prepat=prepat,
  3082     Rrls {id = "cancel", prepat=prepat,
  3083 	  rew_ord=("ord_make_polynomial",
  3083 	  rew_ord=("ord_make_polynomial",
  3084 		   ord_make_polynomial false thy),
  3084 		   ord_make_polynomial false thy),
  3085 	  erls = rational_erls, 
  3085 	  erls = rational_erls, 
  3086 	  calc = [("PLUS"    ,("op +"        ,eval_binop "#add_")),
  3086 	  calc = [("PLUS"    ,("Groups.plus_class.plus"        ,eval_binop "#add_")),
  3087 		  ("TIMES"   ,("op *"        ,eval_binop "#mult_")),
  3087 		  ("TIMES"   ,("op *"        ,eval_binop "#mult_")),
  3088 		  ("DIVIDE" ,("HOL.divide"  ,eval_cancel "#divide_e")),
  3088 		  ("DIVIDE" ,("Rings.inverse_class.divide"  ,eval_cancel "#divide_e")),
  3089 		  ("POWER"  ,("Atools.pow"  ,eval_binop "#power_"))],
  3089 		  ("POWER"  ,("Atools.pow"  ,eval_binop "#power_"))],
  3090 	  scr=Rfuns {init_state  = init_state thy Atools_erls ro,
  3090 	  scr=Rfuns {init_state  = init_state thy Atools_erls ro,
  3091 		     normal_form = cancel_ thy, 
  3091 		     normal_form = cancel_ thy, 
  3092 		     locate_rule = locate_rule thy Atools_erls ro,
  3092 		     locate_rule = locate_rule thy Atools_erls ro,
  3093 		     next_rule   = next_rule thy Atools_erls ro,
  3093 		     next_rule   = next_rule thy Atools_erls ro,
  3233 val common_nominator_p =
  3233 val common_nominator_p =
  3234     Rrls {id = "common_nominator_p", prepat=prepat,
  3234     Rrls {id = "common_nominator_p", prepat=prepat,
  3235 	  rew_ord=("ord_make_polynomial",
  3235 	  rew_ord=("ord_make_polynomial",
  3236 		   ord_make_polynomial false thy),
  3236 		   ord_make_polynomial false thy),
  3237 	  erls = rational_erls,
  3237 	  erls = rational_erls,
  3238 	  calc = [("PLUS"    ,("op +"        ,eval_binop "#add_")),
  3238 	  calc = [("PLUS"    ,("Groups.plus_class.plus"        ,eval_binop "#add_")),
  3239 		  ("TIMES"   ,("op *"        ,eval_binop "#mult_")),
  3239 		  ("TIMES"   ,("op *"        ,eval_binop "#mult_")),
  3240 		  ("DIVIDE" ,("HOL.divide"  ,eval_cancel "#divide_e")),
  3240 		  ("DIVIDE" ,("Rings.inverse_class.divide"  ,eval_cancel "#divide_e")),
  3241 		  ("POWER"  ,("Atools.pow"  ,eval_binop "#power_"))],
  3241 		  ("POWER"  ,("Atools.pow"  ,eval_binop "#power_"))],
  3242 	  scr=Rfuns {init_state  = init_state thy Atools_erls ro,
  3242 	  scr=Rfuns {init_state  = init_state thy Atools_erls ro,
  3243 		     normal_form = add_fraction_p_ thy,(*FIXME.WN0211*)
  3243 		     normal_form = add_fraction_p_ thy,(*FIXME.WN0211*)
  3244 		     locate_rule = locate_rule thy Atools_erls ro,
  3244 		     locate_rule = locate_rule thy Atools_erls ro,
  3245 		     next_rule   = next_rule thy Atools_erls ro,
  3245 		     next_rule   = next_rule thy Atools_erls ro,
  3381 val common_nominator =
  3381 val common_nominator =
  3382     Rrls {id = "common_nominator", prepat=prepat,
  3382     Rrls {id = "common_nominator", prepat=prepat,
  3383 	  rew_ord=("ord_make_polynomial",
  3383 	  rew_ord=("ord_make_polynomial",
  3384 		   ord_make_polynomial false thy),
  3384 		   ord_make_polynomial false thy),
  3385 	  erls = rational_erls,
  3385 	  erls = rational_erls,
  3386 	  calc = [("PLUS"    ,("op +"        ,eval_binop "#add_")),
  3386 	  calc = [("PLUS"    ,("Groups.plus_class.plus"        ,eval_binop "#add_")),
  3387 		  ("TIMES"   ,("op *"        ,eval_binop "#mult_")),
  3387 		  ("TIMES"   ,("op *"        ,eval_binop "#mult_")),
  3388 		  ("DIVIDE" ,("HOL.divide"  ,eval_cancel "#divide_e")),
  3388 		  ("DIVIDE" ,("Rings.inverse_class.divide"  ,eval_cancel "#divide_e")),
  3389 		  ("POWER"  ,("Atools.pow"  ,eval_binop "#power_"))],
  3389 		  ("POWER"  ,("Atools.pow"  ,eval_binop "#power_"))],
  3390 	  (*asm_thm=[("real_mult_div_cancel2","")],*)
  3390 	  (*asm_thm=[("real_mult_div_cancel2","")],*)
  3391 	  scr=Rfuns {init_state  = init_state thy Atools_erls ro,
  3391 	  scr=Rfuns {init_state  = init_state thy Atools_erls ro,
  3392 		     normal_form = add_fraction_ (*NOT common_nominator_*) thy,
  3392 		     normal_form = add_fraction_ (*NOT common_nominator_*) thy,
  3393 		     locate_rule = locate_rule thy Atools_erls ro,
  3393 		     locate_rule = locate_rule thy Atools_erls ro,
  3400 open RationalI;
  3400 open RationalI;
  3401 (*##*)
  3401 (*##*)
  3402 
  3402 
  3403 (*.the expression contains + - * ^ / only ?.*)
  3403 (*.the expression contains + - * ^ / only ?.*)
  3404 fun is_ratpolyexp (Free _) = true
  3404 fun is_ratpolyexp (Free _) = true
  3405   | is_ratpolyexp (Const ("op +",_) $ Free _ $ Free _) = true
  3405   | is_ratpolyexp (Const ("Groups.plus_class.plus",_) $ Free _ $ Free _) = true
  3406   | is_ratpolyexp (Const ("op -",_) $ Free _ $ Free _) = true
  3406   | is_ratpolyexp (Const ("Groups.minus_class.minus",_) $ Free _ $ Free _) = true
  3407   | is_ratpolyexp (Const ("op *",_) $ Free _ $ Free _) = true
  3407   | is_ratpolyexp (Const ("op *",_) $ Free _ $ Free _) = true
  3408   | is_ratpolyexp (Const ("Atools.pow",_) $ Free _ $ Free _) = true
  3408   | is_ratpolyexp (Const ("Atools.pow",_) $ Free _ $ Free _) = true
  3409   | is_ratpolyexp (Const ("HOL.divide",_) $ Free _ $ Free _) = true
  3409   | is_ratpolyexp (Const ("Rings.inverse_class.divide",_) $ Free _ $ Free _) = true
  3410   | is_ratpolyexp (Const ("op +",_) $ t1 $ t2) = 
  3410   | is_ratpolyexp (Const ("Groups.plus_class.plus",_) $ t1 $ t2) = 
  3411                ((is_ratpolyexp t1) andalso (is_ratpolyexp t2))
  3411                ((is_ratpolyexp t1) andalso (is_ratpolyexp t2))
  3412   | is_ratpolyexp (Const ("op -",_) $ t1 $ t2) = 
  3412   | is_ratpolyexp (Const ("Groups.minus_class.minus",_) $ t1 $ t2) = 
  3413                ((is_ratpolyexp t1) andalso (is_ratpolyexp t2))
  3413                ((is_ratpolyexp t1) andalso (is_ratpolyexp t2))
  3414   | is_ratpolyexp (Const ("op *",_) $ t1 $ t2) = 
  3414   | is_ratpolyexp (Const ("op *",_) $ t1 $ t2) = 
  3415                ((is_ratpolyexp t1) andalso (is_ratpolyexp t2))
  3415                ((is_ratpolyexp t1) andalso (is_ratpolyexp t2))
  3416   | is_ratpolyexp (Const ("Atools.pow",_) $ t1 $ t2) = 
  3416   | is_ratpolyexp (Const ("Atools.pow",_) $ t1 $ t2) = 
  3417                ((is_ratpolyexp t1) andalso (is_ratpolyexp t2))
  3417                ((is_ratpolyexp t1) andalso (is_ratpolyexp t2))
  3418   | is_ratpolyexp (Const ("HOL.divide",_) $ t1 $ t2) = 
  3418   | is_ratpolyexp (Const ("Rings.inverse_class.divide",_) $ t1 $ t2) = 
  3419                ((is_ratpolyexp t1) andalso (is_ratpolyexp t2))
  3419                ((is_ratpolyexp t1) andalso (is_ratpolyexp t2))
  3420   | is_ratpolyexp _ = false;
  3420   | is_ratpolyexp _ = false;
  3421 
  3421 
  3422 (*("is_ratpolyexp", ("Rational.is'_ratpolyexp", eval_is_ratpolyexp ""))*)
  3422 (*("is_ratpolyexp", ("Rational.is'_ratpolyexp", eval_is_ratpolyexp ""))*)
  3423 fun eval_is_ratpolyexp (thmid:string) _ 
  3423 fun eval_is_ratpolyexp (thmid:string) _ 
  3460       rules = [Calc ("Atools.is'_atom",eval_is_atom "#is_atom_"),
  3460       rules = [Calc ("Atools.is'_atom",eval_is_atom "#is_atom_"),
  3461 	       Calc ("Atools.is'_even",eval_is_even "#is_even_"),
  3461 	       Calc ("Atools.is'_even",eval_is_even "#is_even_"),
  3462 	       Calc ("op <",eval_equ "#less_"),
  3462 	       Calc ("op <",eval_equ "#less_"),
  3463 	       Thm ("not_false", num_str @{thm not_false}),
  3463 	       Thm ("not_false", num_str @{thm not_false}),
  3464 	       Thm ("not_true", num_str @{thm not_true}),
  3464 	       Thm ("not_true", num_str @{thm not_true}),
  3465 	       Calc ("op +",eval_binop "#add_")
  3465 	       Calc ("Groups.plus_class.plus",eval_binop "#add_")
  3466 	       ],
  3466 	       ],
  3467       scr = EmptyScr
  3467       scr = EmptyScr
  3468       }:rls);
  3468       }:rls);
  3469 (*.all powers over + distributed; atoms over * collected, other distributed
  3469 (*.all powers over + distributed; atoms over * collected, other distributed
  3470    contains absolute minimum of thms for context in norm_Rational .*)
  3470    contains absolute minimum of thms for context in norm_Rational .*)
  3493 	       (*----- distribute none-atoms -----*)
  3493 	       (*----- distribute none-atoms -----*)
  3494 	       Thm ("realpow_def_atom",num_str @{thm realpow_def_atom}),
  3494 	       Thm ("realpow_def_atom",num_str @{thm realpow_def_atom}),
  3495 	       (*"[| 1 < n; not(r is_atom) |]==>r ^^^ n = r * r ^^^ (n + -1)"*)
  3495 	       (*"[| 1 < n; not(r is_atom) |]==>r ^^^ n = r * r ^^^ (n + -1)"*)
  3496 	       Thm ("realpow_eq_oneI",num_str @{thm realpow_eq_oneI}),
  3496 	       Thm ("realpow_eq_oneI",num_str @{thm realpow_eq_oneI}),
  3497 	       (*"1 ^^^ n = 1"*)
  3497 	       (*"1 ^^^ n = 1"*)
  3498 	       Calc ("op +",eval_binop "#add_")
  3498 	       Calc ("Groups.plus_class.plus",eval_binop "#add_")
  3499 	       ],
  3499 	       ],
  3500       scr = EmptyScr
  3500       scr = EmptyScr
  3501       }:rls);
  3501       }:rls);
  3502 (*.contains absolute minimum of thms for context in norm_Rational.*)
  3502 (*.contains absolute minimum of thms for context in norm_Rational.*)
  3503 val rat_mult_divide = prep_rls(
  3503 val rat_mult_divide = prep_rls(
  3517                      num_str @{thm divide_divide_eq_right}),
  3517                      num_str @{thm divide_divide_eq_right}),
  3518 	       (*"?x / (?y / ?z) = ?x * ?z / ?y"*)
  3518 	       (*"?x / (?y / ?z) = ?x * ?z / ?y"*)
  3519 	       Thm ("divide_divide_eq_left",
  3519 	       Thm ("divide_divide_eq_left",
  3520                      num_str @{thm divide_divide_eq_left}),
  3520                      num_str @{thm divide_divide_eq_left}),
  3521 	       (*"?x / ?y / ?z = ?x / (?y * ?z)"*)
  3521 	       (*"?x / ?y / ?z = ?x / (?y * ?z)"*)
  3522 	       Calc ("HOL.divide"  ,eval_cancel "#divide_e")
  3522 	       Calc ("Rings.inverse_class.divide"  ,eval_cancel "#divide_e")
  3523 	       ],
  3523 	       ],
  3524       scr = EmptyScr
  3524       scr = EmptyScr
  3525       }:rls);
  3525       }:rls);
  3526 
  3526 
  3527 (*.contains absolute minimum of thms for context in norm_Rational.*)
  3527 (*.contains absolute minimum of thms for context in norm_Rational.*)
  3693                      num_str @{thm divide_divide_eq_right}),
  3693                      num_str @{thm divide_divide_eq_right}),
  3694 	       (*"?x / (?y / ?z) = ?x * ?z / ?y"*)
  3694 	       (*"?x / (?y / ?z) = ?x * ?z / ?y"*)
  3695 	       Thm ("divide_divide_eq_left",
  3695 	       Thm ("divide_divide_eq_left",
  3696                      num_str @{thm divide_divide_eq_left}),
  3696                      num_str @{thm divide_divide_eq_left}),
  3697 	       (*"?x / ?y / ?z = ?x / (?y * ?z)"*)
  3697 	       (*"?x / ?y / ?z = ?x / (?y * ?z)"*)
  3698 	       Calc ("HOL.divide"  ,eval_cancel "#divide_e"),
  3698 	       Calc ("Rings.inverse_class.divide"  ,eval_cancel "#divide_e"),
  3699 	      
  3699 	      
  3700 	       Thm ("rat_power", num_str @{thm rat_power})
  3700 	       Thm ("rat_power", num_str @{thm rat_power})
  3701 		(*"(?a / ?b) ^^^ ?n = ?a ^^^ ?n / ?b ^^^ ?n"*)
  3701 		(*"(?a / ?b) ^^^ ?n = ?a ^^^ ?n / ?b ^^^ ?n"*)
  3702 	       ],
  3702 	       ],
  3703       scr = EmptyScr}:rls);
  3703       scr = EmptyScr}:rls);