Advertisement
Guest User

numbers 2.0

a guest
Nov 6th, 2016
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.76 KB | None | 0 0
  1. function type(x,...)
  2.     if debug.getmetatable(x).__type then
  3.         return debug.getmetatable(x).__type
  4.     else
  5.         return type(x,...)
  6.     end
  7. end
  8.  
  9. function sametype(a,b)
  10.     assert(type(a) == type(b))
  11. end
  12.  
  13. local Nat = {}
  14.  
  15. local natMeta = {}
  16. natMeta.__index = natMeta
  17. natMeta.__type = "Natural Number"
  18.  
  19. local Zero = nil
  20.  
  21. function NaturalNumber()
  22.     local nat = {data = Zero}
  23.     setmetatable(nat,natMeta)
  24.     return nat
  25. end
  26.  
  27. NaturalZero = NaturalNumber()
  28.  
  29. function natMeta:Succ()
  30.     local ret = self:Copy()
  31.     ret.data = {ret.data}
  32.     return ret
  33. end
  34.  
  35. function natMeta:Copy()
  36.     local dat = Zero
  37.     local t = self.data
  38.     while t ~= Zero do
  39.         t = unpack(t)
  40.         dat = {dat}
  41.     end
  42.     local ret = NaturalNumber()
  43.     ret.data = dat
  44.     return ret
  45. end
  46.  
  47. function natMeta.__add(a,b)
  48.     sametype(a,b)
  49.     local ret = a:Copy()
  50.     local t = b.data
  51.     while t ~= Zero do
  52.         t = unpack(t)
  53.         ret = ret:Succ()
  54.     end
  55.     return ret
  56. end
  57.  
  58. function natMeta.__mul(a,b)
  59.     sametype(a,b)
  60.     local ret = NaturalNumber()
  61.     local t0 = a.data
  62.     while t0 ~= Zero do
  63.         t0 = unpack(t0)
  64.         local t1 = b.data
  65.         while t1 ~= Zero do
  66.             t1 = unpack(t1)
  67.             ret = ret:Succ()
  68.         end
  69.     end
  70.     return ret
  71. end
  72.  
  73. function natMeta.__eq(a,b)
  74.     sametype(a,b)
  75.     local ta = a.data
  76.     local tb = b.data
  77.     while ta ~= Zero and tb ~= Zero do
  78.         ta = unpack(ta)
  79.         tb = unpack(tb)
  80.     end
  81.     return ta == tb
  82. end
  83.  
  84. function natMeta.__lt(a,b)
  85.     sametype(a,b)
  86.     if a == b then return false end
  87.     local ta = a.data
  88.     local tb = b.data
  89.     while ta ~= Zero and tb ~= Zero do
  90.         ta = unpack(ta)
  91.         tb = unpack(tb)
  92.     end
  93.     if ta == Zero then
  94.         return true
  95.     elseif tb == Zero then
  96.         return false
  97.     end
  98. end
  99.  
  100. function natMeta.__le(a,b)
  101.     sametype(a,b)
  102.     return a == b or a < b
  103. end
  104.  
  105. ----------------UTIL STUFF
  106. --The underlying system would function fine without this code
  107. function NaturalSet(nat,n)
  108.     local ret = nat
  109.     for i = 1, n do
  110.         ret = ret:Succ()
  111.     end
  112.     return ret
  113. end
  114.  
  115. function natMeta.__tostring(self)
  116.     local count = self:toLuaNumber()
  117.     return "Natural Number (" .. tostring(count) .. ")"
  118. end
  119.  
  120. function natMeta:toLuaNumber()
  121.     local count = 0
  122.     local d = self.data
  123.     while d ~= Zero do
  124.         d = unpack(d)
  125.         count = count + 1
  126.     end
  127.     return count
  128. end
  129.  
  130. function Nat(num)
  131.     return NaturalSet(NaturalNumber(),num)
  132. end
  133. --------------------------
  134.  
  135. local intMeta = {}
  136. intMeta.__index = intMeta
  137. intMeta.__type = "Integer"
  138.  
  139. function Integer(nat1,nat2)
  140.     local int = {nat1,nat2}
  141.     return setmetatable(int,intMeta)
  142. end
  143.  
  144. local IntegerZero = Integer(NaturalNumber(),NaturalNumber())
  145.  
  146. function intMeta:Copy()
  147.     local a,b = unpack(self)
  148.     return Integer(a:Copy(),b:Copy())
  149. end
  150.  
  151. function intMeta.__add(x,y)
  152.     sametype(x,y)
  153.     local a,b = unpack(x)
  154.     local c,d = unpack(y)
  155.     return Integer(a + c, b + d)
  156. end
  157.  
  158. function intMeta.__unm(x)
  159.     local a,b = unpack(x)
  160.     return Integer(b,a)
  161. end
  162.  
  163. function intMeta.__sub(x,y)
  164.     sametype(x,y)
  165.     return x + (-y)
  166. end
  167.  
  168. function intMeta.__mul(x,y)
  169.     sametype(x,y)
  170.     local a,b = unpack(x)
  171.     local c,d = unpack(y)
  172.     local int1 = Integer(b * c, b * d)
  173.     local int2 = Integer(a * c, a * d)
  174.     return int1 + int2
  175. end
  176.  
  177. function intMeta.__div(x,y)
  178.     sametype(x,y)
  179.     local counter = NaturalNumber()
  180.     local copy = x
  181.     while copy > IntegerZero do
  182.         counter = counter:Succ()
  183.         copy = copy - y
  184.     end
  185.     return Integer(NaturalNumber(),counter)
  186. end
  187.  
  188. function intMeta:reduce()
  189.     local a,b = unpack(self)
  190.     local c,d = a.data,b.data
  191.     while c ~= Zero and d ~= Zero do
  192.         c = unpack(c)
  193.         d = unpack(d)
  194.     end
  195.     local x,y = a:Copy(), b:Copy()
  196.     x.data = c
  197.     y.data = d
  198.     return Integer(x,y)
  199. end
  200.  
  201. function intMeta.__pow(x,y)
  202.     assert(type(x) == intMeta.__type and type(y) == natMeta.__type)
  203.     local ret = Integer(NaturalNumber(),NaturalNumber():Succ())
  204.     local t = y.data
  205.     while t do
  206.         t = unpack(t)
  207.         ret = ret * x
  208.     end
  209.     return ret
  210. end
  211.  
  212. function intMeta.__eq(x,y)
  213.     sametype(x,y)
  214.     local a,b = unpack(x)
  215.     local c,d = unpack(y)
  216.     return b + c == d + a
  217. end
  218.  
  219. function intMeta.__lt(x,y)
  220.     sametype(x,y)
  221.     local a,b = unpack(x)
  222.     local c,d = unpack(y)
  223.     return b + c < d + a
  224. end
  225.  
  226. function intMeta.__le(x,y)
  227.     sametype(x,y)
  228.     return x == y or x < y
  229. end
  230.  
  231. function intMeta.__mod(x,y)
  232.     sametype(x,y)
  233.     if x < y then return x end
  234.     if x == y then return IntegerZero end
  235.     local c = x
  236.     while c >= y do
  237.         c = c - y
  238.     end
  239.     return c
  240. end
  241.  
  242. function intMeta:abs()
  243.     local x = self:reduce()
  244.     local a,b = unpack(x)
  245.     if a == NaturalZero then
  246.         return Integer(NaturalNumber(),b)
  247.     elseif b == NaturalZero then
  248.         return Integer(NaturalNumber(),a)
  249.     end
  250. end
  251.  
  252. function intMeta:sign()
  253.     local a,b = unpack(self)
  254.     if a > b then
  255.         return Integer(NaturalNumber():Succ(),NaturalNumber())
  256.     elseif a < b then
  257.         return Integer(NaturalNumber(),NaturalNumber():Succ())
  258.     else
  259.         return IntegerZero
  260.     end
  261. end
  262.  
  263. ----------------UTIL STUFF
  264. function intMeta.__tostring(self)
  265.     return "Integer (" .. tostring(self[1]) .. " , " .. tostring(self[2]) .. ") [" .. tostring(self:toLuaNumber()) .. "]"
  266. end
  267.  
  268. function intMeta:toLuaNumber()
  269.     return self[2]:toLuaNumber() - self[1]:toLuaNumber()
  270. end
  271.  
  272. function Int(num)
  273.     if num == 0 then return Integer(NaturalNumber(),NaturalNumber()) end
  274.     if num > 0 then
  275.         return Integer(NaturalNumber(),Nat(num))
  276.     else
  277.         return Integer(Nat(math.abs(num)),NaturalNumber())
  278.     end
  279. end
  280. --------------------------
  281.  
  282. local ratMeta = {}
  283. ratMeta.__index = ratMeta
  284. ratMeta.__type = "Rational Number"
  285.  
  286. function RationalNumber(x,y)
  287.     assert(type(x) == intMeta.__type and type(y) == intMeta.__type)
  288.     if y == IntegerZero then error("Division by zero") end
  289.     local rat = {x,y}
  290.     return setmetatable(rat,ratMeta)
  291. end
  292.  
  293. local RationalZero = RationalNumber(IntegerZero,Integer(NaturalNumber(),NaturalNumber():Succ()))
  294.  
  295. function ratMeta.__unm(x)
  296.     local a,b = unpack(x)
  297.     return RationalNumber(-a,-b)
  298. end
  299.  
  300. function ratMeta.__add(x,y)
  301.     sametype(x,y)
  302.     local a,b = unpack(x)
  303.     local c,d = unpack(y)
  304.     return RationalNumber(a * d + c * b, b * d)
  305. end
  306.  
  307. function ratMeta.__sub(x,y)
  308.     sametype(x,y)
  309.     return x + (-y)
  310. end
  311.  
  312. function ratMeta.__mul(x,y)
  313.     sametype(x,y)
  314.     local a,b = unpack(x)
  315.     local c,d = unpack(y)
  316.     return RationalNumber(a * c, b * d)
  317. end
  318.  
  319. function ratMeta.__div(x,y)
  320.     sametype(x,y)
  321.     if y == RationalZero then error("Division by zero") end
  322.     local a,b = unpack(y)
  323.     local new = RationalNumber(b,a)
  324.     return x * new
  325. end
  326.  
  327. function ratMeta.__pow(x,y)
  328.     assert(type(x) == ratMeta.__type and type(y) == intMeta.__type)
  329.     local a,b = unpack(x)
  330.     local c,d = unpack(y)
  331.     return RationalNumber(a^d * b^c, a^c * b^d)
  332. end
  333.  
  334. function ratMeta.__eq(x,y)
  335.     sametype(x,y)
  336.     local a,b = unpack(x)
  337.     local c,d = unpack(y)
  338.     return a * d == b * c
  339. end
  340.  
  341. function ratMeta.__lt(x,y)
  342.     sametype(x,y)
  343.     local a,b = unpack(x)
  344.     local c,d = unpack(y)
  345.     return a * d < c * b
  346. end
  347.  
  348. function ratMeta.__le(x,y)
  349.     sametype(x,y)
  350.     return x == y or x < y
  351. end
  352.  
  353. function ratMeta:floor()
  354.     local x,y = unpack(self)
  355.     if y >= x then return RationalZero end
  356.     return RationalNumber((x % y) - x, -y)
  357. end
  358.  
  359. local function IntegerGCD(a,b)
  360.     sametype(a,b)
  361.     if a == b then return a end
  362.     if b == IntegerZero then return a end
  363.     if a > b then
  364.         return IntegerGCD(a - b, b)
  365.     end
  366.     return IntegerGCD(b, a % b)
  367. end
  368.  
  369. function ratMeta:reduce()
  370.     local x,y = unpack(self)
  371.     x = x:reduce()
  372.     y = y:reduce()
  373.     local gcd = IntegerGCD(x:abs(),y:abs())
  374.     return RationalNumber(x / gcd, y / gcd)
  375. end
  376.  
  377. ----------------UTIL STUFF
  378. function ratMeta.__tostring(self)
  379.     return "Rational Number ( " .. tostring(self[1]:toLuaNumber()) .. " / " .. tostring(self[2]:toLuaNumber()) .. " ) [" .. tostring(self:toLuaNumber()) .. "]"
  380. end
  381.  
  382. function ratMeta:toLuaNumber()
  383.     return self[1]:toLuaNumber() / self[2]:toLuaNumber()
  384. end
  385.  
  386. function Rat(x,y)
  387.     return RationalNumber(Int(x),Int(y))
  388. end
  389. --------------------------
  390.  
  391. local a = Int(2)
  392. local b = Nat(8)
  393. print(a^b) --Integer (Natural Number (0) , Natural Number (256)) [256]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement