13 if (std::dynamic_pointer_cast<const RelationalNode>(
detail::node(expression))) {
32 if (std::dynamic_pointer_cast<const RootOfNode>(
detail::node(root))) {
37 "complete roots require RootOf representation",
"solve.representation");
46 SymbolicExpr::multiply(SymbolicExpr::number(-1),
53 for (
const auto& existing : conditions) {
56 conditions.push_back(condition);
70 if (!left) {
return left; }
74 auto l = left.value();
90 if (std::holds_alternative<ProvedZeroResidual>(residual.value())) { nonzero =
Tribool::False; }
99 (
context).limits().max_ast_nodes,
"transform");
105 if (!nz) {
return nz; }
118}
catch (
const std::bad_alloc&) {
120}
catch (
const std::length_error& error) {
122}
catch (
const std::exception& error) {
127 auto step =
context.consume_steps(1,
"solve.conditions");
130 if (
auto logic = std::dynamic_pointer_cast<const LogicalNode>(node)) {
133 auto relation = std::dynamic_pointer_cast<const RelationalNode>(node);
147 std::vector<ExprPtr> remaining;
148 for (
const auto& condition : conditions) {
154 conditions = std::move(remaining);
160 (
context).limits().max_ast_nodes,
"transform");
161 for (
auto& condition : conditions) {
170 if (!domain_conditions.value()) {
172 "candidate domain cannot be completely expressed",
"solve.finalize");
174 for (
const auto& condition : *domain_conditions.value()) {
append_condition(conditions, condition); }
176 if (!valid || !valid.value()) {
return valid; }
179 if (!std::holds_alternative<ProvedZeroResidual>(residual.value())) {
182 if (pointwise_nonzero.value() ==
Tribool::True) {
return false; }
190}
catch (
const std::bad_alloc&) {
192}
catch (
const std::length_error& error) {
193 return Result<bool>::failure(CasErrc::ResourceLimit, error.what(),
"finalize_value");
194}
catch (
const std::exception& error) {
195 return Result<bool>::failure(CasErrc::InternalInvariant, error.what(),
"finalize_value");
198 template<
class Solutions>
201 for (
auto& solution : solutions.values) {
207 kept.values.push_back(std::move(solution));
222 if (
auto finite = std::get_if<FiniteSolutions>(&solutions)) {
return filter_values(*finite); }
223 if (
auto parametric = std::get_if<ParametricSolutions>(&solutions)) {
return filter_values(*parametric); }
226 if (!obligations.value()) {
228 "original equation domain cannot be completely expressed",
"solve.finalize");
230 if (
auto conditional = std::get_if<ConditionalSolutions>(&solutions)) {
231 for (
const auto& condition : *obligations.value()) {
239 auto conditions = std::move(*obligations.value());
243 if (conditions.empty()) {
return solutions; }
253 if (std::holds_alternative<EmptySolutions>(solutions)) {
return solutions; }
254 AssumptionContext local_facts =
context.assumptions() ?
255 *
context.assumptions() : AssumptionContext{};
260 if (
const auto* families = std::get_if<ParametricSolutions>(&solutions)) {
261 for (
const auto& family : families->values) {
262 for (
const auto& parameter : family.integer_parameters) {
263 auto declared = local_facts.assume_domain_checked(parameter,
Domain::Integer);
AssumptionContext class with scoped push/pop management.
@ Not
一元逻辑非,right 为 nullptr。
const std::shared_ptr< const SymbolicNode > & right() const noexcept
const std::shared_ptr< const SymbolicNode > & left() const noexcept
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
Result< bool > finalize_value(const ExprPtr &value, std::vector< ExprPtr > &conditions) const
ComputationContext & context
Result< bool > finish_conditions(std::vector< ExprPtr > &conditions) const
const std::string & variable
const SolveOptions & options
SolveResult finish(SolutionSet solutions) const
SolveResult filter_values(Solutions &solutions) const
SolutionFinalizer(const ExprPtr &original, const std::string &variable, const FactsQuery &facts, ComputationContext &context, Domain domain, const SolveOptions &options)
ExprPtr substitute_raw(const ExprPtr &expression, const std::string &variable, const ExprPtr &value)
Result< Tribool > relational_condition_truth(const ExprPtr &expression, const RelationalNode &relation, const FactsQuery &facts, ComputationContext &context)
Tribool negate_truth(Tribool value)
Result< void > apply_root_representation_policy(ExprPtr &root, const SolveOptions &options)
ExprPtr equation_residual(const ExprPtr &expression)
void append_condition(std::vector< ExprPtr > &conditions, const ExprPtr &condition)
ExprPtr equation_predicate(const ExprPtr &expression)
Result< Tribool > logical_condition_truth(const LogicalNode &logic, const FactsQuery &facts, ComputationContext &context)
Result< Tribool > equality_condition_truth(const ExprPtr &difference, Tribool nonzero, RelationOp op, ComputationContext &context)
Result< Tribool > solve_condition_truth(const ExprPtr &expression, const FactsQuery &facts, ComputationContext &context)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
ExprPtr substitute_raw(const ExprPtr &expression, const std::string &variable, const ExprPtr &value)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
SolveResult finalize_solution_set(const ExprPtr &original, const std::string &variable, SolutionSet solutions, ComputationContext &context, Domain domain, const SolveOptions &options)
Result< Tribool > query_nonzero_value(const Node &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
const std::string & variable
bool contains_node_type(const SymbolicNodePtr &root)
RewriteBudget const FactsQuery Domain domain
Result< Tribool > query_definedness(const Node &node, const FactsQuery &facts, Domain domain, ComputationContext &context, bool *violated_real_restriction)
ExprPtr equation_predicate(const ExprPtr &expression)
std::shared_ptr< const Node > make_node(Args &&... args)
Result< std::optional< std::vector< std::shared_ptr< SymbolicExpr > > > > domain_constraints(const Node &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
Result< Tribool > query_nonnegative_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
std::size_t std::size_t ComputationContext & context
Result< Tribool > query_positive_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
std::shared_ptr< SymbolicExpr > rootof_simplify(const std::shared_ptr< SymbolicExpr > &rootof_expr)
__attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std std::shared_ptr< SymbolicExpr > r
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
Result< SolutionSet > SolveResult
Domain
Mathematical domain hierarchy (least specific → most specific). Complex ⊃ Real ⊃ Algebraic ⊃ Rational...
@ Complex
Complex numbers (default, least specific)
const std::string ComputationContext const SolveOptions & options
Tribool
Tri-state logic value for property queries.
@ Unknown
Property cannot be determined
@ True
Property definitely holds
@ False
Property definitely does not hold
RelationOp
Stable relational operator used by public APIs.
const ExprPtr RelationOp op
std::shared_ptr< SymbolicExpr > ExprPtr
ResidualCheckResult check_zero_residual(const ExprPtr &residual, ComputationContext &context, const LMCAS::EqvOptions &options)
ExprResult relation(const ExprPtr &lhs, const ExprPtr &rhs, RelationOp op)
std::variant< EmptySolutions, UniversalSolutions, FiniteSolutions, IntervalSolutions, ConditionalSolutions, ParametricSolutions > SolutionSet
成功的 SolveResult 表示操作定义域内的完整解集。 完备性未决时返回外层 Inconclusive 错误;EmptySolutions 表示已证明的空解集。
const std::string const ExprPtr & value
detail::SymbolicNodePtr substitute_free(const detail::SymbolicNodePtr &expression, const std::string &variable, const detail::SymbolicNodePtr &replacement, detail::RewriteBudget *budget)