30 PiecewiseNode(std::vector<Branch> br, std::shared_ptr<const SymbolicNode> def =
nullptr)
33 throw std::invalid_argument(
"PiecewiseNode requires at least one branch");
36 if (!branch.expression || !branch.condition) {
37 throw std::invalid_argument(
"PiecewiseNode branch fields cannot be null");
44 const std::shared_ptr<const SymbolicNode>&
default_expr() const noexcept {
66 if (
branches_.size() != o.branches_.size()) {
67 return branches_.size() < o.branches_.size() ? -1 : 1;
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;
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) {
87 std::shared_ptr<const SymbolicNode>
clone()
const override {
88 std::vector<Branch> new_branches;
91 new_branches.push_back({
b.expression->clone(),
b.condition->clone()});
105 const std::shared_ptr<const SymbolicNode>
body_;
118 std::shared_ptr<const SymbolicNode> lo, std::shared_ptr<const SymbolicNode> hi)
122 throw std::invalid_argument(
"SummationNode children cannot be null");
125 throw std::invalid_argument(
"SummationNode index variable cannot be empty");
130 const std::shared_ptr<const SymbolicNode>&
body() const noexcept {
return body_; }
132 const std::shared_ptr<const SymbolicNode>&
lower_bound() const noexcept {
135 const std::shared_ptr<const SymbolicNode>&
upper_bound() const noexcept {
143 std::size_t seed = 0;
155 if (cmp != 0)
return cmp;
157 if (cmp != 0)
return cmp;
159 if (cmp != 0)
return cmp;
160 return body_->compare(*o.body_);
166 std::shared_ptr<const SymbolicNode>
clone()
const override {
179 const std::shared_ptr<const SymbolicNode>
body_;
192 std::shared_ptr<const SymbolicNode> lo, std::shared_ptr<const SymbolicNode> hi)
196 throw std::invalid_argument(
"ProductNode children cannot be null");
199 throw std::invalid_argument(
"ProductNode index variable cannot be empty");
204 const std::shared_ptr<const SymbolicNode>&
body() const noexcept {
return body_; }
206 const std::shared_ptr<const SymbolicNode>&
lower_bound() const noexcept {
209 const std::shared_ptr<const SymbolicNode>&
upper_bound() const noexcept {
217 std::size_t seed = 0;
227 const auto& o =
static_cast<const ProductNode&
>(other);
229 if (cmp != 0)
return cmp;
231 if (cmp != 0)
return cmp;
233 if (cmp != 0)
return cmp;
234 return body_->compare(*o.body_);
240 std::shared_ptr<const SymbolicNode>
clone()
const override {
265 const std::shared_ptr<const SymbolicNode>
body_;
267 const std::shared_ptr<const SymbolicNode>
target_;
277 std::string src, std::shared_ptr<const SymbolicNode>
target)
281 throw std::invalid_argument(
"TransformNode children cannot be null");
284 throw std::invalid_argument(
"TransformNode source variable cannot be empty");
290 const std::shared_ptr<const SymbolicNode>&
body() const noexcept {
return body_; }
292 const std::shared_ptr<const SymbolicNode>&
target() const noexcept {
return target_; }
298 std::size_t seed = 0;
310 return static_cast<int>(
transform_type_) <
static_cast<int>(o.transform_type_) ? -1 : 1;
313 if (cmp != 0)
return cmp;
314 cmp =
target_->compare(*o.target_);
315 if (cmp != 0)
return cmp;
316 return body_->compare(*o.body_);
322 std::shared_ptr<const SymbolicNode>
clone()
const override {
PiecewiseNode(std::vector< Branch > br, std::shared_ptr< const SymbolicNode > def=nullptr)
构造分段函数节点.
std::shared_ptr< const SymbolicNode > expression
分支值。
int type_priority() const override
LMCAS_AST_NODE_FACTORY_FRIEND
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
LMCAS_AST_NODE_FACTORY_FRIEND
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
LMCAS_AST_NODE_FACTORY_FRIEND
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_
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)
将一个哈希值混合到种子中,用于组合多个字段的哈希.