LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
inference_engine_facts.cpp
浏览该文件的文档.
2
3namespace LMCAS {
4
8
10 return !num.is_positive() && !num.is_zero() ? Tribool::True : Tribool::False;
11}
12
16
20
24
28
30 const InferenceEngine& engine,
31 const SymbolicExpr& expr, ComputationContext& context) const {
32 if (!LMCAS::detail::node(expr)) {
35 "inference expression must not be null",
36 "query_domain_of_checked");
37 }
38 try {
39 auto integer = engine.query_integer_checked(expr, context);
40 if (!integer) {
42 }
43 if (integer.value() == Tribool::True) {
45 }
46 if (auto num = std::dynamic_pointer_cast<const NumberNode>(LMCAS::detail::node(expr))) {
47 if (std::holds_alternative<Rational>(num->value())) {
49 }
50 }
51 if (auto var = std::dynamic_pointer_cast<const VariableNode>(LMCAS::detail::node(expr))) {
52 if (var->is_constant()) return InferenceTriboolResult::success(Tribool::False);
53 const auto& props = ctx;
54 if (props.has_domain(var->name(), Domain::Rational)) {
56 }
57 }
59 } catch (const CasError& error) {
61 } catch (const std::bad_alloc&) {
64 "inference query allocation failed",
65 "query_domain_of_checked");
66 } catch (const std::exception& ex) {
69 ex.what(),
70 "query_domain_of_checked");
71 }
72}
73
75 return checked_inference_result<Tribool>(expr, "query_domain_of_checked", context,
76 [&]() -> InferenceTriboolResult {
77 if (auto num = std::dynamic_pointer_cast<const NumberNode>(LMCAS::detail::node(expr))) {
78 return natural_number(*num);
79 }
80 if (auto var = std::dynamic_pointer_cast<const VariableNode>(LMCAS::detail::node(expr))) {
81 if (var->is_constant()) return Tribool::False;
82 const auto& props = ctx;
83 if (props.has_domain(var->name(), Domain::Natural)) {
84 return Tribool::True;
85 }
86 }
87 return Tribool::Unknown;
88 });
89}
90
95
96
97InferenceTriboolResult InferenceEngine::query_real_checked(const SymbolicExpr& expr) const {
99 return query_real_checked(expr, context);
100}
101
102InferenceTriboolResult InferenceEngine::query_real_checked(const SymbolicExpr& expr, ComputationContext& context) const {
103 return checked_inference_result<Tribool>(expr, "query_real_checked", context,
104 [&]() -> InferenceTriboolResult {
105 DepthGuard guard(*this, *LMCAS::detail::node(expr));
106 if (guard.should_abort()) {
107 return Tribool::Unknown;
108 }
109 if (std::dynamic_pointer_cast<const NumberNode>(LMCAS::detail::node(expr))) {
110 return Tribool::True;
111 }
112
113 if (auto var = std::dynamic_pointer_cast<const VariableNode>(LMCAS::detail::node(expr))) {
114 if (var->is_constant()) return Tribool::True;
115 const auto& props = impl_->ctx;
116 if (props.has_domain(var->name(), Domain::Real)) {
117 return Tribool::True;
118 }
121 auto step = context.consume_steps(1, "query_real_checked");
122 if (!step) return InferenceTriboolResult::failure(step.error());
123 if (props.has_sign(var->name(), sign)) { return Tribool::True; }
124 }
125 return Tribool::Unknown;
126 }
127
128 return impl_->composite_real(*this, expr, context);
129 });
130}
131
132InferenceTriboolResult InferenceEngine::query_integer_checked(const SymbolicExpr& expr) const {
133 ComputationContext context;
134 return query_integer_checked(expr, context);
135}
136
137InferenceTriboolResult InferenceEngine::query_integer_checked(const SymbolicExpr& expr, ComputationContext& context) const {
138 return checked_inference_result<Tribool>(expr, "query_integer_checked", context,
139 [&]() -> InferenceTriboolResult {
140 if (infinity_sign(expr, context) != 0) {
142 }
143 DepthGuard guard(*this, *LMCAS::detail::node(expr));
144 if (guard.should_abort()) {
145 return Tribool::Unknown;
146 }
147 if (auto num = std::dynamic_pointer_cast<const NumberNode>(LMCAS::detail::node(expr))) {
148 return Impl::number_integer(*num);
149 }
150
151 if (auto var = std::dynamic_pointer_cast<const VariableNode>(LMCAS::detail::node(expr))) {
152 if (var->is_constant()) return Tribool::False;
153 const auto& props = impl_->ctx;
154 if (props.has_domain(var->name(), Domain::Integer)) {
155 return Tribool::True;
156 }
157 return Tribool::Unknown;
158 }
159
160 return impl_->composite_integer(*this, expr, context);
161 });
162}
163
164
165
166InferenceTriboolResult InferenceEngine::query_algebraic_checked(const SymbolicExpr& expr) const {
167 ComputationContext context;
168 return query_algebraic_checked(expr, context);
169}
170
171InferenceTriboolResult InferenceEngine::query_algebraic_checked(const SymbolicExpr& expr, ComputationContext& context) const {
172 return checked_inference_result<Tribool>(expr, "query_algebraic_checked", context,
173 [&]() -> InferenceTriboolResult {
174 DepthGuard guard(*this, *LMCAS::detail::node(expr));
175 if (guard.should_abort()) {
176 return Tribool::Unknown;
177 }
178 if (auto num = std::dynamic_pointer_cast<const NumberNode>(LMCAS::detail::node(expr))) {
179 if (std::holds_alternative<BigInt>(num->value())) {
180 return Tribool::True;
181 }
182 if (std::holds_alternative<Rational>(num->value())) {
183 return Tribool::True;
184 }
185 return Tribool::Unknown;
186 }
187
188 if (auto var = std::dynamic_pointer_cast<const VariableNode>(LMCAS::detail::node(expr))) {
189 if (var->is_constant()) return var->name() == "phi" ? Tribool::True : Tribool::False;
190 const auto& props = impl_->ctx;
191 if (props.has_domain(var->name(), Domain::Algebraic)) {
192 return Tribool::True;
193 }
194 if (props.is_transcendental(var->name())) {
195 return Tribool::False;
196 }
197 return Tribool::Unknown;
198 }
199 return Tribool::Unknown;
200 });
201}
202
203
204InferenceTriboolResult InferenceEngine::query_transcendental_checked(const SymbolicExpr& expr) const {
205 ComputationContext context;
206 return query_transcendental_checked(expr, context);
207}
208
209InferenceTriboolResult InferenceEngine::query_transcendental_checked(const SymbolicExpr& expr, ComputationContext& context) const {
210 return checked_inference_result<Tribool>(expr, "query_transcendental_checked", context,
211 [&]() -> InferenceTriboolResult {
212 DepthGuard guard(*this, *LMCAS::detail::node(expr));
213 if (guard.should_abort()) {
214 return Tribool::Unknown;
215 }
216 if (auto num = std::dynamic_pointer_cast<const NumberNode>(LMCAS::detail::node(expr))) {
217 if (std::holds_alternative<BigInt>(num->value())) {
218 return Tribool::False;
219 }
220 if (std::holds_alternative<Rational>(num->value())) {
221 return Tribool::False;
222 }
223 return Tribool::Unknown;
224 }
225
226 if (auto var = std::dynamic_pointer_cast<const VariableNode>(LMCAS::detail::node(expr))) {
227 if (var->is_constant()) return var->name() == "phi" ? Tribool::False : Tribool::True;
228 const auto& props = impl_->ctx;
229 if (props.is_transcendental(var->name())) {
230 return Tribool::True;
231 }
232 if (props.has_domain(var->name(), Domain::Algebraic)) {
233 return Tribool::False;
234 }
235 return Tribool::Unknown;
236 }
237 return Tribool::Unknown;
238 });
239}
240
241
242InferenceTriboolResult InferenceEngine::query_finite_checked(const SymbolicExpr& expr) const {
243 ComputationContext context;
244 return query_finite_checked(expr, context);
245}
246
247InferenceTriboolResult InferenceEngine::query_finite_checked(const SymbolicExpr& expr, ComputationContext& context) const {
248 return checked_inference_result<Tribool>(expr, "query_finite_checked", context,
249 [&]() -> InferenceTriboolResult {
250 DepthGuard guard(*this, *LMCAS::detail::node(expr));
251 if (guard.should_abort()) {
252 return Tribool::Unknown;
253 }
254 if (std::dynamic_pointer_cast<const NumberNode>(LMCAS::detail::node(expr))) {
255 return Tribool::True;
256 }
257
258 if (auto var = std::dynamic_pointer_cast<const VariableNode>(LMCAS::detail::node(expr))) {
259 if (var->is_constant()) return Tribool::True;
260 const auto& props = impl_->ctx;
261 Finiteness f = props.get_finiteness(var->name());
262 if (f == Finiteness::Finite) {
263 return Tribool::True;
264 }
265 if (f == Finiteness::Divergent) {
266 return Tribool::False;
267 }
268 return Tribool::Unknown;
269 }
270 return Tribool::Unknown;
271 });
272}
273
274
275InferenceTriboolResult InferenceEngine::query_divergent_checked(const SymbolicExpr& expr) const {
276 ComputationContext context;
277 return query_divergent_checked(expr, context);
278}
279
280InferenceTriboolResult InferenceEngine::query_divergent_checked(const SymbolicExpr& expr, ComputationContext& context) const {
281 return checked_inference_result<Tribool>(expr, "query_divergent_checked", context,
282 [&]() -> InferenceTriboolResult {
283 DepthGuard guard(*this, *LMCAS::detail::node(expr));
284 if (guard.should_abort()) {
285 return Tribool::Unknown;
286 }
287 if (std::dynamic_pointer_cast<const NumberNode>(LMCAS::detail::node(expr))) {
288 return Tribool::False;
289 }
290
291 if (auto var = std::dynamic_pointer_cast<const VariableNode>(LMCAS::detail::node(expr))) {
292 if (var->is_constant()) return Tribool::False;
293 const auto& props = impl_->ctx;
294 Finiteness f = props.get_finiteness(var->name());
295 if (f == Finiteness::Divergent) {
296 return Tribool::True;
297 }
298 if (f == Finiteness::Finite) {
299 return Tribool::False;
300 }
301 return Tribool::Unknown;
302 }
303 return Tribool::Unknown;
304 });
305}
306
308 if (std::holds_alternative<BigInt>(num.value())) {
309 return true;
310 }
311 return std::get<Rational>(num.value()).is_integer();
312}
314 if (!is_integer_number(num)) {
315 return false;
316 }
317
318 if (std::holds_alternative<BigInt>(num.value())) {
319 return std::get<BigInt>(num.value()).is_even();
320 }
321 return std::get<Rational>(num.value()).get_numerator().is_even();
322}
324 return is_integer_number(num) && num.is_positive();
325}
327 return num.is_zero();
328}
329
330}
CasError & error()
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(Tribool value)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::shared_ptr< SymbolicExpr > num(int value)
bool is_even_integer_number(const NumberNode &num)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult integer(Integer)=delete
Result< T > checked_inference_result(const SymbolicExpr &expr, const std::string &operation, ComputationContext &context, const std::function< Result< T >()> &query)
@ Rational
Rational numbers
@ Natural
Non-negative integers (0, 1, 2, ...)
@ Real
Real numbers
@ Algebraic
Algebraic numbers (roots of polynomials with rational coefficients)
Tribool
Tri-state logic value for property queries.
@ Unknown
Property cannot be determined
@ True
Property definitely holds
@ False
Property definitely does not hold
bool is_integer_number(const NumberNode &num)
bool is_positive_integer_number(const NumberNode &num)
Finiteness
Finiteness classification for limits and sequences.
@ Finite
Has a finite value or limit
@ Divergent
Diverges to infinity or oscillates
bool is_zero_number(const NumberNode &num)
Result< Tribool > InferenceTriboolResult
int infinity_sign(const SymbolicExpr &expression, ComputationContext &context)
Sign
Sign classification for symbols and expressions.
static Tribool number_negative(const NumberNode &num)
InferenceTriboolResult query_rational(const InferenceEngine &engine, const SymbolicExpr &expr, ComputationContext &context) const
static Tribool number_nonzero(const NumberNode &num)
static Tribool number_positive(const NumberNode &num)
static Tribool number_integer(const NumberNode &num)
static Tribool natural_number(const NumberNode &num)
static Tribool number_nonpositive(const NumberNode &num)
InferenceTriboolResult query_natural(const SymbolicExpr &expr, ComputationContext &context) const
static Tribool number_nonnegative(const NumberNode &num)