diff --git a/omnn/math/Integer.h b/omnn/math/Integer.h
index 3cf128e9a..c501abda2 100644
--- a/omnn/math/Integer.h
+++ b/omnn/math/Integer.h
@@ -210,6 +210,7 @@ class Integer
///
///
Valuable IntMod_IsNegativeOrZero() const override { return ca() <= 0 ? 0 : 1; }
+ Valuable NegativeOrZero() const override { return IntMod_IsNegativeOrZero(); }
///
/// Operator 'less' then value to which a param expression is to be evaluated
diff --git a/omnn/math/Valuable.cpp b/omnn/math/Valuable.cpp
index e25828251..b5adf9144 100644
--- a/omnn/math/Valuable.cpp
+++ b/omnn/math/Valuable.cpp
@@ -1,3151 +1,3184 @@
-//
-// Created by Сергей Кривонос on 01.09.17.
-//
-#include "Valuable.h"
-
-#include "e.h"
-#include "i.h"
-#include "Infinity.h"
-#include "pi.h"
-#include "Fraction.h"
-#include "Modulo.h"
-#include "Integer.h"
-#include "VarHost.h"
-#include "Sum.h"
-#include "PrincipalSurd.h"
-
-#include
///
- virtual Valuable IntMod_IsNegativeOrZero() const { return Equals(0) || ((*this - 1) % *this).Equals(-1); }
+ virtual Valuable IntMod_IsNegativeOrZero() const;
///
/// Operator 'less' then value to which a param expression is to be evaluated
@@ -613,6 +614,18 @@ class Valuable
/// An expression that equals zero only when the object is less then param
virtual Valuable IntMod_Less(const Valuable& than) const;
+ ///
+ /// (this < 0) - constraint negative
+ ///
+ /// constraint to negative values: expression that equals zero for given negative *this values
+ virtual Valuable Negative() const;
+
+ ///
+ /// (this <= 0) - constraint negative
+ ///
+ /// constraint values <= 0 : expression that equals zero for given negative or 0 *this values
+ virtual Valuable NegativeOrZero() const;
+
///
/// Operator 'less' then value to which a param expression is to be evaluated
///
diff --git a/omnn/math/test/logic.cpp b/omnn/math/test/logic.cpp
index 9a1407cbb..e85b35f81 100644
--- a/omnn/math/test/logic.cpp
+++ b/omnn/math/test/logic.cpp
@@ -3,6 +3,8 @@
#include "Variable.h"
+#include
+
using namespace omnn::math;
using namespace boost::unit_test;
@@ -50,6 +52,145 @@ BOOST_AUTO_TEST_CASE(Min_operator_test) {
}
}
+BOOST_AUTO_TEST_CASE(Sign_operator_test)
+{
+ DECL_VARS(X);
+ auto SignOperatorExpression = X.Sign();
+ std::cout << "X<0 : " << SignOperatorExpression << std::endl;
+ for (auto x = 10; x--> -10;) {
+ auto sign = std::signbit(x);
+ auto negativeOperatorInstantiation = SignOperatorExpression;
+ Valuable::vars_cont_t evalMap = {{X, x}};
+ std::cout << '\n' << x << "<0 = ";
+ negativeOperatorInstantiation.eval(evalMap);
+ std::cout << " expression that must be equal to zero when true: " << negativeOperatorInstantiation
+ << std::endl;
+
+ negativeOperatorInstantiation.optimize();
+ std::cout << std::endl << "Is " << x << "<0 : " << negativeOperatorInstantiation << std::endl;
+ bool b = {};
+ auto boolLessOrEqualOp = negativeOperatorInstantiation.ToBool();
+ BOOST_TEST(boolLessOrEqualOp == sign);
+ boolLessOrEqualOp.eval(evalMap);
+ BOOST_TEST(boolLessOrEqualOp == sign);
+ if (boolLessOrEqualOp == true) {
+ BOOST_TEST(boolLessOrEqualOp.IsInt());
+ BOOST_TEST(negativeOperatorInstantiation.IsInt());
+ b = negativeOperatorInstantiation.IsInt() && negativeOperatorInstantiation.ca() == 0;
+ std::cout << std::endl << x << "<0 : " << b << std::endl;
+ } else if (boolLessOrEqualOp == false) {
+ BOOST_TEST(boolLessOrEqualOp.IsInt());
+ b = negativeOperatorInstantiation == 0;
+ std::cout << std::endl
+ << x << "<0 : " << b << ' ' << negativeOperatorInstantiation << " != 0" << std::endl;
+ } else {
+ std::cout << std::endl << x << "<0 : " << boolLessOrEqualOp << std::endl;
+ BOOST_TEST(!"boolLessOp must have boolean value");
+ }
+ BOOST_TEST(boolLessOrEqualOp == b);
+
+ auto ok = b == sign;
+ if (!ok) {
+ std::cout << "X=" << x << " " << ok << " bool: " << b << std::endl;
+ BOOST_TEST(ok);
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(Negative_operator_test
+ , *disabled()
+ )
+{
+ DECL_VARS(X);
+ auto NegativeOperatorExpression = X.Negative();
+ std::cout << "X<0 : " << NegativeOperatorExpression << std::endl;
+ for (auto x = 10; x--> -10;) {
+ auto isLessEq = x < 0;
+ auto negativeOperatorInstantiation = NegativeOperatorExpression;
+ Valuable::vars_cont_t evalMap = {{X, x}};
+ std::cout << '\n' << x << "<0 = ";
+ negativeOperatorInstantiation.eval(evalMap);
+ std::cout << " expression that must be equal to zero when true: " << negativeOperatorInstantiation
+ << std::endl;
+
+ negativeOperatorInstantiation.optimize();
+ std::cout << std::endl << "Is " << x << "<0 : " << negativeOperatorInstantiation << std::endl;
+ bool b = {};
+ auto boolLessOrEqualOp = negativeOperatorInstantiation.ToBool();
+ BOOST_TEST(boolLessOrEqualOp == isLessEq);
+ boolLessOrEqualOp.eval(evalMap);
+ BOOST_TEST(boolLessOrEqualOp == isLessEq);
+ if (boolLessOrEqualOp == true) {
+ BOOST_TEST(boolLessOrEqualOp.IsInt());
+ BOOST_TEST(negativeOperatorInstantiation.IsInt());
+ b = negativeOperatorInstantiation.IsInt() && negativeOperatorInstantiation.ca() == 0;
+ std::cout << std::endl << x << "<0 : " << b << std::endl;
+ } else if (boolLessOrEqualOp == false) {
+ BOOST_TEST(boolLessOrEqualOp.IsInt());
+ b = negativeOperatorInstantiation == 0;
+ std::cout << std::endl
+ << x << "<0 : " << b << ' ' << negativeOperatorInstantiation << " != 0" << std::endl;
+ } else {
+ std::cout << std::endl << x << "<0 : " << boolLessOrEqualOp << std::endl;
+ BOOST_TEST(!"boolLessOp must have boolean value");
+ }
+ BOOST_TEST(boolLessOrEqualOp == b);
+
+ auto ok = b == isLessEq;
+ if (!ok) {
+ std::cout << "X=" << x << " " << ok << " bool: " << b << std::endl;
+ BOOST_TEST(ok);
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(NegativeOrZero_operator_test
+ , *disabled()
+ )
+{
+ DECL_VARS(X);
+ auto NegativeOrZeroOperatorExpression = X.NegativeOrZero();
+ std::cout << "X<=0 : " << NegativeOrZeroOperatorExpression << std::endl;
+ for (auto x = 10; x--> -10;) {
+ auto isLessEq = x <= 0;
+ auto negativeOrZeroOperatorInstantiation = NegativeOrZeroOperatorExpression;
+ Valuable::vars_cont_t evalMap = {{X, x}};
+ std::cout << '\n' << x << "<=0 = ";
+ negativeOrZeroOperatorInstantiation.eval(evalMap);
+ std::cout << " expression that must be equal to zero when true: " << negativeOrZeroOperatorInstantiation
+ << std::endl;
+
+ negativeOrZeroOperatorInstantiation.optimize();
+ std::cout << std::endl << "Is " << x << "<=0 : " << negativeOrZeroOperatorInstantiation << std::endl;
+ bool b = {};
+ auto boolLessOrEqualOp = negativeOrZeroOperatorInstantiation.ToBool();
+ BOOST_TEST(boolLessOrEqualOp == isLessEq);
+ boolLessOrEqualOp.eval(evalMap);
+ BOOST_TEST(boolLessOrEqualOp == isLessEq);
+ if (boolLessOrEqualOp == true) {
+ BOOST_TEST(boolLessOrEqualOp.IsInt());
+ BOOST_TEST(negativeOrZeroOperatorInstantiation.IsInt());
+ b = negativeOrZeroOperatorInstantiation.IsInt() && negativeOrZeroOperatorInstantiation.ca() == 0;
+ std::cout << std::endl << x << "<=0 : " << b << std::endl;
+ } else if (boolLessOrEqualOp == false) {
+ BOOST_TEST(boolLessOrEqualOp.IsInt());
+ b = negativeOrZeroOperatorInstantiation == 0;
+ std::cout << std::endl
+ << x << "<=0 : " << b << ' ' << negativeOrZeroOperatorInstantiation << " != 0" << std::endl;
+ } else {
+ std::cout << std::endl << x << "<=0 : " << boolLessOrEqualOp << std::endl;
+ BOOST_TEST(!"boolLessOp must have boolean value");
+ }
+ BOOST_TEST(boolLessOrEqualOp == b);
+
+ auto ok = b == isLessEq;
+ if (!ok) {
+ std::cout << "X=" << x << " Y=0 " << ok << " bool: " << b << std::endl;
+ BOOST_TEST(ok);
+ }
+ }
+}
+
BOOST_AUTO_TEST_CASE(LessOrEqual_operator_test) {
DECL_VARS(X, Y);
auto LE = X.LessOrEqual(Y);