LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
bindings.hpp
浏览该文件的文档.
1#pragma once
3
4namespace LMCAS {
5
6/**
7 * @brief 分段函数节点,表示条件分支表达式.
8 *
9 * 存储有序的 (表达式, 条件) 对列表和可选的默认表达式.
10 * 条件应为 RelationalNode 或 LogicalNode 表达式.
11 */
13public:
14 struct Branch {
15 std::shared_ptr<const SymbolicNode> expression; /**< 分支值。 */
16 std::shared_ptr<const SymbolicNode> condition; /**< 条件(RelationalNode 或 LogicalNode)。 */
17 };
18
19private:
21
22 const std::vector<Branch> branches_;
23 const std::shared_ptr<const SymbolicNode> default_expr_;
24
25 /**
26 * @brief 构造分段函数节点.
27 * @param br 分支列表
28 * @param def 默认表达式(可为 nullptr)
29 */
30 PiecewiseNode(std::vector<Branch> br, std::shared_ptr<const SymbolicNode> def = nullptr)
31 : branches_(std::move(br)), default_expr_(std::move(def)) {
32 if (branches_.empty()) {
33 throw std::invalid_argument("PiecewiseNode requires at least one branch");
34 }
35 for (const auto& branch : branches_) {
36 if (!branch.expression || !branch.condition) {
37 throw std::invalid_argument("PiecewiseNode branch fields cannot be null");
38 }
39 }
40 }
41
42public:
43 const std::vector<Branch>& branches() const noexcept { return branches_; }
44 const std::shared_ptr<const SymbolicNode>& default_expr() const noexcept {
45 return default_expr_;
46 }
47
48 int type_priority() const override { return 7; }
49
50protected:
51 std::size_t compute_hash() const override {
52 std::size_t seed = 0;
54 for (const auto& b : branches_) {
55 hash_combine(seed, b.expression->hash());
56 hash_combine(seed, b.condition->hash());
57 }
58 if (default_expr_) {
59 hash_combine(seed, default_expr_->hash());
60 }
61 return seed;
62 }
63
64 int compare_same_type(const SymbolicNode& other) const override {
65 const auto& o = static_cast<const PiecewiseNode&>(other);
66 if (branches_.size() != o.branches_.size()) {
67 return branches_.size() < o.branches_.size() ? -1 : 1;
68 }
69 for (size_t i = 0; i < branches_.size(); ++i) {
70 int cmp = branches_[i].expression->compare(*o.branches_[i].expression);
71 if (cmp != 0) return cmp;
72 cmp = branches_[i].condition->compare(*o.branches_[i].condition);
73 if (cmp != 0) return cmp;
74 }
75 bool has_def = (default_expr_ != nullptr);
76 bool o_has_def = (o.default_expr_ != nullptr);
77 if (has_def != o_has_def) return has_def ? 1 : -1;
78 if (has_def && o_has_def) {
79 return default_expr_->compare(*o.default_expr_);
80 }
81 return 0;
82 }
83
84public:
85 void accept(LMCAS::detail::SymbolicVisitor& visitor) const override { LMCAS::detail::SymbolicVisitor::DepthGuard guard(visitor); visitor.visit(*this); }
86
87 std::shared_ptr<const SymbolicNode> clone() const override {
88 std::vector<Branch> new_branches;
89 new_branches.reserve(branches_.size());
90 for (const auto& b : branches_) {
91 new_branches.push_back({b.expression->clone(), b.condition->clone()});
92 }
93 auto new_def = default_expr_ ? default_expr_->clone() : nullptr;
94 return LMCAS::detail::make_node<PiecewiseNode>(std::move(new_branches), std::move(new_def));
95 }
96};
97
98/**
99 * @brief 求和节点,表示符号有限/无限求和 sum_{k=a}^{b} f(k).
100 */
102private:
104
105 const std::shared_ptr<const SymbolicNode> body_;
106 const std::string index_var_;
107 const std::shared_ptr<const SymbolicNode> lower_bound_;
108 const std::shared_ptr<const SymbolicNode> upper_bound_;
109
110 /**
111 * @brief 构造求和节点.
112 * @param b 通项表达式
113 * @param idx 指标变量名
114 * @param lo 下界
115 * @param hi 上界
116 */
117 SummationNode(std::shared_ptr<const SymbolicNode> b, std::string idx,
118 std::shared_ptr<const SymbolicNode> lo, std::shared_ptr<const SymbolicNode> hi)
119 : body_(std::move(b)), index_var_(std::move(idx)),
120 lower_bound_(std::move(lo)), upper_bound_(std::move(hi)) {
121 if (!body_ || !lower_bound_ || !upper_bound_) {
122 throw std::invalid_argument("SummationNode children cannot be null");
123 }
124 if (index_var_.empty()) {
125 throw std::invalid_argument("SummationNode index variable cannot be empty");
126 }
127 }
128
129public:
130 const std::shared_ptr<const SymbolicNode>& body() const noexcept { return body_; }
131 const std::string& index_var() const noexcept { return index_var_; }
132 const std::shared_ptr<const SymbolicNode>& lower_bound() const noexcept {
133 return lower_bound_;
134 }
135 const std::shared_ptr<const SymbolicNode>& upper_bound() const noexcept {
136 return upper_bound_;
137 }
138
139 int type_priority() const override { return 8; }
140
141protected:
142 std::size_t compute_hash() const override {
143 std::size_t seed = 0;
145 hash_combine(seed, body_->hash());
146 hash_combine(seed, std::hash<std::string>{}(index_var_));
147 hash_combine(seed, lower_bound_->hash());
148 hash_combine(seed, upper_bound_->hash());
149 return seed;
150 }
151
152 int compare_same_type(const SymbolicNode& other) const override {
153 const auto& o = static_cast<const SummationNode&>(other);
154 int cmp = index_var_.compare(o.index_var_);
155 if (cmp != 0) return cmp;
156 cmp = lower_bound_->compare(*o.lower_bound_);
157 if (cmp != 0) return cmp;
158 cmp = upper_bound_->compare(*o.upper_bound_);
159 if (cmp != 0) return cmp;
160 return body_->compare(*o.body_);
161 }
162
163public:
164 void accept(LMCAS::detail::SymbolicVisitor& visitor) const override { LMCAS::detail::SymbolicVisitor::DepthGuard guard(visitor); visitor.visit(*this); }
165
166 std::shared_ptr<const SymbolicNode> clone() const override {
168 body_->clone(), index_var_, lower_bound_->clone(), upper_bound_->clone());
169 }
170};
171
172/**
173 * @brief 连乘节点,表示符号有限/无限连乘 prod_{k=a}^{b} f(k).
174 */
175class ProductNode : public SymbolicNode {
176private:
178
179 const std::shared_ptr<const SymbolicNode> body_;
180 const std::string index_var_;
181 const std::shared_ptr<const SymbolicNode> lower_bound_;
182 const std::shared_ptr<const SymbolicNode> upper_bound_;
183
184 /**
185 * @brief 构造连乘节点.
186 * @param b 通项表达式
187 * @param idx 指标变量名
188 * @param lo 下界
189 * @param hi 上界
190 */
191 ProductNode(std::shared_ptr<const SymbolicNode> b, std::string idx,
192 std::shared_ptr<const SymbolicNode> lo, std::shared_ptr<const SymbolicNode> hi)
193 : body_(std::move(b)), index_var_(std::move(idx)),
194 lower_bound_(std::move(lo)), upper_bound_(std::move(hi)) {
195 if (!body_ || !lower_bound_ || !upper_bound_) {
196 throw std::invalid_argument("ProductNode children cannot be null");
197 }
198 if (index_var_.empty()) {
199 throw std::invalid_argument("ProductNode index variable cannot be empty");
200 }
201 }
202
203public:
204 const std::shared_ptr<const SymbolicNode>& body() const noexcept { return body_; }
205 const std::string& index_var() const noexcept { return index_var_; }
206 const std::shared_ptr<const SymbolicNode>& lower_bound() const noexcept {
207 return lower_bound_;
208 }
209 const std::shared_ptr<const SymbolicNode>& upper_bound() const noexcept {
210 return upper_bound_;
211 }
212
213 int type_priority() const override { return 9; }
214
215protected:
216 std::size_t compute_hash() const override {
217 std::size_t seed = 0;
219 hash_combine(seed, body_->hash());
220 hash_combine(seed, std::hash<std::string>{}(index_var_));
221 hash_combine(seed, lower_bound_->hash());
222 hash_combine(seed, upper_bound_->hash());
223 return seed;
224 }
225
226 int compare_same_type(const SymbolicNode& other) const override {
227 const auto& o = static_cast<const ProductNode&>(other);
228 int cmp = index_var_.compare(o.index_var_);
229 if (cmp != 0) return cmp;
230 cmp = lower_bound_->compare(*o.lower_bound_);
231 if (cmp != 0) return cmp;
232 cmp = upper_bound_->compare(*o.upper_bound_);
233 if (cmp != 0) return cmp;
234 return body_->compare(*o.body_);
235 }
236
237public:
238 void accept(LMCAS::detail::SymbolicVisitor& visitor) const override { LMCAS::detail::SymbolicVisitor::DepthGuard guard(visitor); visitor.visit(*this); }
239
240 std::shared_ptr<const SymbolicNode> clone() const override {
242 body_->clone(), index_var_, lower_bound_->clone(), upper_bound_->clone());
243 }
244};
245
246/**
247 * @brief 积分变换节点,表示 Laplace,Fourier,Z 变换及其逆变换.
248 *
249 * 统一表示各类积分变换:L{f(t)}(s),F{f(t)}(omega),Z{f[n]}(z) 等.
250 */
252public:
253 enum class TransformType {
254 Laplace, /**< Laplace 变换 L{f(t)}(s)。 */
255 InverseLaplace, /**< 逆 Laplace 变换 L-¹{F(s)}(t)。 */
256 Fourier, /**< Fourier 变换 F{f(t)}(omega)。 */
257 InverseFourier, /**< 逆 Fourier 变换 F-¹{F(omega)}(t)。 */
258 ZTransform /**< Z 变换 Z{f[n]}(z)。 */
259 };
260
261private:
263
265 const std::shared_ptr<const SymbolicNode> body_;
266 const std::string source_var_;
267 const std::shared_ptr<const SymbolicNode> target_;
268
269 /**
270 * @brief 构造积分变换节点.
271 * @param tt 变换类型
272 * @param b 被变换的表达式
273 * @param src 源变量名
274 * @param tgt 目标变量名
275 */
276 TransformNode(TransformType tt, std::shared_ptr<const SymbolicNode> b,
277 std::string src, std::shared_ptr<const SymbolicNode> target)
278 : transform_type_(tt), body_(std::move(b)),
279 source_var_(std::move(src)), target_(std::move(target)) {
280 if (!body_ || !target_) {
281 throw std::invalid_argument("TransformNode children cannot be null");
282 }
283 if (source_var_.empty()) {
284 throw std::invalid_argument("TransformNode source variable cannot be empty");
285 }
286 }
287
288public:
289 TransformType transform_type() const noexcept { return transform_type_; }
290 const std::shared_ptr<const SymbolicNode>& body() const noexcept { return body_; }
291 const std::string& source_var() const noexcept { return source_var_; }
292 const std::shared_ptr<const SymbolicNode>& target() const noexcept { return target_; }
293
294 int type_priority() const override { return 11; }
295
296protected:
297 std::size_t compute_hash() const override {
298 std::size_t seed = 0;
300 hash_combine(seed, static_cast<std::size_t>(transform_type_));
301 hash_combine(seed, body_->hash());
302 hash_combine(seed, std::hash<std::string>{}(source_var_));
303 hash_combine(seed, target_->hash());
304 return seed;
305 }
306
307 int compare_same_type(const SymbolicNode& other) const override {
308 const auto& o = static_cast<const TransformNode&>(other);
309 if (transform_type_ != o.transform_type_) {
310 return static_cast<int>(transform_type_) < static_cast<int>(o.transform_type_) ? -1 : 1;
311 }
312 int cmp = source_var_.compare(o.source_var_);
313 if (cmp != 0) return cmp;
314 cmp = target_->compare(*o.target_);
315 if (cmp != 0) return cmp;
316 return body_->compare(*o.body_);
317 }
318
319public:
320 void accept(LMCAS::detail::SymbolicVisitor& visitor) const override { LMCAS::detail::SymbolicVisitor::DepthGuard guard(visitor); visitor.visit(*this); }
321
322 std::shared_ptr<const SymbolicNode> clone() const override {
324 transform_type_, body_->clone(), source_var_, target_->clone());
325 }
326};
327
328}
PiecewiseNode(std::vector< Branch > br, std::shared_ptr< const SymbolicNode > def=nullptr)
构造分段函数节点.
std::shared_ptr< const SymbolicNode > expression
分支值。
int type_priority() const override
const std::shared_ptr< const SymbolicNode > & default_expr() const noexcept
std::size_t compute_hash() const override
std::shared_ptr< const SymbolicNode > clone() const override
void accept(LMCAS::detail::SymbolicVisitor &visitor) const override
const std::vector< Branch > branches_
const std::vector< Branch > & branches() const noexcept
const std::shared_ptr< const SymbolicNode > default_expr_
std::shared_ptr< const SymbolicNode > condition
条件(RelationalNode 或 LogicalNode)。
int compare_same_type(const SymbolicNode &other) const override
const std::shared_ptr< const SymbolicNode > & lower_bound() const noexcept
void accept(LMCAS::detail::SymbolicVisitor &visitor) const override
const std::shared_ptr< const SymbolicNode > & upper_bound() const noexcept
const std::shared_ptr< const SymbolicNode > body_
std::size_t compute_hash() const override
const std::shared_ptr< const SymbolicNode > upper_bound_
const std::string index_var_
int compare_same_type(const SymbolicNode &other) const override
ProductNode(std::shared_ptr< const SymbolicNode > b, std::string idx, std::shared_ptr< const SymbolicNode > lo, std::shared_ptr< const SymbolicNode > hi)
构造连乘节点.
const std::shared_ptr< const SymbolicNode > & body() const noexcept
std::shared_ptr< const SymbolicNode > clone() const override
int type_priority() const override
const std::shared_ptr< const SymbolicNode > lower_bound_
const std::string & index_var() const noexcept
int compare_same_type(const SymbolicNode &other) const override
std::size_t compute_hash() const override
std::shared_ptr< const SymbolicNode > clone() const override
const std::shared_ptr< const SymbolicNode > & lower_bound() const noexcept
const std::shared_ptr< const SymbolicNode > lower_bound_
const std::shared_ptr< const SymbolicNode > body_
const std::shared_ptr< const SymbolicNode > & body() const noexcept
void accept(LMCAS::detail::SymbolicVisitor &visitor) const override
const std::string & index_var() const noexcept
int type_priority() const override
const std::shared_ptr< const SymbolicNode > upper_bound_
const std::shared_ptr< const SymbolicNode > & upper_bound() const noexcept
SummationNode(std::shared_ptr< const SymbolicNode > b, std::string idx, std::shared_ptr< const SymbolicNode > lo, std::shared_ptr< const SymbolicNode > hi)
构造求和节点.
const std::string index_var_
SymbolicNode()=default
TransformNode(TransformType tt, std::shared_ptr< const SymbolicNode > b, std::string src, std::shared_ptr< const SymbolicNode > target)
构造积分变换节点.
int type_priority() const override
int compare_same_type(const SymbolicNode &other) const override
const std::string & source_var() const noexcept
TransformType transform_type() const noexcept
const std::shared_ptr< const SymbolicNode > body_
const std::shared_ptr< const SymbolicNode > & target() const noexcept
const std::string source_var_
const std::shared_ptr< const SymbolicNode > target_
std::shared_ptr< const SymbolicNode > clone() const override
void accept(LMCAS::detail::SymbolicVisitor &visitor) const override
const std::shared_ptr< const SymbolicNode > & body() const noexcept
const TransformType transform_type_
std::size_t compute_hash() const override
virtual void visit(const NumberNode &node)=0
std::shared_ptr< const Node > make_node(Args &&... args)
void hash_combine(std::size_t &seed, std::size_t value)
将一个哈希值混合到种子中,用于组合多个字段的哈希.
const MultiPoly & b