13 binder->scoped_body->accept(*
this);
18 binder->scoped_body->accept(inner);
23 std::size_t nodes = 1;
24 if (std::holds_alternative<MatrixNode::DenseStorage>(node.storage())) {
25 auto& dense = std::get<MatrixNode::DenseStorage>(node.storage());
27 for(
auto& item : dense) {
37 auto& sparse = std::get<MatrixNode::SparseStorage>(node.storage());
39 for(
auto& [idx, item] : sparse) {
53 std::shared_ptr<const SymbolicNode> new_left =
nullptr;
54 std::shared_ptr<const SymbolicNode> new_right =
nullptr;
57 node.left()->accept(*
this);
62 node.right()->accept(*
this);
66 if (!new_left) new_left = node.left();
67 if (!new_right) new_right = node.right();
79 or_node->accept(*
this);
86 std::shared_ptr<const SymbolicNode> new_left =
nullptr;
88 node.left()->accept(*
this);
91 if (!new_left) new_left = node.left();
94 if (
auto inner_logical = std::dynamic_pointer_cast<const LogicalNode>(new_left)) {
107 or_node->accept(*
this);
118 and_node->accept(*
this);
129 std::shared_ptr<const SymbolicNode> new_left =
nullptr;
130 std::shared_ptr<const SymbolicNode> new_right =
nullptr;
133 node.left()->accept(*
this);
137 node.right()->accept(*
this);
141 if (!new_left) new_left = node.left();
142 if (!new_right) new_right = node.right();
148 std::vector<PiecewiseNode::Branch> new_branches;
149 std::size_t nodes = 1;
151 new_branches.reserve(node.branches().size());
153 for (
const auto&
b : node.branches()) {
155 b.expression->accept(*
this);
159 b.condition->accept(*
this);
166 new_branches.push_back({new_expr, new_cond});
169 std::shared_ptr<const SymbolicNode> new_default =
nullptr;
170 if (node.default_expr()) {
171 node.default_expr()->accept(*
this);
183 node.lower_bound()->accept(*
this);
186 node.upper_bound()->accept(*
this);
190 auto lo_n = std::dynamic_pointer_cast<const NumberNode>(new_lower);
191 auto hi_n = std::dynamic_pointer_cast<const NumberNode>(new_upper);
199 const BigInt span = hi - lo;
200 if (span < BigInt(1000)) {
201 const auto count = span.try_to_uint64();
202 std::vector<std::shared_ptr<const SymbolicNode>> terms;
203 std::size_t nodes = 0;
205 terms.reserve(
static_cast<std::size_t
>(*count) + 1);
207 for (std::uint64_t offset = 0; offset <= *count; ++offset, index += BigInt(1)) {
218 sum_node->accept(*
this);
229 node.lower_bound()->accept(*
this);
232 node.upper_bound()->accept(*
this);
235 auto lo_n = std::dynamic_pointer_cast<const NumberNode>(new_lower);
236 auto hi_n = std::dynamic_pointer_cast<const NumberNode>(new_upper);
244 const BigInt span = hi - lo;
245 if (span < BigInt(1000)) {
246 const auto count = span.try_to_uint64();
247 std::vector<std::shared_ptr<const SymbolicNode>> factors;
248 std::size_t nodes = 0;
250 factors.reserve(
static_cast<std::size_t
>(*count) + 1);
252 for (std::uint64_t offset = 0; offset <= *count; ++offset, index += BigInt(1)) {
262 prod_node->accept(*
this);
272 node.target()->accept(*
this);
276 node.transform_type(), new_body, node.source_var(), new_target));
279 node.domain()->accept(*
this);
286 if (new_predicate->is_one()) {
294 if (new_predicate->is_zero()) {
304 node.domain()->accept(*
this);
314 std::vector<std::shared_ptr<const SymbolicNode>> elements;
315 std::size_t nodes = 1;
317 elements.reserve(node.elements().size());
318 for (
const auto&
element : node.elements()) {
326 node.lower()->accept(*
this);
328 node.upper()->accept(*
this);
331 lower,
result, node.lower_closed(), node.upper_closed()));
335 node.element()->accept(*
this);
337 node.set()->accept(*
this);
339 if (
auto finite = std::dynamic_pointer_cast<const FiniteSetNode>(
set)) {
341 BigInt(finite->contains(*
element) ? 1 : 0)));
349 node.value()->accept(*
this);
352 result, node.dimension(), node.scale_to_base(), node.display_unit()));
357 std::shared_ptr<const SymbolicNode>
lower;
358 std::shared_ptr<const SymbolicNode>
upper;
360 node.lower()->accept(*
this);
362 node.upper()->accept(*
this);
367 std::move(body), node.variable(), std::move(
lower), std::move(
upper)));
372 node.point()->accept(*
this);
375 body, node.variable(),
result, node.direction()));
@ Not
一元逻辑非,right 为 nullptr。
std::map< size_t, std::shared_ptr< const SymbolicNode > > SparseStorage
稀疏存储,索引映射到节点。
std::vector< std::shared_ptr< const SymbolicNode > > DenseStorage
稠密存储,按行优先展开。
void visit(const NumberNode &node) override
NormalizationVisitor(detail::RewriteBudget &budget, const FactsQuery &facts, Domain domain)
void set_result(std::shared_ptr< const SymbolicNode > candidate)
const FactsQuery & facts_
std::shared_ptr< const SymbolicNode > result
std::shared_ptr< const SymbolicNode > get_result() const
std::shared_ptr< const SymbolicNode > normalize_bound_body(const SymbolicNode &node)
连乘节点,表示符号有限/无限连乘 prod_{k=a}^{b} f(k).
求和节点,表示符号有限/无限求和 sum_{k=a}^{b} f(k).
void require_nodes(std::size_t nodes) const
std::size_t append_size(std::size_t current, std::size_t child)
为绑定体提供词法作用域,隔离同名自由变量的外层事实。 无关表达式继续借用外层事实及其关系推论;栈上视图串联保留嵌套作用域。
RewriteBudget * rewrite_budget() const noexcept
std::optional< BinderView > binder_view(const SymbolicNode &node)
const FactsQuery & no_facts() noexcept
std::shared_ptr< const Node > make_node(Args &&... args)
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
bool try_get_integer_value(const std::shared_ptr< const NumberNode > &node, BigInt &value)
std::size_t normalization_check_arithmetic(detail::RewriteBudget *budget, std::size_t extra_nodes, const std::shared_ptr< const Nodes > &... children)
std::size_t normalization_check_count(detail::RewriteBudget *budget, std::size_t rows, std::size_t cols=1, bool wrapped=true)
std::shared_ptr< const SymbolicNode > norm_subst_index(const std::shared_ptr< const SymbolicNode > &node, const std::string &index_var, const std::shared_ptr< const SymbolicNode > &value, detail::RewriteBudget *budget=nullptr)
void normalization_check_children(detail::RewriteBudget *budget, std::size_t roots, const std::shared_ptr< const Nodes > &... children)
std::shared_ptr< const SymbolicNode > make_normalized_multiply_node(const std::vector< std::shared_ptr< const SymbolicNode > > &operands, detail::RewriteBudget *budget=nullptr)
void normalization_append(detail::RewriteBudget *budget, std::size_t &nodes, std::vector< std::shared_ptr< const SymbolicNode > > &children, std::shared_ptr< const SymbolicNode > child)