LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
normalization_signs.cpp
浏览该文件的文档.
2
3namespace LMCAS {
4namespace {
5std::shared_ptr<const NumberNode> positive_negative_number(const NumberNode& number) {
6 if (const auto* integer = std::get_if<BigInt>(&number.value())) {
7 if (integer->is_negative()) {
8 return detail::make_node<NumberNode>(*integer * BigInt(-1));
9 }
10 return nullptr;
11 }
12 const auto& rational = std::get<Rational>(number.value());
13 if (rational.get_numerator().is_negative()) {
14 return detail::make_node<NumberNode>(rational * Rational(-1));
15 }
16 return nullptr;
17}
18
19}
20
21bool check_negative_arg(const std::shared_ptr<const SymbolicNode>& argument,
22 std::shared_ptr<const SymbolicNode>& positive, detail::RewriteBudget* budget) {
23 if (budget) { budget->require_nodes(1); }
24 if (const auto number = std::dynamic_pointer_cast<const NumberNode>(argument)) {
25 auto absolute = positive_negative_number(*number);
26 if (!absolute) {
27 return false;
28 }
29 positive = std::move(absolute);
30 return true;
31 }
32 const auto multiply = std::dynamic_pointer_cast<const MultiplyNode>(argument);
33 if (!multiply || multiply->operands().empty()) {
34 return false;
35 }
36 const auto number = std::dynamic_pointer_cast<const NumberNode>(multiply->operands().front());
37 if (!number) {
38 return false;
39 }
40 auto absolute = positive_negative_number(*number);
41 if (!absolute) {
42 return false;
43 }
44 std::vector<std::shared_ptr<const SymbolicNode>> operands;
45 std::size_t nodes = 0;
46 for (const auto& operand : multiply->operands()) {
47 normalization_append(budget, nodes, operands, operand);
48 }
49 if (number->is_negative_one()) {
50 operands.erase(operands.begin());
51 if (budget) { --nodes; }
52 } else {
53 operands.front() = std::move(absolute);
54 }
55 positive = make_normalized_multiply_node(operands, budget);
56 return true;
57}
58}
const std::variant< BigInt, Rational > & value() const noexcept
void require_nodes(std::size_t nodes) const
std::shared_ptr< const NumberNode > positive_negative_number(const NumberNode &number)
std::shared_ptr< const Node > make_node(Args &&... args)
ExprResult integer(Integer)=delete
bool check_negative_arg(const std::shared_ptr< const SymbolicNode > &argument, std::shared_ptr< const SymbolicNode > &positive, detail::RewriteBudget *budget=nullptr)
std::shared_ptr< const SymbolicNode > make_normalized_multiply_node(const std::vector< std::shared_ptr< const SymbolicNode > > &operands, detail::RewriteBudget *budget=nullptr)
ExprResult rational(const Rational &value)
void normalization_append(detail::RewriteBudget *budget, std::size_t &nodes, std::vector< std::shared_ptr< const SymbolicNode > > &children, std::shared_ptr< const SymbolicNode > child)