1#define _USE_MATH_DEFINES
9 auto step =
context.consume_steps(0,
"inference.relations");
10 if (!step)
throw step.error();
11 if (
auto var = std::dynamic_pointer_cast<const VariableNode>(operand)) {
12 return var->is_constant()
16 if (
auto num = std::dynamic_pointer_cast<const NumberNode>(operand)) {
18 return num->is_positive();
20 return num->is_zero() ||
num->is_positive();
26 const std::shared_ptr<const SymbolicNode>& operand,
const SymbolicExpr& zero_expr,
28 auto step =
context.consume_steps(1,
"inference.relations");
33 auto gt =
ctx.has_relation_checked(
34 op_expr, zero_expr, RelationalNode::Op::GT,
context);
38 auto geq =
ctx.has_relation_checked(
39 op_expr, zero_expr, RelationalNode::Op::GEQ,
context);
44 bool op_geq = geq.value();
48 if (!op_geq && !op_gt) {
54 if (!op_gt && !op_geq) {
62 const SymbolicExpr& zero_expr,
64 if (
add.operands().empty()) {
68 bool all_gt_zero =
true;
69 bool all_geq_zero =
true;
71 for (
const auto& operand :
add.operands()) {
73 operand, zero_expr, all_gt_zero, all_geq_zero,
context);
90 const SymbolicExpr& zero_expr,
92 const auto& rel_store =
ctx;
93 if (
mul.operands().empty()) {
98 bool all_gt_zero =
true;
100 for (
const auto& operand :
mul.operands()) {
101 auto step =
context.consume_steps(1,
"inference.relations");
102 if (!step)
throw step.error();
104 auto gt = rel_store.has_relation_checked(
105 op_expr, zero_expr, RelationalNode::Op::GT,
context);
127 auto step =
context.consume_steps(1,
"inference.relations");
129 const auto& rel_store =
ctx;
131 if (rhs_num->is_zero() || rhs_num->is_positive()) {
137 if (rhs_var->is_constant() ||
143 auto geq = rel_store.has_relation_checked(
144 rel.
rhs, zero_expr, RelationalNode::Op::GEQ,
context);
145 if (!geq || geq.value())
return geq;
146 return rel_store.has_relation_checked(
147 rel.
rhs, zero_expr, RelationalNode::Op::GT,
context);
151 const SymbolicExpr& expr,
153 auto relations =
ctx.get_visible_relations_checked(
context);
156 std::numeric_limits<std::size_t>::max(),
"inference.relations");
158 for (
const auto& rel : relations.value()) {
159 auto step =
context.consume_steps(1,
"inference.relations");
160 if (!step)
throw step.error();
161 if (rel.op != RelationalNode::Op::GT) {
178 if (nonnegative.value()) {
190 "relation sign inference expression must not be null",
191 "infer_sign_from_relations_checked");
199 if (
add->operands().empty()) {
209 if (
mul->operands().empty()) {
212 auto result = impl_->product_relation_sign(*
mul, zero_expr,
target,
context);
219 return impl_->positive_relation_chain(expr, zero_expr,
context);
223 }
catch (
const CasError& error) {
225 }
catch (
const std::bad_alloc&) {
228 "relation sign inference allocation failed",
229 "infer_sign_from_relations_checked");
230 }
catch (
const std::exception& ex) {
234 "infer_sign_from_relations_checked");
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
std::size_t measure(const std::shared_ptr< const SymbolicNode > &node)
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)
std::shared_ptr< SymbolicExpr > num(int value)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
@ Unknown
Property cannot be determined
@ True
Property definitely holds
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
ExprResult gt(const ExprPtr &lhs, const ExprPtr &rhs)
Result< Tribool > InferenceTriboolResult
SymbolicExpr rhs
Right-hand side expression
Sign
Sign classification for symbols and expressions.
A stored relational constraint between two symbolic expressions.
InferenceTriboolResult positive_relation_chain(const SymbolicExpr &expr, const SymbolicExpr &zero_expr, ComputationContext &context) const
InferenceTriboolResult sum_relation_sign(const AddNode &add, const SymbolicExpr &zero_expr, Sign target, ComputationContext &context) const
bool operand_sign(const std::shared_ptr< const SymbolicNode > &operand, Sign target, ComputationContext &context) const
const AssumptionContext & ctx
Result< bool > relation_rhs_nonnegative(const Relation &rel, const SymbolicExpr &zero_expr, ComputationContext &context) const
Result< void > accumulate_sum_relation_sign(const std::shared_ptr< const SymbolicNode > &operand, const SymbolicExpr &zero_expr, bool &all_gt_zero, bool &all_geq_zero, ComputationContext &context) const
InferenceTriboolResult product_relation_sign(const MultiplyNode &mul, const SymbolicExpr &zero_expr, Sign target, ComputationContext &context) const