19 std::optional<detail::AssumptionFacts> assumptions;
20 if (
context.assumptions()) { assumptions.emplace(*
context.assumptions()); }
28 return std::holds_alternative<ProvedZeroResidual>(residual.value()) ?
35 return {std::move(solution)};
42 (
context).limits().max_ast_nodes,
"transform");
43 std::vector<SymbolicExpr> input_polys;
44 input_polys.reserve(equations.size());
45 for (
const auto&
eq : equations) {
48 if (simplified && !simplified->is_zero()) {
49 input_polys.push_back(*simplified);
60 (
context).limits().max_ast_nodes,
"transform");
61 auto G_basis = Solver::groebner_basis(input_polys, unknowns);
63 std::vector<std::shared_ptr<SymbolicExpr>>
basis;
64 basis.reserve(G_basis.size());
65 for (
const auto& g : G_basis) {
68 if (simp && !simp->is_zero()) {
69 basis.push_back(simp);
76 const std::vector<std::string>& unknowns,
78 for (
int index = 0; index <= last && index < static_cast<int>(unknowns.size()); ++index) {
79 if (
contains(expression, unknowns[index])) {
90 (
context).limits().max_ast_nodes,
"transform");
91 auto result = expression;
92 for (
const auto& [
name,
value] : assignment) {
109 reduced.reserve(
basis_.size());
110 for (
const auto& polynomial :
basis_) {
114 "assignment substitution failed",
"solve.parametric");
116 if (expression->is_zero()) {
125 "remaining parameter constraint is not proved",
"solve.parametric");
128 reduced.push_back(expression);
134 int position)
const {
136 std::shared_ptr<SymbolicExpr>
target;
138 int best_degree = std::numeric_limits<int>::max();
139 bool appears =
false;
140 for (
const auto& expression : reduced) {
148 auto polynomial = symbolic_to_poly<SymbolicPolyCoeff>(expression,
variable);
155 int degree = polynomial.value().degree();
156 if (degree >= 1 && degree < best_degree) {
157 best_degree = degree;
159 leading = polynomial.value().coeffs.back().val;
164 "No convertible polynomial target for remaining variable",
"solve.parametric");
168 if (!
contains(*leading, parameter))
continue;
173 "leading parameter coefficient is not proved nonzero",
"solve.parametric");
185 return solve(position - 1, next);
190 const std::vector<std::string>& unknowns,
191 const std::vector<std::string>& parameters,
197 auto consistent =
reduce_basis(position, partial, reduced);
199 if (!consistent.value()) {
207 if (!selected.value()) {
215 auto roots = std::move(solved.value());
220 for (
const auto& root :
roots) {
223 auto branch =
solve(position - 1, next);
227 auto& values = branch.value();
228 results.insert(results.end(), std::make_move_iterator(values.begin()),
229 std::make_move_iterator(values.end()));
238 const std::vector<std::shared_ptr<SymbolicExpr>>& equations,
239 const std::vector<std::string>& unknowns,
240 const std::vector<std::string>& parameters,
243 if (equations.empty() || unknowns.empty()) {
244 return free_unknowns(unknowns);
247 if (input_polys.empty()) {
251 if (unknowns.size() == 1) {
252 basis.reserve(input_polys.size());
253 for (
const auto& polynomial : input_polys)
258 for (
const auto& polynomial :
basis) {
266 "parameter-only constraint is not proved",
"solve.parametric");
269 ParametricBranchSolver branches(
basis, unknowns, parameters,
context);
271 return branches.solve(
static_cast<int>(unknowns.size()) - 1, empty);
static Result failure(CasErrc code, std::string message, std::string operation={})
Result< std::shared_ptr< SymbolicExpr > > select_target(const ParametricBasis &reduced, int position) const
ParametricSolutionsResult solve(int position, const ParametricAssignment &partial) const
Result< bool > reduce_basis(int position, const ParametricAssignment &partial, ParametricBasis &reduced) const
ParametricSolutionsResult solve_free_unknown(int position, const ParametricAssignment &partial) const
const ParametricBasis & basis_
ParametricBranchSolver(const ParametricBasis &basis, const std::vector< std::string > &unknowns, const std::vector< std::string > ¶meters, ComputationContext &context)
const std::vector< std::string > & parameters_
ComputationContext & context_
const std::vector< std::string > & unknowns_
Result< Tribool > parameter_constraint(const ExprPtr &expression, ComputationContext &context)
bool depends_on_remaining_unknown(const SymbolicExpr &expression, const std::vector< std::string > &unknowns, int last)
ParametricSolutionList free_unknowns(const std::vector< std::string > &unknowns)
std::vector< std::shared_ptr< SymbolicExpr > > ParametricBasis
std::shared_ptr< SymbolicExpr > substitute_assignment(const std::shared_ptr< SymbolicExpr > &expression, const ParametricAssignment &assignment, ComputationContext &context)
ParametricBasis parametric_basis(const std::vector< SymbolicExpr > &input_polys, const std::vector< std::string > &unknowns, ComputationContext &context)
std::vector< SymbolicExpr > parametric_input_polynomials(const std::vector< std::shared_ptr< SymbolicExpr > > &equations, ComputationContext &context)
std::map< std::string, std::shared_ptr< SymbolicExpr > > ParametricAssignment
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 FactsQuery & no_facts() noexcept
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
SymbolicNodePtr substitute_node(const SymbolicNodePtr &node, const std::string &variable, const SymbolicNodePtr &replacement, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
const std::string & variable
ExprResult eq(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
@ Complex
Complex numbers (default, least specific)
@ Unknown
Property cannot be determined
@ True
Property definitely holds
@ False
Property definitely does not hold
Result< ParametricSolutionList > ParametricSolutionsResult
bool contains(const SymbolicExpr &expression, const std::string &variable)
LMCAS::FiniteSolveResult solve_finite_checked(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, ComputationContext &context, const SolveOptions &opts)
std::shared_ptr< SymbolicExpr > ExprPtr
const std::vector< FGLMPoly > & basis
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)
ResidualCheckResult check_zero_residual(const ExprPtr &residual, ComputationContext &context, const LMCAS::EqvOptions &options)
const std::string const ExprPtr & value
std::vector< std::map< std::string, std::shared_ptr< SymbolicExpr > > > ParametricSolutionList
__attribute__((visibility("default"))) Result< EqvProfile > eqv_profile_from_name(const std const std::string & name
含参方程组求解器 ParametricSolver,支持分段解。
方程求解策略调度器 solve_dispatch 及相关选项结构体.
多项式方程组求解器 Solver,包含 Gröbner 基、线性系统求解。