LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
inference_engine.hpp
浏览该文件的文档.
1/**
2 * @file inference_engine.hpp
3 * @brief InferenceEngine class for deriving properties of composite expressions.
4 *
5 * Analyzes arithmetic and function expressions to infer sign, domain, and
6 * boundedness properties from their sub-expressions.
7 */
8#pragma once
9
10#include "assumption.hpp"
11#include "symbolic.hpp"
12#include "relation_store.hpp"
13#include "result.hpp"
14#include <memory>
15#include <optional>
16
17namespace LMCAS {
18
19class AddNode;
20class MultiplyNode;
21class PowerNode;
22class FunctionNode;
23
24// Forward declaration for Interval (avoid circular include with interval.hpp)
25
26
27struct Interval;
28}
29
30namespace LMCAS {
31
32// Forward declaration - AssumptionContext is implemented in a later task
33class AssumptionContext;
35
38
39/**
40 * @brief 递归分析子表达式,推导复合表达式的符号、定义域和有界性。
41 *
42 * 符号规则:
43 * - 加法:各项同号时和同号;混合符号或未知符号返回 Unknown。
44 * - 乘法:所有因子均有定义且为实数时,合并可能符号集合。
45 * - 幂:先满足原定义域;零次幂和负整数次幂要求底数非零。
46 * - 函数:exp 的参数有定义且为实数时,结果为正。
47 *
48 * 定义域规则:
49 * - 加法:全为 Integer 时得 Integer,全为 Real 时得 Real。
50 * - 乘法:全为 Integer 时得 Integer,混合 Real/Integer 时得 Real。
51 * - 整数幂:要求底数有定义,零次幂和负次幂还要求底数非零。
52 * - 对数:参数有定义且为正时可证明 Real,仅有 Integer 属性不足。
53 * - 无定义的实表达式返回 DomainError,前提未证实时保留 Unknown。
54 *
55 * @par 线程安全
56 * 递归保护和活动查询状态可变,同一实例限单线程调用。
57 * 绑定不可变上下文的独立实例可并发使用;空闲实例可在下次调用前迁移线程。
58 */
59class LMCAS_API InferenceEngine {
60public:
61 /**
62 * @brief Construct an InferenceEngine bound to an AssumptionContext.
63 * @param ctx The AssumptionContext used to query sub-expression properties
64 */
65 explicit InferenceEngine(const AssumptionContext& ctx);
66 ~InferenceEngine();
67
68 InferenceEngine(const InferenceEngine&) = delete;
69 InferenceEngine& operator=(const InferenceEngine&) = delete;
70 InferenceEngine(InferenceEngine&&) noexcept;
71 InferenceEngine& operator=(InferenceEngine&&) noexcept;
72
73 /// @name Public query methods
74 /// These query sign/domain properties for arbitrary expressions by dispatching
75 /// to the appropriate inference method based on the expression's root node type.
76 /// Context overloads share cancellation and resource limits with recursive queries;
77 /// proof-depth exhaustion still returns Unknown, independently of resource errors.
78 /// @{
79
80
81 InferenceTriboolResult query_positive_checked(const SymbolicExpr& expr) const;
82 InferenceTriboolResult query_positive_checked(const SymbolicExpr& expr, ComputationContext& context) const;
83 InferenceTriboolResult query_negative_checked(const SymbolicExpr& expr) const;
84 InferenceTriboolResult query_negative_checked(const SymbolicExpr& expr, ComputationContext& context) const;
85 InferenceTriboolResult query_nonnegative_checked(const SymbolicExpr& expr) const;
86 InferenceTriboolResult query_nonnegative_checked(const SymbolicExpr& expr, ComputationContext& context) const;
87 InferenceTriboolResult query_nonpositive_checked(const SymbolicExpr& expr) const;
88 InferenceTriboolResult query_nonpositive_checked(const SymbolicExpr& expr, ComputationContext& context) const;
89 InferenceTriboolResult query_real_checked(const SymbolicExpr& expr) const;
90 InferenceTriboolResult query_real_checked(const SymbolicExpr& expr, ComputationContext& context) const;
91 InferenceTriboolResult query_integer_checked(const SymbolicExpr& expr) const;
92 InferenceTriboolResult query_integer_checked(const SymbolicExpr& expr, ComputationContext& context) const;
93 InferenceTriboolResult query_nonzero_checked(const SymbolicExpr& expr) const;
94 InferenceTriboolResult query_nonzero_checked(const SymbolicExpr& expr, ComputationContext& context) const;
95
96 /**
97 * @brief Query whether an expression is algebraic.
98 *
99 * For variables, checks if the domain is Algebraic or more specific
100 * (Rational, Integer, Natural, PositiveInt). For composite expressions,
101 * returns Unknown (inference rules for composite algebraic expressions
102 * can be added later).
103 *
104 * @param expr The expression to query
105 * @return True if algebraic, False if transcendental, Unknown otherwise
106 */
107
108 InferenceTriboolResult query_algebraic_checked(const SymbolicExpr& expr) const;
109 InferenceTriboolResult query_algebraic_checked(const SymbolicExpr& expr, ComputationContext& context) const;
110
111 /**
112 * @brief Query whether an expression is transcendental.
113 *
114 * For variables, checks if the transcendental flag is set in the PropertyStore.
115 * For composite expressions, returns Unknown.
116 *
117 * @param expr The expression to query
118 * @return True if transcendental, False if algebraic, Unknown otherwise
119 */
120
121 InferenceTriboolResult query_transcendental_checked(const SymbolicExpr& expr) const;
122 InferenceTriboolResult query_transcendental_checked(const SymbolicExpr& expr, ComputationContext& context) const;
123
124 /**
125 * @brief Query whether an expression has a finite value/limit.
126 *
127 * For variables, checks if Finiteness::Finite is declared in the PropertyStore.
128 * For composite expressions, returns Unknown.
129 *
130 * @param expr The expression to query
131 * @return True if finite, False if divergent, Unknown otherwise
132 */
133
134 InferenceTriboolResult query_finite_checked(const SymbolicExpr& expr) const;
135 InferenceTriboolResult query_finite_checked(const SymbolicExpr& expr, ComputationContext& context) const;
136
137 /**
138 * @brief Query whether an expression diverges.
139 *
140 * For variables, checks if Finiteness::Divergent is declared in the PropertyStore.
141 * For composite expressions, returns Unknown.
142 *
143 * @param expr The expression to query
144 * @return True if divergent, False if finite, Unknown otherwise
145 */
146
147 InferenceTriboolResult query_divergent_checked(const SymbolicExpr& expr) const;
148 InferenceTriboolResult query_divergent_checked(const SymbolicExpr& expr, ComputationContext& context) const;
149
150 /// @}
151
152 /// @name Depth limit configuration
153 /// @{
154
155 /**
156 * @brief Set the maximum recursion depth for property queries.
157 * @param depth Maximum depth (must be > 0). Default is 32.
158 */
159 void set_max_depth(int depth);
160
161 /**
162 * @brief Get the current maximum recursion depth.
163 * @return The configured maximum depth
164 */
165 int get_max_depth() const;
166
167 /// @}
168
169 /**
170 * @brief 查询表达式相对于指定自变量的周期性。
171 *
172 * sin/cos/tan 的实仿射参数要求系数有定义且斜率非零;
173 * 非线性参数或前提未证实时返回 Unknown。
174 *
175 * @param expr 待查询表达式
176 * @param variable 非空自变量名
177 * @return 周期为 Tribool::True,已知非周期为 False,其余为 Unknown
178 */
179
180 InferenceTriboolResult query_periodic_checked(
181 const SymbolicExpr& expr, const std::string& variable) const;
182 InferenceTriboolResult query_periodic_checked(
183 const SymbolicExpr& expr, const std::string& variable, ComputationContext& context) const;
184
185 /**
186 * @brief 推导表达式相对于指定自变量的已证实正周期。
187 *
188 * 仿射斜率按精确符号 pi 缩放周期,周期声明按变量索引。
189 * 已证实的常量具有周期性,但无最小正周期。
190 *
191 * @param expr 待查询表达式
192 * @param variable 非空自变量名
193 * @return 已证实的周期;常量或周期性未知时返回 nullopt
194 */
195
196 InferencePeriodResult infer_period_checked(
197 const SymbolicExpr& expr, const std::string& variable) const;
198 InferencePeriodResult infer_period_checked(
199 const SymbolicExpr& expr, const std::string& variable, ComputationContext& context) const;
200
201 /**
202 * @brief Infer the monotonicity of an expression with respect to a variable on an interval.
203 *
204 * Auto-infers monotonicity for known functions:
205 * - exp: Increasing on all of R
206 * - ln: Increasing on R+ (positive reals)
207 * - negation (multiply by -1): reverses monotonicity
208 *
209 * Also checks PropertyStore for user-declared monotonicity.
210 *
211 * @param expr The expression to analyze
212 * @param var The variable with respect to which monotonicity is queried
213 * @param interval The interval on which to check monotonicity
214 * @return The inferred Monotonicity classification
215 */
216 Monotonicity infer_monotonicity(const SymbolicExpr& expr, const std::string& var,
217 const Interval& interval) const;
218
219 /**
220 * @brief 沿表达式树传播区间界。
221 *
222 * 保留精确 Number 点和声明的端点开闭性。
223 * 算术运算返回有理数向外包络,实超越运算也使用已证实包络;结果未必最紧。
224 *
225 * @param expr 用于传播边界的表达式
226 * @return 推导区间;事实不足或资源失败时返回 std::nullopt,不返回部分区间
227 */
228 std::optional<Interval> propagate_bounds(const SymbolicExpr& expr) const;
229
230 /**
231 * @brief Apply monotonicity deduction rules when a new relation is added.
232 *
233 * For relations like x > y where both operands have appropriate domain assumptions,
234 * deduces new relations (e.g., ln(x) > ln(y) when both are Positive).
235 *
236 * @param rel The newly added relation
237 * @param store The RelationStore to add deduced relations to
238 * @param prop_store The PropertyStore for checking domain assumptions
239 * @param depth Current recursion depth (stops at MAX_MONOTONICITY_DEPTH)
240 */
241 void apply_monotonicity_rules(const Relation& rel, RelationStore& store,
242 PropertyStore& prop_store, int depth = 0);
243
244 /**
245 * @brief Applies monotonicity deductions transactionally.
246 *
247 * Deduced relations are inserted through RelationStore::add_relation_checked.
248 * 派生关系与既有属性冲突时,插入操作以 CasError 原子地返回诊断,
249 * 关系存储保持提交前状态.
250 */
251 Result<void> apply_monotonicity_rules_checked(const Relation& rel,
252 RelationStore& store,
253 PropertyStore& prop_store,
254 int depth = 0);
255
256private:
257 static constexpr int MAX_MONOTONICITY_DEPTH = 8;
258
259 struct Impl;
260 class DepthGuard;
261 std::unique_ptr<Impl> impl_;
262
263 /// @name Sign inference for specific node types
264 /// @{
265 InferenceTriboolResult infer_add_sign_checked(const AddNode& node, Sign target, ComputationContext& context) const;
266 InferenceTriboolResult infer_multiply_sign_checked(const MultiplyNode& node, Sign target, ComputationContext& context) const;
267 InferenceTriboolResult infer_power_property_checked(const PowerNode& node, Sign target, ComputationContext& context) const;
268 InferenceTriboolResult infer_function_property_checked(const FunctionNode& node, Sign target, ComputationContext& context) const;
269 /// @}
270
271 /**
272 * @brief Infer sign of an arithmetic expression by checking relational constraints.
273 *
274 * Examines the RelationStore for GT/GEQ zero patterns on operands of sums
275 * and products:
276 * - sum: all operands GT 0 -> Positive; all GEQ 0 -> NonNegative
277 * - product: all operands GT 0 -> Positive
278 * - Also checks: x GT y with y non-negative -> x is Positive
279 *
280 * @param expr The expression to check
281 * @param target The sign property being queried
282 * @return True if the target sign can be inferred from relations, Unknown otherwise
283 */
284 InferenceTriboolResult infer_sign_from_relations_checked(const SymbolicExpr& expr, Sign target, ComputationContext& context) const;
285
286 /// @name Division and subtraction sign inference
287 /// @{
288
289 /**
290 * @brief Infer the sign of an internally represented division expression.
291 *
292 * Applies the sign multiplication table for division:
293 * positive / positive -> positive, negative / negative -> positive,
294 * positive / negative -> negative, negative / positive -> negative.
295 * Returns Unknown when denominator sign is unknown or zero.
296 */
297 InferenceTriboolResult infer_division_sign_checked(const MultiplyNode& node, Sign target, ComputationContext& context) const;
298
299 /**
300 * @brief Infer the sign of an internally represented subtraction expression.
301 *
302 * Detects a negated subtrahend and applies subtraction sign rules, such as
303 * positive minus negative producing a positive result.
304 */
305 InferenceTriboolResult infer_subtraction_sign_checked(const AddNode& node, Sign target, ComputationContext& context) const;
306
307 /// @}
308
309 /// @name Domain inference for specific node types
310 /// @{
311 InferenceTriboolResult infer_add_domain_checked(const AddNode& node, Domain target, ComputationContext& context) const;
312 InferenceTriboolResult infer_multiply_domain_checked(const MultiplyNode& node, Domain target, ComputationContext& context) const;
313 InferenceTriboolResult infer_power_domain_checked(const PowerNode& node, Domain target, ComputationContext& context) const;
314 InferenceTriboolResult infer_function_domain_checked(const FunctionNode& node, Domain target, ComputationContext& context) const;
315 /// @}
316
317 /// @name Helper methods for querying sub-expression properties
318 /// @{
319 InferenceTriboolResult query_sign_of_checked(const SymbolicExpr& expr, Sign sign, ComputationContext& context) const;
320 InferenceTriboolResult query_domain_of_checked(const SymbolicExpr& expr, Domain domain, ComputationContext& context) const;
321 /// @}
322};
323
324} // namespace LMCAS
Core enumerations and forward declarations for the Assumption System.
加法节点,表示多个操作数的求和。
函数节点,表示数学函数调用(三角函数、对数、特殊函数等)。
乘法节点,表示多个操作数的乘积。
幂运算节点,表示 base^exponent。
#define LMCAS_API
const std::string & variable
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
Domain
Mathematical domain hierarchy (least specific → most specific). Complex ⊃ Real ⊃ Algebraic ⊃ Rational...
Result< std::optional< SymbolicExpr > > InferencePeriodResult
Monotonicity
Monotonicity classification for functions over intervals.
std::size_t std::size_t depth
const NumberDomainSet & domain
const ExprPtr & target
Result< Tribool > InferenceTriboolResult
Sign
Sign classification for symbols and expressions.
A stored relational constraint between two symbolic expressions.
RelationStore class for storing relational constraints between symbolic expressions.
符号表达式主类 SymbolicExpr 及其工厂方法,运算接口.