From 956a7362230bd51205912900d3c8c61b6bf6bf52 Mon Sep 17 00:00:00 2001
From: "Vladimir V. Kisil" <kisilv@maths.leeds.ac.uk>
Date: Mon, 29 Jul 2013 17:13:21 +0100
Subject: [PATCH 2/2] Elaborate mul::info(). Add to mul::info() rules that a)
 a product of two negative entries is positive; b) a
 product of a positive and non-negative entries is
 non-negative.

Signed-off-by: Vladimir V. Kisil <kisilv@maths.leeds.ac.uk>
---
 ginac/mul.cpp |   54 ++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/ginac/mul.cpp b/ginac/mul.cpp
index 763e603..cee5cd7 100644
--- a/ginac/mul.cpp
+++ b/ginac/mul.cpp
@@ -283,10 +283,6 @@ bool mul::info(unsigned inf) const
 		case info_flags::integer:
 		case info_flags::crational:
 		case info_flags::cinteger:
-		case info_flags::positive:
-		case info_flags::nonnegative:
-		case info_flags::posint:
-		case info_flags::nonnegint:
 		case info_flags::even:
 		case info_flags::crational_polynomial:
 		case info_flags::rational_function: {
@@ -309,39 +305,73 @@ bool mul::info(unsigned inf) const
 			}
 			return false;
 		}
+		case info_flags::positive:
 		case info_flags::negative: {
-			bool neg = false;
+			bool pos = true;
 			epvector::const_iterator i = seq.begin(), end = seq.end();
 			while (i != end) {
 				const ex& factor = recombine_pair_to_ex(*i++);
 				if (factor.info(info_flags::positive))
 					continue;
 				else if (factor.info(info_flags::negative))
-					neg = !neg;
+					pos = !pos;
 				else
 					return false;
 			}
 			if (overall_coeff.info(info_flags::negative))
-				neg = !neg;
-			return neg;
+				pos = !pos;
+			return (inf ==info_flags::positive? pos : !pos);
 		}
+		case info_flags::nonnegative: {
+			bool pos = true;
+			epvector::const_iterator i = seq.begin(), end = seq.end();
+			while (i != end) {
+				const ex& factor = recombine_pair_to_ex(*i++);
+				if (factor.info(info_flags::nonnegative) || factor.info(info_flags::positive))
+					continue;
+				else if (factor.info(info_flags::negative))
+					pos = !pos;
+				else
+					return false;
+			}
+			return (overall_coeff.info(info_flags::negative)? pos : !pos);
+		}
+		case info_flags::posint:
 		case info_flags::negint: {
-			bool neg = false;
+			bool pos = true;
 			epvector::const_iterator i = seq.begin(), end = seq.end();
 			while (i != end) {
 				const ex& factor = recombine_pair_to_ex(*i++);
 				if (factor.info(info_flags::posint))
 					continue;
 				else if (factor.info(info_flags::negint))
-					neg = !neg;
+					pos = !pos;
+				else
+					return false;
+			}
+			if (overall_coeff.info(info_flags::negint))
+				pos = !pos;
+			else if (!overall_coeff.info(info_flags::posint))
+				return false;
+			return (inf ==info_flags::posint? pos : !pos); 
+		}
+		case info_flags::nonnegint: {
+			bool pos = true;
+			epvector::const_iterator i = seq.begin(), end = seq.end();
+			while (i != end) {
+				const ex& factor = recombine_pair_to_ex(*i++);
+				if (factor.info(info_flags::nonnegint) || factor.info(info_flags::posint))
+					continue;
+				else if (factor.info(info_flags::negint))
+					pos = !pos;
 				else
 					return false;
 			}
 			if (overall_coeff.info(info_flags::negint))
-				neg = !neg;
+				pos = !pos;
 			else if (!overall_coeff.info(info_flags::posint))
 				return false;
-			return neg;
+			return pos; 
 		}
 	}
 	return inherited::info(inf);
-- 
1.7.10.4

