LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
inference_engine_domains.cpp
浏览该文件的文档.
1#define _USE_MATH_DEFINES
4
5namespace LMCAS {
6
7
8
9InferenceTriboolResult InferenceEngine::infer_add_domain_checked(
10 const AddNode& node, Domain target, ComputationContext& context) const {
11 try {
12 if (node.operands().empty()) {
14 }
15 for (const auto& operand : node.operands()) {
16 auto op_expr = LMCAS::detail::expression_from_node(operand);
17 Tribool op_result = Tribool::Unknown;
18 switch (target) {
19 case Domain::Integer: {
20 auto queried = query_integer_checked(op_expr, context);
21 if (!queried) {
22 return queried;
23 }
24 op_result = queried.value();
25 break;
26 }
27 case Domain::Real: {
28 auto queried = query_real_checked(op_expr, context);
29 if (!queried) {
30 return queried;
31 }
32 op_result = queried.value();
33 break;
34 }
35 default:
37 }
38
39 if (op_result != Tribool::True) {
40 if (target == Domain::Real) {
41 auto integer = query_integer_checked(op_expr, context);
42 if (!integer) {
43 return integer;
44 }
45 if (integer.value() == Tribool::True) {
46 continue;
47 }
48 }
50 }
51 }
52
54 } catch (const CasError& error) {
56 } catch (const std::bad_alloc&) {
59 "addition domain inference allocation failed",
60 "infer_add_domain_checked");
61 } catch (const std::exception& ex) {
64 ex.what(),
65 "infer_add_domain_checked");
66 }
67}
68
69
70InferenceTriboolResult InferenceEngine::infer_multiply_domain_checked(
71 const MultiplyNode& node, Domain target, ComputationContext& context) const {
72 try {
73 auto defined = Impl::real_definedness(*this, node, context);
74 if (!defined || defined.value() != Tribool::True) { return defined; }
75 if (node.operands().empty()) {
77 }
78
79 return impl_->multiply_domain(*this, node, target, context);
80 } catch (const CasError& error) {
82 } catch (const std::bad_alloc&) {
85 "multiplication domain inference allocation failed",
86 "infer_multiply_domain_checked");
87 } catch (const std::exception& ex) {
90 ex.what(),
91 "infer_multiply_domain_checked");
92 }
93}
94
96 const InferenceEngine& engine, const MultiplyNode& node, Domain target, ComputationContext& context) const {
98 for (const auto& operand : node.operands()) {
99 const auto expression = detail::expression_from_node(operand);
100 auto result = target == Domain::Integer ? engine.query_integer_checked(expression, context)
101 : real_or_integer(engine, expression, context);
102 if (!result) { return result; }
103 if (result.value() != Tribool::True) { return Tribool::Unknown; }
104 }
105 return Tribool::True;
106}
107InferenceTriboolResult InferenceEngine::infer_power_domain_checked(
108 const PowerNode& node, Domain target, ComputationContext& context) const {
109 try {
110 auto defined = Impl::real_definedness(*this, node, context);
111 if (!defined || defined.value() != Tribool::True) { return defined; }
112 if (target == Domain::Real) {
113 const detail::AssumptionFacts facts(*this);
114 const std::shared_ptr<const SymbolicNode> borrowed(
115 std::shared_ptr<const SymbolicNode>{}, &node);
116 auto real = detail::query_real_value(borrowed, facts, context);
117 if (!real) { return real; }
119 }
120 auto base_expr = LMCAS::detail::expression_from_node(node.base());
121 auto exp_num = std::dynamic_pointer_cast<const NumberNode>(node.exponent());
122
123 if (exp_num && is_integer_number(*exp_num)) {
124 return Impl::integral_power_domain(*this, base_expr, *exp_num, target, context);
125 }
126
128 } catch (const CasError& error) {
130 } catch (const std::bad_alloc&) {
133 "power domain inference allocation failed",
134 "infer_power_domain_checked");
135 } catch (const std::exception& ex) {
138 ex.what(),
139 "infer_power_domain_checked");
140 }
141}
142
144 const InferenceEngine& engine, const SymbolicExpr& base,
146 if (target == Domain::Integer) {
147 auto base_int_result = engine.query_integer_checked(base, context);
148 if (!base_int_result) {
149 return base_int_result;
150 }
151 const Tribool base_int = base_int_result.value();
154 }
155 if (base_int == Tribool::True && is_zero_number(exponent)) {
157 }
158 }
159 return Tribool::Unknown;
160}
161
162}
乘法节点,表示多个操作数的乘积。
幂运算节点,表示 base^exponent。
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(Tribool value)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
Result< Tribool > query_real_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult integer(Integer)=delete
ExprResult real(const ExprPtr &expression, ComputationContext &context)
Domain
Mathematical domain hierarchy (least specific → most specific). Complex ⊃ Real ⊃ Algebraic ⊃ Rational...
@ Real
Real numbers
Tribool
Tri-state logic value for property queries.
@ Unknown
Property cannot be determined
@ True
Property definitely holds
bool is_integer_number(const NumberNode &num)
const ExprPtr & exponent
bool is_positive_integer_number(const NumberNode &num)
const ExprPtr & target
bool is_zero_number(const NumberNode &num)
Result< Tribool > InferenceTriboolResult
static InferenceTriboolResult integral_power_domain(const InferenceEngine &engine, const SymbolicExpr &base, const NumberNode &exponent, Domain target, ComputationContext &context)
InferenceTriboolResult real_or_integer(const InferenceEngine &engine, const SymbolicExpr &arg_expr, ComputationContext &context) const
static InferenceTriboolResult real_definedness(const InferenceEngine &engine, const SymbolicNode &node, ComputationContext &context)
InferenceTriboolResult multiply_domain(const InferenceEngine &engine, const MultiplyNode &node, Domain target, ComputationContext &context) const