src/HOL/Real/float.ML
changeset 21820 2f2b6a965ccc
parent 20767 9bc632ae588f
child 22578 b0eb5652f210
equal deleted inserted replaced
21819:8eb82ffcdd15 21820:2f2b6a965ccc
    11     exception Floating_point of string
    11     exception Floating_point of string
    12 
    12 
    13     type floatrep = IntInf.int * IntInf.int
    13     type floatrep = IntInf.int * IntInf.int
    14     val approx_dec_by_bin : IntInf.int -> floatrep -> floatrep * floatrep
    14     val approx_dec_by_bin : IntInf.int -> floatrep -> floatrep * floatrep
    15     val approx_decstr_by_bin : int -> string -> floatrep * floatrep
    15     val approx_decstr_by_bin : int -> string -> floatrep * floatrep
    16 end 
    16 end
    17 =
    17 =
    18 struct
    18 struct
    19 
    19 
    20 exception Destruct_floatstr of string;
    20 exception Destruct_floatstr of string;
    21 
    21 
    22 fun destruct_floatstr isDigit isExp number = 
    22 fun destruct_floatstr isDigit isExp number =
    23     let
    23     let
    24 	val numlist = filter (not o Char.isSpace) (String.explode number)
    24 	val numlist = filter (not o Char.isSpace) (String.explode number)
    25 	
    25 
    26 	fun countsigns ((#"+")::cs) = countsigns cs
    26 	fun countsigns ((#"+")::cs) = countsigns cs
    27 	  | countsigns ((#"-")::cs) = 
    27 	  | countsigns ((#"-")::cs) =
    28 	    let	
    28 	    let
    29 		val (positive, rest) = countsigns cs 
    29 		val (positive, rest) = countsigns cs
    30 	    in
    30 	    in
    31 		(not positive, rest)
    31 		(not positive, rest)
    32 	    end
    32 	    end
    33 	  | countsigns cs = (true, cs)
    33 	  | countsigns cs = (true, cs)
    34 
    34 
    35 	fun readdigits [] = ([], [])
    35 	fun readdigits [] = ([], [])
    36 	  | readdigits (q as c::cs) = 
    36 	  | readdigits (q as c::cs) =
    37 	    if (isDigit c) then 
    37 	    if (isDigit c) then
    38 		let
    38 		let
    39 		    val (digits, rest) = readdigits cs
    39 		    val (digits, rest) = readdigits cs
    40 		in
    40 		in
    41 		    (c::digits, rest)
    41 		    (c::digits, rest)
    42 		end
    42 		end
    43 	    else
    43 	    else
    44 		([], q)		
    44 		([], q)
    45 
    45 
    46 	fun readfromexp_helper cs =
    46 	fun readfromexp_helper cs =
    47 	    let
    47 	    let
    48 		val (positive, rest) = countsigns cs
    48 		val (positive, rest) = countsigns cs
    49 		val (digits, rest') = readdigits rest
    49 		val (digits, rest') = readdigits rest
    50 	    in
    50 	    in
    51 		case rest' of
    51 		case rest' of
    52 		    [] => (positive, digits)
    52 		    [] => (positive, digits)
    53 		  | _ => raise (Destruct_floatstr number)
    53 		  | _ => raise (Destruct_floatstr number)
    54 	    end	    
    54 	    end
    55 
    55 
    56 	fun readfromexp [] = (true, [])
    56 	fun readfromexp [] = (true, [])
    57 	  | readfromexp (c::cs) = 
    57 	  | readfromexp (c::cs) =
    58 	    if isExp c then
    58 	    if isExp c then
    59 		readfromexp_helper cs
    59 		readfromexp_helper cs
    60 	    else 
    60 	    else
    61 		raise (Destruct_floatstr number)		
    61 		raise (Destruct_floatstr number)
    62 
    62 
    63 	fun readfromdot [] = ([], readfromexp [])
    63 	fun readfromdot [] = ([], readfromexp [])
    64 	  | readfromdot ((#".")::cs) = 
    64 	  | readfromdot ((#".")::cs) =
    65 	    let		
    65 	    let
    66 		val (digits, rest) = readdigits cs
    66 		val (digits, rest) = readdigits cs
    67 		val exp = readfromexp rest
    67 		val exp = readfromexp rest
    68 	    in
    68 	    in
    69 		(digits, exp)
    69 		(digits, exp)
    70 	    end		
    70 	    end
    71 	  | readfromdot cs = readfromdot ((#".")::cs)
    71 	  | readfromdot cs = readfromdot ((#".")::cs)
    72 			    
    72 
    73 	val (positive, numlist) = countsigns numlist				 
    73 	val (positive, numlist) = countsigns numlist
    74 	val (digits1, numlist) = readdigits numlist				 
    74 	val (digits1, numlist) = readdigits numlist
    75  	val (digits2, exp) = readfromdot numlist
    75  	val (digits2, exp) = readfromdot numlist
    76     in
    76     in
    77 	(positive, String.implode digits1, String.implode digits2, fst exp, String.implode (snd exp))
    77 	(positive, String.implode digits1, String.implode digits2, fst exp, String.implode (snd exp))
    78     end
    78     end
    79 
    79 
    80 type floatrep = IntInf.int * IntInf.int
    80 type floatrep = IntInf.int * IntInf.int
    81 
    81 
    82 exception Floating_point of string;
    82 exception Floating_point of string;
    83 
    83 
    84 val ln2_10 = (Math.ln 10.0)/(Math.ln 2.0)
    84 val ln2_10 = (Math.ln 10.0)/(Math.ln 2.0)
    85 	
    85 
    86 fun intmul a b = IntInf.* (a,b)
    86 fun intmul a b = IntInf.* (a,b)
    87 fun intsub a b = IntInf.- (a,b)	
    87 fun intsub a b = IntInf.- (a,b)
    88 fun intadd a b = IntInf.+ (a,b) 		 
    88 fun intadd a b = IntInf.+ (a,b) 
    89 fun intpow a b = IntInf.pow (a, IntInf.toInt b);
    89 fun intpow a b = IntInf.pow (a, IntInf.toInt b);
    90 fun intle a b = IntInf.<= (a, b);
    90 fun intle a b = IntInf.<= (a, b);
    91 fun intless a b = IntInf.< (a, b);
    91 fun intless a b = IntInf.< (a, b);
    92 fun intneg a = IntInf.~ a;
    92 fun intneg a = IntInf.~ a;
    93 val zero = IntInf.fromInt 0;
    93 val zero = IntInf.fromInt 0;
    94 val one = IntInf.fromInt 1;
    94 val one = IntInf.fromInt 1;
    95 val two = IntInf.fromInt 2;
    95 val two = IntInf.fromInt 2;
    96 val ten = IntInf.fromInt 10;
    96 val ten = IntInf.fromInt 10;
    97 val five = IntInf.fromInt 5;
    97 val five = IntInf.fromInt 5;
    98 
    98 
    99 fun find_most_significant q r = 
    99 fun find_most_significant q r =
   100     let 
   100     let
   101 	fun int2real i = 
   101 	fun int2real i =
   102 	    case Real.fromString (IntInf.toString i) of 
   102 	    case Real.fromString (IntInf.toString i) of
   103 		SOME r => r 
   103 		SOME r => r
   104 	      | NONE => raise (Floating_point "int2real")	
   104 	      | NONE => raise (Floating_point "int2real")
   105 	fun subtract (q, r) (q', r') = 
   105 	fun subtract (q, r) (q', r') =
   106 	    if intle r r' then
   106 	    if intle r r' then
   107 		(intsub q (intmul q' (intpow ten (intsub r' r))), r)
   107 		(intsub q (intmul q' (intpow ten (intsub r' r))), r)
   108 	    else
   108 	    else
   109 		(intsub (intmul q (intpow ten (intsub r r'))) q', r')
   109 		(intsub (intmul q (intpow ten (intsub r r'))) q', r')
   110 	fun bin2dec d =
   110 	fun bin2dec d =
   111 	    if intle zero d then 
   111 	    if intle zero d then
   112 		(intpow two d, zero)
   112 		(intpow two d, zero)
   113 	    else
   113 	    else
   114 		(intpow five (intneg d), d)				
   114 		(intpow five (intneg d), d)
   115 		
   115 
   116 	val L = IntInf.fromInt (Real.floor (int2real (IntInf.fromInt (IntInf.log2 q)) + (int2real r) * ln2_10))	
   116 	val L = IntInf.fromInt (Real.floor (int2real (IntInf.fromInt (IntInf.log2 q)) + (int2real r) * ln2_10))
   117 	val L1 = intadd L one
   117 	val L1 = intadd L one
   118 
   118 
   119 	val (q1, r1) = subtract (q, r) (bin2dec L1) 		
   119 	val (q1, r1) = subtract (q, r) (bin2dec L1) 
   120     in
   120     in
   121 	if intle zero q1 then 
   121 	if intle zero q1 then
   122 	    let
   122 	    let
   123 		val (q2, r2) = subtract (q, r) (bin2dec (intadd L1 one))
   123 		val (q2, r2) = subtract (q, r) (bin2dec (intadd L1 one))
   124 	    in
   124 	    in
   125 		if intle zero q2 then 
   125 		if intle zero q2 then
   126 		    raise (Floating_point "find_most_significant")
   126 		    raise (Floating_point "find_most_significant")
   127 		else
   127 		else
   128 		    (L1, (q1, r1))
   128 		    (L1, (q1, r1))
   129 	    end
   129 	    end
   130 	else
   130 	else
   133 	    in
   133 	    in
   134 		if intle zero q0 then
   134 		if intle zero q0 then
   135 		    (L, (q0, r0))
   135 		    (L, (q0, r0))
   136 		else
   136 		else
   137 		    raise (Floating_point "find_most_significant")
   137 		    raise (Floating_point "find_most_significant")
   138 	    end		    
   138 	    end
   139     end
   139     end
   140 
   140 
   141 fun approx_dec_by_bin n (q,r) =
   141 fun approx_dec_by_bin n (q,r) =
   142     let	
   142     let
   143 	fun addseq acc d' [] = acc
   143 	fun addseq acc d' [] = acc
   144 	  | addseq acc d' (d::ds) = addseq (intadd acc (intpow two (intsub d d'))) d' ds
   144 	  | addseq acc d' (d::ds) = addseq (intadd acc (intpow two (intsub d d'))) d' ds
   145 
   145 
   146 	fun seq2bin [] = (zero, zero)
   146 	fun seq2bin [] = (zero, zero)
   147 	  | seq2bin (d::ds) = (intadd (addseq zero d ds) one, d)
   147 	  | seq2bin (d::ds) = (intadd (addseq zero d ds) one, d)
   148 
   148 
   149 	fun approx d_seq d0 precision (q,r) = 
   149 	fun approx d_seq d0 precision (q,r) =
   150 	    if q = zero then 
   150 	    if q = zero then
   151 		let val x = seq2bin d_seq in
   151 		let val x = seq2bin d_seq in
   152 		    (x, x)
   152 		    (x, x)
   153 		end
   153 		end
   154 	    else    
   154 	    else
   155 		let 
   155 		let
   156 		    val (d, (q', r')) = find_most_significant q r
   156 		    val (d, (q', r')) = find_most_significant q r
   157 		in	
   157 		in
   158 		    if intless precision (intsub d0 d) then 
   158 		    if intless precision (intsub d0 d) then
   159 			let 
   159 			let
   160 			    val d' = intsub d0 precision
   160 			    val d' = intsub d0 precision
   161 			    val x1 = seq2bin (d_seq)
   161 			    val x1 = seq2bin (d_seq)
   162 			    val x2 = (intadd (intmul (fst x1) (intpow two (intsub (snd x1) d'))) one,  d') (* = seq2bin (d'::d_seq) *) 
   162 			    val x2 = (intadd (intmul (fst x1) (intpow two (intsub (snd x1) d'))) one,  d') (* = seq2bin (d'::d_seq) *)
   163 			in
   163 			in
   164 			    (x1, x2)
   164 			    (x1, x2)
   165 			end
   165 			end
   166 		    else
   166 		    else
   167 			approx (d::d_seq) d0 precision (q', r') 						    		
   167 			approx (d::d_seq) d0 precision (q', r') 						    
   168 		end		
   168 		end
   169 	
   169 
   170 	fun approx_start precision (q, r) =
   170 	fun approx_start precision (q, r) =
   171 	    if q = zero then 
   171 	    if q = zero then
   172 		((zero, zero), (zero, zero))
   172 		((zero, zero), (zero, zero))
   173 	    else
   173 	    else
   174 		let 
   174 		let
   175 		    val (d, (q', r')) = find_most_significant q r
   175 		    val (d, (q', r')) = find_most_significant q r
   176 		in	
   176 		in
   177 		    if intle precision zero then 
   177 		    if intle precision zero then
   178 			let
   178 			let
   179 			    val x1 = seq2bin [d]
   179 			    val x1 = seq2bin [d]
   180 			in
   180 			in
   181 			    if q' = zero then 
   181 			    if q' = zero then
   182 				(x1, x1)
   182 				(x1, x1)
   183 			    else
   183 			    else
   184 				(x1, seq2bin [intadd d one])
   184 				(x1, seq2bin [intadd d one])
   185 			end
   185 			end
   186 		    else
   186 		    else
   187 			approx [d] d precision (q', r')
   187 			approx [d] d precision (q', r')
   188 		end		
   188 		end
   189     in
   189     in
   190 	if intle zero q then 
   190 	if intle zero q then
   191 	    approx_start n (q,r)
   191 	    approx_start n (q,r)
   192 	else
   192 	else
   193 	    let 
   193 	    let
   194 		val ((a1,b1), (a2, b2)) = approx_start n (intneg q, r) 
   194 		val ((a1,b1), (a2, b2)) = approx_start n (intneg q, r)
   195 	    in
   195 	    in
   196 		((intneg a2, b2), (intneg a1, b1))
   196 		((intneg a2, b2), (intneg a1, b1))
   197 	    end					
   197 	    end
   198     end
   198     end
   199 
   199 
   200 fun approx_decstr_by_bin n decstr =
   200 fun approx_decstr_by_bin n decstr =
   201     let 
   201     let
   202 	fun str2int s = case IntInf.fromString s of SOME x => x | NONE => zero 
   202 	fun str2int s = case IntInf.fromString s of SOME x => x | NONE => zero
   203 	fun signint p x = if p then x else intneg x
   203 	fun signint p x = if p then x else intneg x
   204 
   204 
   205 	val (p, d1, d2, ep, e) = destruct_floatstr Char.isDigit (fn e => e = #"e" orelse e = #"E") decstr
   205 	val (p, d1, d2, ep, e) = destruct_floatstr Char.isDigit (fn e => e = #"e" orelse e = #"E") decstr
   206 	val s = IntInf.fromInt (size d2)
   206 	val s = IntInf.fromInt (size d2)
   207 		
   207 
   208 	val q = signint p (intadd (intmul (str2int d1) (intpow ten s)) (str2int d2))
   208 	val q = signint p (intadd (intmul (str2int d1) (intpow ten s)) (str2int d2))
   209 	val r = intsub (signint ep (str2int e)) s
   209 	val r = intsub (signint ep (str2int e)) s
   210     in
   210     in
   211 	approx_dec_by_bin (IntInf.fromInt n) (q,r)
   211 	approx_dec_by_bin (IntInf.fromInt n) (q,r)
   212     end
   212     end
   213 
   213 
   214 end;
   214 end;
   215 
   215 
   216 structure FloatArith = 
   216 structure FloatArith =
   217 struct
   217 struct
   218 
   218 
   219 type float = IntInf.int * IntInf.int 
   219 type float = IntInf.int * IntInf.int
   220 
   220 
   221 val izero = IntInf.fromInt 0
   221 val izero = IntInf.fromInt 0
   222 val ione = IntInf.fromInt 1
   222 val ione = IntInf.fromInt 1
   223 val imone = IntInf.fromInt ~1
   223 val imone = IntInf.fromInt ~1
   224 val itwo = IntInf.fromInt 2
   224 val itwo = IntInf.fromInt 2
   226 fun isub a b = IntInf.- (a,b)
   226 fun isub a b = IntInf.- (a,b)
   227 fun iadd a b = IntInf.+ (a,b)
   227 fun iadd a b = IntInf.+ (a,b)
   228 
   228 
   229 val floatzero = (izero, izero)
   229 val floatzero = (izero, izero)
   230 
   230 
   231 fun positive_part (a,b) = 
   231 fun positive_part (a,b) =
   232     (if IntInf.< (a,izero) then izero else a, b)
   232     (if IntInf.< (a,izero) then izero else a, b)
   233 
   233 
   234 fun negative_part (a,b) = 
   234 fun negative_part (a,b) =
   235     (if IntInf.< (a,izero) then a else izero, b)
   235     (if IntInf.< (a,izero) then a else izero, b)
   236 
   236 
   237 fun is_negative (a,b) = 
   237 fun is_negative (a,b) =
   238     if IntInf.< (a, izero) then true else false
   238     if IntInf.< (a, izero) then true else false
   239 
   239 
   240 fun is_positive (a,b) = 
   240 fun is_positive (a,b) =
   241     if IntInf.< (izero, a) then true else false
   241     if IntInf.< (izero, a) then true else false
   242 
   242 
   243 fun is_zero (a,b) = 
   243 fun is_zero (a,b) =
   244     if a = izero then true else false
   244     if a = izero then true else false
   245 
   245 
   246 fun ipow2 a = IntInf.pow ((IntInf.fromInt 2), IntInf.toInt a)
   246 fun ipow2 a = IntInf.pow ((IntInf.fromInt 2), IntInf.toInt a)
   247 
   247 
   248 fun add (a1, b1) (a2, b2) = 
   248 fun add (a1, b1) (a2, b2) =
   249     if IntInf.< (b1, b2) then
   249     if IntInf.< (b1, b2) then
   250 	(iadd a1 (imul a2 (ipow2 (isub b2 b1))), b1)
   250 	(iadd a1 (imul a2 (ipow2 (isub b2 b1))), b1)
   251     else
   251     else
   252 	(iadd (imul a1 (ipow2 (isub b1 b2))) a2, b2)
   252 	(iadd (imul a1 (ipow2 (isub b1 b2))) a2, b2)
   253 
   253 
   254 fun sub (a1, b1) (a2, b2) = 
   254 fun sub (a1, b1) (a2, b2) =
   255     if IntInf.< (b1, b2) then
   255     if IntInf.< (b1, b2) then
   256 	(isub a1 (imul a2 (ipow2 (isub b2 b1))), b1)
   256 	(isub a1 (imul a2 (ipow2 (isub b2 b1))), b1)
   257     else
   257     else
   258 	(isub (imul a1 (ipow2 (isub b1 b2))) a2, b2)
   258 	(isub (imul a1 (ipow2 (isub b1 b2))) a2, b2)
   259 
   259 
   283     val mk_float : float -> term
   283     val mk_float : float -> term
   284 
   284 
   285     exception Dest_intinf;
   285     exception Dest_intinf;
   286     val dest_intinf : term -> IntInf.int
   286     val dest_intinf : term -> IntInf.int
   287     val dest_nat : term -> IntInf.int
   287     val dest_nat : term -> IntInf.int
   288     
   288 
   289     exception Dest_float;
   289     exception Dest_float;
   290     val dest_float : term -> float
   290     val dest_float : term -> float
   291 
   291 
   292     val float_const : term
   292     val float_const : term
   293 
   293 
   295     val float_diff_const : term
   295     val float_diff_const : term
   296     val float_uminus_const : term
   296     val float_uminus_const : term
   297     val float_pprt_const : term
   297     val float_pprt_const : term
   298     val float_nprt_const : term
   298     val float_nprt_const : term
   299     val float_abs_const : term
   299     val float_abs_const : term
   300     val float_mult_const : term 
   300     val float_mult_const : term
   301     val float_le_const : term
   301     val float_le_const : term
   302 
   302 
   303     val nat_le_const : term
   303     val nat_le_const : term
   304     val nat_less_const : term
   304     val nat_less_const : term
   305     val nat_eq_const : term
   305     val nat_eq_const : term
   312     val float_op_oracle : Sign.sg * exn -> term
   312     val float_op_oracle : Sign.sg * exn -> term
   313     val nat_op_oracle : Sign.sg * exn -> term
   313     val nat_op_oracle : Sign.sg * exn -> term
   314 
   314 
   315     val invoke_float_op : term -> thm
   315     val invoke_float_op : term -> thm
   316     val invoke_nat_op : term -> thm*)
   316     val invoke_nat_op : term -> thm*)
   317 end 
   317 end
   318 = 
   318 =
   319 struct
   319 struct
   320 
   320 
   321 structure Inttab = TableFun(type key = int val ord = (rev_order o int_ord));
   321 structure Inttab = TableFun(type key = int val ord = (rev_order o int_ord));
   322 
   322 
   323 type float = IntInf.int*IntInf.int
   323 type float = IntInf.int*IntInf.int
   335 val float_nprt_const = Const ("OrderedGroup.nprt", HOLogic.realT --> HOLogic.realT)
   335 val float_nprt_const = Const ("OrderedGroup.nprt", HOLogic.realT --> HOLogic.realT)
   336 
   336 
   337 val nat_le_const = Const ("Orderings.less_eq", HOLogic.natT --> HOLogic.natT --> HOLogic.boolT)
   337 val nat_le_const = Const ("Orderings.less_eq", HOLogic.natT --> HOLogic.natT --> HOLogic.boolT)
   338 val nat_less_const = Const ("Orderings.less", HOLogic.natT --> HOLogic.natT --> HOLogic.boolT)
   338 val nat_less_const = Const ("Orderings.less", HOLogic.natT --> HOLogic.natT --> HOLogic.boolT)
   339 val nat_eq_const = Const ("op =", HOLogic.natT --> HOLogic.natT --> HOLogic.boolT)
   339 val nat_eq_const = Const ("op =", HOLogic.natT --> HOLogic.natT --> HOLogic.boolT)
   340  		  
   340  
   341 val zero = FloatArith.izero
   341 val zero = FloatArith.izero
   342 val minus_one = FloatArith.imone
   342 val minus_one = FloatArith.imone
   343 val two = FloatArith.itwo
   343 val two = FloatArith.itwo
   344 	  
   344 
   345 exception Dest_intinf;
   345 exception Dest_intinf;
   346 exception Dest_float;
   346 exception Dest_float;
   347 
   347 
   348 fun mk_intinf ty n =
   348 fun mk_intinf ty n = HOLogic.number_of_const ty $ HOLogic.mk_numeral n;
   349   let
   349 
   350     fun mk_bit n = if n = zero then HOLogic.B0_const else HOLogic.B1_const
   350 val dest_intinf = snd o HOLogic.dest_number
   351     fun bin_of n = 
   351 
   352       if n = zero then HOLogic.pls_const
   352 fun mk_float (a,b) =
   353       else if n = minus_one then HOLogic.min_const
       
   354       else let 
       
   355         val (q,r) = IntInf.divMod (n, two)
       
   356       in
       
   357         HOLogic.bit_const $ bin_of q $ mk_bit r
       
   358       end
       
   359   in 
       
   360     HOLogic.number_of_const ty $ (bin_of n)
       
   361   end
       
   362 
       
   363 fun dest_intinf n = 
       
   364     let
       
   365 	fun dest_bit n = 
       
   366 	    case n of 
       
   367 		Const ("Numeral.bit.B0", _) => FloatArith.izero
       
   368 	      | Const ("Numeral.bit.B1", _) => FloatArith.ione
       
   369 	      | _ => raise Dest_intinf
       
   370 			 
       
   371 	fun int_of n = 
       
   372 	    case n of
       
   373 		Const ("Numeral.Pls", _) => FloatArith.izero
       
   374 	      | Const ("Numeral.Min", _) => FloatArith.imone
       
   375 	      | Const ("Numeral.Bit", _) $ q $ r => FloatArith.iadd (FloatArith.imul (int_of q) FloatArith.itwo) (dest_bit r)
       
   376 	      | _ => raise Dest_intinf
       
   377     in
       
   378 	case n of 
       
   379 	    Const ("Numeral.number_of", _) $ n' => int_of n'
       
   380 	  | Const ("Numeral0", _) => FloatArith.izero
       
   381 	  | Const ("Numeral1", _) => FloatArith.ione    
       
   382 	  | _ => raise Dest_intinf
       
   383     end
       
   384 
       
   385 fun mk_float (a,b) = 
       
   386     float_const $ (HOLogic.mk_prod ((mk_intinf HOLogic.intT a), (mk_intinf HOLogic.intT b)))
   353     float_const $ (HOLogic.mk_prod ((mk_intinf HOLogic.intT a), (mk_intinf HOLogic.intT b)))
   387 
   354 
   388 fun dest_float f = 
   355 fun dest_float f =
   389     case f of 
   356     case f of
   390 	(Const ("Float.float", _) $ (Const ("Pair", _) $ a $ b)) => (dest_intinf a, dest_intinf b)
   357 	(Const ("Float.float", _) $ (Const ("Pair", _) $ a $ b)) => (dest_intinf a, dest_intinf b)
   391       | Const ("Numeral.number_of",_) $ a => (dest_intinf f, 0)
   358       | Const ("Numeral.number_of",_) $ a => (dest_intinf f, 0)
   392       | Const ("Numeral0", _) => (FloatArith.izero, FloatArith.izero)
   359       | Const ("Numeral0", _) => (FloatArith.izero, FloatArith.izero)
   393       | Const ("Numeral1", _) => (FloatArith.ione, FloatArith.izero)
   360       | Const ("Numeral1", _) => (FloatArith.ione, FloatArith.izero)
   394       | _ => raise Dest_float
   361       | _ => raise Dest_float
   395 
   362 
   396 fun dest_nat n = 
   363 fun dest_nat n =
   397     let 
   364     let
   398 	val v = dest_intinf n
   365 	val v = dest_intinf n
   399     in
   366     in
   400 	if IntInf.< (v, FloatArith.izero) then
   367 	if IntInf.< (v, FloatArith.izero) then
   401 	    FloatArith.izero
   368 	    FloatArith.izero
   402 	else
   369 	else
   403 	    v
   370 	    v
   404     end
   371     end
   405 
   372 
   406 fun approx_float prec f value = 
   373 fun approx_float prec f value =
   407     let
   374     let
   408 	val interval = ExactFloatingPoint.approx_decstr_by_bin prec value
   375 	val interval = ExactFloatingPoint.approx_decstr_by_bin prec value
   409 	val (flower, fupper) = f interval
   376 	val (flower, fupper) = f interval
   410     in
   377     in
   411 	(mk_float flower, mk_float fupper)
   378 	(mk_float flower, mk_float fupper)
   413 
   380 
   414 (*exception Float_op_oracle_data of term;
   381 (*exception Float_op_oracle_data of term;
   415 
   382 
   416 fun float_op_oracle (sg, exn as Float_op_oracle_data t) =
   383 fun float_op_oracle (sg, exn as Float_op_oracle_data t) =
   417     Logic.mk_equals (t,
   384     Logic.mk_equals (t,
   418 		     case t of 
   385 		     case t of
   419 			 f $ a $ b => 
   386 			 f $ a $ b =>
   420 			 let 
   387 			 let
   421 			     val a' = dest_float a 
   388 			     val a' = dest_float a
   422 			     val b' = dest_float b
   389 			     val b' = dest_float b
   423 			 in
   390 			 in
   424 			     if f = float_add_const then
   391 			     if f = float_add_const then
   425 				 mk_float (FloatArith.add a' b')	
   392 				 mk_float (FloatArith.add a' b')
   426 			     else if f = float_diff_const then
   393 			     else if f = float_diff_const then
   427 				 mk_float (FloatArith.sub a' b')
   394 				 mk_float (FloatArith.sub a' b')
   428 			     else if f = float_mult_const then
   395 			     else if f = float_mult_const then
   429 				 mk_float (FloatArith.mul a' b')		
   396 				 mk_float (FloatArith.mul a' b')
   430 			     else if f = float_le_const then
   397 			     else if f = float_le_const then
   431 				 (if FloatArith.is_less b' a' then
   398 				 (if FloatArith.is_less b' a' then
   432 				     HOLogic.false_const
   399 				     HOLogic.false_const
   433 				 else
   400 				 else
   434 				     HOLogic.true_const)
   401 				     HOLogic.true_const)
   435 			     else raise exn	    		    	       
   402 			     else raise exn	    		    
   436 			 end
   403 			 end
   437 		       | f $ a => 
   404 		       | f $ a =>
   438 			 let
   405 			 let
   439 			     val a' = dest_float a
   406 			     val a' = dest_float a
   440 			 in
   407 			 in
   441 			     if f = float_uminus_const then
   408 			     if f = float_uminus_const then
   442 				 mk_float (FloatArith.neg a')
   409 				 mk_float (FloatArith.neg a')
   452 		       | _ => raise exn
   419 		       | _ => raise exn
   453 		    )
   420 		    )
   454 val th = ref ([]: theory list)
   421 val th = ref ([]: theory list)
   455 val sg = ref ([]: Sign.sg list)
   422 val sg = ref ([]: Sign.sg list)
   456 
   423 
   457 fun invoke_float_op c = 
   424 fun invoke_float_op c =
   458     let
   425     let
   459 	val th = (if length(!th) = 0 then th := [theory "MatrixLP"] else (); hd (!th))
   426 	val th = (if length(!th) = 0 then th := [theory "MatrixLP"] else (); hd (!th))
   460 	val sg = (if length(!sg) = 0 then sg := [sign_of th] else (); hd (!sg))
   427 	val sg = (if length(!sg) = 0 then sg := [sign_of th] else (); hd (!sg))
   461     in
   428     in
   462 	invoke_oracle th "float_op" (sg, Float_op_oracle_data c)
   429 	invoke_oracle th "float_op" (sg, Float_op_oracle_data c)
   464 
   431 
   465 exception Nat_op_oracle_data of term;
   432 exception Nat_op_oracle_data of term;
   466 
   433 
   467 fun nat_op_oracle (sg, exn as Nat_op_oracle_data t) =
   434 fun nat_op_oracle (sg, exn as Nat_op_oracle_data t) =
   468     Logic.mk_equals (t,
   435     Logic.mk_equals (t,
   469 		     case t of 
   436 		     case t of
   470 			 f $ a $ b => 
   437 			 f $ a $ b =>
   471 			 let 
   438 			 let
   472 			     val a' = dest_nat a 
   439 			     val a' = dest_nat a
   473 			     val b' = dest_nat b
   440 			     val b' = dest_nat b
   474 			 in
   441 			 in
   475 			     if f = nat_le_const then
   442 			     if f = nat_le_const then
   476 				 (if IntInf.<= (a', b') then
   443 				 (if IntInf.<= (a', b') then
   477 				     HOLogic.true_const
   444 				     HOLogic.true_const
   478 				 else
   445 				 else
   479 				     HOLogic.false_const)
   446 				     HOLogic.false_const)
   480 			     else if f = nat_eq_const then
   447 			     else if f = nat_eq_const then
   481 				 (if a' = b' then 
   448 				 (if a' = b' then
   482 				      HOLogic.true_const
   449 				      HOLogic.true_const
   483 				  else
   450 				  else
   484 				      HOLogic.false_const)
   451 				      HOLogic.false_const)
   485 			     else if f = nat_less_const then
   452 			     else if f = nat_less_const then
   486 				 (if IntInf.< (a', b') then
   453 				 (if IntInf.< (a', b') then
   487 				      HOLogic.true_const
   454 				      HOLogic.true_const
   488 				  else
   455 				  else
   489 				      HOLogic.false_const)
   456 				      HOLogic.false_const)
   490 			     else 
   457 			     else
   491 				 raise exn	    	
   458 				 raise exn
       
   459 
   492 			 end
   460 			 end
   493 		       | _ => raise exn)
   461 		       | _ => raise exn)
   494 
   462 
   495 fun invoke_nat_op c = 
   463 fun invoke_nat_op c =
   496     let
   464     let
   497 	val th = (if length (!th) = 0 then th := [theory "MatrixLP"] else (); hd (!th))
   465 	val th = (if length (!th) = 0 then th := [theory "MatrixLP"] else (); hd (!th))
   498 	val sg = (if length (!sg) = 0 then sg := [sign_of th] else (); hd (!sg))
   466 	val sg = (if length (!sg) = 0 then sg := [sign_of th] else (); hd (!sg))
   499     in
   467     in
   500 	invoke_oracle th "nat_op" (sg, Nat_op_oracle_data c)
   468 	invoke_oracle th "nat_op" (sg, Nat_op_oracle_data c)