LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
integration_support.hpp
浏览该文件的文档.
1#pragma once
2
4#include "integration.hpp"
5#include "poly_utils.hpp"
9#include "matcher.hpp"
10#include "polynomial.hpp"
11#include "solve_polynomial.hpp"
13
14#include "lmmc/config.h"
15#include "lmmc/numeric.h"
16
17#include <algorithm>
18#include <cmath>
19#include <functional>
20#include <iostream>
21#include <optional>
22#include <variant>
23#include <unordered_set>
24
25namespace LMCAS::detail {
27 SymbolicExpr primitive;
28 SymbolicExpr remainder;
29};
30
32 std::string name;
33 SymbolicExpr pattern;
34 SymbolicExpr result;
35 std::unordered_set<std::string> wildcards;
36 std::function<bool(const MatchMap&, const std::string&, ComputationContext&)> condition;
37 int priority = 100;
38
39 IntegrationEntry(std::string name, SymbolicExpr pattern, SymbolicExpr result,
40 std::unordered_set<std::string> wildcards,
41 std::function<bool(const MatchMap&, const std::string&, ComputationContext&)> condition = nullptr,
42 int priority = 100)
43 : name(std::move(name)), pattern(std::move(pattern)), result(std::move(result)),
44 wildcards(std::move(wildcards)), condition(std::move(condition)), priority(priority) {}
45};
46
47std::vector<IntegrationEntry> make_integration_entries();
49 const SymbolicExpr& base, const SymbolicExpr& exponent,
50 const std::string& variable, ComputationContext&);
51SymbolicExpr materialize_integral(const IntegralParts&, const std::string&, RewriteBudget&);
52}
53
54namespace LMCAS {
55
57 const SymbolicExpr& expression,
58 const std::string& variable) {
60}
61
62inline std::shared_ptr<SymbolicExpr> sym_sub(
63 const SymbolicExpr& lhs,
64 const SymbolicExpr& rhs) {
65 auto negated_rhs = SymbolicExpr::multiply(
66 SymbolicExpr::number(-1), detail::make_expression_ptr(rhs));
67 return SymbolicExpr::add(detail::make_expression_ptr(lhs), negated_rhs);
68}
69
70inline std::shared_ptr<SymbolicExpr> sym_rational(
71 const BigInt& numerator, const BigInt& denominator) {
72 return SymbolicExpr::number(Rational(numerator, denominator));
73}
74inline std::optional<int> integration_bounded_exponent(
75 const NumberNode& number, int minimum_exponent, int maximum_exponent) {
76 const auto narrow = [minimum_exponent, maximum_exponent](const BigInt& exponent)
77 -> std::optional<int> {
78 if (exponent < BigInt(minimum_exponent) || exponent > BigInt(maximum_exponent)) {
79 return std::nullopt;
80 }
81 const auto bounded_exponent = exponent.try_to_int64();
82 if (!bounded_exponent) { return std::nullopt; }
83 return static_cast<int>(*bounded_exponent);
84 };
85 const auto& value = number.value();
86 if (const auto* exponent = std::get_if<BigInt>(&value)) { return narrow(*exponent); }
87 if (const auto* exponent = std::get_if<Rational>(&value)) {
88 if (!exponent->is_integer()) { return std::nullopt; }
89 return narrow(exponent->to_bigint());
90 }
91 return std::nullopt;
92}
93
94
95inline std::shared_ptr<SymbolicExpr> make_unary_function(
97 const std::shared_ptr<SymbolicExpr>& operand) {
99 type,
100 std::vector<std::shared_ptr<const SymbolicNode>>{
101 detail::node(operand)}));
102}
103
104inline std::shared_ptr<SymbolicExpr> make_arctan(
105 const std::shared_ptr<SymbolicExpr>& operand) {
107}
108
110 const std::shared_ptr<const SymbolicNode>& node) {
112}
113
114
115template <typename Transform>
116std::shared_ptr<SymbolicExpr> lookup_integral(
117 const std::vector<detail::IntegrationEntry>& table, const SymbolicExpr& matched,
118 const std::string& matched_variable, detail::RewriteBudget& budget, Transform&& transform) {
119 for (const auto& rule : table) {
120 const auto* entry = &rule;
121 budget.consume();
123 if (!Matcher::match(entry->pattern, matched, entry->wildcards, bindings)) { continue; }
124 if (bindings.find("__Add_REST__") != bindings.end() ||
125 bindings.find("__Mul_REST__") != bindings.end()) {
126 continue;
127 }
128 const bool complete = std::all_of(entry->wildcards.begin(), entry->wildcards.end(),
129 [&](const std::string& name) { return bindings.find(name) != bindings.end(); });
130 if (!complete || (entry->condition && !entry->condition(bindings, matched_variable, budget.context()))) {
131 continue;
132 }
133 auto instantiated = detail::make_expression_ptr(
134 Matcher::replace(entry->result, bindings, false));
135 budget.measure(detail::node(instantiated));
136 if (contains_unevaluated_integral(detail::node(instantiated))) {
137 continue;
138 }
139 auto candidate = transform(std::move(instantiated));
140 if (!candidate) { continue; }
142 }
143 return nullptr;
144}
145
146} // namespace LMCAS
AssumptionContext class with scoped push/pop management.
const std::variant< BigInt, Rational > & value() const noexcept
ComputationContext & context() const noexcept
std::size_t measure(const std::shared_ptr< const SymbolicNode > &node)
Symbolic integration APIs.
模式匹配引擎 Matcher 与重写规则系统 RewriteEngine。
多元 Hensel 提升(单变量步)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
bool contains_node_type(const SymbolicNodePtr &root)
SymbolicExpr materialize_integral(const IntegralParts &parts, const std::string &variable, RewriteBudget &budget)
Result< std::optional< SymbolicExpr > > integrate_power_primitive(const SymbolicExpr &base, const SymbolicExpr &exponent, const std::string &variable, ComputationContext &)
bool integration_depends_on_variable(const SymbolicNodePtr &expression, const std::string &variable, RewriteBudget *budget=nullptr)
std::shared_ptr< const Node > make_node(Args &&... args)
std::vector< IntegrationEntry > make_integration_entries()
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
const std::string & variable
std::shared_ptr< SymbolicExpr > lookup_integral(const std::vector< detail::IntegrationEntry > &table, const SymbolicExpr &matched, const std::string &matched_variable, detail::RewriteBudget &budget, Transform &&transform)
bool contains_unevaluated_integral(const std::shared_ptr< const SymbolicNode > &node)
std::shared_ptr< SymbolicExpr > make_arctan(const std::shared_ptr< SymbolicExpr > &operand)
bool depends_on_integration_variable(const SymbolicExpr &expression, const std::string &variable)
std::shared_ptr< SymbolicExpr > sym_rational(const BigInt &numerator, const BigInt &denominator)
const ExprPtr & exponent
const std::vector< Binding > & bindings
std::unordered_map< std::string, SymbolicExpr > MatchMap
匹配结果映射,通配符名称 → 绑定的表达式
const std::string const ExprPtr & value
const ExprPtr & rhs
std::shared_ptr< SymbolicExpr > make_unary_function(FunctionNode::FuncType type, const std::shared_ptr< SymbolicExpr > &operand)
std::shared_ptr< SymbolicExpr > sym_sub(const SymbolicExpr &lhs, const SymbolicExpr &rhs)
std::optional< int > integration_bounded_exponent(const NumberNode &number, int minimum_exponent, int maximum_exponent)
const ExprPtr & denominator
__attribute__((visibility("default"))) Result< EqvProfile > eqv_profile_from_name(const std const std::string & name
多项式转换与精确符号多项式代数。
一元多项式模板类 Polynomial<T>,支持四则运算,GCD,求导,求值.
std::unordered_set< std::string > wildcards
std::function< bool(const MatchMap &, const std::string &, ComputationContext &)> condition
IntegrationEntry(std::string name, SymbolicExpr pattern, SymbolicExpr result, std::unordered_set< std::string > wildcards, std::function< bool(const MatchMap &, const std::string &, ComputationContext &)> condition=nullptr, int priority=100)
内部 AST 定义。