LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
expr_transform.cpp
浏览该文件的文档.
1#include "expr.hpp"
2#include "matcher.hpp"
8#include <exception>
9#include <memory>
10#include <string>
11#include <utility>
12#include <vector>
13
14namespace LMCAS {
15
16using namespace expr_detail::expr_common;
17
19 return detail::simplify_expression(expression, context);
20}
21
22ExprResult simplify(const ExprPtr& expression) {
24 return simplify(expression, context);
25}
26
28 return detail::expand_expression(expression, context);
29}
30
31ExprResult expand(const ExprPtr& expression) {
33 return expand(expression, context);
34}
35
37 const std::string& variable,
39 if (variable.empty()) {
41 "differentiate variable cannot be empty",
43 }
45}
46
48 const std::string& variable) {
50 return differentiate(expression, variable, context);
51}
52
53ExprResult substitute(const ExprPtr& expression,
54 const std::string& variable,
55 const ExprPtr& value,
57 auto step = context.consume_steps(1, kSubstituteOperation);
58 if (!step) return ExprResult::failure(step.error());
59 if (!expression) {
61 "expression cannot be null",
63 }
64 if (variable.empty()) {
66 "substitution variable cannot be empty",
68 }
69 if (!value) {
71 "substitution value cannot be null",
73 }
75}
76
77ExprResult substitute(const ExprPtr& expression,
78 const std::string& variable,
79 const ExprPtr& value) {
81 return substitute(expression, variable, value, context);
82}
83
85 if (!symbol || !LMCAS::detail::node(symbol)) {
87 CasErrc::InvalidArgument, "binding symbol cannot be null",
89 }
92 CasErrc::InvalidArgument, "binding value cannot be null",
94 }
95 const auto variable = std::dynamic_pointer_cast<const VariableNode>(
96 LMCAS::detail::node(symbol));
97 if (!variable || variable->is_constant()) {
100 "binding left-hand side must be a symbol",
102 }
103 return BindingResult::success(Binding{std::move(symbol), std::move(value)});
104}
105
106ExprResult substitute(const ExprPtr& expression,
107 const Binding& replacement,
109 auto checked = binding(replacement.symbol, replacement.value);
110 if (!checked) return ExprResult::failure(checked.error());
111 const auto variable = std::dynamic_pointer_cast<const VariableNode>(
112 LMCAS::detail::node(checked.value().symbol));
113 return substitute(expression, variable->name(), checked.value().value, context);
114}
115
116ExprResult substitute(const ExprPtr& expression,
117 const Binding& replacement) {
119 return substitute(expression, replacement, context);
120}
121
122ExprResult substitute(const ExprPtr& expression,
123 const std::vector<Binding>& replacements,
125 return detail::substitute_expression(expression, replacements, context);
126}
127
128ExprResult substitute(const ExprPtr& expression,
129 const std::vector<Binding>& replacements) {
131 return substitute(expression, replacements, context);
132}
133
135 const ExprPtr& target,
136 const std::vector<std::string>& wildcards,
138 auto step = context.consume_steps(1, kExprMatchOperation);
139 if (!step) return ExprMatchResult::failure(step.error());
140 if (!pattern || !LMCAS::detail::node(pattern)) {
142 "match pattern cannot be null",
144 }
147 "match target cannot be null",
149 }
150
151 std::unordered_set<std::string> wildcard_set;
152 wildcard_set.reserve(wildcards.size());
153 for (const auto& wildcard : wildcards) {
154 if (wildcard.empty()) {
156 "wildcard names cannot be empty",
158 }
159 if (!wildcard_set.insert(wildcard).second) {
161 "wildcard names must be unique",
163 }
164 }
165
166 try {
167 MatchMap raw_bindings;
168 const bool matched = Matcher::match(
169 *pattern, *target, wildcard_set, raw_bindings);
170 if (!matched) {
171 return ExprMatchResult::success(ExprMatch{false, {}});
172 }
173
174 std::vector<std::string> names;
175 names.reserve(raw_bindings.size());
176 for (const auto& binding : raw_bindings) {
177 names.push_back(binding.first);
178 }
179 std::sort(names.begin(), names.end());
180
181 ExprMatch result;
182 result.matched = true;
183 result.bindings.reserve(names.size());
184 for (const auto& name : names) {
185 const auto& value = raw_bindings.at(name);
186 auto node = LMCAS::detail::node(value);
187 if (!node) {
189 "matcher produced a null binding",
191 }
192 result.bindings.push_back(
195 }
196 return ExprMatchResult::success(std::move(result));
197 } catch (const std::bad_alloc&) {
199 "expression matching allocation failed",
201 } catch (const std::exception& error) {
204 }
205}
206
208 const ExprPtr& target,
209 const std::vector<std::string>& wildcards) {
211 return expr_match(pattern, target, wildcards, context);
212}
213}
AssumptionContext class with scoped push/pop management.
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(Binding value)
模式匹配引擎 Matcher 与重写规则系统 RewriteEngine。
ExpressionResult substitute_expression(const ExprPtr &expression, const std::string &variable, const ExprPtr &replacement, ComputationContext &context)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
ExpressionResult simplify_expression(const ExprPtr &expression, ComputationContext &context)
ExpressionResult expand_expression(const ExprPtr &expression, ComputationContext &context)
ExpressionResult differentiate_expression(const ExprPtr &expression, const std::string &variable, ComputationContext &context)
constexpr const char * kExprMatchOperation
constexpr const char * kSubstituteOperation
ExprResult expression_failure(CasErrc code, std::string message, const char *operation)
ExprMatchResult expr_match_failure(CasErrc code, std::string message, const char *operation)
constexpr const char * kDifferentiateOperation
const std::string & variable
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
SymbolicExpr wildcard(const std::string &name)
Result< ExprPtr > ExprResult
const Binding & binding
ExprResult expand(const ExprPtr &expression, ComputationContext &context)
ExprResult simplify(const ExprPtr &expression, ComputationContext &context)
std::shared_ptr< SymbolicExpr > ExprPtr
const ExprPtr & target
const ExprPtr const std::vector< std::string > & wildcards
std::unordered_map< std::string, SymbolicExpr > MatchMap
匹配结果映射,通配符名称 → 绑定的表达式
ExprMatchResult expr_match(const ExprPtr &pattern, const ExprPtr &target, const std::vector< std::string > &wildcards, ComputationContext &context)
const std::string const ExprPtr & value
Result< Binding > BindingResult
std::vector< ExprMatchBinding > bindings
Result< ExprMatch > ExprMatchResult
ExprResult differentiate(const ExprPtr &expression, const std::string &variable, ComputationContext &context)
__attribute__((visibility("default"))) Result< EqvProfile > eqv_profile_from_name(const std const std::string & name
ExprResult substitute(const ExprPtr &expression, const std::string &variable, const ExprPtr &value, ComputationContext &context)
内部 AST 定义。