LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
LMCAS::anonymous_namespace{solve_transcendental.cpp} 命名空间参考

函数

void append_finite_union (FiniteSolutions &finite, FiniteSolutions &prior)
void append_parametric_union (FiniteSolutions *finite, ParametricSolutions *families, FiniteSolutions *prior, SolutionSet &output)
void append_solutions (SolutionSet solved, SolutionSet &output, const ExprPtr &original, const std::string &var)
Result< void > coalesce_periodic_families (SolutionSet &solutions, ComputationContext &context)
Result< bool > coalesce_periodic_pair (ParametricSolution &left, const ParametricSolution &right, ComputationContext &context)
bool compatible_periodic_conditions (const ParametricSolution &left, const ParametricSolution &right)
SolveResult inconclusive (const char *message)
Result< std::optional< ExprPtr > > merged_half_period_value (const detail::AffineForm &first, const detail::AffineForm &second, const std::string &parameter, ComputationContext &context)
SolveResult solve_function_pattern (const InversePattern &pattern, const ExprPtr &original, const std::string &var, ComputationContext &context, const SolveOptions &options, int depth)
SolveResult solve_inner_equation (const ExprPtr &original, const ExprPtr &inner, const ExprPtr &value, const std::string &var, ComputationContext &context, const SolveOptions &options, int depth)
SolveResult solve_inverted_values (const ExprPtr &original, const ExprPtr &inner, const std::vector< ExprPtr > &values, const std::string &var, ComputationContext &context, const SolveOptions &options, int depth)
SolveResult solve_substitution (const ExprPtr &original, const SubstitutionResult &substitution, const std::string &var, ComputationContext &context, const SolveOptions &options, int depth)
SolveResult solve_transcendental_constant (const ExprPtr &original, const ExprPtr &expr, const std::string &var, ComputationContext &context)
SolveResult solve_transcendental_impl (const ExprPtr &original, const ExprPtr &expr, const std::string &var, ComputationContext &context, const SolveOptions &options, int depth)
Result< bool > zero_difference (const ExprPtr &left, const ExprPtr &right, ComputationContext &context)

变量

constexpr int maximum_transcendental_depth = 5

函数说明

◆ append_finite_union()

void LMCAS::anonymous_namespace{solve_transcendental.cpp}::append_finite_union ( FiniteSolutions & finite,
FiniteSolutions & prior )

在文件 solve_transcendental.cpp 第 74 行定义.

74 {
75 for (auto& candidate : finite.values) {
76 auto duplicate = std::find_if(prior.values.begin(), prior.values.end(),
77 [&](const FiniteSolution& previous) {
78 return candidate.conditions.empty() && previous.conditions.empty() &&
79 detail::node(candidate.value)->equals(*detail::node(previous.value));
80 });
81 if (duplicate == prior.values.end()) { prior.values.push_back(std::move(candidate)); }
82 }
83}
std::vector< FiniteSolution > values
conditions 是在操作上下文假设下须同时满足的条件。 空条件保留原表达式定义域且不增加约束;整数参数遍历全体整数。

引用了 append_finite_union() , 以及 LMCAS::FiniteSolutions::values.

被这些函数引用 append_finite_union() , 以及 append_solutions().

函数调用图:
这是这个函数的调用关系图:

◆ append_parametric_union()

void LMCAS::anonymous_namespace{solve_transcendental.cpp}::append_parametric_union ( FiniteSolutions * finite,
ParametricSolutions * families,
FiniteSolutions * prior,
SolutionSet & output )

在文件 solve_transcendental.cpp 第 85 行定义.

86 {
87 if (prior) {
88 ParametricSolutions promoted;
89 for (auto& point : prior->values) {
90 promoted.values.push_back({std::move(point.value), {}, std::move(point.conditions)});
91 }
92 output = std::move(promoted);
93 }
94 auto& result = std::get<ParametricSolutions>(output).values;
95 if (finite) {
96 for (auto& point : finite->values) {
97 result.push_back({std::move(point.value), {}, std::move(point.conditions)});
98 }
99 } else {
100 for (auto& family : families->values) { result.push_back(std::move(family)); }
101 }
102}
const std::string const LimitExprPtr & point
std::vector< ParametricSolution > values

引用了 append_parametric_union(), LMCAS::point, LMCAS::FiniteSolutions::values , 以及 LMCAS::ParametricSolutions::values.

被这些函数引用 append_parametric_union() , 以及 append_solutions().

函数调用图:
这是这个函数的调用关系图:

◆ append_solutions()

void LMCAS::anonymous_namespace{solve_transcendental.cpp}::append_solutions ( SolutionSet solved,
SolutionSet & output,
const ExprPtr & original,
const std::string & var )

在文件 solve_transcendental.cpp 第 103 行定义.

104 {
105 if (std::holds_alternative<EmptySolutions>(solved) ||
106 std::holds_alternative<UniversalSolutions>(output)) { return; }
107 if (std::holds_alternative<EmptySolutions>(output) ||
108 std::holds_alternative<UniversalSolutions>(solved)) {
109 output = std::move(solved);
110 return;
111 }
112 auto* finite = std::get_if<FiniteSolutions>(&solved);
113 auto* prior = std::get_if<FiniteSolutions>(&output);
114 if (finite && prior) {
115 append_finite_union(*finite, *prior);
116 return;
117 }
118 auto* families = std::get_if<ParametricSolutions>(&solved);
119 if ((finite || families) && (prior || std::holds_alternative<ParametricSolutions>(output))) {
120 append_parametric_union(finite, families, prior, output);
121 return;
122 }
123 output = conditional_preimage(original, var);
124}
void append_parametric_union(FiniteSolutions *finite, ParametricSolutions *families, FiniteSolutions *prior, SolutionSet &output)
void append_finite_union(FiniteSolutions &finite, FiniteSolutions &prior)
SolutionSet conditional_preimage(const ExprPtr &original, const std::string &var)

引用了 append_finite_union(), append_parametric_union(), append_solutions() , 以及 LMCAS::detail::transcendental::conditional_preimage().

被这些函数引用 append_solutions(), solve_function_pattern(), solve_inverted_values() , 以及 solve_substitution().

函数调用图:
这是这个函数的调用关系图:

◆ coalesce_periodic_families()

Result< void > LMCAS::anonymous_namespace{solve_transcendental.cpp}::coalesce_periodic_families ( SolutionSet & solutions,
ComputationContext & context )

在文件 solve_transcendental.cpp 第 199 行定义.

199 {
200 auto* parametric = std::get_if<ParametricSolutions>(&solutions);
201 if (!parametric) { return Result<void>::success(); }
202 auto& families = parametric->values;
203 for (std::size_t i = 0; i < families.size(); ++i) {
204 if (families[i].integer_parameters.size() != 1) { continue; }
205 for (std::size_t j = i + 1; j < families.size();) {
206 auto merged = coalesce_periodic_pair(families[i], families[j], context);
207 if (!merged) { return Result<void>::failure(merged.error()); }
208 if (!merged.value()) { ++j; continue; }
209 families.erase(families.begin() + j);
210 j = i + 1;
211 }
212 }
213 return Result<void>::success();
214}
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
Result< bool > coalesce_periodic_pair(ParametricSolution &left, const ParametricSolution &right, ComputationContext &context)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context

引用了 coalesce_periodic_families(), coalesce_periodic_pair(), LMCAS::context, LMCAS::Result< T >::failure() , 以及 LMCAS::Result< T >::success().

被这些函数引用 coalesce_periodic_families().

函数调用图:
这是这个函数的调用关系图:

◆ coalesce_periodic_pair()

Result< bool > LMCAS::anonymous_namespace{solve_transcendental.cpp}::coalesce_periodic_pair ( ParametricSolution & left,
const ParametricSolution & right,
ComputationContext & context )

在文件 solve_transcendental.cpp 第 174 行定义.

175 {
176 if (!compatible_periodic_conditions(left, right)) { return false; }
177 auto first = detail::recognize_affine(*left.value, left.integer_parameters.front(), context);
178 if (!first) { return Result<bool>::failure(first.error()); }
179 auto second = detail::recognize_affine(*right.value, right.integer_parameters.front(), context);
180 if (!second) { return Result<bool>::failure(second.error()); }
181 if (!first.value() || !second.value()) { return false; }
182 for (auto* coefficient : {&first.value()->slope, &first.value()->offset,
183 &second.value()->slope, &second.value()->offset}) {
184 auto normalized = detail::simplify_expression(*coefficient, context);
185 if (!normalized) { return Result<bool>::failure(normalized.error()); }
186 *coefficient = std::move(normalized.value());
187 }
188 auto equal_slopes = zero_difference(first.value()->slope, second.value()->slope, context);
189 if (!equal_slopes) { return Result<bool>::failure(equal_slopes.error()); }
190 if (!equal_slopes.value()) { return false; }
191 auto merged = merged_half_period_value(
192 *first.value(), *second.value(), left.integer_parameters.front(), context);
193 if (!merged) { return Result<bool>::failure(merged.error()); }
194 if (!merged.value()) { return false; }
195 left.value = std::move(*merged.value());
196 return true;
197}
bool compatible_periodic_conditions(const ParametricSolution &left, const ParametricSolution &right)
Result< std::optional< ExprPtr > > merged_half_period_value(const detail::AffineForm &first, const detail::AffineForm &second, const std::string &parameter, ComputationContext &context)
Result< bool > zero_difference(const ExprPtr &left, const ExprPtr &right, ComputationContext &context)
ExpressionResult simplify_expression(const ExprPtr &expression, ComputationContext &context)
Result< std::optional< AffineForm > > recognize_affine(const SymbolicExpr &expression, const std::string &variable, ComputationContext &context)
std::vector< std::string > integer_parameters
const ExprPtr & right

引用了 coalesce_periodic_pair(), compatible_periodic_conditions(), LMCAS::context, LMCAS::Result< T >::failure(), LMCAS::ParametricSolution::integer_parameters, merged_half_period_value(), LMCAS::detail::recognize_affine(), LMCAS::right, LMCAS::detail::simplify_expression(), LMCAS::ParametricSolution::value , 以及 zero_difference().

被这些函数引用 coalesce_periodic_families() , 以及 coalesce_periodic_pair().

函数调用图:
这是这个函数的调用关系图:

◆ compatible_periodic_conditions()

bool LMCAS::anonymous_namespace{solve_transcendental.cpp}::compatible_periodic_conditions ( const ParametricSolution & left,
const ParametricSolution & right )

在文件 solve_transcendental.cpp 第 135 行定义.

135 {
136 if (right.integer_parameters.size() != 1 || left.conditions.size() != right.conditions.size()) {
137 return false;
138 }
139 for (std::size_t c = 0; c < left.conditions.size(); ++c) {
141 left.integer_parameters.front()) ||
143 right.integer_parameters.front()) ||
144 !detail::node(left.conditions[c])->equals(*detail::node(right.conditions[c]))) {
145 return false;
146 }
147 }
148 return true;
149}
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
const VectorField const VectorField & c
bool expression_depends_on_variable(const detail::SymbolicNodePtr &expression, const std::string &variable, detail::RewriteBudget *budget)

引用了 LMCAS::c, compatible_periodic_conditions(), LMCAS::ParametricSolution::conditions, LMCAS::expression_depends_on_variable(), LMCAS::ParametricSolution::integer_parameters, LMCAS::detail::node() , 以及 LMCAS::right.

被这些函数引用 coalesce_periodic_pair() , 以及 compatible_periodic_conditions().

函数调用图:
这是这个函数的调用关系图:

◆ inconclusive()

SolveResult LMCAS::anonymous_namespace{solve_transcendental.cpp}::inconclusive ( const char * message)

在文件 solve_transcendental.cpp 第 20 行定义.

20 {
21 return SolveResult::failure(CasErrc::Inconclusive, message, "solve.transcendental");
22}

引用了 LMCAS::Result< SolutionSet >::failure(), LMCAS::Inconclusive , 以及 inconclusive().

被这些函数引用 inconclusive(), solve_inverted_values(), solve_substitution() , 以及 solve_transcendental_impl().

函数调用图:
这是这个函数的调用关系图:

◆ merged_half_period_value()

Result< std::optional< ExprPtr > > LMCAS::anonymous_namespace{solve_transcendental.cpp}::merged_half_period_value ( const detail::AffineForm & first,
const detail::AffineForm & second,
const std::string & parameter,
ComputationContext & context )

在文件 solve_transcendental.cpp 第 151 行定义.

152 {
153 using MergeResult = Result<std::optional<ExprPtr>>;
154 auto half = detail::simplify_expression(SymbolicExpr::multiply(
155 SymbolicExpr::number(Rational(1, 2)), first.slope), context);
156 if (!half) { return MergeResult::failure(half.error()); }
157 const auto& half_period = half.value();
158 auto next_offset = SymbolicExpr::add(first.offset, half_period);
159 auto prior_offset = SymbolicExpr::add(second.offset, half_period);
160 ExprPtr offset;
161 auto forward = zero_difference(next_offset, second.offset, context);
162 if (!forward) { return MergeResult::failure(forward.error()); }
163 auto backward = zero_difference(prior_offset, first.offset, context);
164 if (!backward) { return MergeResult::failure(backward.error()); }
165 if (forward.value()) { offset = second.offset; }
166 else if (backward.value()) { offset = first.offset; }
167 else { return std::optional<ExprPtr>{}; }
168 auto merged = detail::simplify_expression(SymbolicExpr::add(offset,
169 SymbolicExpr::multiply(half_period, SymbolicExpr::variable(parameter))), context);
170 if (!merged) { return MergeResult::failure(merged.error()); }
171 return std::optional<ExprPtr>{std::move(merged.value())};
172}
std::shared_ptr< SymbolicExpr > slope
std::shared_ptr< SymbolicExpr > offset
std::shared_ptr< SymbolicExpr > ExprPtr

引用了 LMCAS::context, merged_half_period_value(), LMCAS::detail::AffineForm::offset, LMCAS::detail::simplify_expression(), LMCAS::detail::AffineForm::slope , 以及 zero_difference().

被这些函数引用 coalesce_periodic_pair() , 以及 merged_half_period_value().

函数调用图:
这是这个函数的调用关系图:

◆ solve_function_pattern()

SolveResult LMCAS::anonymous_namespace{solve_transcendental.cpp}::solve_function_pattern ( const InversePattern & pattern,
const ExprPtr & original,
const std::string & var,
ComputationContext & context,
const SolveOptions & options,
int depth )

在文件 solve_transcendental.cpp 第 280 行定义.

281 {
282 auto inverted = invert_function(pattern, original, var, context, options);
283 if (!inverted) { return inverted; }
284 auto finite = std::get_if<FiniteSolutions>(&inverted.value());
285 if (!finite) { return inverted; }
286 SolutionSet results = EmptySolutions{};
287 for (const auto& value : finite->values) {
288 if (!value.conditions.empty()) { return conditional_preimage(original, var); }
289 auto solved = solve_inner_equation(original, pattern.inner, value.value,
290 var, context, options, depth);
291 if (!solved) { return solved; }
292 append_solutions(std::move(solved).value(), results, original, var);
293 }
294 return results;
295}
SolveResult solve_inner_equation(const ExprPtr &original, const ExprPtr &inner, const ExprPtr &value, const std::string &var, ComputationContext &context, const SolveOptions &options, int depth)
void append_solutions(SolutionSet solved, SolutionSet &output, const ExprPtr &original, const std::string &var)
SolveResult invert_function(const InversePattern &pattern, const ExprPtr &original, const std::string &var, ComputationContext &context, const SolveOptions &options)
const std::string ComputationContext const SolveOptions & options
std::size_t std::size_t depth
std::variant< EmptySolutions, UniversalSolutions, FiniteSolutions, IntervalSolutions, ConditionalSolutions, ParametricSolutions > SolutionSet
成功的 SolveResult 表示操作定义域内的完整解集。 完备性未决时返回外层 Inconclusive 错误;EmptySolutions 表示已证明的空解集。
const std::string const ExprPtr & value

引用了 append_solutions(), LMCAS::detail::transcendental::conditional_preimage(), LMCAS::context, LMCAS::depth, LMCAS::detail::transcendental::InversePattern::inner, LMCAS::detail::transcendental::invert_function(), LMCAS::options, solve_function_pattern(), solve_inner_equation() , 以及 LMCAS::value.

被这些函数引用 solve_function_pattern() , 以及 solve_transcendental_impl().

函数调用图:
这是这个函数的调用关系图:

◆ solve_inner_equation()

SolveResult LMCAS::anonymous_namespace{solve_transcendental.cpp}::solve_inner_equation ( const ExprPtr & original,
const ExprPtr & inner,
const ExprPtr & value,
const std::string & var,
ComputationContext & context,
const SolveOptions & options,
int depth )

在文件 solve_transcendental.cpp 第 28 行定义.

31 {
32 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
33 (context).limits().max_ast_nodes, "transform");
34 auto variable = std::dynamic_pointer_cast<const VariableNode>(detail::node(inner));
35 if (variable && !variable->is_constant() && variable->name() == var) {
37 }
38 const auto product =
39 std::dynamic_pointer_cast<const MultiplyNode>(detail::node(inner));
40 if (product && product->operands().size() == 2) {
41 const auto& first = product->operands()[0];
42 const auto& second = product->operands()[1];
43 const auto coefficient =
44 std::dynamic_pointer_cast<const NumberNode>(first);
45 const auto product_variable =
46 std::dynamic_pointer_cast<const VariableNode>(second);
47 if (coefficient && coefficient->is_negative_one() &&
48 product_variable && !product_variable->is_constant() &&
49 product_variable->name() == var) {
50 auto inverted = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::multiply(
51 SymbolicExpr::number(-1), value)), transform_budget));
52 return SolutionSet{FiniteSolutions{{
53 FiniteSolution{std::move(inverted), 1, {}}}}};
54 }
55 }
56 auto equation = SymbolicExpr::add(inner,
57 SymbolicExpr::multiply(value, SymbolicExpr::number(-1)));
58 auto polynomial = symbolic_to_poly<SymbolicPolyCoeff>(equation, var);
59 if (polynomial) return solve_equation(equation, var, context, options);
60 if (polynomial.error().code != CasErrc::UnsupportedExpression) {
61 return SolveResult::failure(polynomial.error());
62 }
63 return solve_transcendental_impl(original, equation, var, context, options, depth + 1);
64} catch (const CasError& error) {
65 return SolveResult::failure(error);
66} catch (const std::bad_alloc&) {
67 return SolveResult::failure(CasErrc::ResourceLimit, "allocation failed", "solve_inner_equation");
68} catch (const std::length_error& error) {
69 return SolveResult::failure(CasErrc::ResourceLimit, error.what(), "solve_inner_equation");
70} catch (const std::exception& error) {
71 return SolveResult::failure(CasErrc::InternalInvariant, error.what(), "solve_inner_equation");
72}
SolveResult solve_transcendental_impl(const ExprPtr &original, const ExprPtr &expr, const std::string &var, ComputationContext &context, const SolveOptions &options, int depth)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
const std::string & variable
LMCAS::SolveResult solve_equation(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, ComputationContext &context, const SolveOptions &opts)

引用了 LMCAS::context, LMCAS::depth, LMCAS::Result< SolutionSet >::failure(), LMCAS::detail::make_expression_ptr(), LMCAS::detail::node(), LMCAS::detail::normalize_node(), LMCAS::options, LMCAS::solve_equation(), solve_inner_equation(), solve_transcendental_impl(), LMCAS::UnsupportedExpression, LMCAS::value , 以及 LMCAS::variable.

被这些函数引用 solve_function_pattern(), solve_inner_equation(), solve_inverted_values() , 以及 solve_substitution().

函数调用图:
这是这个函数的调用关系图:

◆ solve_inverted_values()

SolveResult LMCAS::anonymous_namespace{solve_transcendental.cpp}::solve_inverted_values ( const ExprPtr & original,
const ExprPtr & inner,
const std::vector< ExprPtr > & values,
const std::string & var,
ComputationContext & context,
const SolveOptions & options,
int depth )

在文件 solve_transcendental.cpp 第 216 行定义.

219 {
220 if (values.empty()) return inconclusive("Inverse did not establish a complete value set");
221 SolutionSet results = EmptySolutions{};
222 for (const auto& value : values) {
223 auto solved = solve_inner_equation(original, inner, value, var, context, options, depth);
224 if (!solved) return solved;
225 append_solutions(std::move(solved).value(), results, original, var);
226 }
227 return results;
228}

引用了 append_solutions(), LMCAS::context, LMCAS::depth, inconclusive(), LMCAS::options, solve_inner_equation(), solve_inverted_values() , 以及 LMCAS::value.

被这些函数引用 solve_inverted_values() , 以及 solve_transcendental_impl().

函数调用图:
这是这个函数的调用关系图:

◆ solve_substitution()

SolveResult LMCAS::anonymous_namespace{solve_transcendental.cpp}::solve_substitution ( const ExprPtr & original,
const SubstitutionResult & substitution,
const std::string & var,
ComputationContext & context,
const SolveOptions & options,
int depth )

在文件 solve_transcendental.cpp 第 230 行定义.

232 {
233 auto polynomial = symbolic_to_poly<SymbolicPolyCoeff>(
234 substitution.poly_in_u, substitution.u_var);
235 if (!polynomial) {
236 if (polynomial.error().code == CasErrc::UnsupportedExpression) {
237 return inconclusive("Substitution is not a supported polynomial");
238 }
239 return SolveResult::failure(polynomial.error());
240 }
241 auto solved = solve_equation(substitution.poly_in_u, substitution.u_var, context, options);
242 if (!solved) return solved;
243 if (std::holds_alternative<EmptySolutions>(solved.value())) return solved;
244 auto finite = std::get_if<FiniteSolutions>(&solved.value());
245 if (!finite) return conditional_preimage(original, var);
246 SolutionSet results = EmptySolutions{};
247 for (const auto& value : finite->values) {
248 if (!value.conditions.empty()) return conditional_preimage(original, var);
249 auto inverted = solve_inner_equation(
250 original, substitution.u_expr, value.value, var, context, options, depth);
251 if (!inverted) return inverted;
252 append_solutions(std::move(inverted).value(), results, original, var);
253 }
254 return results;
255}
std::shared_ptr< SymbolicExpr > u_expr
换元表达式(u = f(x) 中的 f(x))
std::shared_ptr< SymbolicExpr > poly_in_u
换元后关于 u 的多项式

引用了 append_solutions(), LMCAS::detail::transcendental::conditional_preimage(), LMCAS::context, LMCAS::depth, LMCAS::Result< SolutionSet >::failure(), inconclusive(), LMCAS::options, LMCAS::SubstitutionResult::poly_in_u, LMCAS::solve_equation(), solve_inner_equation(), solve_substitution(), LMCAS::SubstitutionResult::u_expr, LMCAS::SubstitutionResult::u_var, LMCAS::UnsupportedExpression , 以及 LMCAS::value.

被这些函数引用 solve_substitution() , 以及 solve_transcendental_impl().

函数调用图:
这是这个函数的调用关系图:

◆ solve_transcendental_constant()

SolveResult LMCAS::anonymous_namespace{solve_transcendental.cpp}::solve_transcendental_constant ( const ExprPtr & original,
const ExprPtr & expr,
const std::string & var,
ComputationContext & context )

在文件 solve_transcendental.cpp 第 257 行定义.

258 {
259 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
260 (context).limits().max_ast_nodes, "transform");
261 std::optional<detail::AssumptionFacts> assumptions;
262 if (context.assumptions()) { assumptions.emplace(*context.assumptions()); }
263 const LMCAS::FactsQuery& facts = assumptions ?
264 static_cast<const LMCAS::FactsQuery&>(*assumptions) : detail::no_facts();
265 auto nonzero = detail::query_nonzero_value(detail::normalize_node(detail::node(expr), transform_budget), facts, Domain::Real, context);
266 if (!nonzero) { return SolveResult::failure(nonzero.error()); }
267 if (nonzero.value() == Tribool::True) { return SolutionSet{EmptySolutions{}}; }
268 if (nonzero.value() == Tribool::False) { return SolutionSet{UniversalSolutions{}}; }
269 return conditional_preimage(original, var);
270} catch (const CasError& error) {
271 return SolveResult::failure(error);
272} catch (const std::bad_alloc&) {
273 return SolveResult::failure(CasErrc::ResourceLimit, "allocation failed", "solve_transcendental_constant");
274} catch (const std::length_error& error) {
275 return SolveResult::failure(CasErrc::ResourceLimit, error.what(), "solve_transcendental_constant");
276} catch (const std::exception& error) {
277 return SolveResult::failure(CasErrc::InternalInvariant, error.what(), "solve_transcendental_constant");
278}
Result< Tribool > query_nonzero_value(const Node &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
const FactsQuery & no_facts() noexcept
@ Real
Real numbers
@ True
Property definitely holds
@ False
Property definitely does not hold

引用了 LMCAS::detail::transcendental::conditional_preimage(), LMCAS::context, LMCAS::Result< SolutionSet >::failure(), LMCAS::False, LMCAS::detail::no_facts(), LMCAS::detail::node(), LMCAS::detail::normalize_node(), LMCAS::detail::query_nonzero_value(), LMCAS::Real, solve_transcendental_constant() , 以及 LMCAS::True.

被这些函数引用 solve_transcendental_constant() , 以及 solve_transcendental_impl().

函数调用图:
这是这个函数的调用关系图:

◆ solve_transcendental_impl()

SolveResult LMCAS::anonymous_namespace{solve_transcendental.cpp}::solve_transcendental_impl ( const ExprPtr & original,
const ExprPtr & expr,
const std::string & var,
ComputationContext & context,
const SolveOptions & options,
int depth )

在文件 solve_transcendental.cpp 第 297 行定义.

299 {
300 auto step = context.consume_steps(1, "solve.transcendental");
301 if (!step) { return SolveResult::failure(step.error()); }
302 if (depth > maximum_transcendental_depth) { return inconclusive("Transcendental inversion depth exceeded"); }
304 return solve_transcendental_constant(original, expr, var, context);
305 }
306 if (auto pattern = decompose_lambert_w_pattern(expr, var, context)) {
307 return solve_inverted_values(original, pattern->inner, invert_lambert_w(pattern->rhs, context),
308 var, context, options, depth);
309 }
310 if (auto pattern = decompose_exp_base_pattern(expr, var, context)) {
311 return solve_inverted_values(original, pattern->inner,
312 invert_exp_base(pattern->base, pattern->rhs, context), var, context, options, depth);
313 }
314 if (auto pattern = decompose_trig_exp_pattern(expr, var)) {
315 return solve_function_pattern(*pattern, original, var, context, options, depth);
316 }
317 auto substitution = detect_substitution(expr, var);
318 if (!substitution) {
319 return SolveResult::failure(substitution.error());
320 }
321 if (substitution.value()) {
322 return solve_substitution(original, *substitution.value(), var, context, options, depth);
323 }
324 return inconclusive("No complete transcendental inversion matched");
325}
SolveResult solve_function_pattern(const InversePattern &pattern, const ExprPtr &original, const std::string &var, ComputationContext &context, const SolveOptions &options, int depth)
SolveResult solve_inverted_values(const ExprPtr &original, const ExprPtr &inner, const std::vector< ExprPtr > &values, const std::string &var, ComputationContext &context, const SolveOptions &options, int depth)
SolveResult solve_transcendental_constant(const ExprPtr &original, const ExprPtr &expr, const std::string &var, ComputationContext &context)
SolveResult solve_substitution(const ExprPtr &original, const SubstitutionResult &substitution, const std::string &var, ComputationContext &context, const SolveOptions &options, int depth)
std::optional< LambertWPattern > decompose_lambert_w_pattern(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, ComputationContext &context)
std::optional< ExpBasePattern > decompose_exp_base_pattern(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, ComputationContext &context)
std::vector< std::shared_ptr< SymbolicExpr > > invert_lambert_w(const std::shared_ptr< SymbolicExpr > &c, ComputationContext &context)
std::optional< InversePattern > decompose_trig_exp_pattern(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var)
std::vector< std::shared_ptr< SymbolicExpr > > invert_exp_base(const std::shared_ptr< SymbolicExpr > &base, const std::shared_ptr< SymbolicExpr > &c, ComputationContext &context)
Result< std::optional< SubstitutionResult > > detect_substitution(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var)

引用了 LMCAS::context, LMCAS::detail::transcendental::decompose_exp_base_pattern(), LMCAS::detail::transcendental::decompose_lambert_w_pattern(), LMCAS::detail::transcendental::decompose_trig_exp_pattern(), LMCAS::depth, LMCAS::detect_substitution(), LMCAS::expression_depends_on_variable(), LMCAS::Result< SolutionSet >::failure(), inconclusive(), LMCAS::detail::transcendental::invert_exp_base(), LMCAS::detail::transcendental::invert_lambert_w(), maximum_transcendental_depth, LMCAS::detail::node(), LMCAS::options, solve_function_pattern(), solve_inverted_values(), solve_substitution(), solve_transcendental_constant() , 以及 solve_transcendental_impl().

被这些函数引用 solve_inner_equation() , 以及 solve_transcendental_impl().

函数调用图:
这是这个函数的调用关系图:

◆ zero_difference()

Result< bool > LMCAS::anonymous_namespace{solve_transcendental.cpp}::zero_difference ( const ExprPtr & left,
const ExprPtr & right,
ComputationContext & context )

在文件 solve_transcendental.cpp 第 126 行定义.

126 {
127 auto difference = detail::simplify_expression(SymbolicExpr::add(left,
128 SymbolicExpr::multiply(SymbolicExpr::number(-1), right)), context);
129 if (!difference) { return Result<bool>::failure(difference.error()); }
130 auto proof = check_zero_residual(difference.value(), context);
131 if (!proof) { return Result<bool>::failure(proof.error()); }
132 return std::holds_alternative<ProvedZeroResidual>(proof.value());
133}
ResidualCheckResult check_zero_residual(const ExprPtr &residual, ComputationContext &context, const LMCAS::EqvOptions &options)

引用了 LMCAS::check_zero_residual(), LMCAS::context, LMCAS::Result< T >::failure(), LMCAS::right, LMCAS::detail::simplify_expression() , 以及 zero_difference().

被这些函数引用 coalesce_periodic_pair(), merged_half_period_value() , 以及 zero_difference().

函数调用图:
这是这个函数的调用关系图:

变量说明

◆ maximum_transcendental_depth

int LMCAS::anonymous_namespace{solve_transcendental.cpp}::maximum_transcendental_depth = 5
constexpr

在文件 solve_transcendental.cpp 第 18 行定义.

被这些函数引用 solve_transcendental_impl().