--- @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 function FactorialExpression:subexpressions() return {self.expression} end --- @param subexpressions table --- @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