LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
property_store.hpp
浏览该文件的文档.
1/**
2 * @file property_store.hpp
3 * @brief PropertyStore class for mapping symbol names to declared properties.
4 *
5 * Provides storage and validation for domain, sign, parity, and boundedness
6 * properties with implication chains and contradiction detection.
7 */
8#pragma once
9
10#include "assumption.hpp"
11#include "symbolic.hpp"
12#include "interval.hpp"
13#include "result.hpp"
14#include <string>
15#include <unordered_map>
16#include <map>
17#include <unordered_set>
18#include <optional>
19#include <vector>
20#include <stdexcept>
21#include <cstdint>
22
23namespace LMCAS {
24
26
27/// Hash functor for Sign enum to allow use in unordered_set.
28struct SignHash {
29 std::size_t operator()(Sign s) const noexcept {
30 return std::hash<int>{}(static_cast<int>(s));
31 }
32};
33
34/**
35 * @brief Stores and validates mathematical properties for named symbols.
36 *
37 * Supports domain hierarchy implication, sign implication, contradiction
38 * detection, and cross-constraint checking between domains and signs.
39 */
40class LMCAS_API PropertyStore {
41public:
42 PropertyStore() = default;
43 PropertyStore(const PropertyStore&) = default;
44 PropertyStore(PropertyStore&& other) noexcept;
45 PropertyStore& operator=(const PropertyStore& other);
46 PropertyStore& operator=(PropertyStore&& other) noexcept;
47
48 /** @brief 成功提交(含赋值)均更新此存储的修订号。 */
49 std::uint64_t revision() const noexcept { return revision_; }
50
51 /// Declare domain for a symbol and report contradictions.
52 PropertyStoreResult declare_domain(const std::string& symbol, Domain domain);
53
54 /** @brief Declares a domain and reports contradictions. */
55 PropertyStoreResult declare_domain_checked(const std::string& symbol, Domain domain);
56
57 /// Declare sign for a symbol and report contradictions.
58 PropertyStoreResult declare_sign(const std::string& symbol, Sign sign);
59
60 /** @brief Declares a sign and reports contradictions. */
61 PropertyStoreResult declare_sign_checked(const std::string& symbol, Sign sign);
62
63 /// Declare parity for a symbol and report contradictions.
64 PropertyStoreResult declare_parity(const std::string& symbol, Parity parity);
65
66 /** @brief Declares parity and reports contradictions. */
67 PropertyStoreResult declare_parity_checked(const std::string& symbol, Parity parity);
68
69 /// Declare boundedness for a symbol, optionally with interval bounds.
70 PropertyStoreResult declare_bounded(const std::string& symbol, Boundedness bounded,
71 std::optional<Interval> bounds = std::nullopt);
72
73 /** @brief Declares boundedness and reports contradictions. */
74 PropertyStoreResult declare_bounded_checked(
75 const std::string& symbol,
76 Boundedness bounded,
77 std::optional<Interval> bounds,
78 ComputationContext& context);
79 PropertyStoreResult declare_bounded_checked(
80 const std::string& symbol,
81 Boundedness bounded,
82 std::optional<Interval> bounds = std::nullopt);
83
84 /// Query the most specific domain for a symbol (default: Complex).
85 Domain get_domain(const std::string& symbol) const;
86
87 /// Query all signs stored for a symbol.
88 std::unordered_set<Sign, SignHash> get_signs(const std::string& symbol) const;
89
90 /// Query parity for a symbol (default: Unknown).
91 Parity get_parity(const std::string& symbol) const;
92
93 /// Query boundedness for a symbol (default: Unknown).
94 Boundedness get_boundedness(const std::string& symbol) const;
95
96 /// Get stored interval bounds (if any).
97 std::optional<Interval> get_bounds(const std::string& symbol) const;
98
99 /// Check if symbol has a specific sign (explicit or implied).
100 bool has_sign(const std::string& symbol, Sign sign) const;
101
102 /// Check if symbol has at least the given domain specificity.
103 bool has_domain(const std::string& symbol, Domain domain) const;
104
105 /**
106 * @brief Declare a symbol as continuous on a specified interval.
107 * @param symbol Symbol name.
108 * @param interval Interval on which continuity holds.
109 * Contradictory overlapping declarations are returned as `CasError`.
110 */
111 PropertyStoreResult declare_continuous(
112 const std::string& symbol, const Interval& interval);
113
114 PropertyStoreResult declare_continuous_checked(
115 const std::string& symbol,
116 const Interval& interval,
117 ComputationContext& context);
118 PropertyStoreResult declare_continuous_checked(
119 const std::string& symbol,
120 const Interval& interval);
121
122 /**
123 * @brief Declare a symbol as differentiable on a specified interval.
124 *
125 * Differentiability implies continuity, so this also ensures the symbol
126 * is recorded as continuous on the same interval.
127 *
128 * @param symbol Symbol name.
129 * @param interval Interval on which differentiability holds.
130 * Contradictory overlapping declarations are returned as `CasError`.
131 */
132 PropertyStoreResult declare_differentiable(
133 const std::string& symbol, const Interval& interval);
134
135 PropertyStoreResult declare_differentiable_checked(
136 const std::string& symbol,
137 const Interval& interval,
138 ComputationContext& context);
139 PropertyStoreResult declare_differentiable_checked(
140 const std::string& symbol,
141 const Interval& interval);
142
143 /**
144 * @brief Query whether a symbol is continuous on a given interval.
145 * @param symbol Symbol name.
146 * @param interval Interval to check.
147 * @return true if the symbol has been declared continuous (or differentiable)
148 * on an interval that covers the queried interval.
149 */
150 Result<bool> is_continuous(const std::string& symbol, const Interval& interval) const;
151
152 Result<bool> is_continuous_checked(
153 const std::string& symbol,
154 const Interval& interval,
155 ComputationContext& context) const;
156 Result<bool> is_continuous_checked(
157 const std::string& symbol,
158 const Interval& interval) const;
159
160 /**
161 * @brief Query whether a symbol is differentiable on a given interval.
162 * @param symbol Symbol name.
163 * @param interval Interval to check.
164 * @return true if the symbol has been declared differentiable on an interval
165 * that covers the queried interval.
166 */
167 Result<bool> is_differentiable(const std::string& symbol, const Interval& interval) const;
168
169 Result<bool> is_differentiable_checked(
170 const std::string& symbol,
171 const Interval& interval,
172 ComputationContext& context) const;
173 Result<bool> is_differentiable_checked(
174 const std::string& symbol,
175 const Interval& interval) const;
176
177
178 /**
179 * @brief Declare a symbol as transcendental.
180 *
181 * Sets the symbol's domain to Real and marks it transcendental.
182 * Returns an error if the symbol already has an algebraic sub-domain.
183 *
184 * @param symbol Symbol name
185 */
186 PropertyStoreResult declare_transcendental(const std::string& symbol);
187
188 /** @brief Declares transcendence and reports domain contradictions. */
189 PropertyStoreResult declare_transcendental_checked(const std::string& symbol);
190
191 /**
192 * @brief Query whether a symbol has been declared transcendental.
193 * @param symbol Symbol name
194 * @return true if the symbol is marked transcendental
195 */
196 bool is_transcendental(const std::string& symbol) const;
197
198
199 /**
200 * @brief Declare finiteness for a symbol.
201 *
202 * Finite implies Bounded. Contradictions are returned as `CasError`.
203 *
204 * @param symbol Symbol name
205 * @param f Finiteness value (Finite, Divergent, or Unknown)
206 */
207 PropertyStoreResult declare_finiteness(const std::string& symbol, Finiteness f);
208
209 /** @brief Declares finiteness and reports contradictions. */
210 PropertyStoreResult declare_finiteness_checked(const std::string& symbol, Finiteness f);
211
212 /**
213 * @brief Query the finiteness classification of a symbol.
214 * @param symbol Symbol name
215 * @return Finiteness value (default: Unknown)
216 */
217 Finiteness get_finiteness(const std::string& symbol) const;
218
219
220 /**
221 * @brief Declare matrix definiteness for a symbol.
222 *
223 * PositiveDefinite implies PositiveSemiDefinite. NegativeDefinite implies
224 * NegativeSemiDefinite. Contradictions are returned as `CasError`.
225 *
226 * @param symbol Symbol name
227 * @param d Definiteness value
228 */
229 PropertyStoreResult declare_definiteness(const std::string& symbol, Definiteness d);
230
231 /** @brief Declares matrix definiteness and reports contradictions. */
232 PropertyStoreResult declare_definiteness_checked(const std::string& symbol, Definiteness d);
233
234 /**
235 * @brief Query the definiteness classification of a symbol.
236 * @param symbol Symbol name
237 * @return Definiteness value (default: Unknown)
238 */
239 Definiteness get_definiteness(const std::string& symbol) const;
240
241
242 /**
243 * @brief 声明符号关于指定变量的候选周期。
244 *
245 * @param symbol 符号名
246 * @param variable 非空自变量名
247 * @param period 非空候选周期;已知非正值会被拒绝。
248 */
249 PropertyStoreResult declare_periodic(
250 const std::string& symbol, const std::string& variable,
251 const SymbolicExpr& period);
252
253 /** @brief Declares periodicity and reports invalid periods. */
254 PropertyStoreResult declare_periodic_checked(
255 const std::string& symbol,
256 const std::string& variable,
257 const SymbolicExpr& period);
258
259 /**
260 * @brief 获取符号关于指定变量声明的候选周期。
261 *
262 * 使用者须证明符号周期为正实数,且相对于该自变量为常量。
263 */
264 std::optional<SymbolicExpr> get_period(
265 const std::string& symbol, const std::string& variable) const;
266
267 /** @brief 查询周期声明是否存在;符号周期的有效性需另行证明。 */
268 bool is_periodic(const std::string& symbol, const std::string& variable) const;
269
270 using PeriodDeclarations = std::map<std::string, SymbolicExpr>;
271 /** @brief 借用按变量索引的全部声明,用于确定性序列化。 */
272 const PeriodDeclarations& get_period_decls(const std::string& symbol) const;
273
274 /**
275 * @brief Get all symbol names that have any declared properties.
276 * @return Vector of symbol names with at least one non-default property.
277 */
278 std::vector<std::string> get_all_symbols() const;
279
280 /// Continuity declaration (public type for serialization access).
281 struct ContinuityInfo {
282 Interval interval;
283 bool is_differentiable;
284 };
285
286 /// Monotonicity declaration (public type for serialization access).
287 struct MonotonicityInfo {
288 std::string variable;
289 Interval interval;
290 Monotonicity type;
291 };
292
293 /**
294 * @brief Get all continuity/differentiability declarations for a symbol.
295 * @param symbol Symbol name.
296 * @return Vector of continuity declarations.
297 */
298 std::vector<ContinuityInfo> get_continuity_decls(const std::string& symbol) const;
299
300 /**
301 * @brief Get all monotonicity declarations for a symbol.
302 * @param symbol Symbol name.
303 * @return Vector of monotonicity declarations.
304 */
305 std::vector<MonotonicityInfo> get_monotonicity_decls(const std::string& symbol) const;
306
307 /**
308 * @brief Declare monotonicity of a symbol with respect to a variable on an interval.
309 *
310 * Stores a MonotonicityDecl recording that the symbol is monotonically
311 * increasing/decreasing (or non-decreasing/non-increasing) with respect to
312 * the given variable over the specified interval.
313 *
314 * @param symbol The symbol (expression name) being declared monotone.
315 * @param variable The variable with respect to which monotonicity holds.
316 * @param interval The interval on which the monotonicity property holds.
317 * @param mono The type of monotonicity (Increasing, Decreasing, etc.).
318 */
319 PropertyStoreResult declare_monotonicity(
320 const std::string& symbol, const std::string& variable,
321 const Interval& interval, Monotonicity mono);
322
323 PropertyStoreResult declare_monotonicity_checked(
324 const std::string& symbol,
325 const std::string& variable,
326 const Interval& interval,
327 Monotonicity mono,
328 ComputationContext& context);
329 PropertyStoreResult declare_monotonicity_checked(
330 const std::string& symbol,
331 const std::string& variable,
332 const Interval& interval,
333 Monotonicity mono);
334
335 /**
336 * @brief Query the monotonicity of a symbol with respect to a variable on an interval.
337 *
338 * Searches stored MonotonicityDecl entries for the symbol. Returns the
339 * monotonicity type if the queried interval is covered by a stored
340 * declaration (i.e., the stored interval contains the queried interval),
341 * otherwise returns Monotonicity::Unknown.
342 *
343 * @param symbol The symbol to query.
344 * @param variable The variable with respect to which monotonicity is queried.
345 * @param interval The interval to check coverage for.
346 * @return The monotonicity type if covered, or Monotonicity::Unknown.
347 */
348 Result<Monotonicity> get_monotonicity(
349 const std::string& symbol, const std::string& variable,
350 const Interval& interval) const;
351
352 Result<Monotonicity> get_monotonicity_checked(
353 const std::string& symbol,
354 const std::string& variable,
355 const Interval& interval,
356 ComputationContext& context) const;
357 Result<Monotonicity> get_monotonicity_checked(
358 const std::string& symbol,
359 const std::string& variable,
360 const Interval& interval) const;
361
362private:
363 struct SymbolProperties {
364 Domain most_specific_domain = Domain::Complex;
365 std::unordered_set<Sign, SignHash> signs;
366 Parity parity = Parity::Unknown;
367 Boundedness boundedness = Boundedness::Unknown;
368 std::optional<Interval> bounds;
369
370 /// Whether the symbol is classified as transcendental.
371 bool transcendental = false;
372
373 /// Finiteness classification (Finite, Divergent, or Unknown).
374 Finiteness finiteness = Finiteness::Unknown;
375
376 /// Matrix definiteness classification.
377 Definiteness definiteness = Definiteness::Unknown;
378
379 /** @brief 按自变量索引的候选周期。 */
380 PeriodDeclarations periods;
381
382 /// Continuity declaration over an interval.
383 struct ContinuityDecl {
384 Interval interval; ///< Interval on which continuity/differentiability holds
385 bool is_differentiable; ///< True if differentiable (implies continuous)
386 };
387
388 /// Declared continuity/differentiability intervals.
389 std::vector<ContinuityDecl> continuity_decls;
390
391 /// Monotonicity declaration with respect to a variable over an interval.
392 struct MonotonicityDecl {
393 std::string variable; ///< Variable with respect to which monotonicity holds
394 Interval interval; ///< Interval on which monotonicity holds
395 Monotonicity type; ///< Type of monotonicity
396 };
397
398 /// Declared monotonicity intervals.
399 std::vector<MonotonicityDecl> monotonicity_decls;
400 };
401
402 std::unordered_map<std::string, SymbolProperties> properties_;
403 std::uint64_t revision_ = 0;
404
405 static Result<bool> check_continuous_declarations(
406 const std::vector<SymbolProperties::ContinuityDecl>& declarations,
407 const std::string& symbol,
408 const Interval& interval,
409 ComputationContext& context);
410 static bool has_differentiable_declaration(
411 const std::vector<SymbolProperties::ContinuityDecl>& declarations,
412 const Interval& interval);
413
414 void declare_domain_unchecked(const std::string& symbol, Domain domain);
415 void declare_sign_unchecked(const std::string& symbol, Sign sign);
416 void declare_parity_unchecked(const std::string& symbol, Parity parity);
417 void declare_bounded_unchecked(const std::string& symbol,
418 Boundedness bounded,
419 std::optional<Interval> bounds);
420 void declare_transcendental_unchecked(const std::string& symbol);
421 void declare_finiteness_unchecked(const std::string& symbol, Finiteness f);
422 void declare_definiteness_unchecked(const std::string& symbol, Definiteness d);
423 void declare_periodic_unchecked(const std::string& symbol,
424 const std::string& variable,
425 const SymbolicExpr& period);
426
427 /// Check domain-sign cross-constraints. Throws on contradiction.
428 void check_domain_sign_consistency(const std::string& symbol,
429 const SymbolProperties& props,
430 Domain new_domain);
431
432 /// Check sign contradiction pairs. Throws on contradiction.
433 void check_sign_contradiction(const std::string& symbol,
434 const std::unordered_set<Sign, SignHash>& existing,
435 Sign new_sign);
436
437 /// Get all signs implied by a given sign.
438 std::unordered_set<Sign, SignHash> get_implied_signs(Sign sign) const;
439
440
441 /// Get the specificity level of a domain (higher = more specific).
442 int domain_specificity(Domain domain) const;
443
444};
445
446} // namespace LMCAS
Core enumerations and forward declarations for the Assumption System.
区间与区间并集 IntervalUnion,用于不等式解集表示。
#define LMCAS_API
const std::string & variable
ExprResult interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
Result< void > PropertyStoreResult
Domain
Mathematical domain hierarchy (least specific → most specific). Complex ⊃ Real ⊃ Algebraic ⊃ Rational...
Boundedness
Boundedness classification for symbols.
Monotonicity
Monotonicity classification for functions over intervals.
Definiteness
Matrix definiteness classification.
Finiteness
Finiteness classification for limits and sequences.
Parity
Integer parity classification.
Sign
Sign classification for symbols and expressions.
Hash functor for Sign enum to allow use in unordered_set.
std::size_t operator()(Sign s) const noexcept
符号表达式主类 SymbolicExpr 及其工厂方法,运算接口.