13 std::vector<std::shared_ptr<const SymbolicNode>> ops,
19 std::size_t nodes = 0;
20 for (
const auto&
op : ops) {
22 throw std::invalid_argument(
"create_add operand cannot be null");
28 if (ops.size() == 1) {
32 std::vector<std::shared_ptr<const SymbolicNode>> flat_ops;
34 flat_ops.reserve(ops.size());
35 for (
const auto&
op : ops) {
39 if (
auto add = std::dynamic_pointer_cast<const AddNode>(
op)) {
41 for (
const auto& child :
add->operands()) {
45 flat_ops.insert(flat_ops.end(),
add->operands().begin(),
add->operands().end());
51 if (flat_ops.empty()) {
55 if (flat_ops.size() == 1) {
66 const auto zero = std::find_if(operands.begin(), operands.end(), [](
const auto& operand) {
67 return operand->is_zero();
69 if (zero == operands.end()) {
return nullptr; }
70 std::optional<ComputationContext> local_context;
71 if (!budget) { local_context.emplace(); }
73 if (std::all_of(operands.begin(), operands.end(), [&](
const auto& operand) {
74 return normalization_can_discard(operand, detail::no_facts(), Domain::Real, context);
84 std::vector<std::shared_ptr<const SymbolicNode>> ops,
91 std::size_t nodes = 0;
92 for (
const auto&
op : ops) {
94 throw std::invalid_argument(
"create_multiply operand cannot be null");
100 if (
auto zero = discardable_zero_factor(ops, budget)) {
104 if (ops.size() == 1) {
108 std::vector<std::shared_ptr<const SymbolicNode>> flat_ops;
110 flat_ops.reserve(ops.size());
111 for (
const auto&
op : ops) {
115 if (
auto mul = std::dynamic_pointer_cast<const MultiplyNode>(
op)) {
117 for (
const auto& child :
mul->operands()) {
121 flat_ops.insert(flat_ops.end(),
mul->operands().begin(),
mul->operands().end());
127 if (flat_ops.empty()) {
131 if (flat_ops.size() == 1) {
141 throw std::invalid_argument(
"create_power operands cannot be null");
154 if (base->is_zero()) {
169 throw std::invalid_argument(
"create_complex operands cannot be null");
171 if (
imag->is_zero()) {
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)
ComputationContext & context() const noexcept
std::size_t measure(const std::shared_ptr< const SymbolicNode > &node)
std::size_t append_size(std::size_t current, std::size_t child)
detail::SymbolicNodePtr discardable_zero_factor(const std::vector< detail::SymbolicNodePtr > &operands, detail::RewriteBudget *budget)
Result< Tribool > query_nonzero_value(const Node &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
std::shared_ptr< const SymbolicNode > SymbolicNodePtr
const FactsQuery & no_facts() noexcept
std::shared_ptr< const Node > make_node(Args &&... args)
Result< Tribool > query_positive_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
__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
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult real(const ExprPtr &expression, ComputationContext &context)
bool normalization_can_discard(const std::shared_ptr< const SymbolicNode > &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
@ Complex
Complex numbers (default, least specific)
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
std::size_t normalization_check_arithmetic(detail::RewriteBudget *budget, std::size_t extra_nodes, const std::shared_ptr< const Nodes > &... children)
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
const ExprPtr RelationOp op
void normalization_check_children(detail::RewriteBudget *budget, std::size_t roots, const std::shared_ptr< const Nodes > &... children)
bool normalization_proved(const Result< Tribool > &result)
__attribute__((visibility("default"))) Result< EqvProfile > eqv_profile_from_name(const std const std::string & name
void normalization_append(detail::RewriteBudget *budget, std::size_t &nodes, std::vector< std::shared_ptr< const SymbolicNode > > &children, std::shared_ptr< const SymbolicNode > child)