LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
expr_facade.cpp
浏览该文件的文档.
1#include "expr.hpp"
2#include <exception>
3#include <memory>
4#include <string>
5#include <utility>
6#include <vector>
8#include "matcher.hpp"
11namespace LMCAS {
13ExprResult expression_failure(CasErrc code, std::string message,
14 const char* operation) {
15 return ExprResult::failure(code, std::move(message), operation);
16}
17
18ExprMatchResult expr_match_failure(CasErrc code, std::string message,
19 const char* operation) {
20 return ExprMatchResult::failure(code, std::move(message), operation);
21}
22
25 const char* function_name,
26 ExprPtr (*factory)(ExprPtr)) {
27 auto step = context.consume_steps(1, kMathOperation);
28 if (!step) return ExprResult::failure(step.error());
29 if (!expression || !LMCAS::detail::node(expression)) {
31 std::string(function_name) +
32 " argument cannot be null",
34 }
35 try {
36 auto result = factory(expression);
37 if (!result || !LMCAS::detail::node(result)) {
39 std::string(function_name) +
40 " expression construction failed",
42 }
43 return ExprResult::success(std::move(result));
44 } catch (const std::bad_alloc&) {
46 std::string(function_name) +
47 " expression allocation failed",
49 } catch (const std::exception& error) {
52 }
53}
54
55
58 const char* function_name,
60 auto step = context.consume_steps(1, kMathOperation);
61 if (!step) return ExprResult::failure(step.error());
62 if (!expression || !LMCAS::detail::node(expression)) {
64 std::string(function_name) +
65 " argument cannot be null",
67 }
68 try {
70 type, std::vector<std::shared_ptr<const SymbolicNode>>{
71 LMCAS::detail::node(expression)});
73 LMCAS::detail::make_expression_ptr(std::move(node)));
74 } catch (const std::bad_alloc&) {
76 std::string(function_name) +
77 " expression allocation failed",
79 } catch (const std::exception& error) {
82 }
83}
84
86 const char* operation) {
87 if (!result) {
88 return ExprResult::failure(result.error());
89 }
90 if (!result.value() || !LMCAS::detail::node(result.value())) {
92 "complex expression result is null",
93 operation);
94 }
95 return ExprResult::success(result.value());
96}
97
98
99bool is_reserved_symbol_name(const std::string& name) {
100 return name == "I" || name == "pi" || name == "π" ||
101 name == "e" || name == "phi";
102}
103
104
106 const char* function_name) {
107 if (!expression || !LMCAS::detail::node(expression)) {
109 std::string(function_name) + " argument cannot be null",
111 }
112 auto dimension = dimension_of(*expression);
113 if (!dimension) return ExprResult::failure(dimension.error());
114 if (!dimension.value().is_dimensionless()) {
116 std::string(function_name) +
117 " requires a dimensionless argument",
119 }
120 return ExprResult::success(expression);
121}
122
125 if (std::dynamic_pointer_cast<const QuantityNode>(LMCAS::detail::node(expression))) {
126 return strip_unit(expression, UnitStripMode::BaseValue, context);
127 }
128 return ExprResult::success(expression);
129}
130
131} // namespace expr_detail::expr_common
132using namespace expr_detail::expr_common;
133
134
135ExprResult function(const std::string& name, std::vector<ExprPtr> arguments) {
136 constexpr const char* operation = "LMCAS.function";
137 if (name.empty()) {
139 "function name cannot be empty", operation);
140 }
141 std::vector<std::shared_ptr<const SymbolicNode>> nodes;
142 nodes.reserve(arguments.size());
143 for (const auto& argument : arguments) {
144 if (!argument || !LMCAS::detail::node(argument)) {
146 "function arguments cannot be null", operation);
147 }
148 nodes.push_back(LMCAS::detail::node(argument));
149 }
150 try {
153 name, std::move(nodes))));
154 } catch (const std::bad_alloc&) {
156 "function allocation failed", operation);
157 } catch (const std::exception& error) {
159 error.what(), operation);
160 }
161}
162
163ExprResult finite_set(std::vector<ExprPtr> elements) {
165 return finite_set(std::move(elements), context);
166}
167
173
175 constexpr const char* operation = "LMCAS.relation";
176 if (!lhs || !rhs) {
178 "relation operands cannot be null", operation);
179 }
180 try {
184 } catch (const std::bad_alloc&) {
186 "relation allocation failed", operation);
187 } catch (const std::exception& error) {
189 error.what(), operation);
190 }
191}
192
193ExprResult ne(const ExprPtr& lhs, const ExprPtr& rhs) {
194 return relation(lhs, rhs, RelationOp::NEQ);
195}
196
197ExprResult lt(const ExprPtr& lhs, const ExprPtr& rhs) {
198 return relation(lhs, rhs, RelationOp::LT);
199}
200
201ExprResult le(const ExprPtr& lhs, const ExprPtr& rhs) {
202 return relation(lhs, rhs, RelationOp::LEQ);
203}
204
205ExprResult gt(const ExprPtr& lhs, const ExprPtr& rhs) {
206 return relation(lhs, rhs, RelationOp::GT);
207}
208
209ExprResult ge(const ExprPtr& lhs, const ExprPtr& rhs) {
210 return relation(lhs, rhs, RelationOp::GEQ);
211}
212
213namespace {
215 LogicalNode::Op op, const char* operation) {
216 if (!lhs || (op != LogicalNode::Op::Not && !rhs)) {
218 "logical operands cannot be null", operation);
219 }
220 try {
224 rhs ? LMCAS::detail::node(rhs) : nullptr, op)));
225 } catch (const std::bad_alloc&) {
227 "logical expression allocation failed",
228 operation);
229 } catch (const std::exception& error) {
231 error.what(), operation);
232 }
233}
234} // namespace
235
237 return logical_expression(lhs, rhs, LogicalNode::Op::And, "LMCAS.logical_and");
238}
239
241 return logical_expression(lhs, rhs, LogicalNode::Op::Or, "LMCAS.logical_or");
242}
243
244ExprResult logical_not(const ExprPtr& expression) {
245 return logical_expression(expression, nullptr, LogicalNode::Op::Not,
246 "LMCAS.logical_not");
247}
248
251 auto result = member(element, set, context);
252 if (!result || !negated) return result;
253 return logical_not(result.value());
254}
255
256} // namespace LMCAS
@ Not
一元逻辑非,right 为 nullptr。
CasError & error()
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(ExprPtr value)
复变函数分析:留数计算,柯西积分公式,解析延拓.
模式匹配引擎 Matcher 与重写规则系统 RewriteEngine。
ExprResult logical_expression(const ExprPtr &lhs, const ExprPtr &rhs, LogicalNode::Op op, const char *operation)
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)
ExprResult make_unary_function_expr(const ExprPtr &expression, ComputationContext &context, const char *function_name, FunctionNode::FuncType type)
ExprResult require_dimensionless(const ExprPtr &expression, const char *function_name)
ExprResult expression_failure(CasErrc code, std::string message, const char *operation)
ExprMatchResult expr_match_failure(CasErrc code, std::string message, const char *operation)
ExprResult make_unary_math_expr(const ExprPtr &expression, ComputationContext &context, const char *function_name, ExprPtr(*factory)(ExprPtr))
ExprResult comparison_value(const ExprPtr &expression, ComputationContext &context)
bool is_reserved_symbol_name(const std::string &name)
constexpr const char * kMathOperation
ExprResult expr_from_complex_result(const ExpressionResult &result, const char *operation)
Result< DimensionSignature > dimension_of(const SymbolicExpr &expression)
const ExprPtr & element
ExprResult le(const ExprPtr &lhs, const ExprPtr &rhs)
ExprResult logical_or(const ExprPtr &lhs, const ExprPtr &rhs)
__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 interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
const ExprPtr & lower
ExprResult ge(const ExprPtr &lhs, const ExprPtr &rhs)
const ExprPtr & set
Result< ExprPtr > ExprResult
Result< std::shared_ptr< SymbolicExpr > > ExpressionResult
Result of an operation that produces a symbolic expression.
ExprResult logical_not(const ExprPtr &expression)
ExprResult ne(const ExprPtr &lhs, const ExprPtr &rhs)
RelationOp
Stable relational operator used by public APIs.
const ExprPtr RelationOp op
ExprResult finite_set(std::vector< ExprPtr > elements)
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr bool lower_closed
ExprResult member(const ExprPtr &element, const ExprPtr &set, ComputationContext &context)
std::shared_ptr< SymbolicExpr > ExprPtr
ExprResult membership(const ExprPtr &element, const ExprPtr &set, bool negated)
ExprResult relation(const ExprPtr &lhs, const ExprPtr &rhs, RelationOp op)
ExprResult gt(const ExprPtr &lhs, const ExprPtr &rhs)
const ExprPtr & rhs
ExprResult lt(const ExprPtr &lhs, const ExprPtr &rhs)
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr bool bool upper_closed
Result< ExprMatch > ExprMatchResult
ExprResult function(const std::string &name, std::vector< ExprPtr > arguments)
const ExprPtr bool negated
__attribute__((visibility("default"))) Result< EqvProfile > eqv_profile_from_name(const std const std::string & name
QuantityResult strip_unit(const std::shared_ptr< SymbolicExpr > &expression, UnitStripMode mode, ComputationContext &context)
ExprResult logical_and(const ExprPtr &lhs, const ExprPtr &rhs)
内部 AST 定义。