--[[ Rational Arithmetic Module (used global RATIONAL_CORE) H. Conrad Cunningham, Professor Computer and Information Science University of Mississippi Developed for CSci 450/503, Organization of Programming Languages, Fall 2016 1234567890123456789012345678901234567890123456789012345678901234567890 2016-09-11: Adapted from Haskell Rational Module This work was based on a Haskell version that was itself adapted from section 2.1 of Abelson and Sussman's _Structure and Interpretation of Computer Programs_ (http://mitpress.mit.edu/sicp/). Note: The Haskell version has "showRat" in the "core' but it is moved the out module in this Lua version. --]] -- Haskell -- module Rational -- ( Rat, makeRat, numer, denom, showRat, -- negRat, addRat, subRat, mulRat, divRat, eqRat ) -- where -- import RationalCore -- -- import RationalDeferGCD -- RATIONAL_CORE is a GLOBAL variable that has the base name -- for the "core" data representation module (e.g., "rationalCore", -- "rationalDeferGCD", rationalClo) local ratco = require(RATIONAL_CORE) local makeRat, numer, denom = ratco.makeRat, ratco.numer, ratco.denom -- Haskell -- negRat :: Rat -> Rat -- negRat r = makeRat (- numer r) (denom r) -- addRat, subRat, mulRat, divRat :: Rat -> Rat -> Rat -- addRat r s = makeRat (numer r * denom s + numer s * denom r) -- (denom r * denom s) -- subRat r s = makeRat (numer r * denom s - numer s * denom r) -- (denom r * denom s) -- mulRat r s = makeRat (numer r * numer s) --- (denom r * denom s) -- divRat r s = makeRat (numer r * denom s) (denom r * numer s) -- -- eqRat :: Rat -> Rat -> Bool -- eqRat r s = (numer r) * (denom s) == (numer s) * (denom r) -- -- showRat :: Rat -> String -- showRat r = show (numer r) ++ "/" ++ show (denom r) -- We assume all Rational number arguments to the functions in -- this Lua module were created using makeRat. local function negRat(r) return makeRat(- numer(r), denom(r)) end local function addRat(r,s) return makeRat(numer(r) * denom(s) + numer(s) * denom(r), denom(r) * denom(s) ) end local function subRat(r,s) return makeRat(numer(r) * denom(s) - numer(s) * denom(r), denom(r) * denom(s) ) end local function mulRat(r,s) return makeRat(numer(r) * numer(s), denom(r) * denom(s)) end local function divRat(r,s) return makeRat(numer(r) * denom(s), denom(r) * numer(s)) end local function showRat(r) return tostring(numer(r)) .. "/" .. tostring(denom(r)) end -- Haskell -- compareRat :: (Int -> Int -> Bool) -> Rat -> Rat -> Bool -- compareRat r x y = r (numer x * denom y) (denom x * numer y) -- -- eqRat,neqRat,ltRat,leqRat,gtRat,geqRat :: Rat -> Rat -> Bool -- eqRat = compareRat (==) -- neqRat = compareRat (/=) -- ltRat = compareRat (<) -- leqRat = compareRat (<=) -- gtRat = compareRat (>) -- geqRat = compareRat (>=) local function compare(comp) return function(r,s) local x, y = numer(r) * denom(s), denom(r) * numer(s) return comp(x,y) end end local eqRat = compare(function(x,y) return x == y end) local neqRat = compare(function(x,y) return x ~= y end) local ltRat = compare(function(x,y) return x < y end) local leqRat = compare(function(x,y) return x <= y end) local gtRat = compare(function(x,y) return x > y end) local geqRat = compare(function(x,y) return x >= y end) -- Export operations, including data representation primitives return { makeRat = makeRat, numer = numer, denom = denom, negRat = negRat, addRat = addRat, subRat = subRat, mulRat = mulRat, divRat = divRat, showRat = showRat, eqRat = eqRat, neqRat = neqRat, ltRat = ltRat, leqRat = leqRat, gtRat = gtRat, geqRat = geqRat }