1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
--- @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)
|