LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
integration_basic_strategies.cpp
浏览该文件的文档.
1#include <stdexcept>
5
6namespace LMCAS {
7
9 const SymbolicExpr& base, const SymbolicExpr& exponent,
10 const std::string& variable, ComputationContext& context) {
12 return std::optional<SymbolicExpr>{};
13 }
14 RewriteBudget budget(context, context.limits().max_recursion_depth,
15 context.limits().max_ast_nodes, "integrate.power");
16 auto exact = exact_rational_value(node(exponent));
17 if (exact && *exact == Rational(-1)) {
18 return std::optional<SymbolicExpr>{*SymbolicExpr::ln(make_expression_ptr(base))};
19 }
20 auto next = exact ? SymbolicExpr::number(*exact + Rational(1)) :
21 make_expression_ptr(normalize_node(node(SymbolicExpr::add(
22 make_expression_ptr(exponent), SymbolicExpr::number(1))), budget));
23 if (!exact) {
24 std::optional<AssumptionFacts> facts;
25 if (context.assumptions()) { facts.emplace(*context.assumptions()); }
26 auto nonzero = query_nonzero_value(node(next),
27 facts ? static_cast<const FactsQuery&>(*facts) : no_facts(), Domain::Real, context);
28 if (!nonzero) {
29 return Result<std::optional<SymbolicExpr>>::failure(nonzero.error());
30 }
31 if (nonzero.value() != Tribool::True) { return std::optional<SymbolicExpr>{}; }
32 }
33 return std::optional<SymbolicExpr>{*SymbolicExpr::divide(
34 SymbolicExpr::power(make_expression_ptr(base), next), next)};
35}
36
37Result<std::optional<detail::IntegralParts>> Integrator::try_table_lookup(
38 const SymbolicExpr& expr, const std::string& var,
39 ComputationContext& computation, int) {
40 detail::RewriteBudget budget(computation, computation.limits().max_recursion_depth,
41 computation.limits().max_ast_nodes, "transform");
42 auto primitive = lookup_integral(entries_, expr, var, budget,
43 [](std::shared_ptr<SymbolicExpr> candidate) { return candidate; });
44 if (!primitive) { return std::optional<detail::IntegralParts>{}; }
45 return std::optional<detail::IntegralParts>{{*primitive, zero_}};
46}
47
48Result<std::optional<detail::IntegralParts>> Integrator::try_power_rule(
49 const SymbolicExpr& expr, const std::string& var,
51 if (auto variable = std::dynamic_pointer_cast<const VariableNode>(detail::node(expr))) {
52 if (!variable->is_constant() && variable->name() == var) {
53 return std::optional<detail::IntegralParts>{{*SymbolicExpr::multiply(
54 SymbolicExpr::power(detail::make_expression_ptr(expr), SymbolicExpr::number(2)),
55 sym_rational(1, 2)), zero_}};
56 }
57 }
58 auto power = std::dynamic_pointer_cast<const PowerNode>(detail::node(expr));
59 if (!power) { return std::optional<detail::IntegralParts>{}; }
60 auto variable = std::dynamic_pointer_cast<const VariableNode>(power->base());
61 if (!variable || variable->is_constant() || variable->name() != var) {
62 return std::optional<detail::IntegralParts>{};
63 }
65 detail::expression_from_node(power->exponent()), var, context);
66 if (!primitive) {
67 return Result<std::optional<detail::IntegralParts>>::failure(primitive.error());
68 }
69 if (!primitive.value()) { return std::optional<detail::IntegralParts>{}; }
70 return std::optional<detail::IntegralParts>{{std::move(*primitive.value()), zero_}};
71}
72
73}
const ResourceLimits & limits() const noexcept
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
Result< Tribool > query_nonzero_value(const Node &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
const std::string & variable
const FactsQuery & no_facts() noexcept
inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
RewriteBudget const FactsQuery & facts
Result< std::optional< SymbolicExpr > > integrate_power_primitive(const SymbolicExpr &base, const SymbolicExpr &exponent, const std::string &variable, ComputationContext &)
std::optional< Rational > exact_rational_value(const NumberNode &number)
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
std::size_t std::size_t ComputationContext & context
const std::string & variable
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
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)
@ Real
Real numbers
@ True
Property definitely holds
std::size_t max_recursion_depth
Simultaneous checked depth.
bool depends_on_integration_variable(const SymbolicExpr &expression, const std::string &variable)
std::size_t max_ast_nodes
Reference-expanded nodes per AST or output forest.
std::shared_ptr< SymbolicExpr > sym_rational(const BigInt &numerator, const BigInt &denominator)
const ExprPtr & exponent