blob: 1c5b824ff7ec4f28dd2108c2514cb32c72ad9797 (
plain)
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
--- @class FactorialExpression
--- The factorial of an expression.
--- @field expression Expression
FactorialExpression = {}
__FactorialExpression = {}
----------------------------
-- Instance functionality --
----------------------------
--- Creates a new factorial expression with the given expression.
--- @param expression Expression
--- @return FactorialExpression
function FactorialExpression:new(expression)
local o = {}
local __o = Copy(__ExpressionOperations)
o.expression = expression
__o.__index = FactorialExpression
__o.__tostring = function(a)
return '(' .. tostring(a.expression) .. ')!'
end
o = setmetatable(o, __o)
return o
end
--- @return Expression
function FactorialExpression:evaluate()
if self.expression:type() == Integer then
if self.expression < Integer.zero() then
error("Aritmetic Error: Factorials of negative integers are not defined.")
end
if not FactorialExpression.LIMIT then
FactorialExpression.LIMIT = Integer(5000)
end
if self.expression > FactorialExpression.LIMIT then
return self
end
-- TODO: More efficient factorial computations.
local out = Integer.one()
local i = Integer.zero()
while i < self.expression do
i = i + Integer.one()
out = out * i
end
return out
end
return self
end
--- @return Expression
function FactorialExpression:autosimplify()
return FactorialExpression(self.expression:autosimplify()):evaluate()
end
--- @return table<number, Expression>
function FactorialExpression:subexpressions()
return {self.expression}
end
--- @param subexpressions table<number, Expression>
--- @return AbsExpression
function FactorialExpression:setsubexpressions(subexpressions)
return FactorialExpression(subexpressions[1])
end
--- @param other Expression
--- @return boolean
function FactorialExpression:order(other)
return FunctionExpression("fact", self.expression):order(other)
end
--- @return string
function FactorialExpression:tolatex()
if self.expression:isatomic() then
return self.expression:tolatex() .. "!"
end
return "(" .. self.expression:tolatex() .. ")!"
end
-----------------
-- Inheritance --
-----------------
__FactorialExpression.__index = CompoundExpression
__FactorialExpression.__call = FactorialExpression.new
FactorialExpression = setmetatable(FactorialExpression, __FactorialExpression)
----------------------
-- Static constants --
----------------------
-- Do not attempt to compute factorials larger than this.
FactorialExpression.LIMIT = Integer(5000)
FACT = function (a)
return FactorialExpression(a)
end
|