28 [[noreturn]]
void invalid(
const char* message)
const {
32 std::size_t length = 0;
36 if (length > (std::numeric_limits<std::size_t>::max() - digit) / 10)
37 invalid(
"serialized expression length overflow");
38 length = length * 10 + digit;
47 invalid(
"invalid serialized expression length");
50 invalid(
"invalid serialized expression length");
53 invalid(
"invalid serialized expression length");
56 invalid(
"invalid serialized expression length");
59 invalid(
"truncated serialized expression field");
62 invalid(
"truncated serialized expression field");
69 const auto text =
field();
70 std::size_t result = 0;
71 auto parsed = std::from_chars(text.data(), text.data() + text.size(), result);
72 if (text.empty() || (text.size() > 1 && text[0] ==
'0') ||
73 parsed.ec != std::errc{} || parsed.ptr != text.data() + text.size())
74 invalid(
"invalid serialized expression integer");
80 invalid(
"invalid serialized expression count");
81 if (n >
context_.limits().max_ast_nodes)
87 if (text ==
"0")
return false;
88 if (text ==
"1")
return true;
89 invalid(
"invalid serialized expression flag");
91 template <
typename Enum, std::
size_t N>
92 Enum
choice(
const std::array<std::string_view, N>& names) {
94 for (std::size_t i = 0; i < names.size(); ++i)
95 if (text == names[i])
return static_cast<Enum
>(i);
96 invalid(
"invalid serialized expression operator");
99 for (std::size_t i = first; i < text.size(); ++i)
100 if (text[i] <
'0' || text[i] >
'9')
invalid(
"invalid serialized expression integer");
105 invalid(
"invalid serialized expression integer");
107 std::size_t first = text.front() ==
'-' ? 1 : 0;
108 if (first == text.size()) {
109 invalid(
"invalid serialized expression integer");
111 if (text.size() - first > 1 && text[first] ==
'0') {
112 invalid(
"invalid serialized expression integer");
115 if (first != 0 && text.substr(first) ==
"0") {
116 invalid(
"invalid serialized expression integer");
119 if (text.size() - first >
context_.limits().max_integer_bits / 3 + 1) {
122 BigInt result{std::string(text)};
134 std::vector<NodePtr> result;
136 for (std::size_t i = 0; i < n; ++i) result.push_back(
node());
141 if (!rows || !cols || rows > std::numeric_limits<std::size_t>::max() / cols ||
143 invalid(
"invalid matrix dimensions");
144 if (rows * cols >
context_.limits().max_ast_nodes)
147 elements.reserve(rows * cols);
148 for (std::size_t i = 0; i < rows * cols; ++i) elements.push_back(
node());
152 auto count_branches =
count();
153 std::vector<PiecewiseNode::Branch> branches;
154 branches.reserve(count_branches);
155 for (std::size_t i = 0; i < count_branches; ++i) {
156 auto expression =
node();
157 branches.push_back({expression,
node()});
159 auto has_default =
flag();
163 auto dimensions =
count();
164 DimensionSignature::Exponents exponents;
165 for (std::size_t i = 0; i < dimensions; ++i) {
169 !exponents.emplace(std::move(
name), std::move(
exponent)).second)
170 invalid(
"invalid dimension exponent");
172 auto dimension = DimensionSignature(std::move(exponents));
178 std::vector<Rational> coefficients;
179 coefficients.reserve(size);
180 for (std::size_t i = 0; i < size; ++i) coefficients.push_back(
rational());
181 if (coefficients.size() < 2 || coefficients.back().is_zero() ||
182 index >= coefficients.size() - 1)
invalid(
"invalid root identity");
188 if (
nodes_ == std::numeric_limits<std::size_t>::max()) {
195 if (kind ==
"symbol") {
199 if (kind ==
"constant") {
212 if (kind ==
"function") {
216 if (kind ==
"call") {
221 if (kind ==
"matrix")
return matrix();
222 if (kind ==
"relation") {
226 if (kind ==
"logic") {
231 if (kind ==
"piecewise")
return piecewise();
235 if (kind ==
"sum" || kind ==
"product") {
241 if (kind ==
"transform") {
247 if (kind ==
"quantifier") {
253 if (kind ==
"set_builder") {
259 if (kind ==
"interval") {
264 if (kind ==
"membership") {
267 if (kind ==
"quantity")
return quantity();
268 if (kind ==
"integral") {
270 auto bounded =
flag();
275 if (kind ==
"limit") {
281 if (kind ==
"root_of")
return root_of();
293 auto input =
context.require_input_bytes(source.size(), kDecode);
295 if (source.compare(0, kHeader.size(), kHeader.data(), kHeader.size()) != 0)
297 "unknown serialized expression version", kDecode);
300 }
catch (
const CasError& error) {
302 }
catch (
const std::bad_alloc&) {
304 "expression parse allocation failed", kDecode);
305 }
catch (
const std::exception& error) {
312 return parse_serialized_expr(source,
context);
@ Not
一元逻辑非,right 为 nullptr。
std::vector< std::shared_ptr< const SymbolicNode > > DenseStorage
稠密存储,按行优先展开。
static Result failure(CasErrc code, std::string message, std::string operation={})
NodePtr extended_node(std::string_view kind)
ComputationContext & context_
Reader(const std::string &source, ComputationContext &context)
std::size_t unsigned_field()
const std::string & source_
NodePtr compound_node(std::string_view kind)
Enum choice(const std::array< std::string_view, N > &names)
void check_integer_digits(std::string_view text, std::size_t first) const
void invalid(const char *message) const
std::size_t read_length()
std::vector< NodePtr > nodes()
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
std::shared_ptr< const Node > make_node(Args &&... args)
constexpr std::array< std::string_view, 36 > kFunctions
detail::SymbolicNodePtr NodePtr
constexpr std::array< std::string_view, 5 > kTransforms
constexpr std::array< std::string_view, 3 > kDirections
constexpr std::string_view kHeader
constexpr std::array< std::string_view, 6 > kRelations
constexpr std::array< std::string_view, 2 > kQuantifiers
void check(Result< void > result)
constexpr const char * kDecode
constexpr std::array< std::string_view, 4 > kLogic
const std::string const LimitExprPtr & point
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult real(const ExprPtr &expression, ComputationContext &context)
const std::string const LimitExprPtr LimitDirection direction
Result< std::shared_ptr< SymbolicExpr > > ExpressionResult
Result of an operation that produces a symbolic expression.
const ExprPtr RelationOp op
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr bool lower_closed
std::size_t std::size_t depth
const NumberDomainSet & domain
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr bool bool upper_closed
const ExprPtr & denominator
__attribute__((visibility("default"))) Result< EqvProfile > eqv_profile_from_name(const std const std::string & name