LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
inference_engine_power.cpp
浏览该文件的文档.
1#define _USE_MATH_DEFINES
4
5namespace LMCAS {
6
8 const InferenceEngine& engine,
9 const SymbolicExpr& base_expr,
10 const NumberNode* exp_num,
12 if (!exp_num || !is_zero_number(*exp_num)) {
13 return Tribool::Unknown;
14 }
15 const detail::AssumptionFacts facts(engine);
16 auto base_nonzero = detail::query_nonzero_value(detail::node(base_expr), facts, Domain::Real, context);
17 if (!base_nonzero) return base_nonzero;
18 if (base_nonzero.value() == Tribool::True) {
19 return known_sign(1, target);
20 }
21 return Tribool::Unknown;
22}
23
25 const InferenceEngine& engine,
26 const SymbolicExpr& base_expr,
27 const SymbolicExpr& exp_expr,
29 const detail::AssumptionFacts facts(engine);
30 auto base_pos = detail::query_positive_value(detail::node(base_expr), facts, context);
31 if (!base_pos) {
32 return base_pos;
33 }
34 if (base_pos.value() != Tribool::True) {
35 return Tribool::Unknown;
36 }
37 auto exp_real = detail::query_real_value(detail::node(exp_expr), facts, context);
38 if (!exp_real) {
39 return exp_real;
40 }
41 if (exp_real.value() == Tribool::True) {
42 return known_sign(1, target);
43 }
44 return Tribool::Unknown;
45}
46
48 const InferenceEngine& engine,
49 const SymbolicExpr& base_expr,
50 const NumberNode& exponent,
53 return Tribool::Unknown;
54 }
55 const detail::AssumptionFacts facts(engine);
56 auto base = detail::query_real_value(detail::node(base_expr), facts, context);
57 if (!base) {
58 return base;
59 }
60 if (base.value() == Tribool::True) {
61 auto nonzero = detail::query_nonzero_value(detail::node(base_expr), facts, Domain::Real, context);
62 if (!nonzero) return nonzero;
63 if (nonzero.value() == Tribool::True) return known_sign(1, target);
64 if (nonzero.value() == Tribool::False) return known_sign(0, target);
66 }
67 return Tribool::Unknown;
68}
69
71 const InferenceEngine& engine,
72 const SymbolicExpr& base_expr,
73 const NumberNode& exponent,
76 return Tribool::Unknown;
77 }
78 auto base = engine.query_sign_of_checked(base_expr, Sign::NonNegative, context);
79 if (!base) {
80 return base;
81 }
82 if (base.value() == Tribool::True) {
84 }
85 return Tribool::Unknown;
86}
87
89 const InferenceEngine& engine,
90 const SymbolicExpr& base_expr,
91 const NumberNode& exponent,
94 return Tribool::Unknown;
95 }
96 auto base = engine.query_sign_of_checked(base_expr, Sign::NonZero, context);
97 if (!base) {
98 return base;
99 }
100 if (base.value() == Tribool::True) {
102 }
103 return Tribool::Unknown;
104}
105
107 const InferenceEngine& engine,
108 const SymbolicExpr& base_expr,
109 const NumberNode& exponent,
112 const detail::AssumptionFacts facts(engine);
113 auto real = detail::query_real_value(detail::node(base_expr), facts, context);
114 if (!real) return real;
115 if (real.value() != Tribool::True)
116 return nonzero_power_sign(engine, base_expr, exponent, target, context);
117 return engine.query_sign_of_checked(base_expr, target, context);
118 }
119 auto even = even_power_sign(engine, base_expr, exponent, target, context);
120 if (!even) {
121 return even;
122 }
123 if (even.value() != Tribool::Unknown) {
124 return even;
125 }
126 auto positive = positive_integer_power_sign(engine, base_expr, exponent, target, context);
127 if (!positive) {
128 return positive;
129 }
130 if (positive.value() != Tribool::Unknown) {
131 return positive;
132 }
133 return nonzero_power_sign(engine, base_expr, exponent, target, context);
134}
135
136InferenceTriboolResult InferenceEngine::infer_power_property_checked(
137 const PowerNode& node, Sign target, ComputationContext& context) const {
138 try {
139 auto defined = Impl::real_definedness(*this, node, context);
140 if (!defined || defined.value() != Tribool::True) return defined;
141 auto base_expr = LMCAS::detail::expression_from_node(node.base());
142 auto exp_expr = LMCAS::detail::expression_from_node(node.exponent());
143 auto exp_num = std::dynamic_pointer_cast<const NumberNode>(node.exponent());
144
145 auto zero = impl_->zero_power_sign(*this, base_expr, exp_num.get(), target, context);
146 if (!zero) {
147 return zero;
148 }
149 if (zero.value() != Tribool::Unknown) {
150 return zero;
151 }
152
153 auto positive = impl_->positive_power_sign(*this, base_expr, exp_expr, target, context);
154 if (!positive) {
155 return positive;
156 }
157 if (positive.value() != Tribool::Unknown) {
158 return positive;
159 }
160
161 if (exp_num) {
162 return impl_->integer_power_sign(*this, base_expr, *exp_num, target, context);
163 }
165 } catch (const CasError& error) {
167 } catch (const std::bad_alloc&) {
170 "power sign inference allocation failed",
171 "infer_power_property_checked");
172 } catch (const std::exception& ex) {
175 ex.what(),
176 "infer_power_property_checked");
177 }
178}
179
180}
幂运算节点,表示 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
Result< Tribool > query_nonzero_value(const Node &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
Result< Tribool > query_real_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
Result< Tribool > query_positive_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
bool is_even_integer_number(const NumberNode &num)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult real(const ExprPtr &expression, ComputationContext &context)
@ Real
Real numbers
@ Unknown
Property cannot be determined
@ True
Property definitely holds
@ False
Property definitely does not hold
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
Sign
Sign classification for symbols and expressions.
InferenceTriboolResult even_power_sign(const InferenceEngine &engine, const SymbolicExpr &base_expr, const NumberNode &exponent, Sign target, ComputationContext &context) const
InferenceTriboolResult integer_power_sign(const InferenceEngine &engine, const SymbolicExpr &base_expr, const NumberNode &exponent, Sign target, ComputationContext &context) const
InferenceTriboolResult positive_power_sign(const InferenceEngine &engine, const SymbolicExpr &base_expr, const SymbolicExpr &exp_expr, Sign target, ComputationContext &context) const
static InferenceTriboolResult real_definedness(const InferenceEngine &engine, const SymbolicNode &node, ComputationContext &context)
InferenceTriboolResult zero_power_sign(const InferenceEngine &engine, const SymbolicExpr &base_expr, const NumberNode *exp_num, Sign target, ComputationContext &context) const
static Tribool known_sign(int value, Sign target)
InferenceTriboolResult nonzero_power_sign(const InferenceEngine &engine, const SymbolicExpr &base_expr, const NumberNode &exponent, Sign target, ComputationContext &context) const
InferenceTriboolResult positive_integer_power_sign(const InferenceEngine &engine, const SymbolicExpr &base_expr, const NumberNode &exponent, Sign target, ComputationContext &context) const