LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
expr.hpp
浏览该文件的文档.
1#pragma once
2
3#include <memory>
4#include <optional>
5#include <string>
6#include <string_view>
7#include <vector>
8#include <type_traits>
9
10#include "bigint.hpp"
14#include "rational.hpp"
15#include "solve_strategies.hpp"
16#include "quantity.hpp"
17#include "symbolic_set.hpp"
18#include "symbolic.hpp"
19
20namespace LMCAS {
22}
23
24namespace LMCAS {
25
26using Expr = SymbolicExpr;
27using ConstExprPtr = std::shared_ptr<const SymbolicExpr>;
29
31
33 std::string name;
35};
36
37struct ExprMatch {
38 bool matched = false;
39 std::vector<ExprMatchBinding> bindings;
40};
41
43
44
45
46class LMCAS_API ExprSet {
47public:
48 /** @brief 构造具有非空表达式的规范空有限集。 */
49 ExprSet();
50
51 /** @brief 快照输入包装对象,后续赋值保持集合成员不变。 */
52 static Result<ExprSet> make(std::vector<ExprPtr> elements);
53
54 bool empty() const noexcept { return elements_.empty(); }
55 std::size_t size() const noexcept { return elements_.size(); }
56 /** @brief 返回由规范有限集表达式派生的只读包装视图。 */
57 const std::vector<ConstExprPtr>& elements() const noexcept { return elements_; }
58 const ConstExprPtr& expression() const noexcept { return expression_; }
59
60 bool contains(const SymbolicExpr& expression) const;
61 bool subset_of(const ExprSet& other) const;
62
63 ExprSet set_union(const ExprSet& other) const;
64 ExprSet intersection(const ExprSet& other) const;
65 ExprSet difference(const ExprSet& other) const;
66 ExprSet symmetric_difference(const ExprSet& other) const;
67
68private:
69 explicit ExprSet(ConstExprPtr expression);
71 const ExprSet&, const ExprSet&);
73 const ExprSet&, const ExprSet&);
75 const ExprSet&, const ExprSet&);
77 const ExprSet&, const ExprSet&);
78
79 std::vector<ConstExprPtr> elements_;
80 ConstExprPtr expression_;
81};
82
84
92
93class LMCAS_API NumberDomainSet {
94public:
95 explicit NumberDomainSet(NumberDomain domain) : domain_(domain) {}
96
97 NumberDomain domain() const noexcept { return domain_; }
98 const char* name() const noexcept;
99 bool subset_of(const NumberDomainSet& other) const noexcept;
100
101 Result<bool> contains(const ConstExprPtr& element) const;
102
103private:
104 NumberDomain domain_;
105};
106
107/**
108 * @brief 借用单个符号的名称。
109 * @return 空表达式、非符号表达式或数学常量返回 nullopt。
110 * @note 借用名称仅在原表达式存活且未被重新赋值时有效。
111 */
112LMCAS_API std::optional<std::string_view> symbol_name(
113 const ExprPtr& expression) noexcept;
114
115/** @brief 查看关系运算符;空表达式或非关系表达式返回 nullopt。 */
116LMCAS_API std::optional<RelationOp> relation_op(
117 const ExprPtr& expression) noexcept;
118
119LMCAS_API ExprResult sym(const std::string& name);
120LMCAS_API ExprResult parse_expr(const std::string& source);
121LMCAS_API ExprResult parse_expr(const std::string& source,
122 ComputationContext& context);
123/** Versioned, lossless semantic expression encoding (independent of to_string). */
124LMCAS_API Result<std::string> serialize_expr(const ExprPtr& expression,
125 ComputationContext& context);
126LMCAS_API Result<std::string> serialize_expr(const ExprPtr& expression);
127LMCAS_API ExprResult parse_serialized_expr(const std::string& source,
128 ComputationContext& context);
129LMCAS_API ExprResult parse_serialized_expr(const std::string& source);
130LMCAS_API ExprResult integer(int value);
131LMCAS_API ExprResult integer(const BigInt& value);
132template <typename Integer,
133 std::enable_if_t<std::is_integral_v<Integer> &&
134 !std::is_same_v<Integer, int>, int> = 0>
135ExprResult integer(Integer) = delete;
136LMCAS_API ExprResult rational(const Rational& value);
138
142
145LMCAS_API ExprResult function(const std::string& name,
146 std::vector<ExprPtr> arguments);
147LMCAS_API ExprResult finite_set(std::vector<ExprPtr> elements);
152LMCAS_API ExprResult ne(const ExprPtr& lhs, const ExprPtr& rhs);
153LMCAS_API ExprResult lt(const ExprPtr& lhs, const ExprPtr& rhs);
154LMCAS_API ExprResult le(const ExprPtr& lhs, const ExprPtr& rhs);
155LMCAS_API ExprResult gt(const ExprPtr& lhs, const ExprPtr& rhs);
156LMCAS_API ExprResult ge(const ExprPtr& lhs, const ExprPtr& rhs);
159LMCAS_API ExprResult logical_not(const ExprPtr& expression);
161 const ExprPtr& set, bool negated = false);
163 const std::string& unit,
166 std::string display_unit,
170 const std::string& unit,
173 std::string display_unit,
180LMCAS_API ExprResult finite_set(std::vector<ExprPtr> elements,
183 bool lower_closed, bool upper_closed,
188 const ExprPtr& rhs,
190LMCAS_API ExprResult add(const ExprPtr& lhs, const ExprPtr& rhs);
192 const ExprPtr& rhs,
194LMCAS_API ExprResult sub(const ExprPtr& lhs, const ExprPtr& rhs);
196 const ExprPtr& rhs,
198LMCAS_API ExprResult mul(const ExprPtr& lhs, const ExprPtr& rhs);
199LMCAS_API ExprResult div(const ExprPtr& numerator,
202LMCAS_API ExprResult div(const ExprPtr& numerator,
203 const ExprPtr& denominator);
204LMCAS_API ExprResult neg(const ExprPtr& expression,
206LMCAS_API ExprResult neg(const ExprPtr& expression);
207LMCAS_API ExprResult eq(const ExprPtr& lhs,
208 const ExprPtr& rhs,
210LMCAS_API ExprResult eq(const ExprPtr& lhs, const ExprPtr& rhs);
211LMCAS_API ExprResult sqrt(const ExprPtr& expression,
213LMCAS_API ExprResult sqrt(const ExprPtr& expression);
214LMCAS_API ExprResult pow(const ExprPtr& base,
217LMCAS_API ExprResult pow(const ExprPtr& base, const ExprPtr& exponent);
218LMCAS_API ExprResult sin(const ExprPtr& expression,
220LMCAS_API ExprResult sin(const ExprPtr& expression);
221LMCAS_API ExprResult cos(const ExprPtr& expression,
223LMCAS_API ExprResult cos(const ExprPtr& expression);
224LMCAS_API ExprResult tan(const ExprPtr& expression,
226LMCAS_API ExprResult tan(const ExprPtr& expression);
227LMCAS_API ExprResult asin(const ExprPtr& expression,
229LMCAS_API ExprResult asin(const ExprPtr& expression);
230LMCAS_API ExprResult acos(const ExprPtr& expression,
232LMCAS_API ExprResult acos(const ExprPtr& expression);
233LMCAS_API ExprResult atan(const ExprPtr& expression,
235LMCAS_API ExprResult atan(const ExprPtr& expression);
236LMCAS_API ExprResult exp(const ExprPtr& expression,
238LMCAS_API ExprResult exp(const ExprPtr& expression);
239LMCAS_API ExprResult log(const ExprPtr& expression,
241LMCAS_API ExprResult log(const ExprPtr& expression);
242LMCAS_API ExprResult log10(const ExprPtr& expression,
244LMCAS_API ExprResult log10(const ExprPtr& expression);
245LMCAS_API ExprResult floor(const ExprPtr& expression,
247LMCAS_API ExprResult floor(const ExprPtr& expression);
248LMCAS_API ExprResult ceil(const ExprPtr& expression,
250LMCAS_API ExprResult ceil(const ExprPtr& expression);
251LMCAS_API ExprResult round(const ExprPtr& expression,
253LMCAS_API ExprResult round(const ExprPtr& expression);
254LMCAS_API ExprResult clamp(const ExprPtr& expression,
256 const ExprPtr& upper,
258LMCAS_API ExprResult clamp(const ExprPtr& expression,
259 const ExprPtr& lower,
260 const ExprPtr& upper);
261LMCAS_API ExprResult real(const ExprPtr& expression,
263LMCAS_API ExprResult real(const ExprPtr& expression);
264LMCAS_API ExprResult imag(const ExprPtr& expression,
266LMCAS_API ExprResult imag(const ExprPtr& expression);
267LMCAS_API ExprResult conj(const ExprPtr& expression,
269LMCAS_API ExprResult conj(const ExprPtr& expression);
270/**
271 * @brief Construct the complex modulus in square-sum form.
272 *
273 * Exact numeric components retain exact simplification. Approximate components
274 * and bound real components use a scaled norm without forming their squares.
275 */
276LMCAS_API ExprResult abs(const ExprPtr& expression,
278LMCAS_API ExprResult abs(const ExprPtr& expression);
279LMCAS_API ExprResult simplify(const ExprPtr& expression,
281LMCAS_API ExprResult simplify(const ExprPtr& expression);
282LMCAS_API ExprResult expand(const ExprPtr& expression,
284LMCAS_API ExprResult expand(const ExprPtr& expression);
285LMCAS_API ExprResult differentiate(const ExprPtr& expression,
286 const std::string& variable,
288LMCAS_API ExprResult differentiate(const ExprPtr& expression,
289 const std::string& variable);
290
291LMCAS_API ExprResult substitute(const ExprPtr& expression,
292 const std::string& variable,
295
296LMCAS_API ExprResult substitute(const ExprPtr& expression,
297 const std::string& variable,
298 const ExprPtr& value);
299
301
302LMCAS_API ExprResult substitute(const ExprPtr& expression,
305
306LMCAS_API ExprResult substitute(const ExprPtr& expression,
307 const Binding& binding);
308
309LMCAS_API ExprResult substitute(const ExprPtr& expression,
310 const std::vector<Binding>& bindings,
312
313LMCAS_API ExprResult substitute(const ExprPtr& expression,
314 const std::vector<Binding>& bindings);
315
318 const std::vector<std::string>& wildcards,
320
322 const ExprPtr& target,
323 const std::vector<std::string>& wildcards);
324
325LMCAS_API Result<ApproxReal> evalf(const SymbolicExpr& expression,
328
329LMCAS_API Result<ApproxReal> evalf(const SymbolicExpr& expression,
330 const NumericBindings& bindings = {});
331
332/**
333 * @brief Explicitly evaluate an expression as a finite complex value.
334 *
335 * Powers with integer exponents in [-64, 64] use exponentiation by squaring.
336 * Exact exponent expressions are normalized before numeric conversion, with
337 * rational exponents classified in their exact number domain.
338 * Negative powers first form the reciprocal base, keeping the computation
339 * on the magnitude scale of the requested result.
340 * Complex traversal and real-component evaluation share the context's active
341 * recursion budget. Each frame releases its depth on return or stack unwinding.
342 * Complex products use LMMC's component-wise binary scaling at exponent
343 * boundaries and retain the propagated component error estimates.
344 */
345LMCAS_API Result<ApproxComplex> eval_complex(const SymbolicExpr& expression,
346 const NumericBindings& bindings,
347 ComputationContext& context);
348
349LMCAS_API Result<ApproxComplex> eval_complex(const SymbolicExpr& expression,
350 const NumericBindings& bindings = {});
351
352LMCAS_API SolveResult solve_set(const ExprPtr& equation,
353 const std::string& variable,
354 ComputationContext& context,
355 const SolveOptions& options = {});
356
357LMCAS_API SolveResult solve_set(const ExprPtr& equation,
358 const std::string& variable,
359 const SolveOptions& options = {});
360
361LMCAS_API ExprSetResult expr_set(std::vector<ExprPtr> elements);
362LMCAS_API NumberDomainSet integers();
363LMCAS_API NumberDomainSet rationals();
364LMCAS_API NumberDomainSet reals();
365LMCAS_API NumberDomainSet complexes();
366LMCAS_API NumberDomainSet expressions();
367LMCAS_API Result<bool> domain_contains(const NumberDomainSet& domain,
369LMCAS_API Result<bool> domain_subset(const NumberDomainSet& lhs,
370 const NumberDomainSet& rhs);
372 const ExprPtr& element);
374 const ExprPtr& element);
375LMCAS_API Result<bool> expr_set_subset(const ExprSet& lhs,
376 const ExprSet& rhs);
378 const NumberDomainSet& domain);
379LMCAS_API ExprSetResult expr_set_union(const ExprSet& lhs,
380 const ExprSet& rhs);
382 const ExprSet& rhs);
384 const ExprSet& rhs);
386 const ExprSet& rhs);
387
389 const std::string& variable,
391 const SolveOptions& options = {});
392
393LMCAS_API ExprSetResult solve_expr_set(const ExprPtr& equation,
394 const std::string& variable,
395 const SolveOptions& options = {});
396
397LMCAS_API ExprSetResult roots(const ExprPtr& expression,
398 const std::string& variable,
399 ComputationContext& context,
400 const SolveOptions& options = {});
401
402LMCAS_API ExprSetResult roots(const ExprPtr& expression,
403 const std::string& variable,
404 const SolveOptions& options = {});
405
406LMCAS_API ExprSetResult solve(const ExprPtr& equation,
407 const std::string& variable,
408 ComputationContext& context,
409 const SolveOptions& options = {});
410
411LMCAS_API ExprSetResult solve(const ExprPtr& equation,
412 const std::string& variable,
413 const SolveOptions& options = {});
414
415LMCAS_API const char* error_name(CasErrc code) noexcept;
416LMCAS_API const char* error_name(const CasError& error) noexcept;
417
418LMCAS_API bool structurally_equal(const SymbolicExpr& lhs,
419 const SymbolicExpr& rhs);
420
421LMCAS_API Result<bool> equivalent(const SymbolicExpr& lhs,
422 const SymbolicExpr& rhs,
423 ComputationContext& context,
424 const EqvOptions& options = {});
425
426} // namespace LMCAS
任意精度整数 BigInt,底层调用 LMMP 实现高性能大数运算。
#define LMCAS_API
Result< ApproxReal > evalf(const SymbolicExpr &expression, const NumericBindings &bindings, ComputationContext &context)
std::string display_unit
ExprResult strip_to_display_value(const ExprPtr &quantity, ComputationContext &context)
ExprResult pow(const ExprPtr &base, const ExprPtr &exponent, ComputationContext &context)
const std::string & variable
ExprResult eq(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
const ExprPtr & element
ExprResult le(const ExprPtr &lhs, const ExprPtr &rhs)
ExprResult exp(const ExprPtr &expression, ComputationContext &context)
ExprResult with_unit(const ExprPtr &value, const std::string &unit, ComputationContext &context)
ExprResult imaginary_unit()
ExprResult logical_or(const ExprPtr &lhs, const ExprPtr &rhs)
ExprResult log10(const ExprPtr &expression, ComputationContext &context)
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
ExprResult e()
ExprResult ceil(const ExprPtr &expression, ComputationContext &context)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
ExprResult integer(Integer)=delete
ExprResult neg(const ExprPtr &expression, ComputationContext &context)
ExprResult real(const ExprPtr &expression, ComputationContext &context)
ExprResult approx_real(double value)
ExprResult acos(const ExprPtr &expression, ComputationContext &context)
Result< SolutionSet > SolveResult
ExprResult sub(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
ExprSetResult expr_set(std::vector< ExprPtr > elements)
ExprResult with_unit_definition(const ExprPtr &value, std::string display_unit, UnitDefinition definition, ComputationContext &context)
const ExprPtr & lower
ExprResult div(const ExprPtr &numerator, const ExprPtr &denominator, ComputationContext &context)
ExprResult ge(const ExprPtr &lhs, const ExprPtr &rhs)
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
const ExprPtr & set
const std::string ComputationContext const SolveOptions & options
Result< bool > expr_set_contains(const ExprSet &set, const ExprPtr &element)
ExprResult strip_to_base_value(const ExprPtr &quantity, ComputationContext &context)
Result< ExprPtr > ExprResult
ExprSetResult solve_expr_set(const ExprPtr &equation, const std::string &variable, ComputationContext &context, const SolveOptions &options)
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
const Binding & binding
NumberDomainSet reals()
ExprResult conj(const ExprPtr &expression, ComputationContext &context)
Result< bool > equivalent(const SymbolicExpr &lhs, const SymbolicExpr &rhs, ComputationContext &context, const EqvOptions &options)
ExprResult atan(const ExprPtr &expression, ComputationContext &context)
ExprResult clamp(const ExprPtr &expression, const ExprPtr &lower, const ExprPtr &upper, ComputationContext &context)
ExprResult asin(const ExprPtr &expression, ComputationContext &context)
ExprResult logical_not(const ExprPtr &expression)
ExprResult sin(const ExprPtr &expression, ComputationContext &context)
ExprResult expand(const ExprPtr &expression, ComputationContext &context)
std::shared_ptr< const SymbolicExpr > ConstExprPtr
ExprResult convert_to_unit_definition(const ExprPtr &quantity, std::string display_unit, UnitDefinition definition, ComputationContext &context)
ExprResult ne(const ExprPtr &lhs, const ExprPtr &rhs)
Result< bool > expr_set_subset(const ExprSet &lhs, const ExprSet &rhs)
RelationOp
Stable relational operator used by public APIs.
ExprSetResult expr_set_symmetric_difference(const ExprSet &lhs, const ExprSet &rhs)
ExprResult simplify(const ExprPtr &expression, ComputationContext &context)
ExprSetResult expr_set_intersection(const ExprSet &lhs, const ExprSet &rhs)
ExprResult tan(const ExprPtr &expression, ComputationContext &context)
Result< bool > expr_set_not_contains(const ExprSet &set, const ExprPtr &element)
const ExprPtr RelationOp op
SymbolicExpr Expr
std::string UnitDefinition definition
ExprResult complex(ExprPtr real, ExprPtr imag)
Result< bool > expr_set_subset_domain(const ExprSet &set, const NumberDomainSet &domain)
ExprResult finite_set(std::vector< ExprPtr > elements)
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr bool lower_closed
const ExprPtr & exponent
bool contains(const SymbolicExpr &expression, const std::string &variable)
NumberDomainSet integers()
const std::vector< Binding > & bindings
const NumberDomainSet & domain
ExprPtr imag
ExprResult member(const ExprPtr &element, const ExprPtr &set, ComputationContext &context)
ExprResult cos(const ExprPtr &expression, ComputationContext &context)
std::shared_ptr< SymbolicExpr > ExprPtr
ExprResult membership(const ExprPtr &element, const ExprPtr &set, bool negated)
const ExprPtr & target
const std::string & unit
Result< bool > domain_subset(const NumberDomainSet &lhs, const NumberDomainSet &rhs)
ExprSetResult expr_set_difference(const ExprSet &lhs, const ExprSet &rhs)
ExprResult pi()
const ExprPtr const std::vector< std::string > & wildcards
ExprResult sqrt(const ExprPtr &expression, ComputationContext &context)
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)
ExprMatchResult expr_match(const ExprPtr &pattern, const ExprPtr &target, const std::vector< std::string > &wildcards, ComputationContext &context)
ExprResult relation(const ExprPtr &lhs, const ExprPtr &rhs, RelationOp op)
ExprResult gt(const ExprPtr &lhs, const ExprPtr &rhs)
const std::string const ExprPtr & value
const ExprPtr & rhs
const char * error_name(CasErrc code) noexcept
ExprResult phi()
ExprResult log(const ExprPtr &expression, ComputationContext &context)
Result< Binding > BindingResult
NumberDomainSet expressions()
NumberDomainSet rationals()
Result< bool > domain_contains(const NumberDomainSet &domain, const ExprPtr &element)
NumberDomainSet complexes()
std::vector< ExprMatchBinding > bindings
ExprResult lt(const ExprPtr &lhs, const ExprPtr &rhs)
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr bool bool upper_closed
Result< ExprSet > ExprSetResult
Result< ExprMatch > ExprMatchResult
ExprResult floor(const ExprPtr &expression, ComputationContext &context)
const ExprPtr & denominator
ExprResult function(const std::string &name, std::vector< ExprPtr > arguments)
ExprResult differentiate(const ExprPtr &expression, const std::string &variable, ComputationContext &context)
SolveResult solve_set(const ExprPtr &equation, const std::string &variable, ComputationContext &context, const SolveOptions &options)
const ExprPtr bool negated
ExprResult convert_to_unit(const ExprPtr &quantity, const std::string &unit, ComputationContext &context)
bool structurally_equal(const SymbolicExpr &lhs, const SymbolicExpr &rhs)
std::unordered_map< std::string, double > NumericBindings
ExprResult abs(const ExprPtr &expression, ComputationContext &context)
__attribute__((visibility("default"))) Result< EqvProfile > eqv_profile_from_name(const std const std::string & name
ExprResult logical_and(const ExprPtr &lhs, const ExprPtr &rhs)
ExprResult rational(const Rational &value)
ExprSetResult solve(const ExprPtr &equation, const std::string &variable, ComputationContext &context, const SolveOptions &options)
ExprResult round(const ExprPtr &expression, ComputationContext &context)
ExprSetResult expr_set_union(const ExprSet &lhs, const ExprSet &rhs)
ExprResult substitute(const ExprPtr &expression, const std::string &variable, const ExprPtr &value, ComputationContext &context)
方程求解选项,控制数值求解行为和结果形式.
精确有理数 Rational,基于 BigInt 分子/分母表示,自动约分。
方程求解策略调度器 solve_dispatch 及相关选项结构体.
符号表达式主类 SymbolicExpr 及其工厂方法,运算接口.