LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
inference_engine_impl.hpp
浏览该文件的文档.
1#pragma once
2
6#include "interval.hpp"
8#include "property_store.hpp"
9#include "relation_store.hpp"
11
12#include <algorithm>
13#include <climits>
14#include <cstdint>
15#include <functional>
16#include <optional>
17#include <unordered_set>
18
19namespace LMCAS {
20
21bool is_integer_number(const NumberNode& number);
22bool is_even_integer_number(const NumberNode& number);
23bool is_positive_integer_number(const NumberNode& number);
24bool is_zero_number(const NumberNode& number);
25
26inline bool is_negative_infinity_coefficient(const NumberNode& number) {
27 if (std::holds_alternative<BigInt>(number.value())) {
28 return std::get<BigInt>(number.value()) < BigInt(0);
29 }
30 return std::get<Rational>(number.value()) < Rational(0);
31}
32
33inline int infinity_sign(const SymbolicExpr& expression, ComputationContext& context) {
34 const auto& node = detail::node(expression);
35 if (auto function = std::dynamic_pointer_cast<const FunctionNode>(node)) {
36 return function->type() == FunctionNode::FuncType::Infinity ? 1 : 0;
37 }
38 auto product = std::dynamic_pointer_cast<const MultiplyNode>(node);
39 if (!product) {
40 return 0;
41 }
42
43 bool has_infinity = false;
44 int sign = 1;
45 for (const auto& operand : product->operands()) {
46 auto step = context.consume_steps(1, "inference.infinity");
47 if (!step) throw step.error();
48 if (auto function = std::dynamic_pointer_cast<const FunctionNode>(operand)) {
49 has_infinity = has_infinity ||
51 }
52 if (auto number = std::dynamic_pointer_cast<const NumberNode>(operand)) {
54 sign = -sign;
55 }
56 }
57 }
58 return has_infinity ? sign : 0;
59}
60
61template <typename T>
63 const SymbolicExpr& expr,
64 const std::string& operation,
66 const std::function<Result<T>()>& query) {
67 if (!detail::node(expr)) {
68 return Result<T>::failure(
70 "inference expression must not be null", operation);
71 }
72 try {
73 auto entered = context.enter_recursion(operation);
74 if (!entered) return Result<T>::failure(entered.error());
75 struct Leave {
77 ~Leave() { context.leave_recursion(); }
78 } leave{context};
79 return query();
80 } catch (const CasError& error) {
81 return Result<T>::failure(error);
82 } catch (const std::bad_alloc&) {
83 return Result<T>::failure(
85 "inference query allocation failed", operation);
86 } catch (const std::exception& error) {
87 return Result<T>::failure(
88 CasErrc::InternalInvariant, error.what(), operation);
89 }
90}
91
92
94 explicit Impl(const AssumptionContext& context)
95 : ctx(context), max_depth(context.get_max_query_depth()) {}
97 const InferenceEngine& engine, const SymbolicExpr& expr, ComputationContext& context) const;
99 const InferenceEngine& engine, const SymbolicNode& node, ComputationContext& context);
100 static Tribool number_positive(const NumberNode& num);
101 static Tribool number_negative(const NumberNode& num);
104 static Tribool number_integer(const NumberNode& num);
105 static Tribool number_nonzero(const NumberNode& num);
106 static Tribool natural_number(const NumberNode& num);
108 const InferenceEngine& engine, const SymbolicExpr& expr, ComputationContext& context) const;
110 const InferenceEngine& engine, const SymbolicExpr& expr, ComputationContext& context) const;
112 const InferenceEngine& engine, const SymbolicExpr& expr, ComputationContext& context) const;
114 const InferenceEngine& engine, const SymbolicExpr& expr, ComputationContext& context) const;
116 const InferenceEngine& engine, const SymbolicExpr& expr, ComputationContext& context) const;
118 const InferenceEngine& engine, const SymbolicExpr& expr, ComputationContext& context) const;
120 const InferenceEngine& engine, const SymbolicExpr& expr, ComputationContext& context) const;
122 const InferenceEngine& engine, const AddNode& add, ComputationContext& context) const;
124 const InferenceEngine& engine, const SymbolicExpr& expr, ComputationContext& context) const;
125 InferenceTriboolResult query_natural(const SymbolicExpr& expr, ComputationContext& context) const;
126 static Tribool known_sign(int value, Sign target);
128 static std::shared_ptr<const SymbolicNode> subtrahend(
129 const std::shared_ptr<const SymbolicNode>& operand, ComputationContext& context);
130 static bool has_negated_operand(const AddNode& node, ComputationContext& context);
132 const InferenceEngine& engine, const AddNode& node, Sign target, ComputationContext& context) const;
134 const InferenceEngine& engine, const SymbolicExpr& minuend_expr,
135 const SymbolicExpr& subtrahend_expr, Sign target, ComputationContext& context) const;
137 const InferenceEngine& engine, const SymbolicExpr& minuend_expr,
138 const SymbolicExpr& subtrahend_expr, Sign target, ComputationContext& context) const;
139 bool operand_sign(
140 const std::shared_ptr<const SymbolicNode>& operand, Sign target, ComputationContext& context) const;
142 const std::shared_ptr<const SymbolicNode>& operand, const SymbolicExpr& zero_expr,
143 bool& all_gt_zero, bool& all_geq_zero, ComputationContext& context) const;
145 const AddNode& add, const SymbolicExpr& zero_expr, Sign target, ComputationContext& context) const;
147 const MultiplyNode& mul, const SymbolicExpr& zero_expr, Sign target, ComputationContext& context) const;
149 const Relation& rel, const SymbolicExpr& zero_expr, ComputationContext& context) const;
151 const SymbolicExpr& expr, const SymbolicExpr& zero_expr, ComputationContext& context) const;
153 const InferenceEngine& engine,
154 const std::shared_ptr<const SymbolicNode>& operand,
155 std::uint8_t& possible, ComputationContext& context) const;
157 std::uint8_t possible, Sign target);
159 const InferenceEngine& engine, const MultiplyNode& node, Sign target, ComputationContext& context) const;
161 const InferenceEngine& engine, const SymbolicExpr& num_expr,
162 const SymbolicExpr& den_expr, Sign target, ComputationContext& context) const;
164 const InferenceEngine& engine, const MultiplyNode& node, Domain target, ComputationContext& context) const;
166 const InferenceEngine& engine, const SymbolicExpr& base,
169 const InferenceEngine& engine, const SymbolicExpr& base_expr,
170 const NumberNode* exp_num, Sign target, ComputationContext& context) const;
172 const InferenceEngine& engine, const SymbolicExpr& base_expr,
173 const SymbolicExpr& exp_expr, Sign target, ComputationContext& context) const;
175 const InferenceEngine& engine, const SymbolicExpr& base_expr,
178 const InferenceEngine& engine, const SymbolicExpr& base_expr,
181 const InferenceEngine& engine, const SymbolicExpr& base_expr,
184 const InferenceEngine& engine, const SymbolicExpr& base_expr,
187 const InferenceEngine& engine, const SymbolicExpr& arg_expr, Sign target, ComputationContext& context) const;
189 const InferenceEngine& engine, const SymbolicExpr& arg_expr, ComputationContext& context) const;
191 const InferenceEngine& engine, const SymbolicExpr& arg_expr, Sign target, ComputationContext& context) const;
193 const InferenceEngine& engine, const SymbolicExpr& arg_expr, Sign target, ComputationContext& context) const;
195 const InferenceEngine& engine, const SymbolicExpr& arg_expr, Sign target, ComputationContext& context) const;
197 const InferenceEngine& engine, const SymbolicExpr& arg_expr, ComputationContext& context) const;
199 const InferenceEngine& engine, const SymbolicExpr& arg_expr, Domain target, ComputationContext& context) const;
201 const InferenceEngine& engine, const SymbolicExpr& arg_expr, Domain target, ComputationContext& context) const;
203 const InferenceEngine& engine, const SymbolicExpr& arg_expr, Domain target, ComputationContext& context) const;
205 const InferenceEngine& engine, const SymbolicExpr& arg_expr, Domain target, ComputationContext& context) const;
207 const InferenceEngine& engine, const SymbolicExpr& arg_expr, Domain target, ComputationContext& context) const;
209 const InferenceEngine& engine, FunctionNode::FuncType type,
210 const SymbolicExpr& argument, Sign target, ComputationContext& context) const;
212 const InferenceEngine& engine, FunctionNode::FuncType type,
213 const SymbolicExpr& argument, Domain target, ComputationContext& context) const;
214 static Monotonicity logarithm_monotonicity(const Interval& interval);
216 const FunctionNode& func, const std::string& var, const Interval& interval);
217 static std::optional<int> small_positive_exponent(
218 const std::shared_ptr<const NumberNode>& number);
219 static void collect_node_exponent(
220 const std::shared_ptr<const SymbolicNode>& node,
221 const std::string& lhs_name, const std::string& rhs_name,
222 std::unordered_set<int>& exponents);
223 static std::vector<int> collect_power_exponents(
224 const RelationStore& store,
225 const std::string& lhs_name, const std::string& rhs_name);
227 InferenceEngine& engine, const SymbolicExpr& new_lhs,
228 const SymbolicExpr& new_rhs, RelationStore& store,
229 PropertyStore& prop_store, int depth) const;
231 InferenceEngine& engine, const VariableNode& lhs,
233 RelationStore& store, PropertyStore& prop_store, int depth) const;
235 InferenceEngine& engine, const VariableNode& lhs,
236 const VariableNode& rhs, RelationStore& store,
237 PropertyStore& prop_store, int depth) const;
238
239 const AssumptionContext& ctx;
241 mutable std::unordered_set<const SymbolicNode*> visited;
242 mutable int current_depth = 0;
243};
244
246public:
247 DepthGuard(const InferenceEngine& engine, const SymbolicNode& node);
248 ~DepthGuard();
249
250 bool should_abort() const { return abort_; }
251
252 DepthGuard(const DepthGuard&) = delete;
253 DepthGuard& operator=(const DepthGuard&) = delete;
254
255private:
256 const InferenceEngine& engine_;
258 bool abort_ = false;
259 bool inserted_ = false;
260};
261
262} // namespace LMCAS
AssumptionContext class with scoped push/pop management.
加法节点,表示多个操作数的求和。
函数节点,表示数学函数调用(三角函数、对数、特殊函数等)。
DepthGuard & operator=(const DepthGuard &)=delete
DepthGuard(const DepthGuard &)=delete
DepthGuard(const InferenceEngine &engine, const SymbolicNode &node)
乘法节点,表示多个操作数的乘积。
const std::variant< BigInt, Rational > & value() const noexcept
static Result failure(CasErrc code, std::string message, std::string operation={})
变量节点,表示一个符号变量。
InferenceEngine class for deriving properties of composite expressions.
区间与区间并集 IntervalUnion,用于不等式解集表示。
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 interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
Result< T > checked_inference_result(const SymbolicExpr &expr, const std::string &operation, ComputationContext &context, const std::function< Result< T >()> &query)
Domain
Mathematical domain hierarchy (least specific → most specific). Complex ⊃ Real ⊃ Algebraic ⊃ Rational...
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
Tribool
Tri-state logic value for property queries.
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
bool is_integer_number(const NumberNode &num)
Monotonicity
Monotonicity classification for functions over intervals.
const ExprPtr & exponent
std::size_t std::size_t depth
bool is_positive_integer_number(const NumberNode &num)
const ExprPtr & target
bool is_negative_infinity_coefficient(const NumberNode &number)
bool is_zero_number(const NumberNode &num)
const std::string const ExprPtr & value
const ExprPtr & rhs
Result< Tribool > InferenceTriboolResult
int infinity_sign(const SymbolicExpr &expression, ComputationContext &context)
ExprResult function(const std::string &name, std::vector< ExprPtr > arguments)
Sign
Sign classification for symbols and expressions.
A stored relational constraint between two symbolic expressions.
PropertyStore class for mapping symbol names to declared properties.
RelationStore class for storing relational constraints between symbolic expressions.
static InferenceTriboolResult integral_power_domain(const InferenceEngine &engine, const SymbolicExpr &base, const NumberNode &exponent, Domain target, ComputationContext &context)
InferenceTriboolResult positive_relation_chain(const SymbolicExpr &expr, const SymbolicExpr &zero_expr, ComputationContext &context) const
static Tribool number_negative(const NumberNode &num)
static void collect_node_exponent(const std::shared_ptr< const SymbolicNode > &node, const std::string &lhs_name, const std::string &rhs_name, std::unordered_set< int > &exponents)
InferenceTriboolResult quotient_sign(const InferenceEngine &engine, const SymbolicExpr &num_expr, const SymbolicExpr &den_expr, Sign target, ComputationContext &context) const
InferenceTriboolResult real_or_integer(const InferenceEngine &engine, const SymbolicExpr &arg_expr, ComputationContext &context) const
InferenceTriboolResult sum_relation_sign(const AddNode &add, const SymbolicExpr &zero_expr, Sign target, ComputationContext &context) const
Result< void > deduce_power_relations(InferenceEngine &engine, const VariableNode &lhs, const VariableNode &rhs, RelationStore &store, PropertyStore &prop_store, int depth) const
InferenceTriboolResult sum_nonzero(const InferenceEngine &engine, const AddNode &add, ComputationContext &context) const
InferenceTriboolResult even_power_sign(const InferenceEngine &engine, const SymbolicExpr &base_expr, const NumberNode &exponent, Sign target, ComputationContext &context) const
InferenceTriboolResult exponential_domain(const InferenceEngine &engine, const SymbolicExpr &arg_expr, Domain target, ComputationContext &context) const
static InferenceTriboolResult product_parity_sign(std::uint8_t possible, Sign target)
InferenceTriboolResult integer_power_sign(const InferenceEngine &engine, const SymbolicExpr &base_expr, const NumberNode &exponent, Sign target, ComputationContext &context) const
InferenceTriboolResult trigonometric_sign(const InferenceEngine &engine, const SymbolicExpr &arg_expr, ComputationContext &context) const
InferenceTriboolResult weak_subtraction_sign(const InferenceEngine &engine, const SymbolicExpr &minuend_expr, const SymbolicExpr &subtrahend_expr, Sign target, ComputationContext &context) const
static Monotonicity logarithm_monotonicity(const Interval &interval)
bool operand_sign(const std::shared_ptr< const SymbolicNode > &operand, Sign target, ComputationContext &context) const
Result< void > deduce_function_relation(InferenceEngine &engine, const VariableNode &lhs, const VariableNode &rhs, FunctionNode::FuncType type, RelationStore &store, PropertyStore &prop_store, int depth) const
InferenceTriboolResult query_rational(const InferenceEngine &engine, const SymbolicExpr &expr, ComputationContext &context) const
static Tribool number_nonzero(const NumberNode &num)
static std::vector< int > collect_power_exponents(const RelationStore &store, const std::string &lhs_name, const std::string &rhs_name)
static Tribool number_positive(const NumberNode &num)
InferenceTriboolResult square_root_sign(const InferenceEngine &engine, const SymbolicExpr &arg_expr, Sign target, ComputationContext &context) const
Impl(const AssumptionContext &context)
static std::shared_ptr< const SymbolicNode > subtrahend(const std::shared_ptr< const SymbolicNode > &operand, ComputationContext &context)
InferenceTriboolResult sum_sign(const InferenceEngine &engine, const AddNode &node, Sign target, ComputationContext &context) const
std::unordered_set< const SymbolicNode * > visited
InferenceTriboolResult positive_power_sign(const InferenceEngine &engine, const SymbolicExpr &base_expr, const SymbolicExpr &exp_expr, Sign target, ComputationContext &context) const
InferenceTriboolResult composite_nonpositive(const InferenceEngine &engine, const SymbolicExpr &expr, ComputationContext &context) const
static Tribool number_integer(const NumberNode &num)
static Tribool natural_number(const NumberNode &num)
Result< void > add_deduced(InferenceEngine &engine, const SymbolicExpr &new_lhs, const SymbolicExpr &new_rhs, RelationStore &store, PropertyStore &prop_store, int depth) const
static InferenceTriboolResult real_definedness(const InferenceEngine &engine, const SymbolicNode &node, ComputationContext &context)
InferenceTriboolResult exponential_sign(const InferenceEngine &engine, const SymbolicExpr &arg_expr, Sign target, ComputationContext &context) const
InferenceTriboolResult subtraction_sign(const InferenceEngine &engine, const SymbolicExpr &minuend_expr, const SymbolicExpr &subtrahend_expr, Sign target, ComputationContext &context) const
InferenceTriboolResult arctangent_domain(const InferenceEngine &engine, const SymbolicExpr &arg_expr, Domain target, ComputationContext &context) const
InferenceTriboolResult zero_power_sign(const InferenceEngine &engine, const SymbolicExpr &base_expr, const NumberNode *exp_num, Sign target, ComputationContext &context) const
static bool has_negated_operand(const AddNode &node, ComputationContext &context)
InferenceTriboolResult square_root_domain(const InferenceEngine &engine, const SymbolicExpr &arg_expr, Domain target, ComputationContext &context) const
static Tribool known_sign(int value, Sign target)
InferenceTriboolResult absolute_domain(const InferenceEngine &engine, const SymbolicExpr &arg_expr, Domain target, ComputationContext &context) const
InferenceTriboolResult composite_real(const InferenceEngine &engine, const SymbolicExpr &expr, ComputationContext &context) const
InferenceTriboolResult function_sign(const InferenceEngine &engine, FunctionNode::FuncType type, const SymbolicExpr &argument, Sign target, ComputationContext &context) const
InferenceTriboolResult composite_integer(const InferenceEngine &engine, const SymbolicExpr &expr, ComputationContext &context) const
InferenceTriboolResult query_zero(const InferenceEngine &engine, const SymbolicExpr &expr, ComputationContext &context) const
InferenceTriboolResult composite_negative(const InferenceEngine &engine, const SymbolicExpr &expr, ComputationContext &context) const
Result< bool > relation_rhs_nonnegative(const Relation &rel, const SymbolicExpr &zero_expr, ComputationContext &context) const
InferenceTriboolResult multiply_domain(const InferenceEngine &engine, const MultiplyNode &node, Domain target, ComputationContext &context) const
static Tribool number_nonpositive(const NumberNode &num)
Result< void > accumulate_sum_relation_sign(const std::shared_ptr< const SymbolicNode > &operand, const SymbolicExpr &zero_expr, bool &all_gt_zero, bool &all_geq_zero, ComputationContext &context) const
InferenceTriboolResult accumulate_product_sign(const InferenceEngine &engine, const std::shared_ptr< const SymbolicNode > &operand, std::uint8_t &possible, ComputationContext &context) const
InferenceTriboolResult composite_positive(const InferenceEngine &engine, const SymbolicExpr &expr, ComputationContext &context) const
InferenceTriboolResult absolute_sign(const InferenceEngine &engine, const SymbolicExpr &arg_expr, Sign target, ComputationContext &context) const
InferenceTriboolResult composite_nonzero(const InferenceEngine &engine, const SymbolicExpr &expr, ComputationContext &context) const
static Monotonicity function_monotonicity(const FunctionNode &func, const std::string &var, const Interval &interval)
InferenceTriboolResult function_domain(const InferenceEngine &engine, FunctionNode::FuncType type, const SymbolicExpr &argument, Domain target, ComputationContext &context) const
InferenceTriboolResult nonzero_power_sign(const InferenceEngine &engine, const SymbolicExpr &base_expr, const NumberNode &exponent, Sign target, ComputationContext &context) const
InferenceTriboolResult logarithm_sign(const InferenceEngine &engine, const SymbolicExpr &arg_expr, Sign target, ComputationContext &context) const
InferenceTriboolResult product_sign(const InferenceEngine &engine, const MultiplyNode &node, Sign target, ComputationContext &context) const
static std::optional< int > small_positive_exponent(const std::shared_ptr< const NumberNode > &number)
InferenceTriboolResult composite_nonnegative(const InferenceEngine &engine, const SymbolicExpr &expr, ComputationContext &context) const
InferenceTriboolResult query_natural(const SymbolicExpr &expr, ComputationContext &context) const
static Tribool number_nonnegative(const NumberNode &num)
InferenceTriboolResult positive_integer_power_sign(const InferenceEngine &engine, const SymbolicExpr &base_expr, const NumberNode &exponent, Sign target, ComputationContext &context) const
InferenceTriboolResult product_relation_sign(const MultiplyNode &mul, const SymbolicExpr &zero_expr, Sign target, ComputationContext &context) const
InferenceTriboolResult logarithm_domain(const InferenceEngine &engine, const SymbolicExpr &arg_expr, Domain target, ComputationContext &context) const
内部 AST 定义。