--- @class EuclideanDomain --- Interface for an element of a euclidean domain. EuclideanDomain = {} local __EuclideanDomain = {} ---------------------- -- Required methods -- ---------------------- --- @param b EuclideanDomain --- @return EuclideanDomain, EuclideanDomain function EuclideanDomain:divremainder(b) error("Called unimplemented method : divremainder()") end ---------------------------- -- Instance functionality -- ---------------------------- --- @return boolean function EuclideanDomain:iscommutative() return true end -------------------------- -- Instance metamethods -- -------------------------- __EuclideanOperations = Copy(__RingOperations) -- Division with remainder -- Unfortunately, this can only return 1 result, so it returns the quotient - for the remainder use a % b, or a:divremainder(b) __EuclideanOperations.__idiv = function(a, b) if(b == b:zero()) then error("Cannot divide by zero.") end local aring, bring = a:getring(), b:getring() local oring = Ring.resultantring(aring, bring) if not oring then error("Attempted to divide two elements of incompatable rings") end return a:inring(oring):divremainder(b:inring(oring)) end __EuclideanOperations.__mod = function(a, b) if(b == b:zero()) then error("Cannot divide by zero.") end local aring, bring = a:getring(), b:getring() local oring = Ring.resultantring(aring, bring) if not oring then error("Attempted to divide two elements of incompatable rings") end local _,q = a:inring(oring):divremainder(b:inring(oring)) return q end ----------------- -- Inheritance -- ----------------- __EuclideanDomain.__index = Ring EuclideanDomain = setmetatable(EuclideanDomain, __EuclideanDomain)