# HG changeset patch # User wenzelm # Date 1464717061 -7200 # Node ID af562e9760380e67140763ec883fa6b319118d84 # Parent c3896c385c3e4e2f8df5d4862888a2f08f28d2e9 rat.ML is now part of Pure to allow tigther integration with Isabelle/ML; diff -r c3896c385c3e -r af562e976038 src/HOL/Nat.thy --- a/src/HOL/Nat.thy Tue May 31 18:31:33 2016 +0200 +++ b/src/HOL/Nat.thy Tue May 31 19:51:01 2016 +0200 @@ -11,8 +11,6 @@ imports Inductive Typedef Fun Rings begin -ML_file "~~/src/Tools/rat.ML" - named_theorems arith "arith facts -- only ground formulas" ML_file "Tools/arith_data.ML" diff -r c3896c385c3e -r af562e976038 src/Pure/General/rat.ML --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Pure/General/rat.ML Tue May 31 19:51:01 2016 +0200 @@ -0,0 +1,118 @@ +(* Title: Pure/General/rat.ML + Author: Tobias Nipkow, Florian Haftmann, TU Muenchen + +Canonical implementation of exact rational numbers. +*) + +signature RAT = +sig + eqtype rat + exception DIVZERO + val zero: rat + val one: rat + val two: rat + val rat_of_int: int -> rat + val rat_of_quotient: int * int -> rat + val quotient_of_rat: rat -> int * int + val string_of_rat: rat -> string + val eq: rat * rat -> bool + val ord: rat * rat -> order + val le: rat -> rat -> bool + val lt: rat -> rat -> bool + val sign: rat -> order + val abs: rat -> rat + val add: rat -> rat -> rat + val mult: rat -> rat -> rat + val neg: rat -> rat + val inv: rat -> rat + val rounddown: rat -> rat + val roundup: rat -> rat +end; + +structure Rat : RAT = +struct + +fun common (p1, q1) (p2, q2) = + let + val m = Integer.lcm q1 q2; + in ((p1 * (m div q1), p2 * (m div q2)), m) end; + +datatype rat = Rat of int * int; (*nominator, denominator (positive!)*) + +exception DIVZERO; + +fun rat_of_quotient (p, q) = + let + val m = Integer.gcd (Int.abs p) q + in Rat (p div m, q div m) end handle Div => raise DIVZERO; + +fun quotient_of_rat (Rat r) = r; + +fun rat_of_int i = Rat (i, 1); + +val zero = rat_of_int 0; +val one = rat_of_int 1; +val two = rat_of_int 2; + +fun string_of_rat (Rat (p, q)) = + string_of_int p ^ "/" ^ string_of_int q; + +fun eq (Rat (p1, q1), Rat (p2, q2)) = (p1 = p2 andalso q1 = q2); + +fun ord (Rat (p1, q1), Rat (p2, q2)) = + case (Integer.sign p1, Integer.sign p2) + of (LESS, EQUAL) => LESS + | (LESS, GREATER) => LESS + | (EQUAL, LESS) => GREATER + | (EQUAL, EQUAL) => EQUAL + | (EQUAL, GREATER) => LESS + | (GREATER, LESS) => GREATER + | (GREATER, EQUAL) => GREATER + | _ => int_ord (fst (common (p1, q1) (p2, q2))); + +fun le a b = not (ord (a, b) = GREATER); +fun lt a b = (ord (a, b) = LESS); + +fun sign (Rat (p, _)) = Integer.sign p; + +fun abs (Rat (p, q)) = Rat (Int.abs p, q); + +fun add (Rat (p1, q1)) (Rat (p2, q2)) = + let + val ((m1, m2), n) = common (p1, q1) (p2, q2); + in rat_of_quotient (m1 + m2, n) end; + +fun mult (Rat (p1, q1)) (Rat (p2, q2)) = + rat_of_quotient (p1 * p2, q1 * q2); + +fun neg (Rat (p, q)) = Rat (~ p, q); + +fun inv (Rat (p, q)) = + case Integer.sign p + of LESS => Rat (~ q, ~ p) + | EQUAL => raise DIVZERO + | GREATER => Rat (q, p); + +fun rounddown (Rat (p, q)) = Rat (p div q, 1); + +fun roundup (Rat (p, q)) = + case Integer.div_mod p q + of (m, 0) => Rat (m, 1) + | (m, _) => Rat (m + 1, 1); + +end; + +infix 7 */ //; +infix 6 +/ -/; +infix 4 =/ / >=/ <>/; + +fun a +/ b = Rat.add a b; +fun a -/ b = a +/ Rat.neg b; +fun a */ b = Rat.mult a b; +fun a // b = a */ Rat.inv b; +fun a =/ b = Rat.eq (a, b); +fun a / b = b =/ b = b <=/ a; +fun a <>/ b = not (a =/ b); diff -r c3896c385c3e -r af562e976038 src/Pure/ROOT.ML --- a/src/Pure/ROOT.ML Tue May 31 18:31:33 2016 +0200 +++ b/src/Pure/ROOT.ML Tue May 31 19:51:01 2016 +0200 @@ -52,6 +52,7 @@ subsection "Library of general tools"; ML_file "General/integer.ML"; +ML_file "General/rat.ML"; ML_file "General/stack.ML"; ML_file "General/queue.ML"; ML_file "General/heap.ML"; diff -r c3896c385c3e -r af562e976038 src/Tools/rat.ML --- a/src/Tools/rat.ML Tue May 31 18:31:33 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -(* Title: Tools/rat.ML - Author: Tobias Nipkow, Florian Haftmann, TU Muenchen - -Canonical implementation of exact rational numbers. -*) - -signature RAT = -sig - eqtype rat - exception DIVZERO - val zero: rat - val one: rat - val two: rat - val rat_of_int: int -> rat - val rat_of_quotient: int * int -> rat - val quotient_of_rat: rat -> int * int - val string_of_rat: rat -> string - val eq: rat * rat -> bool - val ord: rat * rat -> order - val le: rat -> rat -> bool - val lt: rat -> rat -> bool - val sign: rat -> order - val abs: rat -> rat - val add: rat -> rat -> rat - val mult: rat -> rat -> rat - val neg: rat -> rat - val inv: rat -> rat - val rounddown: rat -> rat - val roundup: rat -> rat -end; - -structure Rat : RAT = -struct - -fun common (p1, q1) (p2, q2) = - let - val m = Integer.lcm q1 q2; - in ((p1 * (m div q1), p2 * (m div q2)), m) end; - -datatype rat = Rat of int * int; (*nominator, denominator (positive!)*) - -exception DIVZERO; - -fun rat_of_quotient (p, q) = - let - val m = Integer.gcd (Int.abs p) q - in Rat (p div m, q div m) end handle Div => raise DIVZERO; - -fun quotient_of_rat (Rat r) = r; - -fun rat_of_int i = Rat (i, 1); - -val zero = rat_of_int 0; -val one = rat_of_int 1; -val two = rat_of_int 2; - -fun string_of_rat (Rat (p, q)) = - string_of_int p ^ "/" ^ string_of_int q; - -fun eq (Rat (p1, q1), Rat (p2, q2)) = (p1 = p2 andalso q1 = q2); - -fun ord (Rat (p1, q1), Rat (p2, q2)) = - case (Integer.sign p1, Integer.sign p2) - of (LESS, EQUAL) => LESS - | (LESS, GREATER) => LESS - | (EQUAL, LESS) => GREATER - | (EQUAL, EQUAL) => EQUAL - | (EQUAL, GREATER) => LESS - | (GREATER, LESS) => GREATER - | (GREATER, EQUAL) => GREATER - | _ => int_ord (fst (common (p1, q1) (p2, q2))); - -fun le a b = not (ord (a, b) = GREATER); -fun lt a b = (ord (a, b) = LESS); - -fun sign (Rat (p, _)) = Integer.sign p; - -fun abs (Rat (p, q)) = Rat (Int.abs p, q); - -fun add (Rat (p1, q1)) (Rat (p2, q2)) = - let - val ((m1, m2), n) = common (p1, q1) (p2, q2); - in rat_of_quotient (m1 + m2, n) end; - -fun mult (Rat (p1, q1)) (Rat (p2, q2)) = - rat_of_quotient (p1 * p2, q1 * q2); - -fun neg (Rat (p, q)) = Rat (~ p, q); - -fun inv (Rat (p, q)) = - case Integer.sign p - of LESS => Rat (~ q, ~ p) - | EQUAL => raise DIVZERO - | GREATER => Rat (q, p); - -fun rounddown (Rat (p, q)) = Rat (p div q, 1); - -fun roundup (Rat (p, q)) = - case Integer.div_mod p q - of (m, 0) => Rat (m, 1) - | (m, _) => Rat (m + 1, 1); - -end; - -infix 7 */ //; -infix 6 +/ -/; -infix 4 =/ / >=/ <>/; - -fun a +/ b = Rat.add a b; -fun a -/ b = a +/ Rat.neg b; -fun a */ b = Rat.mult a b; -fun a // b = a */ Rat.inv b; -fun a =/ b = Rat.eq (a, b); -fun a / b = b =/ b = b <=/ a; -fun a <>/ b = not (a =/ b);