12 const std::shared_ptr<SymbolicExpr>& root,
28 intervals.push_back(Interval::point(root));
36 (
context).limits().max_ast_nodes,
"transform");
38 endpoint.is_open =
false;
41 auto diff = SymbolicExpr::add(endpoint.value,
42 SymbolicExpr::multiply(root, SymbolicExpr::number(-1)));
46 endpoint.is_open =
false;
66 intervals.push_back(Interval::point(root));
71 const std::vector<std::shared_ptr<SymbolicExpr>>&
roots,
72 const std::vector<int>& signs,
int target_sign) {
73 std::vector<Interval> intervals;
74 for (
size_t index = 0; index < signs.size(); ++index) {
75 if (signs[index] != target_sign) {
79 interval.lower = index == 0 ? Endpoint::neg_inf() : Endpoint::open(
roots[index - 1]);
80 interval.upper = index ==
roots.size() ? Endpoint::pos_inf() : Endpoint::open(
roots[index]);
87 const std::vector<std::shared_ptr<SymbolicExpr>>& symbolic_roots,
88 const std::vector<int>& multiplicities,
92 if (symbolic_roots.empty()) {
95 int target_sign = want_positive ? 1 : -1;
96 if (leading_sign == target_sign) {
97 return IntervalUnion::entire_line();
99 return IntervalUnion::empty();
102 size_t n = symbolic_roots.size();
103 std::vector<int> interval_signs(n + 1);
105 interval_signs[n] = leading_sign;
107 for (
int i = (
int)n - 1; i >= 0; --i) {
108 interval_signs[i] = interval_signs[i + 1];
109 if (multiplicities[i] % 2 != 0) {
110 interval_signs[i] = -interval_signs[i];
116 int target_sign = want_positive ? 1 : -1;
123 return IntervalUnion(result_intervals);
128std::vector<SignChartEntry> InequalitySolver::build_sign_chart(
129 const std::shared_ptr<SymbolicExpr>& poly,
131 const std::vector<std::shared_ptr<SymbolicExpr>>&
roots,
134 std::vector<SignChartEntry> chart;
135 auto converted = symbolic_to_poly<SymbolicPolyCoeff>(poly,
variable);
136 if (!converted)
throw std::invalid_argument(converted.error().message);
137 const auto& p = converted.value();
142 chart.push_back({Interval::entire_line(), sign});
148 size_t n =
roots.size();
149 std::vector<int> interval_signs(n + 1);
151 interval_signs[n] = leading_sign;
153 for (
int i = (
int)n - 1; i >= 0; --i) {
154 interval_signs[i] = interval_signs[i + 1];
155 if (multiplicities[i] % 2 != 0) {
156 interval_signs[i] = -interval_signs[i];
162 iv.lower = Endpoint::neg_inf();
163 iv.upper = Endpoint::open(
roots[0]);
164 chart.push_back({iv, interval_signs[0]});
167 for (
size_t i = 0; i + 1 < n; ++i) {
169 iv.lower = Endpoint::open(
roots[i]);
170 iv.upper = Endpoint::open(
roots[i + 1]);
171 chart.push_back({iv, interval_signs[i + 1]});
176 iv.lower = Endpoint::open(
roots[n - 1]);
177 iv.upper = Endpoint::pos_inf();
178 chart.push_back({iv, interval_signs[n]});
184IntervalUnion InequalitySolver::select_intervals(
185 const std::vector<SignChartEntry>& chart,
187 const std::vector<std::shared_ptr<SymbolicExpr>>&
roots,
190 std::vector<Interval> result_intervals;
194 int target_sign = want_positive ? 1 : -1;
196 for (
const auto& entry : chart) {
197 if (entry.sign == target_sign) {
198 result_intervals.push_back(entry.interval);
205 return IntervalUnion(result_intervals);
208IntervalUnion InequalitySolver::build_parametric_solution(
209 const std::vector<std::shared_ptr<SymbolicExpr>>& symbolic_roots,
210 const std::vector<int>& multiplicities,
bool roots_equal(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, ComputationContext &context)
static std::vector< Interval > select_open_intervals(const std::vector< std::shared_ptr< SymbolicExpr > > &roots, const std::vector< int > &signs, int target_sign)
static bool close_symbolic_endpoint(Endpoint &endpoint, const std::shared_ptr< SymbolicExpr > &root, ComputationContext &context)
static void include_symbolic_root(std::vector< Interval > &intervals, const std::shared_ptr< SymbolicExpr > &root, ComputationContext &context)
void include_numeric_root(std::vector< Interval > &intervals, const std::shared_ptr< SymbolicExpr > &root, ComputationContext &context)
int determine_leading_sign(const Polynomial< SymbolicPolyCoeff > &poly, ComputationContext &context)
IntervalUnion build_parametric_intervals(const std::vector< std::shared_ptr< SymbolicExpr > > &symbolic_roots, const std::vector< int > &multiplicities, int leading_sign, InequalityType type, ComputationContext &context)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
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
ExprResult interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)