LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
query_interface.hpp
浏览该文件的文档.
1/**
2 * @file query_interface.hpp
3 * @brief QueryInterface class - unified tri-state query API for property questions on arbitrary expressions.
4 *
5 * The QueryInterface is the single public entry point for property queries on SymbolicExpr trees.
6 * It handles special cases (NaN, Infinity, Matrix, Relational, Logical nodes) and
7 * delegates to the InferenceEngine for NumberNode, VariableNode, and composite node queries.
8 */
9#pragma once
10
11#include "assumption.hpp"
12#include "symbolic.hpp"
13#include "relation_store.hpp"
14#include "result.hpp"
15#include <unordered_map>
16#include <functional>
17#include <vector>
18#include <utility>
19#include <optional>
20
21namespace LMCAS {
22
23// Forward declaration
24class AssumptionContext;
25class InferenceEngine;
26
29
30/**
31 * @brief Identifies which property is being queried, used as part of the cache key.
32 */
49
50/**
51 * @brief 由表达式结构哈希、属性和自变量组成缓存键。
52 * @note 结构相同的表达式具有相同哈希,与指针身份无关。
53 */
54struct CacheKey {
55 std::size_t expression_hash;
57 std::string variable{};
58
59 bool operator==(const CacheKey& other) const {
60 return expression_hash == other.expression_hash && property == other.property &&
61 variable == other.variable;
62 }
63};
64
65/** @brief 缓存键哈希,计入周期查询的自变量。 */
67 std::size_t operator()(const CacheKey& key) const {
68 std::size_t seed = key.expression_hash;
69 seed ^= static_cast<std::size_t>(key.property) + 0x9e3779b9U
70 + (seed << 6U) + (seed >> 2U);
71 if (!key.variable.empty()) {
72 seed ^= std::hash<std::string>{}(key.variable) + 0x9e3779b9U
73 + (seed << 6U) + (seed >> 2U);
74 }
75 return seed;
76 }
77};
78
79/**
80 * @brief Unified query API for property questions on arbitrary SymbolicExpr trees.
81 *
82 * Provides query_positive, query_negative, query_nonnegative, query_real,
83 * query_integer, and query_nonzero methods that return Tribool results.
84 *
85 * 结果先按(表达式哈希,属性类型)分桶,再以结构相等性确认表达式身份.
86 * AssumptionContext 发生 push,pop 或 assume 变更时,缓存世代触发整体失效.
87 *
88 * Dispatch logic:
89 * - Null root node -> Unknown
90 * - MatrixNode, RelationalNode, LogicalNode -> Unknown
91 * - NumberNode with NaN -> False for integer, Unknown for sign queries
92 * - FunctionNode::Infinity -> derive sign from infinity's sign, False for integer
93 * - All other nodes -> delegate to InferenceEngine
94 */
95class LMCAS_API QueryInterface {
96public:
97 /**
98 * @brief Construct a QueryInterface bound to an AssumptionContext.
99 * @param ctx The AssumptionContext used for property lookups and inference
100 */
101 explicit QueryInterface(const AssumptionContext& ctx);
102
103 /// @name Public query methods
104 /// @{
105
106 /// Query whether the expression is positive (> 0).
107 QueryTriboolResult query_positive(const SymbolicExpr& expr) const;
108
109 QueryTriboolResult query_positive_checked(const SymbolicExpr& expr) const;
110
111 /// Query whether the expression is negative (< 0).
112 QueryTriboolResult query_negative(const SymbolicExpr& expr) const;
113
114 QueryTriboolResult query_negative_checked(const SymbolicExpr& expr) const;
115
116 /// Query whether the expression is non-negative (>= 0).
117 QueryTriboolResult query_nonnegative(const SymbolicExpr& expr) const;
118
119 QueryTriboolResult query_nonnegative_checked(const SymbolicExpr& expr) const;
120
121 /// Query whether the expression is real.
122 QueryTriboolResult query_real(const SymbolicExpr& expr) const;
123
124 QueryTriboolResult query_real_checked(const SymbolicExpr& expr) const;
125
126 /// Query whether the expression is an integer.
127 QueryTriboolResult query_integer(const SymbolicExpr& expr) const;
128
129 QueryTriboolResult query_integer_checked(const SymbolicExpr& expr) const;
130
131 /// Query whether the expression is non-zero (!= 0).
132 QueryTriboolResult query_nonzero(const SymbolicExpr& expr) const;
133
134 QueryTriboolResult query_nonzero_checked(const SymbolicExpr& expr) const;
135
136 /// @}
137
138 /// @name Extended property queries
139 /// @{
140
141 /// Query whether the expression is algebraic (root of a polynomial with rational coefficients).
142 QueryTriboolResult query_algebraic(const SymbolicExpr& expr) const;
143
144 QueryTriboolResult query_algebraic_checked(const SymbolicExpr& expr) const;
145
146 /// Query whether the expression is transcendental (real but not algebraic).
147 QueryTriboolResult query_transcendental(const SymbolicExpr& expr) const;
148
149 QueryTriboolResult query_transcendental_checked(const SymbolicExpr& expr) const;
150
151 /// Query whether the expression has a finite value/limit.
152 QueryTriboolResult query_finite(const SymbolicExpr& expr) const;
153
154 QueryTriboolResult query_finite_checked(const SymbolicExpr& expr) const;
155
156 /// Query whether the expression diverges.
157 QueryTriboolResult query_divergent(const SymbolicExpr& expr) const;
158
159 QueryTriboolResult query_divergent_checked(const SymbolicExpr& expr) const;
160
161 /** @brief 查询相对于指定自变量的周期性,自变量名须非空。 */
162 QueryTriboolResult query_periodic(
163 const SymbolicExpr& expr, const std::string& variable) const;
164
165 QueryTriboolResult query_periodic_checked(
166 const SymbolicExpr& expr, const std::string& variable) const;
167
168 /**
169 * @brief 获取相对于指定自变量的认证正周期。
170 * @return 精确周期;常数或周期性未获证明时返回 nullopt。
171 */
172 QueryPeriodResult get_period(
173 const SymbolicExpr& expr, const std::string& variable) const;
174
175 QueryPeriodResult get_period_checked(
176 const SymbolicExpr& expr, const std::string& variable) const;
177
178 /// Query whether the expression (matrix symbol) is positive definite.
179 QueryTriboolResult query_positive_definite(const SymbolicExpr& expr) const;
180
181 QueryTriboolResult query_positive_definite_checked(const SymbolicExpr& expr) const;
182
183 /// Query whether the expression (matrix symbol) is positive semidefinite.
184 QueryTriboolResult query_positive_semidefinite(const SymbolicExpr& expr) const;
185
186 QueryTriboolResult query_positive_semidefinite_checked(const SymbolicExpr& expr) const;
187
188 /// @}
189
190 /**
191 * @brief Invalidate the entire query result cache.
192 *
193 * AssumptionContext 执行 push_scope,pop_scope,assume_domain,
194 * assume_sign 或关系插入后调用本函数.
195 */
196 void invalidate_cache() const;
197
198 /**
199 * @brief A set of sufficient conditions for a property to hold on an expression.
200 *
201 * Each ConditionSet represents one alternative set of conditions. If all conditions
202 * within a single ConditionSet are satisfied, the target property holds.
203 */
204 struct ConditionSet {
205 /// Sign conditions: pairs of (variable_name, required_sign)
206 std::vector<std::pair<std::string, Sign>> sign_conditions;
207 /// Domain conditions: pairs of (variable_name, required_domain)
208 std::vector<std::pair<std::string, Domain>> domain_conditions;
209 /// Relational conditions between expressions
210 std::vector<Relation> relational_conditions;
211 };
212
213 using QueryConditionSetsResult = Result<std::vector<ConditionSet>>;
214
215 /**
216 * @brief Query sufficient conditions for a target sign property to hold on an expression.
217 *
218 * Analyzes the expression structure and returns a list of alternative condition sets.
219 * Each condition set, if fully satisfied, guarantees the target sign property holds.
220 *
221 * - Single variable: returns the direct sign assumption needed (e.g., {x: Positive})
222 * - Composite expression (e.g., x - y): derives condition sets from sub-expression
223 * analysis (e.g., {x: Positive, y: Negative} or {x GT y, y: NonNegative})
224 * - Returns empty list when no sufficient conditions can be determined
225 *
226 * @param expr The expression to analyze
227 * @param target The target sign property (e.g., Sign::Positive)
228 * @return A list of alternative sufficient condition sets (empty if undetermined)
229 */
230 QueryConditionSetsResult query_conditions(
231 const SymbolicExpr& expr, Sign target) const;
232
233 QueryConditionSetsResult query_conditions_checked(const SymbolicExpr& expr, Sign target) const;
234
235private:
236 struct CacheEntry {
237 SymbolicExpr expression;
238 Tribool result;
239 };
240
241 const AssumptionContext& ctx_;
242
243 /// The cache generation at the time of last cache validation.
244 /// If ctx_.cache_generation() differs, the cache is stale and must be cleared.
245 mutable uint64_t observed_generation_;
246
247 /// Query result cache: (expression_hash, property_type) -> collision bucket.
248 /// Mutable because queries are logically const but populate the cache.
249 mutable std::unordered_map<CacheKey, std::vector<CacheEntry>, CacheKeyHash> cache_;
250
251 /// Check if the root node is a special case that should return Unknown immediately.
252 /// Returns true if the node is null, MatrixNode, RelationalNode, or LogicalNode.
253 bool is_unhandled_type(const SymbolicExpr& expression) const;
254
255 /// Check if a FunctionNode represents infinity (FuncType::Infinity).
256 bool is_infinity_node(const SymbolicExpr& expression) const;
257
258 /// Determine the sign of an infinity expression.
259 /// Positive infinity: FunctionNode::Infinity directly.
260 /// Negative infinity: MultiplyNode(-1, FunctionNode::Infinity).
261 /// Returns +1 for positive infinity, -1 for negative infinity, 0 if indeterminate.
262 int get_infinity_sign(const SymbolicExpr& expression) const;
263
264
265 QueryTriboolResult cached_query_checked(
266 const SymbolicExpr& expr,
267 PropType prop,
268 const std::string& operation,
269 const std::function<QueryTriboolResult()>& compute,
270 const std::string& variable = {}) const;
271
272 std::vector<ConditionSet> query_conditions_impl(
273 const SymbolicExpr& expr,
274 Sign target) const;
275};
276
277} // namespace LMCAS
Core enumerations and forward declarations for the Assumption System.
#define LMCAS_API
@ Real
Real numbers
Result< Tribool > QueryTriboolResult
Tribool
Tri-state logic value for property queries.
@ PositiveSemiDefinite
All eigenvalues non-negative
@ PositiveDefinite
All eigenvalues positive
@ Finite
Has a finite value or limit
@ Divergent
Diverges to infinity or oscillates
Result< std::optional< SymbolicExpr > > QueryPeriodResult
PropType
Identifies which property is being queried, used as part of the cache key.
RelationStore class for storing relational constraints between symbolic expressions.
缓存键哈希,计入周期查询的自变量。
std::size_t operator()(const CacheKey &key) const
由表达式结构哈希、属性和自变量组成缓存键。
bool operator==(const CacheKey &other) const
符号表达式主类 SymbolicExpr 及其工厂方法,运算接口.