6void RewriteEngine::add_rule(
const Rule& rule) {
14 std::shared_ptr<const SymbolicNode>
result;
22 std::shared_ptr<const SymbolicNode>
try_match(std::shared_ptr<const SymbolicNode> node) {
24 const auto& rules =
engine.get_rules();
25 const AssumptionContext* ctx =
context.assumptions().get();
26 for (
const auto& rule : rules) {
29 if (Matcher::match(rule.pattern, current_expr, rule.wildcards,
bindings)) {
31 if (rule.condition && !rule.condition(
bindings)) {
34 if (rule.assumption_condition &&
35 (!ctx || !rule.assumption_condition(
bindings, ctx))) {
39 SymbolicExpr new_expr = Matcher::replace(rule.replacement,
bindings,
true);
48 std::shared_ptr<const SymbolicNode>
visit_child(
const std::shared_ptr<const SymbolicNode>& child,
49 bool& child_changed) {
54 if (
changed || !rewritten->equals(*child)) {
61 void finish_rewrite(std::shared_ptr<const SymbolicNode> node,
bool child_changed,
62 bool original_changed) {
65 if (matched != node && !matched->equals(*node))
changed =
true;
68 if (
changed) original_changed =
true;
83 std::vector<std::shared_ptr<const SymbolicNode>> new_ops;
84 bool child_changed =
false;
86 bool original_changed =
changed;
89 for (
auto&
op : node.operands()) {
94 if (
changed) child_changed =
true;
98 std::shared_ptr<const SymbolicNode> node_to_match;
107 if (matched != node_to_match && !matched->equals(*node_to_match))
changed =
true;
110 if (
changed) original_changed =
true;
115 std::vector<std::shared_ptr<const SymbolicNode>> new_ops;
116 bool child_changed =
false;
117 bool original_changed =
changed;
120 for (
auto&
op : node.operands()) {
121 bool current_changed =
changed;
124 new_ops.push_back(
result);
125 if (
changed) child_changed =
true;
126 else changed = current_changed;
129 std::shared_ptr<const SymbolicNode> node_to_match;
138 if (matched != node_to_match && !matched->equals(*node_to_match))
changed =
true;
141 if (
changed) original_changed =
true;
146 bool original_changed =
changed;
149 node.base()->accept(*
this);
154 node.exponent()->accept(*
this);
158 bool child_changed = base_changed || exp_changed;
163 if (matched != node_to_match && !matched->equals(*node_to_match))
changed =
true;
166 if (
changed) original_changed =
true;
171 bool original_changed =
changed;
173 bool child_changed =
false;
175 std::vector<std::shared_ptr<const SymbolicNode>> new_args;
176 for (
auto& arg : node.arguments()) {
177 bool current_changed =
changed;
180 new_args.push_back(
result);
181 if (
changed) child_changed =
true;
182 else changed = current_changed;
189 if (matched != node_to_match && !matched->equals(*node_to_match))
changed =
true;
192 if (
changed) original_changed =
true;
197 bool original_changed =
changed;
198 bool child_changed =
false;
199 if (
const auto* dense =
200 std::get_if<MatrixNode::DenseStorage>(&node.storage())) {
202 entries.reserve(dense->size());
203 for (
const auto& entry : *dense) {
204 entries.push_back(
visit_child(entry, child_changed));
207 node.rows(), node.cols(), std::move(entries)),
208 child_changed, original_changed);
212 for (
const auto& [index, entry] :
213 std::get<MatrixNode::SparseStorage>(node.storage())) {
214 entries.emplace(index,
visit_child(entry, child_changed));
217 node.rows(), node.cols(), std::move(entries)),
218 child_changed, original_changed);
222 bool original_changed =
changed;
223 bool child_changed =
false;
224 auto left =
visit_child(node.left(), child_changed);
227 child_changed, original_changed);
231 bool original_changed =
changed;
232 bool child_changed =
false;
233 auto left =
visit_child(node.left(), child_changed);
234 std::shared_ptr<const SymbolicNode>
right =
nullptr;
237 child_changed, original_changed);
241 bool original_changed =
changed;
242 bool child_changed =
false;
243 std::vector<PiecewiseNode::Branch> branches;
244 branches.reserve(node.branches().size());
245 for (
const auto& branch : node.branches()) {
246 auto expression =
visit_child(branch.expression, child_changed);
247 auto condition =
visit_child(branch.condition, child_changed);
248 branches.push_back({expression, condition});
250 std::shared_ptr<const SymbolicNode> default_expr =
nullptr;
251 if (node.default_expr()) default_expr =
visit_child(node.default_expr(), child_changed);
253 child_changed, original_changed);
257 bool original_changed =
changed;
258 bool child_changed =
false;
259 auto body =
visit_child(node.body(), child_changed);
263 child_changed, original_changed);
267 bool original_changed =
changed;
268 bool child_changed =
false;
269 auto body =
visit_child(node.body(), child_changed);
273 child_changed, original_changed);
277 bool original_changed =
changed;
278 bool child_changed =
false;
279 auto body =
visit_child(node.body(), child_changed);
282 node.transform_type(), body, node.source_var(),
target),
283 child_changed, original_changed);
287 bool original_changed =
changed;
288 bool child_changed =
false;
290 auto predicate =
visit_child(node.predicate(), child_changed);
292 node.quantifier_type(), node.bound_var(),
domain, predicate),
293 child_changed, original_changed);
297 bool original_changed =
changed;
298 bool child_changed =
false;
300 auto predicate =
visit_child(node.predicate(), child_changed);
302 node.element_var(),
domain, predicate),
303 child_changed, original_changed);
307 bool original_changed =
changed;
308 bool child_changed =
false;
312 child_changed, original_changed);
315 bool original_changed =
changed;
316 bool child_changed =
false;
317 std::vector<std::shared_ptr<const SymbolicNode>> elements;
318 for (
const auto&
element : node.elements()) {
322 child_changed, original_changed);
325 bool original_changed =
changed;
326 bool child_changed =
false;
330 lower,
upper, node.lower_closed(), node.upper_closed()),
331 child_changed, original_changed);
334 bool original_changed =
changed;
335 bool child_changed =
false;
339 child_changed, original_changed);
342 bool original_changed =
changed;
343 bool child_changed =
false;
344 std::vector<std::shared_ptr<const SymbolicNode>> arguments;
345 arguments.reserve(node.arguments().size());
346 for (
const auto& argument : node.arguments()) {
347 arguments.push_back(
visit_child(argument, child_changed));
350 node.name(), std::move(arguments)),
351 child_changed, original_changed);
354 bool original_changed =
changed;
355 bool child_changed =
false;
358 value, node.dimension(), node.scale_to_base(), node.display_unit()),
359 child_changed, original_changed);
362 bool original_changed =
changed;
363 bool child_changed =
false;
364 auto body =
visit_child(node.body(), child_changed);
365 auto lower = node.lower()
366 ?
visit_child(node.lower(), child_changed) :
nullptr;
367 auto upper = node.upper()
368 ?
visit_child(node.upper(), child_changed) :
nullptr;
371 child_changed, original_changed);
374 bool original_changed =
changed;
375 bool child_changed =
false;
376 auto body =
visit_child(node.body(), child_changed);
379 body, node.variable(),
point, node.direction()),
380 child_changed, original_changed);
383 const bool original_changed =
changed;
388Result<SymbolicExpr> RewriteEngine::apply_step_checked(
389 const SymbolicExpr& expr,
390 ComputationContext&
context)
const {
391 auto budget =
context.consume_steps(1,
"rewrite.apply_step");
396 "rewrite.apply_step");
405 const SymbolicExpr& expr,
407 int max_iterations)
const {
408 if (max_iterations < 0) {
413 SymbolicExpr current = expr;
414 for (
int i = 0; i < max_iterations; ++i) {
415 auto next_result = apply_step_checked(current,
context);
416 if (!next_result)
return next_result;
417 SymbolicExpr next = std::move(next_result.value());
428 return apply_step_checked(expr,
context);
432 const SymbolicExpr& expr,
433 int max_iterations)
const {
435 return apply_checked(expr,
context, max_iterations);
函数节点,表示数学函数调用(三角函数、对数、特殊函数等)。
std::map< size_t, std::shared_ptr< const SymbolicNode > > SparseStorage
稀疏存储,索引映射到节点。
std::vector< std::shared_ptr< const SymbolicNode > > DenseStorage
稠密存储,按行优先展开。
连乘节点,表示符号有限/无限连乘 prod_{k=a}^{b} f(k).
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
void visit(const TransformNode &node) override
void visit(const PowerNode &node) override
RewriteVisitor(const RewriteEngine &e, ComputationContext &ctx)
void visit(const FiniteSetNode &node) override
void visit(const ComplexNode &node) override
const RewriteEngine & engine
void visit(const VariableNode &node) override
void visit(const IntegralNode &node) override
void visit(const MatrixNode &node) override
void visit(const IntervalNode &node) override
void visit(const AddNode &node) override
void visit(const UninterpretedFunctionNode &node) override
ComputationContext & context
void visit(const MultiplyNode &node) override
std::shared_ptr< const SymbolicNode > visit_child(const std::shared_ptr< const SymbolicNode > &child, bool &child_changed)
void visit(const NumberNode &node) override
void visit(const SetBuilderNode &node) override
void visit(const RootOfNode &node) override
void visit(const FunctionNode &node) override
void visit(const LogicalNode &node) override
std::shared_ptr< const SymbolicNode > result
void visit(const PiecewiseNode &node) override
void visit(const QuantityNode &node) override
void visit(const ProductNode &node) override
void visit(const MembershipNode &node) override
std::shared_ptr< const SymbolicNode > try_match(std::shared_ptr< const SymbolicNode > node)
void finish_rewrite(std::shared_ptr< const SymbolicNode > node, bool child_changed, bool original_changed)
std::shared_ptr< const SymbolicNode > get_result() const
void visit(const RelationalNode &node) override
void visit(const QuantifierNode &node) override
void visit(const SummationNode &node) override
void visit(const LimitNode &node) override
求和节点,表示符号有限/无限求和 sum_{k=a}^{b} f(k).
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_multiply(std::vector< std::shared_ptr< const SymbolicNode > > ops, detail::RewriteBudget *budget=nullptr)
创建乘法节点,自动扁平化嵌套乘法并消除单位元.
virtual void accept(LMCAS::detail::SymbolicVisitor &visitor) const =0
模式匹配引擎 Matcher 与重写规则系统 RewriteEngine。
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
std::shared_ptr< const Node > make_node(Args &&... args)
const std::string const LimitExprPtr & point
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
__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)
const ExprPtr RelationOp op
const std::vector< Binding > & bindings
const NumberDomainSet & domain
std::unordered_map< std::string, SymbolicExpr > MatchMap
匹配结果映射,通配符名称 → 绑定的表达式
const std::string const ExprPtr & value