1#define _USE_MATH_DEFINES
26 std::uint8_t result = 0;
29 if (!(left &
a) || !(
right &
b))
continue;
39 const InferenceEngine& engine,
40 const std::shared_ptr<const SymbolicNode>& operand,
43 std::uint8_t operand_signs = all_signs;
46 auto fact = engine.query_sign_of_checked(expression, sign,
context);
47 if (!fact)
return fact;
48 if (fact.value() ==
Tribool::True) operand_signs &= sign_set(sign);
50 possible = multiply_sign_sets(possible, operand_signs);
57 const auto wanted = sign_set(
target);
66 if (!defined || defined.value() !=
Tribool::True) {
return defined; }
69 for (
const auto& operand : node.operands()) {
75 std::uint8_t possible = positive_sign;
76 for (
const auto& operand : node.operands()) {
78 if (!result) {
return result; }
84 const InferenceEngine& engine,
const SymbolicExpr& numerator,
87 bool all_defined =
true;
89 for (
const auto* expression : {&numerator, &
denominator}) {
91 if (!defined) {
return defined; }
92 all_defined = all_defined && defined.value() ==
Tribool::True;
98 if (!nonzero) {
return nonzero; }
103 if (!all_defined || !all_real || nonzero.value() !=
Tribool::True)
105 std::uint8_t possible = positive_sign;
107 if (!first) {
return first; }
109 if (!second) {
return second; }
116 if (node.operands().size() != 2) {
119 std::shared_ptr<const SymbolicNode> numerator;
121 for (
const auto& operand : node.operands()) {
122 auto step =
context.consume_steps(1,
"inference.product");
126 const auto power = std::dynamic_pointer_cast<const PowerNode>(operand);
128 ? std::dynamic_pointer_cast<const NumberNode>(
142 }
catch (
const CasError& error) {
144 }
catch (
const std::bad_alloc&) {
146 "division sign inference allocation failed",
"infer_division_sign_checked");
147 }
catch (
const std::exception& ex) {
149 ex.what(),
"infer_division_sign_checked");
156 if (
node.operands().size() == 2) {
157 for (
const auto& operand :
node.operands()) {
158 auto step =
context.consume_steps(1,
"inference.product");
159 if (!step)
throw step.error();
161 std::dynamic_pointer_cast<const PowerNode>(operand);
163 ? std::dynamic_pointer_cast<const NumberNode>(
171 }
catch (
const CasError& error) {
173 }
catch (
const std::bad_alloc&) {
175 "multiplication sign inference allocation failed",
"infer_multiply_sign_checked");
176 }
catch (
const std::exception& ex) {
178 ex.what(),
"infer_multiply_sign_checked");
static Result failure(CasErrc code, std::string message, std::string operation={})
std::uint8_t sign_set(Sign target)
constexpr std::uint8_t negative_sign
std::uint8_t multiply_sign_sets(std::uint8_t left, std::uint8_t right)
constexpr std::uint8_t zero_sign
constexpr std::uint8_t all_signs
constexpr std::uint8_t positive_sign
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
Result< Tribool > query_nonzero_value(const Node &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
Result< Tribool > query_real_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult real(const ExprPtr &expression, ComputationContext &context)
@ Unknown
Property cannot be determined
@ True
Property definitely holds
@ False
Property definitely does not hold
__attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::shared_ptr< SymbolicExpr > & a
Result< Tribool > InferenceTriboolResult
const ExprPtr & denominator
Sign
Sign classification for symbols and expressions.
InferenceTriboolResult quotient_sign(const InferenceEngine &engine, const SymbolicExpr &num_expr, const SymbolicExpr &den_expr, Sign target, ComputationContext &context) const
static InferenceTriboolResult product_parity_sign(std::uint8_t possible, Sign target)
static InferenceTriboolResult real_definedness(const InferenceEngine &engine, const SymbolicNode &node, ComputationContext &context)
InferenceTriboolResult accumulate_product_sign(const InferenceEngine &engine, const std::shared_ptr< const SymbolicNode > &operand, std::uint8_t &possible, ComputationContext &context) const
InferenceTriboolResult product_sign(const InferenceEngine &engine, const MultiplyNode &node, Sign target, ComputationContext &context) const