LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
base.hpp
浏览该文件的文档.
1/**
2 * @file internal/symbolic_ast/base.hpp
3 * @brief 内部 AST 的所有权、节点协议、访问者契约与工厂声明。
4 */
5#pragma once
6#define LMCAS_INTERNAL_AST_INCLUDED 1
7#include <memory>
8#include <vector>
9#include <string>
10#include <variant>
11#include <algorithm>
12#include <typeindex>
13#include <unordered_map>
14#include <unordered_set>
15#include <limits>
16#include "lmcas_export.hpp"
17#include "symbolic.hpp"
18#include "rational.hpp"
19#include "bigint.hpp"
20#include "unit.hpp"
22#include "lmmc/config.h"
23#include "lmmc/numeric.h"
24#include <stdexcept>
25#include <atomic>
26#include <type_traits>
27#include <utility>
28
29namespace LMCAS {
30
31class SymbolicNode;
32class NumberNode;
33class VariableNode;
34class AddNode;
35class MultiplyNode;
36class PowerNode;
37class FunctionNode;
38class UninterpretedFunctionNode;
39class MatrixNode;
40class RelationalNode;
41class LogicalNode;
42class TransformNode;
43class QuantifierNode;
44class SetBuilderNode;
45class FiniteSetNode;
46class IntervalNode;
47class MembershipNode;
48class QuantityNode;
49class PiecewiseNode;
50class SummationNode;
51class ProductNode;
52class ComplexNode;
53class IntegralNode;
54class LimitNode;
55class RootOfNode;
56
58 explicit Impl(std::shared_ptr<const SymbolicNode> root_node)
59 : root(std::move(root_node)) {
60 if (!root) {
61 throw std::invalid_argument("SymbolicExpr requires a non-null AST root");
62 }
63 }
64
65 const std::shared_ptr<const SymbolicNode> root;
66};
67
68}
69
70
71namespace LMCAS::detail {
72
73using SymbolicNodePtr = std::shared_ptr<const SymbolicNode>;
74
76 static const SymbolicNodePtr& node(const ::LMCAS::SymbolicExpr& expression) noexcept {
77 return expression.impl_->root;
78 }
79
80 static ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root) {
81 return ::LMCAS::SymbolicExpr(
82 std::make_shared<const ::LMCAS::SymbolicExpr::Impl>(std::move(root)));
83 }
84
85 static std::shared_ptr<::LMCAS::SymbolicExpr> make_expression_ptr(SymbolicNodePtr root) {
86 return std::shared_ptr<::LMCAS::SymbolicExpr>(new ::LMCAS::SymbolicExpr(
87 std::make_shared<const ::LMCAS::SymbolicExpr::Impl>(std::move(root))));
88 }
89};
90
91inline const SymbolicNodePtr& node(const ::LMCAS::SymbolicExpr& expression) noexcept {
92 return SymbolicExprAccess::node(expression);
93}
94
95inline const SymbolicNodePtr& node(
96 const std::shared_ptr<::LMCAS::SymbolicExpr>& expression) noexcept {
97 static const SymbolicNodePtr empty;
98 return expression ? node(*expression) : empty;
99}
100
101inline const SymbolicNodePtr& node(
102 const std::shared_ptr<const ::LMCAS::SymbolicExpr>& expression) noexcept {
103 static const SymbolicNodePtr empty;
104 return expression ? node(*expression) : empty;
105}
106
107inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root) {
108 return SymbolicExprAccess::expression_from_node(std::move(root));
109}
110
111inline std::shared_ptr<::LMCAS::SymbolicExpr> make_expression_ptr(SymbolicNodePtr root) {
112 return SymbolicExprAccess::make_expression_ptr(std::move(root));
113}
114
115inline std::shared_ptr<::LMCAS::SymbolicExpr> make_expression_ptr(
116 const ::LMCAS::SymbolicExpr& expression) {
117 return std::make_shared<::LMCAS::SymbolicExpr>(expression);
118}
119
120class SymbolicVisitor;
121
122template <typename Node, typename... Args>
123std::shared_ptr<const Node> make_node(Args&&... args) {
124 static_assert(std::is_base_of<SymbolicNode, Node>::value,
125 "make_node only constructs SymbolicNode implementations");
126 return std::shared_ptr<const Node>(
127 new Node(std::forward<Args>(args)...));
128}
129
130}
131
132#define LMCAS_AST_NODE_FACTORY_FRIEND \
133 template <typename Node, typename... Args> \
134 friend std::shared_ptr<const Node> \
135 LMCAS::detail::make_node(Args&&... args)
136
137namespace LMCAS {
138
139/**
140 * @brief 将一个哈希值混合到种子中,用于组合多个字段的哈希.
141 * @param seed 当前哈希种子,混合后就地更新
142 * @param value 要混合的哈希值
143 */
144inline void hash_combine(std::size_t& seed, std::size_t value) {
145 seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2);
146}
148protected:
149 mutable std::atomic<std::size_t> cached_hash{0};
150 mutable std::atomic<bool> hash_computed{false};
151
152 SymbolicNode() = default;
154 SymbolicNode& operator=(const SymbolicNode&) { return *this; }
155 virtual std::size_t compute_hash() const = 0;
156 virtual int compare_same_type(const SymbolicNode& other) const = 0;
157
158public:
159 virtual ~SymbolicNode() = default;
160 virtual void accept(LMCAS::detail::SymbolicVisitor& visitor) const = 0;
161 virtual std::shared_ptr<const SymbolicNode> clone() const = 0;
162 virtual int type_priority() const = 0;
163
164 /**
165 * @brief 获取节点哈希值(带缓存).
166 * @return 哈希值
167 */
168 std::size_t hash() const {
169 if (!hash_computed.load(std::memory_order_acquire)) {
170 std::size_t h = compute_hash();
171 cached_hash.store(h, std::memory_order_relaxed);
172 hash_computed.store(true, std::memory_order_release);
173 return h;
174 }
175 return cached_hash.load(std::memory_order_relaxed);
176 }
177
178 /**
179 * @brief 与另一个节点进行全序比较.
180 * @param other 待比较的节点
181 * @return 小于返回 -1,等于返回 0,大于返回 1
182 */
183 int compare(const SymbolicNode& other) const {
184 if (type_priority() != other.type_priority()) {
185 return type_priority() < other.type_priority() ? -1 : 1;
186 }
187 return compare_same_type(other);
188 }
189
190 /**
191 * @brief 判断两个节点是否结构相等.
192 * @param other 待比较的节点
193 * @return 相等返回 true
194 */
195 bool equals(const SymbolicNode& other) const {
196 if (this == &other) return true;
197 if (hash() != other.hash()) return false;
198 if (type_priority() != other.type_priority()) return false;
199 return compare_same_type(other) == 0;
200 }
201 virtual bool is_number() const { return false; }
202 virtual bool is_one() const { return false; }
203 virtual bool is_zero() const { return false; }
204 virtual bool is_positive() const { return false; }
205};
206
207/**
208 * @brief AST 访问者基类,由子类实现各节点的 visit 方法。
209 * 遍历深度超限时抛出异常。
210 */
211
212}
213
214namespace LMCAS::detail {
215
217protected:
219 static constexpr int MAX_DEPTH = 200;
220 RewriteBudget* rewrite_budget() const noexcept { return rewrite_budget_; }
221
222private:
224public:
225 SymbolicVisitor() = default;
227 struct DepthGuard {
231 visitor.rewrite_budget_->enter();
232 } else if (visitor.current_depth >= MAX_DEPTH) {
233 throw std::runtime_error("AST traversal depth limit exceeded");
234 }
236 }
241 DepthGuard(const DepthGuard&) = delete;
242 DepthGuard& operator=(const DepthGuard&) = delete;
243 };
244
245 virtual ~SymbolicVisitor() = default;
246
247 virtual void visit(const NumberNode& node) = 0;
248 virtual void visit(const VariableNode& node) = 0;
249 virtual void visit(const AddNode& node) = 0;
250 virtual void visit(const MultiplyNode& node) = 0;
251 virtual void visit(const PowerNode& node) = 0;
252 virtual void visit(const FunctionNode& node) = 0;
253 virtual void visit(const UninterpretedFunctionNode& node) = 0;
254 virtual void visit(const MatrixNode& node) = 0;
255 virtual void visit(const RelationalNode& node) = 0;
256 virtual void visit(const LogicalNode& node) = 0;
257 virtual void visit(const PiecewiseNode& node) = 0;
258 virtual void visit(const SummationNode& node) = 0;
259 virtual void visit(const ProductNode& node) = 0;
260 virtual void visit(const TransformNode& node) = 0;
261 virtual void visit(const QuantifierNode& node) = 0;
262 virtual void visit(const SetBuilderNode& node) = 0;
263 virtual void visit(const FiniteSetNode& node) = 0;
264 virtual void visit(const IntervalNode& node) = 0;
265 virtual void visit(const MembershipNode& node) = 0;
266 virtual void visit(const QuantityNode& node) = 0;
267 virtual void visit(const ComplexNode& node) = 0;
268 virtual void visit(const IntegralNode& node) = 0;
269 virtual void visit(const LimitNode& node) = 0;
270 virtual void visit(const RootOfNode& node) = 0;
271};
272
273} namespace LMCAS {
274struct NodeHash {
275 std::size_t operator()(const std::shared_ptr<const SymbolicNode>& node) const {
276 return node ? node->hash() : 0;
277 }
278};
279struct NodeEqual {
280 bool operator()(const std::shared_ptr<const SymbolicNode>& lhs, const std::shared_ptr<const SymbolicNode>& rhs) const {
281 if (!lhs || !rhs) return lhs == rhs;
282 return lhs->equals(*rhs);
283 }
284};
285
286template<typename T>
287using NodeMap = std::unordered_map<std::shared_ptr<const SymbolicNode>, T, NodeHash, NodeEqual>;
288
289using NodeSet = std::unordered_set<std::shared_ptr<const SymbolicNode>, NodeHash, NodeEqual>;
291public:
292 static std::shared_ptr<const SymbolicNode> create_number(const ::LMCAS::BigInt& v);
293 static std::shared_ptr<const SymbolicNode> create_number(const ::LMCAS::Rational& v);
294 static std::shared_ptr<const SymbolicNode> create_number(lmmc_real_t v);
295 static std::shared_ptr<const SymbolicNode> create_variable(const std::string& name);
296
297 /**
298 * @brief 创建加法节点,自动扁平化嵌套加法并消除零项.
299 * @param ops 操作数列表
300 * @return 简化后的节点
301 */
302 static std::shared_ptr<const SymbolicNode> create_add(
303 std::vector<std::shared_ptr<const SymbolicNode>> ops,
304 detail::RewriteBudget* budget = nullptr);
305
306 /**
307 * @brief 创建乘法节点,自动扁平化嵌套乘法并消除单位元.
308 * @param ops 操作数列表
309 * @return 简化后的节点
310 */
311 static std::shared_ptr<const SymbolicNode> create_multiply(
312 std::vector<std::shared_ptr<const SymbolicNode>> ops,
313 detail::RewriteBudget* budget = nullptr);
314
315 /**
316 * @brief 创建幂运算节点,自动处理指数为 0/1 及底数为 0/1 的情况.
317 * @param base 底数节点
318 * @param exponent 指数节点
319 * @return 简化后的节点
320 */
321 static std::shared_ptr<const SymbolicNode> create_power(std::shared_ptr<const SymbolicNode> base, std::shared_ptr<const SymbolicNode> exponent);
322
323 /**
324 * @brief 创建复数节点,自动简化(若虚部为 0,则返回实部).
325 */
326 static std::shared_ptr<const SymbolicNode> create_complex(std::shared_ptr<const SymbolicNode> real, std::shared_ptr<const SymbolicNode> imag);
327};
328
329}
任意精度整数 BigInt,底层调用 LMMP 实现高性能大数运算。
加法节点,表示多个操作数的求和。
复数节点,表示 real + imag * i。
函数节点,表示数学函数调用(三角函数、对数、特殊函数等)。
矩阵节点,支持稠密和稀疏两种存储方式。
乘法节点,表示多个操作数的乘积。
分段函数节点,表示条件分支表达式.
幂运算节点,表示 base^exponent。
连乘节点,表示符号有限/无限连乘 prod_{k=a}^{b} f(k).
求和节点,表示符号有限/无限求和 sum_{k=a}^{b} f(k).
static std::shared_ptr< const SymbolicNode > create_add(std::vector< std::shared_ptr< const SymbolicNode > > ops, detail::RewriteBudget *budget=nullptr)
创建加法节点,自动扁平化嵌套加法并消除零项.
static std::shared_ptr< const SymbolicNode > create_complex(std::shared_ptr< const SymbolicNode > real, std::shared_ptr< const SymbolicNode > imag)
创建复数节点,自动简化(若虚部为 0,则返回实部).
static std::shared_ptr< const SymbolicNode > create_variable(const std::string &name)
static std::shared_ptr< const SymbolicNode > create_power(std::shared_ptr< const SymbolicNode > base, std::shared_ptr< const SymbolicNode > exponent)
创建幂运算节点,自动处理指数为 0/1 及底数为 0/1 的情况.
static std::shared_ptr< const SymbolicNode > create_multiply(std::vector< std::shared_ptr< const SymbolicNode > > ops, detail::RewriteBudget *budget=nullptr)
创建乘法节点,自动扁平化嵌套乘法并消除单位元.
static std::shared_ptr< const SymbolicNode > create_number(const ::LMCAS::BigInt &v)
virtual void accept(LMCAS::detail::SymbolicVisitor &visitor) const =0
virtual std::size_t compute_hash() const =0
virtual int compare_same_type(const SymbolicNode &other) const =0
SymbolicNode(const SymbolicNode &)
std::atomic< std::size_t > cached_hash
bool equals(const SymbolicNode &other) const
判断两个节点是否结构相等.
virtual bool is_number() const
std::size_t hash() const
获取节点哈希值(带缓存).
SymbolicNode()=default
virtual bool is_zero() const
virtual bool is_positive() const
virtual bool is_one() const
virtual ~SymbolicNode()=default
SymbolicNode & operator=(const SymbolicNode &)
virtual int type_priority() const =0
std::atomic< bool > hash_computed
int compare(const SymbolicNode &other) const
与另一个节点进行全序比较.
virtual std::shared_ptr< const SymbolicNode > clone() const =0
积分变换节点,表示 Laplace,Fourier,Z 变换及其逆变换.
变量节点,表示一个符号变量。
virtual void visit(const ComplexNode &node)=0
virtual void visit(const QuantifierNode &node)=0
virtual void visit(const MultiplyNode &node)=0
virtual void visit(const RelationalNode &node)=0
virtual void visit(const PiecewiseNode &node)=0
virtual void visit(const IntervalNode &node)=0
virtual void visit(const LogicalNode &node)=0
RewriteBudget * rewrite_budget() const noexcept
virtual void visit(const TransformNode &node)=0
SymbolicVisitor(RewriteBudget *budget) noexcept
virtual void visit(const VariableNode &node)=0
virtual void visit(const IntegralNode &node)=0
virtual void visit(const QuantityNode &node)=0
virtual void visit(const NumberNode &node)=0
virtual void visit(const UninterpretedFunctionNode &node)=0
virtual void visit(const ProductNode &node)=0
virtual void visit(const FunctionNode &node)=0
virtual void visit(const MatrixNode &node)=0
virtual void visit(const LimitNode &node)=0
virtual void visit(const MembershipNode &node)=0
static constexpr int MAX_DEPTH
virtual void visit(const RootOfNode &node)=0
virtual void visit(const PowerNode &node)=0
virtual ~SymbolicVisitor()=default
virtual void visit(const SummationNode &node)=0
virtual void visit(const SetBuilderNode &node)=0
virtual void visit(const FiniteSetNode &node)=0
virtual void visit(const AddNode &node)=0
多元 Hensel 提升(单变量步)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::shared_ptr< const SymbolicNode > Node
std::shared_ptr< const SymbolicNode > SymbolicNodePtr
inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
std::shared_ptr< const Node > make_node(Args &&... args)
std::unordered_set< std::shared_ptr< const SymbolicNode >, NodeHash, NodeEqual > NodeSet
__attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::string & v
ExprResult real(const ExprPtr &expression, ComputationContext &context)
void hash_combine(std::size_t &seed, std::size_t value)
将一个哈希值混合到种子中,用于组合多个字段的哈希.
std::unordered_map< std::shared_ptr< const SymbolicNode >, T, NodeHash, NodeEqual > NodeMap
const ExprPtr & exponent
ExprPtr imag
const std::string const ExprPtr & value
const ExprPtr & rhs
__attribute__((visibility("default"))) Result< EqvProfile > eqv_profile_from_name(const std const std::string & name
精确有理数 Rational,基于 BigInt 分子/分母表示,自动约分。
bool operator()(const std::shared_ptr< const SymbolicNode > &lhs, const std::shared_ptr< const SymbolicNode > &rhs) const
std::size_t operator()(const std::shared_ptr< const SymbolicNode > &node) const
Impl(std::shared_ptr< const SymbolicNode > root_node)
const std::shared_ptr< const SymbolicNode > root
static std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
static const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
DepthGuard & operator=(const DepthGuard &)=delete
DepthGuard(const DepthGuard &)=delete
符号表达式主类 SymbolicExpr 及其工厂方法,运算接口.