LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
facts_query_rational.cpp
浏览该文件的文档.
6
7#include <algorithm>
8
9namespace LMCAS::detail {
10using Node = std::shared_ptr<const SymbolicNode>;
11
12std::optional<Rational> closed_rational_value(
14
15namespace {
16
17std::optional<Rational> closed_rational_power(
19 ExactBoundArithmetic& arithmetic) {
20 auto base = closed_rational_value(power.base(), domain, context);
21 if (!base) { return std::nullopt; }
23 if (!exponent || !exponent->is_integer()) { return std::nullopt; }
24 BigInt count = exponent->to_bigint();
25 if (base->is_zero() && (count.is_negative() ||
26 (count.is_zero() && domain == Domain::Real))) { return std::nullopt; }
27 if (count.is_negative()) {
28 *base = arithmetic.div(Rational(1), *base);
29 count = -count;
30 }
31 Rational value(1);
32 while (!count.is_zero()) {
33 arithmetic.step();
34 if (count.is_odd()) { value = arithmetic.mul(value, *base); }
35 count = count >> 1;
36 if (!count.is_zero()) { *base = arithmetic.mul(*base, *base); }
37 }
38 return value;
39}
40
41}
42
43// Fold closed rational arithmetic without normalization or fact queries.
44std::optional<Rational> closed_rational_value(
45 const std::shared_ptr<const SymbolicNode>& node, Domain domain, ComputationContext& context) {
46 ExactBoundArithmetic arithmetic(context, "facts.constant_exponent");
47 arithmetic.require(context.enter_recursion("facts.constant_exponent"));
48 struct Leave {
50 ~Leave() { context.leave_recursion(); }
51 } leave{context};
52 if (const auto* number = dynamic_cast<const NumberNode*>(node.get())) {
53 auto value = exact_number_as_rational(*number);
54 arithmetic.bits(std::max(value.get_numerator().bit_length(),
55 value.get_denominator().bit_length()));
56 return value;
57 }
58 const auto* sum = dynamic_cast<const AddNode*>(node.get());
59 const auto* product = dynamic_cast<const MultiplyNode*>(node.get());
60 if (sum || product) {
61 Rational value(product ? 1 : 0);
62 for (const auto& operand : sum ? sum->operands() : product->operands()) {
63 auto child = closed_rational_value(operand, domain, context);
64 if (!child) { return std::nullopt; }
65 value = product ? arithmetic.mul(value, *child) : arithmetic.add(value, *child);
66 }
67 return value;
68 }
69 const auto* power = dynamic_cast<const PowerNode*>(node.get());
70 if (!power) { return std::nullopt; }
71 return closed_rational_power(*power, domain, context, arithmetic);
72}
73
74}
加法节点,表示多个操作数的求和。
乘法节点,表示多个操作数的乘积。
幂运算节点,表示 base^exponent。
const std::shared_ptr< const SymbolicNode > & exponent() const noexcept
const std::shared_ptr< const SymbolicNode > & base() const noexcept
常数及根式包围区间共用的内部算术策略。 保守界覆盖未约分 Rational 的交叉乘积及结果;受检入口统一捕获 CasError,仅返回完整结果。
Rational mul(const Rational &a, const Rational &b) const
Rational add(const Rational &a, const Rational &b) const
Rational div(const Rational &a, const Rational &b) const
void require(Result< void > result) const
std::optional< Rational > closed_rational_power(const PowerNode &power, Domain domain, ComputationContext &context, ExactBoundArithmetic &arithmetic)
多元 Hensel 提升(单变量步)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::shared_ptr< const SymbolicNode > Node
RewriteBudget const FactsQuery Domain domain
std::optional< Rational > closed_rational_value(const std::shared_ptr< const SymbolicNode > &node, Domain domain, ComputationContext &context)
std::size_t std::size_t ComputationContext & context
Domain
Mathematical domain hierarchy (least specific → most specific). Complex ⊃ Real ⊃ Algebraic ⊃ Rational...
@ Real
Real numbers
const ExprPtr & exponent
const std::string const ExprPtr & value
Rational exact_number_as_rational(const NumberNode &node)
内部 AST 定义。