13 const std::vector<detail::SymbolicNodePtr>& operands,
15 std::vector<detail::SymbolicNodePtr> rewritten;
18 rewritten.reserve(operands.size());
19 for (
const auto& operand : operands) {
28 const AssumptionContext* assumptions) {
29 auto inner_ln = std::dynamic_pointer_cast<const FunctionNode>(node);
31 inner_ln->arguments().size() != 1) {
35 auto positive = assumptions
36 ? assumptions->is_positive(*argument)
38 const bool known_positive = inner_ln->arguments()[0]->is_positive() ||
40 return known_positive ? argument :
nullptr;
44 const auto product = std::dynamic_pointer_cast<const MultiplyNode>(node);
45 if (!product || product->operands().size() != 2) {
50 lambert_node = product->operands()[1];
52 lambert_node = product->operands()[0];
56 const auto lambert = std::dynamic_pointer_cast<const FunctionNode>(lambert_node);
58 lambert->arguments().size() != 1) {
62 std::dynamic_pointer_cast<const NumberNode>(lambert->arguments()[0]);
63 if (!argument || !argument->is_positive()) {
66 if (argument->is_one()) {
74 {lambert_node, std::move(reciprocal)}, &budget);
80 const AssumptionContext* assumptions,
83 if (arguments.size() == 1) {
87 return SymbolicExpr::number(1);
92 return std::move(*lambert);
94 if (argument) {
return argument; }
99 return SymbolicExpr::number(0);
104 function.type(), std::move(arguments)));
110 const AssumptionContext* assumptions,
112 if (!node) {
return nullptr; }
114 if (
auto add = std::dynamic_pointer_cast<const AddNode>(node)) {
116 rewrite_operands(
add->operands(), assumptions, budget), &budget));
118 if (
auto multiply = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
120 rewrite_operands(multiply->operands(), assumptions, budget), &budget));
122 if (
auto power = std::dynamic_pointer_cast<const PowerNode>(node)) {
127 return SymbolicExpr::power(base,
exponent);
129 if (
auto function = std::dynamic_pointer_cast<const FunctionNode>(node)) {
130 return rewrite_exp_log_function(*
function, assumptions, budget);
132 if (
auto complex_node = std::dynamic_pointer_cast<const ComplexNode>(node)) {
AssumptionContext class with scoped push/pop management.
函数节点,表示数学函数调用(三角函数、对数、特殊函数等)。
static Result success(T value)
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_multiply(std::vector< std::shared_ptr< const SymbolicNode > > ops, detail::RewriteBudget *budget=nullptr)
创建乘法节点,自动扁平化嵌套乘法并消除单位元.
std::size_t measure(const std::shared_ptr< const SymbolicNode > &node)
void require_nodes(std::size_t nodes) const
std::size_t append_size(std::size_t current, std::size_t child)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::shared_ptr< const SymbolicNode > SymbolicNodePtr
std::shared_ptr< const Node > make_node(Args &&... args)
std::vector< detail::SymbolicNodePtr > rewrite_operands(const std::vector< detail::SymbolicNodePtr > &operands, const AssumptionContext *assumptions, detail::RewriteBudget &budget)
ExprPtr positive_log_argument(const detail::SymbolicNodePtr &node, const AssumptionContext *assumptions)
ExprPtr rewrite_exp_log_function(const FunctionNode &function, const AssumptionContext *assumptions, detail::RewriteBudget &budget)
std::optional< ExprPtr > rewrite_negative_lambert_exponential(const detail::SymbolicNodePtr &node, detail::RewriteBudget &budget)
ExprPtr normalize_equivalence(const ExprPtr &expression, detail::RewriteBudget &budget)
bool exact_integer_node(const std::shared_ptr< const SymbolicNode > &node, int expected)
ExprPtr rewrite_exp_log_basic_identity(const detail::SymbolicNodePtr &node, const AssumptionContext *assumptions, detail::RewriteBudget &budget)
ExprPtr rewritten_complex(const ExprPtr &real, const ExprPtr &imag, const detail::SymbolicNodePtr &original, detail::RewriteBudget &budget)
ExprResult real(const ExprPtr &expression, ComputationContext &context)
@ Unknown
Property cannot be determined
@ True
Property definitely holds
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
void normalization_check_children(detail::RewriteBudget *budget, std::size_t roots, const std::shared_ptr< const Nodes > &... children)
std::shared_ptr< SymbolicExpr > ExprPtr
ExprResult function(const std::string &name, std::vector< ExprPtr > arguments)