9#include <unordered_set>
40 const std::shared_ptr<const SymbolicNode>& node,
41 const std::string& var,
42 std::vector<std::shared_ptr<const SymbolicNode>>& candidates) {
46 if (
auto func = std::dynamic_pointer_cast<const FunctionNode>(node)) {
47 if (func->arguments().size() == 1 &&
50 candidates.push_back(node);
52 for (
auto& arg : func->arguments()) {
58 if (
auto add = std::dynamic_pointer_cast<const AddNode>(node)) {
59 for (
auto&
op :
add->operands()) {
65 if (
auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
66 for (
auto&
op :
mul->operands()) {
72 if (
auto pow = std::dynamic_pointer_cast<const PowerNode>(node)) {
86static void tf_deduplicate(std::vector<std::shared_ptr<const SymbolicNode>>& candidates) {
88 std::vector<std::shared_ptr<const SymbolicNode>> unique;
90 for (
auto& node : candidates) {
91 if (seen.find(node) == seen.end()) {
93 unique.push_back(node);
97 candidates = std::move(unique);
108 const std::shared_ptr<const SymbolicNode>&
b) {
109 if (!
a || !
b)
return a ==
b;
110 return a->equals(*
b);
122 const std::shared_ptr<const SymbolicNode>& arg) {
127 auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node);
128 if (!
mul ||
mul->operands().size() != 2) {
132 for (
int i = 0; i < 2; ++i) {
133 auto num_node = std::dynamic_pointer_cast<const NumberNode>(
mul->operands()[i]);
138 if (num_node->is_negative_one()) {
139 int other_idx = 1 - i;
158 const std::shared_ptr<const SymbolicNode>& node,
159 const std::vector<TransSubstitution>& mappings) {
161 if (!node)
return nullptr;
163 for (
const auto& m : mappings) {
170 if (
auto func = std::dynamic_pointer_cast<const FunctionNode>(node)) {
171 std::vector<std::shared_ptr<const SymbolicNode>> new_args;
172 new_args.reserve(func->arguments().size());
173 for (
const auto& arg : func->arguments()) {
179 if (
auto add = std::dynamic_pointer_cast<const AddNode>(node)) {
180 std::vector<std::shared_ptr<const SymbolicNode>> new_ops;
181 new_ops.reserve(
add->operands().size());
182 for (
const auto&
op :
add->operands()) {
188 if (
auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
189 std::vector<std::shared_ptr<const SymbolicNode>> new_ops;
190 new_ops.reserve(
mul->operands().size());
191 for (
const auto&
op :
mul->operands()) {
197 if (
auto pow = std::dynamic_pointer_cast<const PowerNode>(node)) {
216 const auto first_type = first.
type();
217 const auto second_type = second.
type();
221 auto uj = SymbolicExpr::variable(
right.indeterminate);
222 auto two = SymbolicExpr::number(2);
223 auto sum = SymbolicExpr::add(SymbolicExpr::power(ui, two), SymbolicExpr::power(uj, two));
224 return SymbolicExpr::add(sum, SymbolicExpr::number(-1));
235 auto uj = SymbolicExpr::variable(
right.indeterminate);
236 return SymbolicExpr::add(SymbolicExpr::multiply(ui, uj), SymbolicExpr::number(-1));
240 const auto& mappings = result.
mappings;
241 for (
size_t i = 0; i < mappings.size(); ++i) {
242 auto first = std::dynamic_pointer_cast<const FunctionNode>(
244 if (!first || first->arguments().size() != 1)
continue;
245 for (
size_t j = i + 1; j < mappings.size(); ++j) {
246 auto second = std::dynamic_pointer_cast<const FunctionNode>(
248 if (!second || second->arguments().size() != 1)
continue;
250 if (constraint) result.
constraints.push_back(std::move(constraint));
265 const std::shared_ptr<SymbolicExpr>& expr,
266 const std::string& var) {
275 std::vector<std::shared_ptr<const SymbolicNode>> candidates;
280 for (
size_t i = 0; i < candidates.size(); ++i) {
284 result.
mappings.push_back(std::move(mapping));
函数节点,表示数学函数调用(三角函数、对数、特殊函数等)。
FuncType type() const noexcept
const std::vector< std::shared_ptr< const SymbolicNode > > & arguments() const noexcept
bool equals(const SymbolicNode &other) const
判断两个节点是否结构相等.
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::shared_ptr< const Node > make_node(Args &&... args)
std::unordered_set< std::shared_ptr< const SymbolicNode >, NodeHash, NodeEqual > NodeSet
ExprResult pow(const ExprPtr &base, const ExprPtr &exponent, ComputationContext &context)
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
bool expression_depends_on_variable(const detail::SymbolicNodePtr &expression, const std::string &variable, detail::RewriteBudget *budget)
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
std::shared_ptr< SymbolicExpr > poly_expr
换元后的多项式表达式
static bool tf_is_sine_cosine_pair(FunctionNode::FuncType first, FunctionNode::FuncType second)
const ExprPtr RelationOp op
__attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::shared_ptr< SymbolicExpr > & a
static std::shared_ptr< SymbolicExpr > tf_pair_constraint(const TransSubstitution &left, const TransSubstitution &right, const FunctionNode &first, const FunctionNode &second)
std::string indeterminate
代数不定元名 (e.g., "u0")
static std::shared_ptr< const SymbolicNode > tf_substitute_expr(const std::shared_ptr< const SymbolicNode > &node, const std::vector< TransSubstitution > &mappings)
按映射顺序将超越子表达式替换为不定元,递归重建未匹配节点。
bool tf_is_transcendental_type(FunctionNode::FuncType function_type)
判断函数类型是否支持超越函数换元。
TransSubstitutionResult detect_trans_substitutions(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var)
为依赖 var 的 Sin、Cos、Exp、Ln、Tan 子表达式构造换元结果。
static void tf_collect_transcendental(const std::shared_ptr< const SymbolicNode > &node, const std::string &var, std::vector< std::shared_ptr< const SymbolicNode > > &candidates)
按先序收集依赖 var 的超越函数子表达式。
static void tf_deduplicate(std::vector< std::shared_ptr< const SymbolicNode > > &candidates)
按结构哈希和 equals 比较去重,保留首次出现的顺序。
std::shared_ptr< SymbolicExpr > trans_expr
原始超越子表达式 (e.g., sin(x))
std::vector< TransSubstitution > mappings
所有换元映射
static void tf_detect_constraints(TransSubstitutionResult &result)
static bool tf_is_negation_of(const std::shared_ptr< const SymbolicNode > &node, const std::shared_ptr< const SymbolicNode > &arg)
匹配 (-1)*arg 或 arg*(-1) 的二因子乘积结构。
static bool tf_nodes_equal(const std::shared_ptr< const SymbolicNode > &a, const std::shared_ptr< const SymbolicNode > &b)
判断两个 AST 节点是否结构相等。
std::vector< std::shared_ptr< SymbolicExpr > > constraints
代数约束 (e.g., u0^2+u1^2-1=0)