LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
expr_sets.cpp
浏览该文件的文档.
1#include "expr.hpp"
2
3#include <exception>
4#include <utility>
5#include <vector>
6
10
11namespace LMCAS {
12
13ExprSet::ExprSet()
14 : ExprSet(std::make_shared<const SymbolicExpr>(detail::expression_from_node(
16 std::vector<std::shared_ptr<const SymbolicNode>>{})))) {}
17
18ExprSet::ExprSet(ConstExprPtr expression)
19 : expression_(std::move(expression)) {
20 const auto& node = static_cast<const FiniteSetNode&>(*detail::node(*expression_));
21 elements_.reserve(node.elements().size());
22 for (const auto& element : node.elements()) {
23 elements_.push_back(std::make_shared<const SymbolicExpr>(
24 detail::expression_from_node(element)));
25 }
26}
27
28Result<ExprSet> ExprSet::make(std::vector<ExprPtr> elements) {
29 ComputationContext context;
30 for (const auto& element : elements) {
31 if (!element) {
32 return expr_set_failure(CasErrc::InvalidArgument,
33 "set<Expr> elements cannot be null",
34 kExprSetOperation);
35 }
36 }
37 auto expression = make_finite_set(std::move(elements), context);
38 if (!expression) { return Result<ExprSet>::failure(expression.error()); }
39 return Result<ExprSet>::success(
40 ExprSet(std::make_shared<const SymbolicExpr>(*expression.value())));
41}
42
43bool ExprSet::contains(const SymbolicExpr& expression) const {
44 const auto& node = static_cast<const FiniteSetNode&>(*detail::node(*expression_));
45 return node.contains(*detail::node(expression));
46}
47
48bool ExprSet::subset_of(const ExprSet& other) const {
49 for (const auto& element : elements_) {
50 if (!other.contains(*element)) {
51 return false;
52 }
53 }
54 return true;
55}
56
57ExprSet ExprSet::set_union(const ExprSet& other) const {
58 ComputationContext context;
59 auto result = finite_set_union(*expression_, *other.expression_, context);
60 return ExprSet(std::make_shared<const SymbolicExpr>(*result.value()));
61}
62
63ExprSet ExprSet::intersection(const ExprSet& other) const {
64 ComputationContext context;
65 auto result = finite_set_intersection(*expression_, *other.expression_, context);
66 return ExprSet(std::make_shared<const SymbolicExpr>(*result.value()));
67}
68
69ExprSet ExprSet::difference(const ExprSet& other) const {
70 ComputationContext context;
71 auto result = finite_set_difference(*expression_, *other.expression_, context);
72 return ExprSet(std::make_shared<const SymbolicExpr>(*result.value()));
73}
74
75ExprSet ExprSet::symmetric_difference(const ExprSet& other) const {
76 ComputationContext context;
77 auto result = finite_set_symmetric_difference(*expression_, *other.expression_, context);
78 return ExprSet(std::make_shared<const SymbolicExpr>(*result.value()));
79}
80
81
82ExprSetResult expr_set(std::vector<ExprPtr> elements) {
83 try {
84 return ExprSet::make(std::move(elements));
85 } catch (const std::bad_alloc&) {
87 "set<Expr> allocation failed",
89 } catch (const std::exception& error) {
92 }
93}
94
95
97 const ExprPtr& element) {
98 if (!element) {
100 "set<Expr> membership element cannot be null",
102 }
103 return Result<bool>::success(set.contains(*element));
104}
105
107 const ExprPtr& element) {
108 auto result = expr_set_contains(set, element);
109 if (!result) { return result; }
110 return Result<bool>::success(!result.value());
111}
112
113Result<bool> expr_set_subset(const ExprSet& lhs,
114 const ExprSet& rhs) {
115 return Result<bool>::success(lhs.subset_of(rhs));
116}
117
119 const NumberDomainSet& domain) {
120 for (const auto& element : set.elements()) {
121 auto contains = domain.contains(element);
122 if (!contains) {
123 return contains;
124 }
125 if (!contains.value()) {
126 return Result<bool>::success(false);
127 }
128 }
129 return Result<bool>::success(true);
130}
131
133 const ExprSet& lhs, const ExprSet& rhs)
134{
135 try {
137 auto expression =
138 finite_set_union(*lhs.expression_, *rhs.expression_, context);
139 if (!expression) {
140 return ExprSetResult::failure(expression.error());
141 }
142 return ExprSetResult::success(ExprSet(
143 std::make_shared<const SymbolicExpr>(*expression.value())));
144 } catch (const std::bad_alloc&) {
145 return expr_set_failure(
146 CasErrc::ResourceLimit, "set<Expr> union allocation failed",
148 }
149}
150
152 const ExprSet& lhs, const ExprSet& rhs)
153{
154 try {
156 auto expression = finite_set_intersection(
157 *lhs.expression_, *rhs.expression_, context);
158 if (!expression) {
159 return ExprSetResult::failure(expression.error());
160 }
161 return ExprSetResult::success(ExprSet(
162 std::make_shared<const SymbolicExpr>(*expression.value())));
163 } catch (const std::bad_alloc&) {
164 return expr_set_failure(
166 "set<Expr> intersection allocation failed",
168 }
169}
170
172 const ExprSet& lhs, const ExprSet& rhs)
173{
174 try {
176 auto expression =
177 finite_set_difference(*lhs.expression_, *rhs.expression_, context);
178 if (!expression) {
179 return ExprSetResult::failure(expression.error());
180 }
181 return ExprSetResult::success(ExprSet(
182 std::make_shared<const SymbolicExpr>(*expression.value())));
183 } catch (const std::bad_alloc&) {
184 return expr_set_failure(
186 "set<Expr> difference allocation failed",
188 }
189}
190
192 const ExprSet& lhs, const ExprSet& rhs)
193{
194 try {
196 auto expression = finite_set_symmetric_difference(
197 *lhs.expression_, *rhs.expression_, context);
198 if (!expression) {
199 return ExprSetResult::failure(expression.error());
200 }
201 return ExprSetResult::success(ExprSet(
202 std::make_shared<const SymbolicExpr>(*expression.value())));
203 } catch (const std::bad_alloc&) {
204 return expr_set_failure(
206 "set<Expr> symmetric difference allocation failed",
208 }
209}
210
211}
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
多元 Hensel 提升(单变量步)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
std::shared_ptr< const Node > make_node(Args &&... args)
const ExprPtr & element
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprSetResult expr_set(std::vector< ExprPtr > elements)
const ExprPtr & set
Result< bool > expr_set_contains(const ExprSet &set, const ExprPtr &element)
Result< bool > expr_set_subset(const ExprSet &lhs, const ExprSet &rhs)
ExprSetResult expr_set_symmetric_difference(const ExprSet &lhs, const ExprSet &rhs)
ExprSetResult expr_set_intersection(const ExprSet &lhs, const ExprSet &rhs)
Result< bool > expr_set_not_contains(const ExprSet &set, const ExprPtr &element)
SymbolicSetResult finite_set_difference(const SymbolicExpr &lhs, const SymbolicExpr &rhs, ComputationContext &context)
Result< bool > expr_set_subset_domain(const ExprSet &set, const NumberDomainSet &domain)
bool contains(const SymbolicExpr &expression, const std::string &variable)
const NumberDomainSet & domain
SymbolicSetResult make_finite_set(std::vector< std::shared_ptr< SymbolicExpr > > elements, ComputationContext &context)
std::shared_ptr< SymbolicExpr > ExprPtr
ExprSetResult expr_set_difference(const ExprSet &lhs, const ExprSet &rhs)
SymbolicSetResult finite_set_intersection(const SymbolicExpr &lhs, const SymbolicExpr &rhs, ComputationContext &context)
const ExprPtr & rhs
Result< ExprSet > ExprSetResult
constexpr const char * kExprSetOperation
ExprSetResult expr_set_union(const ExprSet &lhs, const ExprSet &rhs)
ExprSetResult expr_set_failure(CasErrc code, std::string message, const char *operation)
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)
内部 AST 定义。