LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
integral.hpp
浏览该文件的文档.
1/** @file internal/symbolic_ast/integral.hpp */
2#pragma once
3
5
6namespace LMCAS {
7
8class IntegralNode : public SymbolicNode {
9private:
10 template <typename Node, typename... Args>
11 friend std::shared_ptr<const Node>
12 LMCAS::detail::make_node(Args&&... args);
13 const std::shared_ptr<const SymbolicNode> body_;
14 const std::string variable_;
15 const std::shared_ptr<const SymbolicNode> lower_;
16 const std::shared_ptr<const SymbolicNode> upper_;
17
18 IntegralNode(std::shared_ptr<const SymbolicNode> body,
19 std::string variable,
20 std::shared_ptr<const SymbolicNode> lower = nullptr,
21 std::shared_ptr<const SymbolicNode> upper = nullptr)
22 : body_(std::move(body)), variable_(std::move(variable)),
23 lower_(std::move(lower)), upper_(std::move(upper)) {
24 if (!body_) throw std::invalid_argument("integral body cannot be null");
25 if (variable_.empty()) throw std::invalid_argument("integral variable cannot be empty");
26 if (static_cast<bool>(lower_) != static_cast<bool>(upper_)) {
27 throw std::invalid_argument("integral bounds must both be present or absent");
28 }
29 }
30
31public:
32 const auto& body() const noexcept { return body_; }
33 const std::string& variable() const noexcept { return variable_; }
34 const auto& lower() const noexcept { return lower_; }
35 const auto& upper() const noexcept { return upper_; }
36 bool is_definite() const noexcept { return lower_ && upper_; }
37 int type_priority() const override { return 108; }
38
39protected:
40 std::size_t compute_hash() const override {
41 std::size_t seed = static_cast<std::size_t>(type_priority());
42 hash_combine(seed, body_->hash());
43 hash_combine(seed, std::hash<std::string>{}(variable_));
44 if (lower_) hash_combine(seed, lower_->hash());
45 if (upper_) hash_combine(seed, upper_->hash());
46 return seed;
47 }
48
49 int compare_same_type(const SymbolicNode& other) const override {
50 const auto& integral = static_cast<const IntegralNode&>(other);
51 int comparison = variable_.compare(integral.variable_);
52 if (comparison != 0) {
53 return comparison;
54 }
55 comparison = body_->compare(*integral.body_);
56 if (comparison != 0) {
57 return comparison;
58 }
59 if (is_definite() != integral.is_definite()) {
60 return is_definite() ? 1 : -1;
61 }
62 if (!is_definite()) {
63 return 0;
64 }
65 comparison = lower_->compare(*integral.lower_);
66 return comparison != 0 ? comparison : upper_->compare(*integral.upper_);
67 }
68
69public:
70 void accept(LMCAS::detail::SymbolicVisitor& visitor) const override {
72 visitor.visit(*this);
73 }
74
75 std::shared_ptr<const SymbolicNode> clone() const override {
77 body_->clone(), variable_,
78 lower_ ? lower_->clone() : nullptr,
79 upper_ ? upper_->clone() : nullptr);
80 }
81};
82
83}
const std::shared_ptr< const SymbolicNode > lower_
const auto & body() const noexcept
const auto & upper() const noexcept
int type_priority() const override
const std::shared_ptr< const SymbolicNode > upper_
const auto & lower() const noexcept
int compare_same_type(const SymbolicNode &other) const override
IntegralNode(std::shared_ptr< const SymbolicNode > body, std::string variable, std::shared_ptr< const SymbolicNode > lower=nullptr, std::shared_ptr< const SymbolicNode > upper=nullptr)
bool is_definite() const noexcept
const std::shared_ptr< const SymbolicNode > body_
const std::string & variable() const noexcept
const std::string variable_
std::size_t compute_hash() const override
std::shared_ptr< const SymbolicNode > clone() const override
void accept(LMCAS::detail::SymbolicVisitor &visitor) const override
SymbolicNode()=default
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)
将一个哈希值混合到种子中,用于组合多个字段的哈希.