13static bool match_recursive(
const std::shared_ptr<const SymbolicNode>& p_node,
14 const std::shared_ptr<const SymbolicNode>& t_node,
15 const std::unordered_set<std::string>&
wildcards,
19 const std::vector<std::shared_ptr<const SymbolicNode>>& t_ops,
20 std::vector<bool>& used_t,
22 const std::unordered_set<std::string>&
wildcards,
25 if (p_index == p_ops.size()) {
29 for (
size_t j = 0; j < t_ops.size(); ++j) {
41 results = saved_results;
44 results = saved_results;
52static bool is_wildcard(
const std::shared_ptr<const SymbolicNode>& node,
53 const std::unordered_set<std::string>&
wildcards,
54 std::string& name_out) {
55 if (!node)
return false;
57 auto var = std::dynamic_pointer_cast<const VariableNode>(node);
58 if (var && !var->is_constant()) {
60 name_out = var->name();
67template <
typename Operation>
69 std::vector<std::shared_ptr<const SymbolicNode>> operands) {
70 if constexpr (std::is_same_v<Operation, AddNode>) {
77template <
typename Operation>
79 const char* key,
MatchMap& results) {
80 std::vector<std::shared_ptr<const SymbolicNode>> rest;
81 for (
size_t index = 0; index < used.size(); ++index) {
83 rest.push_back(
target.operands()[index]);
90 const auto found = results.find(key);
91 if (found == results.end()) {
95 std::vector<std::shared_ptr<const SymbolicNode>> operands;
96 if (
const auto* existing =
dynamic_cast<const Operation*
>(
detail::node(found->second).get())) {
97 operands.insert(operands.end(), existing->operands().begin(), existing->operands().end());
101 operands.push_back(remainder);
105template <
typename Operation>
107 const std::unordered_set<std::string>&
wildcards,
108 const char* rest_key,
MatchMap& results) {
109 if (pattern.operands().size() >
target.operands().size()) {
112 std::vector<bool> used(
target.operands().size(),
false);
125 for (
size_t index = 0; index < pattern.
arguments().size(); ++index) {
134 const std::shared_ptr<const SymbolicNode>&
target,
144 const auto existing = results.find(
name);
145 if (existing != results.end()) {
151 if (pattern->type_priority() !=
target->type_priority()) {
154 if (pattern->is_number() ||
dynamic_cast<const VariableNode*
>(pattern.get())) {
155 return pattern->equals(*
target);
157 if (
const auto*
add =
dynamic_cast<const AddNode*
>(pattern.get())) {
160 if (
const auto* multiply =
dynamic_cast<const MultiplyNode*
>(pattern.get())) {
163 if (
const auto* power =
dynamic_cast<const PowerNode*
>(pattern.get())) {
164 const auto& other =
static_cast<const PowerNode&
>(*target);
171 return pattern->equals(*
target);
174bool Matcher::match(
const SymbolicExpr& pattern,
const SymbolicExpr&
target,
175 const std::unordered_set<std::string>&
wildcards,
182SymbolicExpr Matcher::replace(
const SymbolicExpr& template_expr,
const MatchMap&
bindings,
bool use_rest) {
189 occupied.insert(names.begin(), names.end());
192 std::vector<std::pair<std::string, std::string>> placeholders;
193 placeholders.reserve(
bindings.size());
194 std::size_t suffix = 0;
197 std::string placeholder;
199 placeholder =
"__lmcas_match_binding_" + std::to_string(suffix++);
200 }
while (!occupied.insert(placeholder).second);
203 placeholders.emplace_back(
name, std::move(placeholder));
205 for (
const auto& [
name, placeholder] : placeholders) {
214 auto rest =
bindings.at(
"__Add_REST__");
216 std::vector<std::shared_ptr<const SymbolicNode>> ops;
218 ops = add_node->operands();
224 ops.insert(ops.end(), rest_add->operands().begin(), rest_add->operands().end());
232 auto rest =
bindings.at(
"__Mul_REST__");
234 std::vector<std::shared_ptr<const SymbolicNode>> ops;
235 if (
auto mul_node = std::dynamic_pointer_cast<const MultiplyNode>(
LMCAS::detail::node(res))) {
236 ops = mul_node->operands();
241 if (
auto rest_mul = std::dynamic_pointer_cast<const MultiplyNode>(
LMCAS::detail::node(rest))) {
242 ops.insert(ops.end(), rest_mul->operands().begin(), rest_mul->operands().end());
函数节点,表示数学函数调用(三角函数、对数、特殊函数等)。
FuncType type() const noexcept
const std::vector< std::shared_ptr< const SymbolicNode > > & arguments() const noexcept
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_variable(const std::string &name)
static std::shared_ptr< const SymbolicNode > create_multiply(std::vector< std::shared_ptr< const SymbolicNode > > ops, detail::RewriteBudget *budget=nullptr)
创建乘法节点,自动扁平化嵌套乘法并消除单位元.
bool equals(const SymbolicNode &other) const
判断两个节点是否结构相等.
模式匹配引擎 Matcher 与重写规则系统 RewriteEngine。
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
static bool match_operation(const Operation &pattern, const Operation &target, const std::unordered_set< std::string > &wildcards, const char *rest_key, MatchMap &results)
static bool match_commutative_recursive(const std::vector< std::shared_ptr< const SymbolicNode > > &p_ops, const std::vector< std::shared_ptr< const SymbolicNode > > &t_ops, std::vector< bool > &used_t, size_t p_index, const std::unordered_set< std::string > &wildcards, MatchMap &results)
SymbolicExpr wildcard(const std::string &name)
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
static void record_remainder(const Operation &target, const std::vector< bool > &used, const char *key, MatchMap &results)
const std::vector< Binding > & bindings
std::set< std::string > free_variables(const detail::SymbolicNodePtr &expression, detail::RewriteBudget *budget)
const ExprPtr const std::vector< std::string > & wildcards
std::unordered_map< std::string, SymbolicExpr > MatchMap
匹配结果映射,通配符名称 → 绑定的表达式
static std::shared_ptr< const SymbolicNode > combine_operands(std::vector< std::shared_ptr< const SymbolicNode > > operands)
ExprResult function(const std::string &name, std::vector< ExprPtr > arguments)
__attribute__((visibility("default"))) Result< EqvProfile > eqv_profile_from_name(const std const std::string & name
static bool match_function(const FunctionNode &pattern, const FunctionNode &target, const std::unordered_set< std::string > &wildcards, MatchMap &results)
static bool is_wildcard(const std::shared_ptr< const SymbolicNode > &node, const std::unordered_set< std::string > &wildcards, std::string &name_out)
detail::SymbolicNodePtr substitute_free(const detail::SymbolicNodePtr &expression, const std::string &variable, const detail::SymbolicNodePtr &replacement, detail::RewriteBudget *budget)
static bool match_recursive(const std::shared_ptr< const SymbolicNode > &p_node, const std::shared_ptr< const SymbolicNode > &t_node, const std::unordered_set< std::string > &wildcards, MatchMap &results)