23std::shared_ptr<const FiniteSetNode>
finite_set_node(
const SymbolicExpr& expression) {
24 return std::dynamic_pointer_cast<const FiniteSetNode>(
detail::node(expression));
28 auto number = std::dynamic_pointer_cast<const NumberNode>(node);
29 if (!number)
return false;
30 if (std::holds_alternative<BigInt>(number->value())) {
31 value = Rational(std::get<BigInt>(number->value()));
34 if (std::holds_alternative<Rational>(number->value())) {
35 value = std::get<Rational>(number->value());
45 }
catch (
const std::bad_alloc&) {
47 }
catch (
const std::exception& error) {
75 std::vector<std::shared_ptr<SymbolicExpr>> elements,
79 std::vector<std::shared_ptr<const SymbolicNode>> nodes;
80 nodes.reserve(elements.size());
81 for (
const auto&
element : elements) {
84 "finite set elements cannot be null");
88 return from_nodes(std::move(nodes));
92 const std::shared_ptr<SymbolicExpr>&
lower,
93 const std::shared_ptr<SymbolicExpr>&
upper,
104 Rational lower_value;
105 Rational upper_value;
108 upper_value < lower_value) {
110 "interval lower endpoint exceeds upper endpoint");
116 }
catch (
const std::bad_alloc&) {
122 const std::shared_ptr<SymbolicExpr>&
element,
123 const std::shared_ptr<SymbolicExpr>&
set,
132 if (
auto finite = finite_set_node(*
set)) {
146 const SymbolicExpr& lhs,
const SymbolicExpr&
rhs,
150 auto left = finite_set_node(lhs);
153 "set union requires two finite sets");
154 auto elements = left->elements();
155 elements.insert(elements.end(),
right->elements().begin(),
right->elements().end());
156 return from_nodes(std::move(elements));
160 const SymbolicExpr& lhs,
const SymbolicExpr&
rhs,
164 auto left = finite_set_node(lhs);
167 "set intersection requires two finite sets");
168 std::vector<std::shared_ptr<const SymbolicNode>> elements;
169 for (
const auto&
element : left->elements()) {
172 return from_nodes(std::move(elements));
176 const SymbolicExpr& lhs,
const SymbolicExpr&
rhs,
180 auto left = finite_set_node(lhs);
183 "set difference requires two finite sets");
184 std::vector<std::shared_ptr<const SymbolicNode>> elements;
185 for (
const auto&
element : left->elements()) {
188 return from_nodes(std::move(elements));
192 const SymbolicExpr& lhs,
const SymbolicExpr&
rhs,
195 if (!left)
return left;
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(std::shared_ptr< SymbolicExpr > value)
constexpr const char * kOperation
std::shared_ptr< const FiniteSetNode > finite_set_node(const SymbolicExpr &expression)
std::optional< bool > exact_interval_membership(const std::shared_ptr< const SymbolicNode > &element, const IntervalNode &interval)
SymbolicSetResult from_nodes(std::vector< std::shared_ptr< const SymbolicNode > > elements)
Result< void > consume(ComputationContext &context)
SymbolicSetResult failure(CasErrc code, std::string message)
bool exact_value(const std::shared_ptr< const SymbolicNode > &node, Rational &value)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::shared_ptr< const Node > make_node(Args &&... args)
SymbolicSetResult make_membership(const std::shared_ptr< SymbolicExpr > &element, const std::shared_ptr< SymbolicExpr > &set, ComputationContext &context)
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
SymbolicSetResult make_interval(const std::shared_ptr< SymbolicExpr > &lower, const std::shared_ptr< SymbolicExpr > &upper, bool lower_closed, bool upper_closed, ComputationContext &context)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
SymbolicSetResult finite_set_difference(const SymbolicExpr &lhs, const SymbolicExpr &rhs, ComputationContext &context)
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr bool lower_closed
SymbolicSetResult make_finite_set(std::vector< std::shared_ptr< SymbolicExpr > > elements, ComputationContext &context)
const std::string const ExprPtr & value
SymbolicSetResult finite_set_intersection(const SymbolicExpr &lhs, const SymbolicExpr &rhs, ComputationContext &context)
Result< std::shared_ptr< SymbolicExpr > > SymbolicSetResult
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr bool bool upper_closed
SymbolicSetResult finite_set_symmetric_difference(const SymbolicExpr &lhs, const SymbolicExpr &rhs, ComputationContext &context)
SymbolicSetResult finite_set_union(const SymbolicExpr &lhs, const SymbolicExpr &rhs, ComputationContext &context)