11 const std::shared_ptr<const SymbolicNode>& node) {
12 const auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node);
13 if (!
mul ||
mul->operands().size() != 2)
return nullptr;
14 for (std::size_t j = 0; j < 2; ++j) {
15 const auto coefficient =
16 std::dynamic_pointer_cast<const NumberNode>(
mul->operands()[j]);
17 if (coefficient && coefficient->is_negative_one()) {
18 return mul->operands()[1 - j];
25 const std::shared_ptr<const SymbolicNode>& pos_operand,
26 const std::shared_ptr<const SymbolicNode>& neg_operand,
Sign target) {
27 const auto lhs_var = std::dynamic_pointer_cast<const VariableNode>(pos_operand);
28 const auto rhs_var = std::dynamic_pointer_cast<const VariableNode>(neg_operand);
29 if (!lhs_var || lhs_var->is_constant() ||
30 !rhs_var || rhs_var->is_constant())
return {};
38 Relation rel{lhs_expr, rhs_expr, RelationalNode::Op::GT};
39 cs2.relational_conditions.push_back(rel);
51 Relation rel{rhs_expr, lhs_expr, RelationalNode::Op::GT};
52 cs2.relational_conditions.push_back(rel);
64 Relation rel{lhs_expr, rhs_expr, RelationalNode::Op::GEQ};
65 cs2.relational_conditions.push_back(rel);
73 const std::vector<std::shared_ptr<const SymbolicNode>>& operands,
Sign target) {
75 for (
const auto& operand : operands) {
76 const auto variable = std::dynamic_pointer_cast<const VariableNode>(operand);
80 if (cs.sign_conditions.empty())
return {};
85 if (
add.operands().size() == 2) {
86 for (std::size_t i = 0; i < 2; ++i) {
88 if (!negative)
continue;
90 if (!result.empty())
return result;
101 const std::shared_ptr<const SymbolicNode>& numerator,
103 const auto num_var = std::dynamic_pointer_cast<const VariableNode>(numerator);
104 const auto den_var = std::dynamic_pointer_cast<const VariableNode>(
denominator);
105 if (!num_var || num_var->is_constant() ||
106 !den_var || den_var->is_constant())
return {};
109 cs1.sign_conditions.emplace_back(num_var->name(),
Sign::Positive);
110 cs1.sign_conditions.emplace_back(den_var->name(),
Sign::Positive);
113 cs2.sign_conditions.emplace_back(num_var->name(),
Sign::Negative);
114 cs2.sign_conditions.emplace_back(den_var->name(),
Sign::Negative);
119 cs1.sign_conditions.emplace_back(num_var->name(),
Sign::Positive);
120 cs1.sign_conditions.emplace_back(den_var->name(),
Sign::Negative);
123 cs2.sign_conditions.emplace_back(num_var->name(),
Sign::Negative);
124 cs2.sign_conditions.emplace_back(den_var->name(),
Sign::Positive);
132 if (
mul.operands().size() == 2) {
133 for (std::size_t i = 0; i < 2; ++i) {
134 const auto power = std::dynamic_pointer_cast<const PowerNode>(
mul.operands()[i]);
136 power ? std::dynamic_pointer_cast<const NumberNode>(
152QueryInterface::QueryConditionSetsResult QueryInterface::query_conditions(
153 const SymbolicExpr& expr, Sign
target)
const {
154 return query_conditions_checked(expr,
target);
157std::vector<QueryInterface::ConditionSet> QueryInterface::query_conditions_impl(
158 const SymbolicExpr& expr,
Sign target)
const {
163 if (var->is_constant())
return {};
165 cs.sign_conditions.emplace_back(var->name(),
target);
177QueryInterface::QueryConditionSetsResult QueryInterface::query_conditions_checked(
178 const SymbolicExpr& expr,
Sign target)
const {
180 expr,
"query_conditions", [&]() {
181 return query_conditions_impl(expr,
target);
std::vector< ConditionSet > ConditionSets
ConditionSets quotient_conditions(const std::shared_ptr< const SymbolicNode > &numerator, const std::shared_ptr< const SymbolicNode > &denominator, Sign target)
ConditionSets product_conditions(const MultiplyNode &mul, Sign target)
QueryInterface::ConditionSet ConditionSet
ConditionSets variable_operand_conditions(const std::vector< std::shared_ptr< const SymbolicNode > > &operands, Sign target)
ConditionSets difference_conditions(const std::shared_ptr< const SymbolicNode > &pos_operand, const std::shared_ptr< const SymbolicNode > &neg_operand, Sign target)
std::shared_ptr< const SymbolicNode > subtracted_operand(const std::shared_ptr< const SymbolicNode > &node)
ConditionSets sum_conditions(const AddNode &add, Sign target)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
Result< T > checked_expression_result(const SymbolicExpr &expr, const std::string &operation, Query &&query)
const std::string & variable
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
const ExprPtr & denominator
Sign
Sign classification for symbols and expressions.
A stored relational constraint between two symbolic expressions.