diff --git a/pom.xml b/pom.xml
index 782c829..67a42c4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com.github.s1ck
gdl
- 0.3.3
+ 0.4
GDL - Graph Definition Language
diff --git a/src/main/java/org/s1ck/gdl/GDLLoader.java b/src/main/java/org/s1ck/gdl/GDLLoader.java
index 5adc1e0..1f74c38 100644
--- a/src/main/java/org/s1ck/gdl/GDLLoader.java
+++ b/src/main/java/org/s1ck/gdl/GDLLoader.java
@@ -309,6 +309,7 @@ public void exitGraph(GDLParser.GraphContext ctx) {
*/
@Override
public void exitQuery(GDLParser.QueryContext ctx) {
+ predicates = Predicate.unfoldTemporalComparisons(predicates);
for(Vertex v : vertices) {
addPredicates(Predicate.fromGraphElement(v, getDefaultVertexLabel()));
}
diff --git a/src/main/java/org/s1ck/gdl/model/comparables/time/MaxTimePoint.java b/src/main/java/org/s1ck/gdl/model/comparables/time/MaxTimePoint.java
index 1701691..6348a42 100644
--- a/src/main/java/org/s1ck/gdl/model/comparables/time/MaxTimePoint.java
+++ b/src/main/java/org/s1ck/gdl/model/comparables/time/MaxTimePoint.java
@@ -1,5 +1,14 @@
package org.s1ck.gdl.model.comparables.time;
+import org.s1ck.gdl.model.predicates.Predicate;
+import org.s1ck.gdl.model.predicates.booleans.And;
+import org.s1ck.gdl.model.predicates.booleans.Not;
+import org.s1ck.gdl.model.predicates.booleans.Or;
+import org.s1ck.gdl.model.predicates.expressions.Comparison;
+import org.s1ck.gdl.utils.Comparator;
+
+import java.util.ArrayList;
+
/**
* Represents a MAX(p1,...,pn) term, where p1...pn are TimePoints
*/
@@ -22,8 +31,8 @@ public long evaluate(){
long mn = Long.MIN_VALUE;
for (TimePoint p:args){
long eval = p.evaluate();
- if(eval==-1){
- return -1;
+ if(eval== UNDEFINED){
+ return UNDEFINED;
}
if(eval > mn){
mn = eval;
@@ -38,7 +47,7 @@ public long getLowerBound(){
long res = Long.MIN_VALUE;
for (TimePoint p: args){
long val = p.getLowerBound();
- if(val>-1 && val>res){
+ if(val!=UNDEFINED && val>res){
res = val;
}
}
@@ -61,4 +70,110 @@ public long getUpperBound(){
return res;
}
+ @Override
+ protected Predicate unfoldEQ(TimePoint arg){
+ //MAX(p1...pn) == x <=> exists pi: (pi>=p1 AND pi>=p2...AND pi>=pn) AND (pi==x)
+
+ // // the predicates (pi>=p1 AND pi>=p2...AND pi>=pn) AND (pi==x)
+ Predicate[] piPredicates = new Predicate[args.size()];
+ for(int i= 0; i=p1), (pi>=p2),..., (pi>=pn)
+ ArrayList comparisons = new ArrayList<>();
+ for(int j=0; j=p1 AND pi>=p2...AND pi>=pn)
+ And conj = new And(new Comparison(args.get(i), Comparator.EQ, arg),
+ comparisons.get(0));
+ for(int k=1; k=p1 AND pi>=p2...AND pi>=pn) AND (pi==x))
+ Or result = new Or(piPredicates[0], piPredicates[1]);
+ for(int l=2; l for all pi: (pip1 OR pi>p2...OR pi>pn) OR (pi!=x)
+ Predicate[] piPredicates = new Predicate[args.size()];
+ for(int i= 0; i comparisons = new ArrayList<>();
+ for(int j=0; jp1 OR pi>p2...OR pi>pn)
+ Or disj = new Or(new Comparison(args.get(i), Comparator.NEQ, arg),
+ comparisons.get(0));
+ for(int k=1; k x <=> p1>x OR p2>x...OR pn>x
+ Or disjGt = new Or(new Comparison(args.get(0), Comparator.GT, arg),
+ new Comparison(args.get(1), Comparator.GT, arg));
+ for (int i=2; i= x <=> p1>=x OR p2>=x...OR pn>=x
+ Or disjGte = new Or(new Comparison(args.get(0), Comparator.GTE, arg),
+ new Comparison(args.get(1), Comparator.GTE, arg));
+ for(int i=2; i p1 p1<=x AND p2<=x...AND pn<=x
+ And disjGt = new And(new Comparison(args.get(0), Comparator.LTE, arg),
+ new Comparison(args.get(1), Comparator.LTE, arg));
+ for (int i=2; i-1 && val < res){
+ if(val!=UNDEFINED && val < res){
res = val;
}
}
return res;
}
+
+ @Override
+ protected Predicate unfoldEQ(TimePoint arg){
+ //MIN(p1...pn) == x <=> exists pi: (pi<=p1 AND pi<=p2...AND pi<=pn) AND (pi==x)
+
+ // the predicates (pi<=p1 AND pi<=p2...AND pi<=pn) AND (pi==x)
+ Predicate[] piPredicates = new Predicate[args.size()];
+ for(int i= 0; i comparisons = new ArrayList<>();
+ for(int j=0; j for all pi: (pi>p1 OR pi>p2...OR pi>pn) OR (pi!=x)
+
+ // the predicates (pi>p1 OR pi>p2...OR pi>pn) OR (pi!=x)
+ Predicate[] piPredicates = new Predicate[args.size()];
+ for(int i= 0; ip1), (pi>p2),..., (pi>pn)
+ ArrayList comparisons = new ArrayList<>();
+ for(int j=0; jp1 OR pi>p2...OR pi>pn)
+ Or disj = new Or(new Comparison(args.get(i), Comparator.NEQ, arg),
+ comparisons.get(0));
+ for(int k=1; kp1 OR pi>p2...OR pi>pn) OR (pi!=x))
+ And result = new And(piPredicates[0], piPredicates[1]);
+ for(int l=2; l x <=> p1>x AND p2>x...AND pn>x
+ And conjGt = new And(new Comparison(args.get(0), Comparator.GT, arg),
+ new Comparison(args.get(1), Comparator.GT, arg));
+ for (int i=2; i= x <=> p1>=x AND p2>=x...AND pn>=x
+ And conjGte = new And(new Comparison(args.get(0), Comparator.GTE, arg),
+ new Comparison(args.get(1), Comparator.GTE, arg));
+ for(int i=2; i p1 p1<=x OR p2<=x ... OR pn<=x
+ Or disjLte = new Or(new Comparison(args.get(0), Comparator.LTE, arg),
+ new Comparison(args.get(1), Comparator.LTE, arg));
+ for(int i=2; i getVariables() {
+ return timePoint.getVariables();
}
@Override
public long evaluate(){
- long ret = 0;
- for (TimePoint p: args){
- long p_val = p.evaluate();
- if(p_val == -1){
- return -1;
- }
- ret +=p_val;
+ long tp = timePoint.evaluate();
+ if(tp==UNDEFINED){
+ return UNDEFINED;
}
- return ret;
+ return tp + constant.getMillis();
}
@Override
public long getLowerBound(){
- // lower bound of a sum of positive elements is the sum of all known elements
- long ret = 0;
- for (TimePoint p: args){
- ret += p.getLowerBound();
+ long tp_lb = timePoint.getLowerBound();
+ if(tp_lb == UNDEFINED){
+ return constant.getMillis();
}
- return ret;
+ return tp_lb + constant.getMillis();
}
@Override
public long getUpperBound(){
- // upper bound of a sum of positive elements is either the sum of them (if all known)
- // or the maximum long value (if not all known)
- long ret = 0;
- for (TimePoint p: args){
- long up_p = p.getUpperBound();
- if(up_p == Long.MAX_VALUE){
- return Long.MAX_VALUE;
- }
- ret += up_p;
+ long tp_ub = timePoint.getUpperBound();
+ if(tp_ub == Long.MAX_VALUE){
+ return Long.MAX_VALUE;
}
- return ret;
+ return tp_ub + constant.getMillis();
}
+
}
diff --git a/src/main/java/org/s1ck/gdl/model/comparables/time/TimeAtom.java b/src/main/java/org/s1ck/gdl/model/comparables/time/TimeAtom.java
new file mode 100644
index 0000000..0d33fd2
--- /dev/null
+++ b/src/main/java/org/s1ck/gdl/model/comparables/time/TimeAtom.java
@@ -0,0 +1,53 @@
+package org.s1ck.gdl.model.comparables.time;
+
+import org.s1ck.gdl.model.predicates.Predicate;
+import org.s1ck.gdl.model.predicates.expressions.Comparison;
+import org.s1ck.gdl.utils.Comparator;
+
+/**
+ * Base class for atoms in a {@link TimeTerm}, e.g. simple timestamps
+ */
+public abstract class TimeAtom extends TimePoint {
+
+ @Override
+ public Predicate unfoldComparison(Comparator comparator, TimePoint arg){
+ // nothing to unfold here
+ return new Comparison(this, comparator, arg);
+ }
+
+ @Override
+ protected Predicate unfoldEQ(TimePoint arg){
+ // nothing to unfold here
+ return new Comparison(this, Comparator.EQ, arg);
+ }
+
+ @Override
+ protected Predicate unfoldNEQ(TimePoint arg){
+ // nothing to unfold here
+ return new Comparison(this, Comparator.NEQ, arg);
+ }
+
+ @Override
+ protected Predicate unfoldGT(TimePoint arg){
+ // nothing to unfold here
+ return new Comparison(this, Comparator.GT, arg);
+ }
+
+ @Override
+ protected Predicate unfoldGTE(TimePoint arg){
+ // nothing to unfold here
+ return new Comparison(this, Comparator.GTE, arg);
+ }
+
+ @Override
+ protected Predicate unfoldLT(TimePoint arg){
+ // nothing to unfold here
+ return new Comparison(this, Comparator.LT, arg);
+ }
+
+ @Override
+ protected Predicate unfoldLTE(TimePoint arg){
+ // nothing to unfold here
+ return new Comparison(this, Comparator.LTE, arg);
+ }
+}
diff --git a/src/main/java/org/s1ck/gdl/model/comparables/time/TimeConstant.java b/src/main/java/org/s1ck/gdl/model/comparables/time/TimeConstant.java
deleted file mode 100644
index 4bccb1a..0000000
--- a/src/main/java/org/s1ck/gdl/model/comparables/time/TimeConstant.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.s1ck.gdl.model.comparables.time;
-
-import java.util.ArrayList;
-
-/**
- * Represents a fixed number of milliseconds
- * Not really a timestamp, but needed for certain related computations (e.g. deltas)
- */
-public class TimeConstant extends TimePoint{
-
- /**
- * The number of miliseconds wrapped by this class
- */
- private long millis;
-
-
- public TimeConstant(long absoluteMillis){
- if(absoluteMillis<0){
- throw new IllegalArgumentException("expected positive value");
- }
- this.millis = absoluteMillis;
- }
-
- /**
- * Create a constant of size days+hours+minutes+seconds+millis
- * @param days number of days
- * @param hours number of hours [0-23]
- * @param minutes number of minutes [0-59]
- * @param seconds number of seconds [0-59]
- * @param millis number of millis [0-999]
- */
- public TimeConstant(int days, int hours, int minutes, int seconds, int millis){
- if( (hours<0 || hours>23) || (minutes<0 || minutes>59) || (seconds<0||seconds>59) || (millis<0 || millis>999)){
- throw new IllegalArgumentException("not a valid timestamp");
- }
- this.millis = millis;
- this.millis+=1000*seconds;
- this.millis+=1000*60*minutes;
- this.millis+=1000*60*60*hours;
- this.millis+=1000*60*60*24*days;
- }
-
- /**
- * Return the wrapped number of milliseconds
- * @return number of milliseconds
- */
- public long getMillis(){
- return millis;
- }
-
- @Override
- public ArrayList getVariables(){
- return new ArrayList<>();
- }
-
- @Override
- public long evaluate(){
- return millis;
- }
-
- @Override
- public long getLowerBound(){
- return millis;
- }
-
- @Override
- public long getUpperBound(){
- return millis;
- }
-
-}
diff --git a/src/main/java/org/s1ck/gdl/model/comparables/time/TimeLiteral.java b/src/main/java/org/s1ck/gdl/model/comparables/time/TimeLiteral.java
index 97dd47a..963b5a9 100644
--- a/src/main/java/org/s1ck/gdl/model/comparables/time/TimeLiteral.java
+++ b/src/main/java/org/s1ck/gdl/model/comparables/time/TimeLiteral.java
@@ -1,13 +1,16 @@
package org.s1ck.gdl.model.comparables.time;
-import java.text.SimpleDateFormat;
+import org.s1ck.gdl.model.predicates.expressions.Comparison;
+
import java.time.*;
-import java.util.*;
+import java.util.ArrayList;
+
+import org.s1ck.gdl.utils.Comparator;
/**
* Represents a constant Timestamp. Wraps a java.time.LocalDateTime
*/
-public class TimeLiteral extends TimePoint {
+public class TimeLiteral extends TimeAtom {
/**
* The wrapped LocalDateTime
@@ -130,6 +133,7 @@ public long getUpperBound(){
return getMilliseconds();
}
+
/**
* Utility method to handle input strings like 1970-01-01. They are not recognized by LocalDateTime.
* Thus they must be augmented to e.g. 1970-01-01T00:00
diff --git a/src/main/java/org/s1ck/gdl/model/comparables/time/TimePoint.java b/src/main/java/org/s1ck/gdl/model/comparables/time/TimePoint.java
index 9e09eeb..f435b73 100644
--- a/src/main/java/org/s1ck/gdl/model/comparables/time/TimePoint.java
+++ b/src/main/java/org/s1ck/gdl/model/comparables/time/TimePoint.java
@@ -1,6 +1,8 @@
package org.s1ck.gdl.model.comparables.time;
import org.s1ck.gdl.model.comparables.ComparableExpression;
+import org.s1ck.gdl.model.predicates.Predicate;
+import org.s1ck.gdl.utils.Comparator;
import java.util.ArrayList;
@@ -9,6 +11,12 @@
*/
public abstract class TimePoint implements ComparableExpression {
+ /**
+ * Used in evaluation methods to indicate that the value (in millis) of a TimePoint can
+ * not be determined (yet).
+ */
+ public static final long UNDEFINED = -1L;
+
/**
* Returns null, no variable involved in a timestamp by default
* Not often used in implementations, as typically more than one variable can be involved
@@ -44,4 +52,76 @@ public String getVariable() {
*/
public abstract long getUpperBound();
+ /**
+ * Translates a term "this comparator arg" into a Predicate over comparisons.
+ * E.g. "Max(p1,p2) > x" would translate to "(p1 > x) AND (p2 > x)"
+ * Used to replace complex TimePoints like MAX, MIN by Comparisons of simple TimePoints
+ * @param comparator the comparator of the term to be translated
+ * @param arg the second argument of the term to be translated (first argument is this)
+ * @return the translated term
+ */
+ public Predicate unfoldComparison(Comparator comparator, TimePoint arg){
+ if(comparator == Comparator.EQ){
+ return unfoldEQ(arg);
+ }
+ else if(comparator == Comparator.NEQ){
+ return unfoldNEQ(arg);
+ }
+ else if(comparator == Comparator.GT){
+ return unfoldGT(arg);
+ }
+ else if(comparator == Comparator.GTE){
+ return unfoldGTE(arg);
+ }
+ else if(comparator == Comparator.LT){
+ return unfoldLT(arg);
+ }
+ else if(comparator == Comparator.LTE){
+ return unfoldLTE(arg);
+ }
+ return null;
+ }
+
+ /**
+ * Unfolds a comparison "this == arg":
+ * @param arg the second argument in the comparison to unfold
+ * @return unfolded comparison
+ */
+ protected abstract Predicate unfoldEQ(TimePoint arg);
+
+ /**
+ * Unfolds a comparison "this <> arg":
+ * @param arg the second argument in the comparison to unfold
+ * @return unfolded comparison
+ */
+ protected abstract Predicate unfoldNEQ(TimePoint arg);
+
+ /**
+ * Unfolds a comparison "this > arg":
+ * @param arg the second argument in the comparison to unfold
+ * @return unfolded comparison
+ */
+ protected abstract Predicate unfoldGT(TimePoint arg);
+
+ /**
+ * Unfolds a comparison "this >= arg":
+ * @param arg the second argument in the comparison to unfold
+ * @return unfolded comparison
+ */
+ protected abstract Predicate unfoldGTE(TimePoint arg);
+
+ /**
+ * Unfolds a comparison "this < arg":
+ * @param arg the second argument in the comparison to unfold
+ * @return unfolded comparison
+ */
+ protected abstract Predicate unfoldLT(TimePoint arg);
+
+ /**
+ * Unfolds a comparison "this <= arg":
+ * @param arg the second argument in the comparison to unfold
+ * @return unfolded comparison
+ */
+ protected abstract Predicate unfoldLTE(TimePoint arg);
+
}
diff --git a/src/main/java/org/s1ck/gdl/model/comparables/time/TimeSelector.java b/src/main/java/org/s1ck/gdl/model/comparables/time/TimeSelector.java
index d9b0d1f..9611bdf 100644
--- a/src/main/java/org/s1ck/gdl/model/comparables/time/TimeSelector.java
+++ b/src/main/java/org/s1ck/gdl/model/comparables/time/TimeSelector.java
@@ -1,13 +1,16 @@
package org.s1ck.gdl.model.comparables.time;
import org.s1ck.gdl.model.comparables.ComparableExpression;
+import org.s1ck.gdl.model.predicates.Predicate;
+import org.s1ck.gdl.model.predicates.expressions.Comparison;
+import org.s1ck.gdl.utils.Comparator;
import java.util.ArrayList;
/**
* Represents a timestamp selection of a graph variable, e.g. v.VAL_FROM selects the VAL_FROM value of a graph element v
*/
-public class TimeSelector extends TimePoint{
+public class TimeSelector extends TimeAtom{
/**
* The variable name
@@ -73,7 +76,7 @@ public TimeField getTimeProp(){
@Override
public long evaluate(){
- return -1;
+ return UNDEFINED;
}
@Override
@@ -86,6 +89,36 @@ public long getUpperBound(){
return Long.MAX_VALUE;
}
+ @Override
+ protected Predicate unfoldEQ(TimePoint arg){
+ return new Comparison(this, Comparator.EQ, arg);
+ }
+
+ @Override
+ protected Predicate unfoldNEQ(TimePoint arg){
+ return new Comparison(this, Comparator.NEQ, arg);
+ }
+
+ @Override
+ protected Predicate unfoldGT(TimePoint arg){
+ return new Comparison(this, Comparator.GT, arg);
+ }
+
+ @Override
+ protected Predicate unfoldGTE(TimePoint arg){
+ return new Comparison(this, Comparator.GTE, arg);
+ }
+
+ @Override
+ protected Predicate unfoldLT(TimePoint arg){
+ return new Comparison(this, Comparator.LT, arg);
+ }
+
+ @Override
+ protected Predicate unfoldLTE(TimePoint arg){
+ return new Comparison(this, Comparator.LTE, arg);
+ }
+
/**
* Parses a string to a TimeField
* @param field a string equal to "tx_from", "tx_to", "val_from", "val_to" (cases irrelevant)
diff --git a/src/main/java/org/s1ck/gdl/model/comparables/time/TimeTerm.java b/src/main/java/org/s1ck/gdl/model/comparables/time/TimeTerm.java
index 0e66fc7..0792479 100644
--- a/src/main/java/org/s1ck/gdl/model/comparables/time/TimeTerm.java
+++ b/src/main/java/org/s1ck/gdl/model/comparables/time/TimeTerm.java
@@ -1,5 +1,8 @@
package org.s1ck.gdl.model.comparables.time;
+import org.s1ck.gdl.model.predicates.Predicate;
+import org.s1ck.gdl.utils.Comparator;
+
import java.util.ArrayList;
import java.util.Collections;
@@ -25,6 +28,9 @@ public abstract class TimeTerm extends TimePoint {
* @param args the arguments
*/
protected TimeTerm(TimePoint...args){
+ if(args.length < 2){
+ throw new IllegalArgumentException("need at least 2 arguments");
+ }
this.args = new ArrayList<>();
Collections.addAll(this.args, args);
}
diff --git a/src/main/java/org/s1ck/gdl/model/comparables/time/util/TimeConstant.java b/src/main/java/org/s1ck/gdl/model/comparables/time/util/TimeConstant.java
new file mode 100644
index 0000000..3a097bc
--- /dev/null
+++ b/src/main/java/org/s1ck/gdl/model/comparables/time/util/TimeConstant.java
@@ -0,0 +1,51 @@
+package org.s1ck.gdl.model.comparables.time.util;
+
+/**
+ * Represents a constant duration via a fixed number of milliseconds
+ * Not really a timestamp, but needed for certain related computations (e.g. deltas)
+ */
+public class TimeConstant{
+
+ /**
+ * The number of milliseconds wrapped by this class
+ */
+ private long millis;
+
+
+ /**
+ * Create a constant of size days+hours+minutes+seconds+millis (in millis)
+ * @param days number of days
+ * @param hours number of hours [0-23]
+ * @param minutes number of minutes [0-59]
+ * @param seconds number of seconds [0-59]
+ * @param millis number of millis [0-999]
+ */
+ public TimeConstant(int days, int hours, int minutes, int seconds, int millis){
+ if( (hours<0 || hours>23) || (minutes<0 || minutes>59) || (seconds<0||seconds>59) || (millis <0 || millis >999)){
+ throw new IllegalArgumentException("not a valid timestamp");
+ }
+ long sum = millis;
+ sum +=1000*seconds;
+ sum +=1000*60*minutes;
+ sum +=1000*60*60*hours;
+ sum +=1000*60*60*24*days;
+ this.millis = sum;
+ }
+
+ /**
+ * Creates a constant from the given milliseconds
+ * @param millis size of the constant in milliseconds
+ */
+ public TimeConstant(long millis){
+ this.millis = millis;
+ }
+
+ /**
+ * Return the wrapped number of milliseconds
+ * @return number of milliseconds
+ */
+ public long getMillis(){
+ return millis;
+ }
+
+}
diff --git a/src/main/java/org/s1ck/gdl/model/predicates/Predicate.java b/src/main/java/org/s1ck/gdl/model/predicates/Predicate.java
index e3bf102..86e0c70 100644
--- a/src/main/java/org/s1ck/gdl/model/predicates/Predicate.java
+++ b/src/main/java/org/s1ck/gdl/model/predicates/Predicate.java
@@ -69,6 +69,34 @@ static List fromGraphElement(GraphElement element, String defaultLabe
return predicates;
}
+ /**
+ * Unfolds a predicate, i.e. reduces complex temporal predicates to simple comparisons
+ * This is needed for predicates containing complex temporal elements like e.g. MIN, MAX.
+ * These elements can be reduced to simple comparisons, thus yielding a predicate only
+ * consisting of comparisons between literals.
+ * e.g. [(MAX(a,b)> t1) AND (t2t1) OR (b>t1)) AND ((t2 fromGraphElement(GraphElement element, String defaultLabe
* @return referenced variables
*/
Set getVariables();
+
+
+
+ /**
+ * Unfolds a predicate, but only the left hand side of each temporal comparison.
+ * e.g. [(MAX(a,b)> t1) AND (t2t1) OR (b>t1)) AND ((t2 getVariables() {
return variables;
}
+ @Override
+ public Predicate switchSides(){
+ return new And(lhs.switchSides(), rhs.switchSides());
+ }
+
+ @Override
+ public Predicate unfoldTemporalComparisonsLeft(){
+ return new And(lhs.unfoldTemporalComparisonsLeft(), rhs.unfoldTemporalComparisonsLeft());
+ }
+
@Override
public String toString() {
return String.format("(%s AND %s)", lhs, rhs);
}
+
+ @Override
+ public boolean equals(Object o){
+ if(o==null){
+ return false;
+ }
+ if(!this.getClass().equals(o.getClass())){
+ return false;
+ }
+ And that = (And)o;
+ return (that.lhs.equals(this.lhs) && that.rhs.equals(this.rhs));
+ }
}
diff --git a/src/main/java/org/s1ck/gdl/model/predicates/booleans/Not.java b/src/main/java/org/s1ck/gdl/model/predicates/booleans/Not.java
index dbce0d2..dba7cab 100644
--- a/src/main/java/org/s1ck/gdl/model/predicates/booleans/Not.java
+++ b/src/main/java/org/s1ck/gdl/model/predicates/booleans/Not.java
@@ -43,8 +43,30 @@ public Set getVariables() {
return expression.getVariables();
}
+ @Override
+ public Predicate unfoldTemporalComparisonsLeft(){
+ return new Not(expression.unfoldTemporalComparisonsLeft());
+ }
+
+ @Override
+ public Predicate switchSides(){
+ return new Not(expression.switchSides());
+ }
+
@Override
public String toString() {
return String.format("(NOT %s)", expression);
}
+
+ @Override
+ public boolean equals(Object o){
+ if(o==null){
+ return false;
+ }
+ if(!this.getClass().equals(o.getClass())){
+ return false;
+ }
+ Not that = (Not)o;
+ return that.expression.equals(this.expression);
+ }
}
diff --git a/src/main/java/org/s1ck/gdl/model/predicates/booleans/Or.java b/src/main/java/org/s1ck/gdl/model/predicates/booleans/Or.java
index 351b007..6ae52b8 100644
--- a/src/main/java/org/s1ck/gdl/model/predicates/booleans/Or.java
+++ b/src/main/java/org/s1ck/gdl/model/predicates/booleans/Or.java
@@ -50,8 +50,30 @@ public Set getVariables() {
return variables;
}
+ @Override
+ public Predicate unfoldTemporalComparisonsLeft(){
+ return new Or(lhs.unfoldTemporalComparisonsLeft(), rhs.unfoldTemporalComparisonsLeft());
+ }
+
+ @Override
+ public Predicate switchSides(){
+ return new Or(lhs.switchSides(), rhs.switchSides());
+ }
+
@Override
public String toString() {
return String.format("(%s OR %s)", lhs, rhs);
}
+
+ @Override
+ public boolean equals(Object o){
+ if(o==null){
+ return false;
+ }
+ if(!this.getClass().equals(o.getClass())){
+ return false;
+ }
+ Or that = (Or)o;
+ return (that.lhs.equals(this.lhs) && that.rhs.equals(this.rhs));
+ }
}
diff --git a/src/main/java/org/s1ck/gdl/model/predicates/booleans/Xor.java b/src/main/java/org/s1ck/gdl/model/predicates/booleans/Xor.java
index 164f50c..9349904 100644
--- a/src/main/java/org/s1ck/gdl/model/predicates/booleans/Xor.java
+++ b/src/main/java/org/s1ck/gdl/model/predicates/booleans/Xor.java
@@ -38,6 +38,16 @@ public Predicate[] getArguments() {
return new Predicate[] { lhs, rhs };
}
+ @Override
+ public Predicate unfoldTemporalComparisonsLeft(){
+ return new Xor(lhs.unfoldTemporalComparisonsLeft(), rhs.unfoldTemporalComparisonsLeft());
+ }
+
+ @Override
+ public Predicate switchSides(){
+ return new Xor(lhs.switchSides(), rhs.switchSides());
+ }
+
/**
* Returns a set of variables referenced by the predicates
* @return set of variables
@@ -54,4 +64,16 @@ public Set getVariables() {
public String toString() {
return String.format("(%s XOR %s)", lhs, rhs);
}
+
+ @Override
+ public boolean equals(Object o){
+ if(o==null){
+ return false;
+ }
+ if(!this.getClass().equals(o.getClass())){
+ return false;
+ }
+ Xor that = (Xor)o;
+ return (that.lhs.equals(this.lhs) && that.rhs.equals(this.rhs));
+ }
}
diff --git a/src/main/java/org/s1ck/gdl/model/predicates/expressions/Comparison.java b/src/main/java/org/s1ck/gdl/model/predicates/expressions/Comparison.java
index c6f6755..2f933ec 100644
--- a/src/main/java/org/s1ck/gdl/model/predicates/expressions/Comparison.java
+++ b/src/main/java/org/s1ck/gdl/model/predicates/expressions/Comparison.java
@@ -16,6 +16,7 @@
package org.s1ck.gdl.model.predicates.expressions;
+import org.s1ck.gdl.model.comparables.time.TimePoint;
import org.s1ck.gdl.model.predicates.Predicate;
import org.s1ck.gdl.model.comparables.ComparableExpression;
import org.s1ck.gdl.utils.Comparator;
@@ -75,6 +76,49 @@ public ComparableExpression[] getComparableExpressions() {
return list;
}
+ /**
+ * Comparisons can be temporal or not (TimePoints can only be compared to TimePoints, enforced by the grammar)
+ * Method returns whether the comparison is temporal
+ * @return whether the comparison is temporal
+ */
+ public boolean isTemporal(){
+ //time data can only be compared to time data, thus it suffices to check whether lhs a TimePoint
+ return lhs instanceof TimePoint;
+ }
+
+ @Override
+ public Predicate unfoldTemporalComparisonsLeft(){
+ if (!isTemporal()){
+ return this;
+ }
+ return ((TimePoint)lhs).unfoldComparison(comparator, (TimePoint)rhs);
+ }
+
+ @Override
+ public Comparison switchSides(){
+ Comparator newComp = null;
+ if(comparator == Comparator.EQ){
+ newComp = Comparator.EQ;
+ }
+ else if(comparator == Comparator.NEQ){
+ newComp = Comparator.NEQ;
+ }
+ else if(comparator == Comparator.GT){
+ newComp = Comparator.LT;
+ }
+ else if(comparator == Comparator.GTE){
+ newComp = Comparator.LTE;
+ }
+ else if(comparator == Comparator.LT){
+ newComp = Comparator.GT;
+ }
+ //LTE
+ else{
+ newComp = Comparator.GTE;
+ }
+ return new Comparison(rhs, newComp, lhs);
+ }
+
/**
* Returns a set of variables referenced by the predicates
* @return set of variables
diff --git a/src/test/java/org/s1ck/gdl/comparables/time/ComparisonTest.java b/src/test/java/org/s1ck/gdl/comparables/time/ComparisonTest.java
new file mode 100644
index 0000000..af4b7fb
--- /dev/null
+++ b/src/test/java/org/s1ck/gdl/comparables/time/ComparisonTest.java
@@ -0,0 +1,49 @@
+package org.s1ck.gdl.comparables.time;
+import org.junit.Test;
+import org.s1ck.gdl.model.comparables.PropertySelector;
+import org.s1ck.gdl.model.comparables.time.TimeLiteral;
+import org.s1ck.gdl.model.comparables.time.TimeSelector;
+import org.s1ck.gdl.model.predicates.expressions.Comparison;
+import org.s1ck.gdl.utils.Comparator;
+
+import static org.junit.Assert.*;
+
+public class ComparisonTest {
+ @Test
+ public void testIsTemporal(){
+ TimeSelector ts = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral tl = new TimeLiteral("1970-01-01T01:01:01");
+ Comparison timeComp = new Comparison(ts, Comparator.NEQ, tl);
+ assertTrue(timeComp.isTemporal());
+
+ PropertySelector ps1 = new PropertySelector("p", "prop");
+ PropertySelector ps2 = new PropertySelector("q", "prop");
+ Comparison propertyComp = new Comparison(ps1, Comparator.LT, ps2);
+ assertFalse(propertyComp.isTemporal());
+ }
+
+ @Test
+ public void testSwitchSides(){
+ TimeSelector ts = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral tl = new TimeLiteral("1970-01-01T01:01:01");
+
+ Comparison timeComp = new Comparison(ts, Comparator.EQ, tl);
+ assertEquals(timeComp.switchSides(), new Comparison(tl, Comparator.EQ, ts));
+
+ timeComp = new Comparison(ts, Comparator.NEQ, tl);
+ assertEquals(timeComp.switchSides(), new Comparison(tl, Comparator.NEQ, ts));
+
+ timeComp = new Comparison(ts, Comparator.LT, tl);
+ assertEquals(timeComp.switchSides(), new Comparison(tl, Comparator.GT, ts));
+
+ timeComp = new Comparison(ts, Comparator.LTE, tl);
+ assertEquals(timeComp.switchSides(), new Comparison(tl, Comparator.GTE, ts));
+
+ timeComp = new Comparison(ts, Comparator.GTE, tl);
+ assertEquals(timeComp.switchSides(), new Comparison(tl, Comparator.LTE, ts));
+
+ timeComp = new Comparison(ts, Comparator.GT, tl);
+ assertEquals(timeComp.switchSides(), new Comparison(tl, Comparator.LT, ts));
+ }
+
+}
diff --git a/src/test/java/org/s1ck/gdl/comparables/time/MaxTimeTest.java b/src/test/java/org/s1ck/gdl/comparables/time/MaxTimeTest.java
index 2e3417b..0e05497 100644
--- a/src/test/java/org/s1ck/gdl/comparables/time/MaxTimeTest.java
+++ b/src/test/java/org/s1ck/gdl/comparables/time/MaxTimeTest.java
@@ -1,9 +1,12 @@
package org.s1ck.gdl.comparables.time;
import org.junit.Test;
import org.s1ck.gdl.model.comparables.time.*;
+import org.s1ck.gdl.model.predicates.Predicate;
+import org.s1ck.gdl.model.predicates.booleans.And;
+import org.s1ck.gdl.model.predicates.booleans.Or;
+import org.s1ck.gdl.model.predicates.expressions.Comparison;
+import org.s1ck.gdl.utils.Comparator;
-import java.util.ArrayList;
-import java.util.Arrays;
import static org.junit.Assert.assertEquals;
@@ -116,4 +119,172 @@ public void maxMinTest4(){
assertEquals(mx.getUpperBound(), Long.MAX_VALUE);
assertEquals(mx.getLowerBound(), l5.evaluate());
}
+
+ @Test
+ public void unfoldEQTest(){
+ TimeLiteral p1 = new TimeLiteral("2020-04-10T12:30:00");
+ TimeSelector p2 = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral p3 = new TimeLiteral("1970-01-01T01:01:01");
+ MaxTimePoint mn = new MaxTimePoint(p1, p2, p3);
+ TimeLiteral arg = new TimeLiteral("2020-04-10T12:28:45");
+
+ Predicate expected =
+ new Or(
+ new Or(
+ new And(
+ new And(
+ new Comparison(p1, Comparator.EQ, arg),
+ new Comparison(p1, Comparator.GTE, p2)
+ ),
+ new Comparison(p1, Comparator.GTE, p3)
+ ),
+ new And(
+ new And(
+ new Comparison(p2, Comparator.EQ, arg),
+ new Comparison(p2, Comparator.GTE, p1)
+ ),
+ new Comparison(p2, Comparator.GTE, p3)
+ )
+ ),
+ new And(
+ new And(
+ new Comparison(p3, Comparator.EQ, arg),
+ new Comparison(p3, Comparator.GTE, p1)
+ ),
+ new Comparison(p3, Comparator.GTE, p2)
+ )
+ );
+
+ Predicate unfolded = mn.unfoldComparison(Comparator.EQ, arg);
+ System.out.println(unfolded);
+ assertEquals(expected, unfolded);
+ }
+
+ @Test
+ public void unfoldNEQTest(){
+ TimeLiteral p1 = new TimeLiteral("2020-04-10T12:30:00");
+ TimeSelector p2 = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral p3 = new TimeLiteral("1970-01-01T01:01:01");
+ MaxTimePoint mn = new MaxTimePoint(p1, p2, p3);
+ TimeLiteral arg = new TimeLiteral("2020-04-10T12:28:45");
+
+ Predicate expected =
+ new And(
+ new And(
+ new Or(
+ new Or(
+ new Comparison(p1, Comparator.NEQ, arg),
+ new Comparison(p1, Comparator.LT, p2)
+ ),
+ new Comparison(p1, Comparator.LT, p3)
+ ),
+ new Or(
+ new Or(
+ new Comparison(p2, Comparator.NEQ, arg),
+ new Comparison(p2, Comparator.LT, p1)
+ ),
+ new Comparison(p2, Comparator.LT, p3)
+ )
+ ),
+ new Or(
+ new Or(
+ new Comparison(p3, Comparator.NEQ, arg),
+ new Comparison(p3, Comparator.LT, p1)
+ ),
+ new Comparison(p3, Comparator.LT,p2)
+ )
+ );
+
+ Predicate unfolded = mn.unfoldComparison(Comparator.NEQ, arg);
+ System.out.println(unfolded);
+ assertEquals(expected, unfolded);
+ }
+
+ @Test
+ public void unfoldGTTest(){
+ TimeLiteral p1 = new TimeLiteral("2020-04-10T12:30:00");
+ TimeSelector p2 = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral p3 = new TimeLiteral("1970-01-01T01:01:01");
+ MaxTimePoint mn = new MaxTimePoint(p1, p2, p3);
+ TimeLiteral arg = new TimeLiteral("2020-04-10T12:28:45");
+
+ Predicate expected =
+ new Or(
+ new Or(
+ new Comparison(p1, Comparator.GT, arg),
+ new Comparison(p2, Comparator.GT, arg)
+ ),
+ new Comparison(p3, Comparator.GT, arg)
+ );
+
+ Predicate unfolded = mn.unfoldComparison(Comparator.GT, arg);
+ System.out.println(unfolded);
+ assertEquals(expected, unfolded);
+ }
+
+ @Test
+ public void unfoldGTETest(){
+ TimeLiteral p1 = new TimeLiteral("2020-04-10T12:30:00");
+ TimeSelector p2 = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral p3 = new TimeLiteral("1970-01-01T01:01:01");
+ MaxTimePoint mn = new MaxTimePoint(p1, p2, p3);
+ TimeLiteral arg = new TimeLiteral("2020-04-10T12:28:45");
+
+ Predicate expected =
+ new Or(
+ new Or(
+ new Comparison(p1, Comparator.GTE, arg),
+ new Comparison(p2, Comparator.GTE, arg)
+ ),
+ new Comparison(p3, Comparator.GTE, arg)
+ );
+
+ Predicate unfolded = mn.unfoldComparison(Comparator.GTE, arg);
+ System.out.println(unfolded);
+ assertEquals(expected, unfolded);
+ }
+
+ @Test
+ public void unfoldLTTest(){
+ TimeLiteral p1 = new TimeLiteral("2020-04-10T12:30:00");
+ TimeSelector p2 = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral p3 = new TimeLiteral("1970-01-01T01:01:01");
+ MaxTimePoint mn = new MaxTimePoint(p1, p2, p3);
+ TimeLiteral arg = new TimeLiteral("2020-04-10T12:28:45");
+
+ Predicate expected =
+ new And(
+ new And(
+ new Comparison(p1, Comparator.LT, arg),
+ new Comparison(p2, Comparator.LT, arg)
+ ),
+ new Comparison(p3, Comparator.LT, arg)
+ );
+
+ Predicate unfolded = mn.unfoldComparison(Comparator.LT, arg);
+ System.out.println(unfolded);
+ assertEquals(expected, unfolded);
+ }
+
+ @Test
+ public void unfoldLTETest(){
+ TimeLiteral p1 = new TimeLiteral("2020-04-10T12:30:00");
+ TimeSelector p2 = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral p3 = new TimeLiteral("1970-01-01T01:01:01");
+ MaxTimePoint mn = new MaxTimePoint(p1, p2, p3);
+ TimeLiteral arg = new TimeLiteral("2020-04-10T12:28:45");
+
+ Predicate expected =
+ new And(
+ new And(
+ new Comparison(p1, Comparator.LTE, arg),
+ new Comparison(p2, Comparator.LTE, arg)
+ ),
+ new Comparison(p3, Comparator.LTE, arg)
+ );
+
+ Predicate unfolded = mn.unfoldComparison(Comparator.LTE, arg);
+ System.out.println(unfolded);
+ assertEquals(expected, unfolded);
+ }
}
diff --git a/src/test/java/org/s1ck/gdl/comparables/time/MinTimeTest.java b/src/test/java/org/s1ck/gdl/comparables/time/MinTimeTest.java
index 4f1854c..b58b25d 100644
--- a/src/test/java/org/s1ck/gdl/comparables/time/MinTimeTest.java
+++ b/src/test/java/org/s1ck/gdl/comparables/time/MinTimeTest.java
@@ -5,6 +5,12 @@
import org.s1ck.gdl.model.comparables.time.MinTimePoint;
import org.s1ck.gdl.model.comparables.time.TimeLiteral;
import org.s1ck.gdl.model.comparables.time.TimeSelector;
+import org.s1ck.gdl.model.predicates.Predicate;
+import org.s1ck.gdl.model.predicates.booleans.And;
+import org.s1ck.gdl.model.predicates.booleans.Not;
+import org.s1ck.gdl.model.predicates.booleans.Or;
+import org.s1ck.gdl.model.predicates.expressions.Comparison;
+import org.s1ck.gdl.utils.Comparator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -121,4 +127,176 @@ public void minMaxTest4(){
assertEquals(mn.getUpperBound(), l1.evaluate());
assertEquals(mn.getLowerBound(), 0);
}
+
+ @Test
+ public void unfoldEQTest(){
+ TimeLiteral p1 = new TimeLiteral("2020-04-10T12:30:00");
+ TimeSelector p2 = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral p3 = new TimeLiteral("1970-01-01T01:01:01");
+ MinTimePoint mn = new MinTimePoint(p1, p2, p3);
+ TimeLiteral arg = new TimeLiteral("2020-04-10T12:28:45");
+
+ Predicate expected =
+ new Or(
+ new Or(
+ new And(
+ new And(
+ new Comparison(p1, Comparator.EQ, arg),
+ new Comparison(p1, Comparator.LTE, p2)
+ ),
+ new Comparison(p1, Comparator.LTE, p3)
+ ),
+ new And(
+ new And(
+ new Comparison(p2, Comparator.EQ, arg),
+ new Comparison(p2, Comparator.LTE, p1)
+ ),
+ new Comparison(p2, Comparator.LTE, p3)
+ )
+ ),
+ new And(
+ new And(
+ new Comparison(p3, Comparator.EQ, arg),
+ new Comparison(p3, Comparator.LTE, p1)
+ ),
+ new Comparison(p3, Comparator.LTE, p2)
+ )
+ );
+
+ Predicate unfolded = mn.unfoldComparison(Comparator.EQ, arg);
+ System.out.println(unfolded);
+ assertEquals(expected, unfolded);
+ }
+
+ @Test
+ public void unfoldNEQTest(){
+ TimeLiteral p1 = new TimeLiteral("2020-04-10T12:30:00");
+ TimeSelector p2 = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral p3 = new TimeLiteral("1970-01-01T01:01:01");
+ MinTimePoint mn = new MinTimePoint(p1, p2, p3);
+ TimeLiteral arg = new TimeLiteral("2020-04-10T12:28:45");
+
+ Predicate expected =
+ new And(
+ new And(
+ new Or(
+ new Or(
+ new Comparison(p1, Comparator.NEQ, arg),
+ new Comparison(p1, Comparator.GT, p2)
+ ),
+ new Comparison(p1, Comparator.GT, p3)
+ ),
+ new Or(
+ new Or(
+ new Comparison(p2, Comparator.NEQ, arg),
+ new Comparison(p2, Comparator.GT, p1)
+ ),
+ new Comparison(p2, Comparator.GT, p3)
+ )
+ ),
+ new Or(
+ new Or(
+ new Comparison(p3, Comparator.NEQ, arg),
+ new Comparison(p3, Comparator.GT, p1)
+ ),
+ new Comparison(p3, Comparator.GT,p2)
+ )
+ );
+
+ Predicate unfolded = mn.unfoldComparison(Comparator.NEQ, arg);
+ System.out.println(unfolded);
+ assertEquals(expected, unfolded);
+ }
+
+ @Test
+ public void unfoldGTTest(){
+ TimeLiteral p1 = new TimeLiteral("2020-04-10T12:30:00");
+ TimeSelector p2 = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral p3 = new TimeLiteral("1970-01-01T01:01:01");
+ MinTimePoint mn = new MinTimePoint(p1, p2, p3);
+ TimeLiteral arg = new TimeLiteral("2020-04-10T12:28:45");
+
+ Predicate expected =
+ new And(
+ new And(
+ new Comparison(p1, Comparator.GT, arg),
+ new Comparison(p2, Comparator.GT, arg)
+ ),
+ new Comparison(p3, Comparator.GT, arg)
+ );
+
+ Predicate unfolded = mn.unfoldComparison(Comparator.GT, arg);
+ System.out.println(unfolded);
+ assertEquals(expected, unfolded);
+ }
+
+ @Test
+ public void unfoldGTETest(){
+ TimeLiteral p1 = new TimeLiteral("2020-04-10T12:30:00");
+ TimeSelector p2 = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral p3 = new TimeLiteral("1970-01-01T01:01:01");
+ MinTimePoint mn = new MinTimePoint(p1, p2, p3);
+ TimeLiteral arg = new TimeLiteral("2020-04-10T12:28:45");
+
+ Predicate expected =
+ new And(
+ new And(
+ new Comparison(p1, Comparator.GTE, arg),
+ new Comparison(p2, Comparator.GTE, arg)
+ ),
+ new Comparison(p3, Comparator.GTE, arg)
+ );
+
+ Predicate unfolded = mn.unfoldComparison(Comparator.GTE, arg);
+ System.out.println(unfolded);
+ assertEquals(expected, unfolded);
+ }
+
+ @Test
+ public void unfoldLTTest(){
+ TimeLiteral p1 = new TimeLiteral("2020-04-10T12:30:00");
+ TimeSelector p2 = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral p3 = new TimeLiteral("1970-01-01T01:01:01");
+ MinTimePoint mn = new MinTimePoint(p1, p2, p3);
+ TimeLiteral arg = new TimeLiteral("2020-04-10T12:28:45");
+
+ Predicate expected =
+ new Or(
+ new Or(
+ new Comparison(p1, Comparator.LT, arg),
+ new Comparison(p2, Comparator.LT, arg)
+ ),
+ new Comparison(p3, Comparator.LT, arg)
+ );
+
+ Predicate unfolded = mn.unfoldComparison(Comparator.LT, arg);
+ System.out.println(unfolded);
+ assertEquals(expected, unfolded);
+ }
+
+ @Test
+ public void unfoldLTETest(){
+ TimeLiteral p1 = new TimeLiteral("2020-04-10T12:30:00");
+ TimeSelector p2 = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeLiteral p3 = new TimeLiteral("1970-01-01T01:01:01");
+ MinTimePoint mn = new MinTimePoint(p1, p2, p3);
+ TimeLiteral arg = new TimeLiteral("2020-04-10T12:28:45");
+
+ Predicate expected =
+ new Or(
+ new Or(
+ new Comparison(p1, Comparator.LTE, arg),
+ new Comparison(p2, Comparator.LTE, arg)
+ ),
+ new Comparison(p3, Comparator.LTE, arg)
+ );
+
+ Predicate unfolded = mn.unfoldComparison(Comparator.LTE, arg);
+ System.out.println(unfolded);
+ assertEquals(expected, unfolded);
+ }
+
+
+
+
}
diff --git a/src/test/java/org/s1ck/gdl/comparables/time/PlusTimeTest.java b/src/test/java/org/s1ck/gdl/comparables/time/PlusTimeTest.java
index f575c5b..3e5a5fe 100644
--- a/src/test/java/org/s1ck/gdl/comparables/time/PlusTimeTest.java
+++ b/src/test/java/org/s1ck/gdl/comparables/time/PlusTimeTest.java
@@ -2,6 +2,9 @@
import org.junit.Test;
import org.s1ck.gdl.model.comparables.time.*;
+import org.s1ck.gdl.model.comparables.time.util.TimeConstant;
+import org.s1ck.gdl.model.predicates.expressions.Comparison;
+import org.s1ck.gdl.utils.Comparator;
import static org.junit.Assert.assertEquals;
@@ -10,11 +13,10 @@ public class PlusTimeTest {
@Test
public void simplePlusTest(){
TimeLiteral l1 = new TimeLiteral("2017-01-12T08:00");
- TimeLiteral l2 = new TimeLiteral("2005-08-12T17:21:43");
- TimeLiteral l3 = new TimeLiteral("2019-04-05");
+ TimeConstant c = new TimeConstant(1000);
- PlusTimePoint p = new PlusTimePoint(l1,l2,l3);
- long sum = l1.getMilliseconds() + l2.getMilliseconds() + l3.getMilliseconds();
+ PlusTimePoint p = new PlusTimePoint(l1,c);
+ long sum = l1.getMilliseconds() + c.getMillis();
assertEquals(p.evaluate(), sum);
assertEquals(p.getLowerBound(), p.evaluate());
assertEquals(p.getUpperBound(), p.evaluate());
@@ -23,16 +25,13 @@ public void simplePlusTest(){
}
@Test
- public void mixedPlusTest(){
- TimeLiteral l1 = new TimeLiteral("2017-01-12T08:00");
- TimeLiteral l2 = new TimeLiteral("2005-08-12T17:21:43");
- TimeLiteral l3 = new TimeLiteral("2019-04-05");
- TimeSelector s1 = new TimeSelector("p", TimeSelector.TimeField.VAL_FROM);
-
- PlusTimePoint p = new PlusTimePoint(l1, s1, l2,l3);
- long sum = l1.getMilliseconds() + l2.getMilliseconds() + l3.getMilliseconds();
- assertEquals(p.evaluate(), -1);
- assertEquals(p.getLowerBound(), sum);
+ public void selectorPlusTest(){
+ TimeSelector s = new TimeSelector("p", TimeSelector.TimeField.VAL_FROM);
+ TimeConstant c = new TimeConstant(1234);
+ PlusTimePoint p = new PlusTimePoint(s,c);
+
+ assertEquals(p.evaluate(), TimePoint.UNDEFINED);
+ assertEquals(p.getLowerBound(), 1234);
assertEquals(p.getUpperBound(), Long.MAX_VALUE);
assertEquals(p.getVariables().size(),1);
@@ -40,29 +39,67 @@ public void mixedPlusTest(){
}
@Test
- public void selectorPlusTest(){
- TimeSelector s1 = new TimeSelector("p", TimeSelector.TimeField.VAL_TO);
- TimeSelector s2 = new TimeSelector("q", TimeSelector.TimeField.TX_FROM);
- PlusTimePoint p = new PlusTimePoint(s1, s2);
- assertEquals(p.evaluate(), -1);
- assertEquals(p.getLowerBound(), 0);
- assertEquals(p.getUpperBound(), Long.MAX_VALUE);
+ public void maxPlusTest(){
+ TimeLiteral l1 = new TimeLiteral("2017-01-12");
+ TimeLiteral l2 = new TimeLiteral("2017-01-12T08:00");
+ MaxTimePoint mx1 = new MaxTimePoint(l1,l2);
+ TimeConstant c = new TimeConstant(1);
+ PlusTimePoint p = new PlusTimePoint(mx1, c);
+ assertEquals(p.evaluate(), l2.getMilliseconds()+1);
+ assertEquals(p.evaluate(), p.getLowerBound());
+ assertEquals(p.evaluate(), p.getUpperBound());
+
+ // now with undetermined maximum
+ TimeSelector s1 = new TimeSelector("x", "tx_to");
+ MaxTimePoint mx2 = new MaxTimePoint(l1, s1);
+ PlusTimePoint p2 = new PlusTimePoint(mx2, c);
+ assertEquals(p2.evaluate(), TimePoint.UNDEFINED);
+ assertEquals(p2.getLowerBound(), l1.getMilliseconds()+c.getMillis());
+ assertEquals(p2.getUpperBound(), Long.MAX_VALUE);
}
@Test
- public void minMaxPlusTest(){
+ public void minPlusTest(){
TimeLiteral l1 = new TimeLiteral("2017-01-12");
TimeLiteral l2 = new TimeLiteral("2017-01-12T08:00");
- MaxTimePoint mx1 = new MaxTimePoint(l1,l2);
- TimeLiteral l3 = new TimeLiteral("2019-04-05");
- TimeLiteral l4 = new TimeLiteral("2019-04-05T01:02:31");
- MinTimePoint mn1 = new MinTimePoint(l3,l4);
+ MinTimePoint mn1 = new MinTimePoint(l1,l2);
+ TimeConstant c = new TimeConstant(1);
- PlusTimePoint p = new PlusTimePoint(mx1, mn1);
- long sum = l2.getMilliseconds()+l3.getMilliseconds();
- assertEquals(p.evaluate(), sum);
+ PlusTimePoint p = new PlusTimePoint(mn1, c);
+ assertEquals(p.evaluate(), l1.getMilliseconds()+1);
assertEquals(p.evaluate(), p.getLowerBound());
assertEquals(p.evaluate(), p.getUpperBound());
+
+ // now with undetermined minimum
+ TimeSelector s1 = new TimeSelector("x", "tx_to");
+ MinTimePoint mn2 = new MinTimePoint(l1, s1);
+ PlusTimePoint p2 = new PlusTimePoint(mn2, c);
+ assertEquals(p2.evaluate(), TimePoint.UNDEFINED);
+ assertEquals(p2.getLowerBound(), c.getMillis());
+ assertEquals(p2.getUpperBound(), l1.getMilliseconds()+c.getMillis());
+ }
+
+ @Test
+ public void unfoldPredicateTest(){
+ TimeLiteral lit = new TimeLiteral("2020-04-10T12:00:00");
+ TimeConstant c = new TimeConstant(1000);
+ PlusTimePoint plus = new PlusTimePoint(lit, c);
+ TimeSelector s = new TimeSelector("x", TimeSelector.TimeField.VAL_TO);
+ //expected values
+ Comparison cEq = new Comparison(plus, Comparator.EQ, s);
+ Comparison cNeq = new Comparison(plus, Comparator.NEQ, s);
+ Comparison cGt = new Comparison(plus, Comparator.GT, s);
+ Comparison cGte = new Comparison(plus, Comparator.GTE, s);
+ Comparison cLt = new Comparison(plus, Comparator.LT, s);
+ Comparison cLte = new Comparison(plus, Comparator.LTE, s);
+
+ assertEquals(plus.unfoldComparison(Comparator.EQ, s), cEq);
+ assertEquals(plus.unfoldComparison(Comparator.NEQ, s), cNeq);
+ assertEquals(plus.unfoldComparison(Comparator.GT, s), cGt);
+ assertEquals(plus.unfoldComparison(Comparator.GTE, s), cGte);
+ assertEquals(plus.unfoldComparison(Comparator.LT, s), cLt);
+ assertEquals(plus.unfoldComparison(Comparator.LTE, s), cLte);
+
}
}
diff --git a/src/test/java/org/s1ck/gdl/comparables/time/TimeConstantTest.java b/src/test/java/org/s1ck/gdl/comparables/time/TimeConstantTest.java
index 8be06a5..e4f85ea 100644
--- a/src/test/java/org/s1ck/gdl/comparables/time/TimeConstantTest.java
+++ b/src/test/java/org/s1ck/gdl/comparables/time/TimeConstantTest.java
@@ -1,7 +1,6 @@
package org.s1ck.gdl.comparables.time;
-import org.junit.Assert;
import org.junit.Test;
-import org.s1ck.gdl.model.comparables.time.TimeConstant;
+import org.s1ck.gdl.model.comparables.time.util.TimeConstant;
import org.s1ck.gdl.model.comparables.time.TimeLiteral;
import static org.junit.Assert.assertEquals;
@@ -12,9 +11,6 @@ public class TimeConstantTest {
public void constantTest(){
TimeConstant c = new TimeConstant(1000);
assertEquals(c.getMillis(), 1000);
- assertEquals(c.evaluate(), c.getLowerBound());
- assertEquals(c.getLowerBound(), c.getUpperBound());
- assertEquals(c.getUpperBound(), c.getMillis());
int days = 23;
int hours = 11;
@@ -22,10 +18,10 @@ public void constantTest(){
int seconds = 42;
int millis = 1;
TimeConstant c2 = new TimeConstant(days, hours, minutes, seconds, millis);
- TimeLiteral c2lit = new TimeLiteral(c2.getMillis());
- assertEquals(c2lit.getDay(), days+1);
- assertEquals(c2lit.getHour(), hours);
- assertEquals(c2lit.getMinute(), minutes);
- assertEquals(c2lit.getSecond(), seconds);
+
+ int expected_millis = millis + 1000*seconds + (1000*60)*minutes + (1000*60*60)*hours +
+ (1000*60*60*24)*days;
+ assertEquals(expected_millis, c2.getMillis());
+
}
}
diff --git a/src/test/java/org/s1ck/gdl/comparables/time/TimeLiteralTest.java b/src/test/java/org/s1ck/gdl/comparables/time/TimeLiteralTest.java
index eb39104..4ba06e2 100644
--- a/src/test/java/org/s1ck/gdl/comparables/time/TimeLiteralTest.java
+++ b/src/test/java/org/s1ck/gdl/comparables/time/TimeLiteralTest.java
@@ -1,6 +1,9 @@
package org.s1ck.gdl.comparables.time;
import org.junit.Test;
import org.s1ck.gdl.model.comparables.time.TimeLiteral;
+import org.s1ck.gdl.model.comparables.time.TimeSelector;
+import org.s1ck.gdl.model.predicates.expressions.Comparison;
+import org.s1ck.gdl.utils.Comparator;
import static org.junit.Assert.assertEquals;
@@ -43,4 +46,25 @@ public void stringInitTest(){
assertEquals(tl2.getMinute(),0);
assertEquals(tl2.getSecond(), 0);
}
+
+ @Test
+ public void unfoldPredicateTest(){
+ TimeLiteral literal = new TimeLiteral("1970-02-01T15:23:05");
+ TimeSelector s = new TimeSelector("x", TimeSelector.TimeField.VAL_TO);
+ //expected values
+ Comparison cEq = new Comparison(literal, Comparator.EQ, s);
+ Comparison cNeq = new Comparison(literal, Comparator.NEQ, s);
+ Comparison cGt = new Comparison(literal, Comparator.GT, s);
+ Comparison cGte = new Comparison(literal, Comparator.GTE, s);
+ Comparison cLt = new Comparison(literal, Comparator.LT, s);
+ Comparison cLte = new Comparison(literal, Comparator.LTE, s);
+
+ assertEquals(literal.unfoldComparison(Comparator.EQ, s), cEq);
+ assertEquals(literal.unfoldComparison(Comparator.NEQ, s), cNeq);
+ assertEquals(literal.unfoldComparison(Comparator.GT, s), cGt);
+ assertEquals(literal.unfoldComparison(Comparator.GTE, s), cGte);
+ assertEquals(literal.unfoldComparison(Comparator.LT, s), cLt);
+ assertEquals(literal.unfoldComparison(Comparator.LTE, s), cLte);
+
+ }
}
diff --git a/src/test/java/org/s1ck/gdl/comparables/time/TimeSelectorTest.java b/src/test/java/org/s1ck/gdl/comparables/time/TimeSelectorTest.java
index 9b74627..f9d43d6 100644
--- a/src/test/java/org/s1ck/gdl/comparables/time/TimeSelectorTest.java
+++ b/src/test/java/org/s1ck/gdl/comparables/time/TimeSelectorTest.java
@@ -1,6 +1,8 @@
package org.s1ck.gdl.comparables.time;
import org.junit.Test;
import org.s1ck.gdl.model.comparables.time.TimeSelector;
+import org.s1ck.gdl.model.predicates.expressions.Comparison;
+import org.s1ck.gdl.utils.Comparator;
import static org.junit.Assert.assertEquals;
@@ -16,4 +18,25 @@ public void selectorTest(){
assertEquals(selector.getUpperBound(), Long.MAX_VALUE);
assertEquals(selector.getTimeProp(), TimeSelector.TimeField.TX_FROM);
}
+
+ @Test
+ public void unfoldPredicateTest(){
+ TimeSelector selector = new TimeSelector("var", TimeSelector.TimeField.VAL_TO);
+ TimeSelector s2 = new TimeSelector("x", TimeSelector.TimeField.VAL_TO);
+ //expected values
+ Comparison cEq = new Comparison(selector, Comparator.EQ, s2);
+ Comparison cNeq = new Comparison(selector, Comparator.NEQ, s2);
+ Comparison cGt = new Comparison(selector, Comparator.GT, s2);
+ Comparison cGte = new Comparison(selector, Comparator.GTE, s2);
+ Comparison cLt = new Comparison(selector, Comparator.LT, s2);
+ Comparison cLte = new Comparison(selector, Comparator.LTE, s2);
+
+ assertEquals(selector.unfoldComparison(Comparator.EQ, s2), cEq);
+ assertEquals(selector.unfoldComparison(Comparator.NEQ, s2), cNeq);
+ assertEquals(selector.unfoldComparison(Comparator.GT, s2), cGt);
+ assertEquals(selector.unfoldComparison(Comparator.GTE, s2), cGte);
+ assertEquals(selector.unfoldComparison(Comparator.LT, s2), cLt);
+ assertEquals(selector.unfoldComparison(Comparator.LTE, s2), cLte);
+
+ }
}
diff --git a/src/test/java/org/s1ck/gdl/predicates/PredicateTest.java b/src/test/java/org/s1ck/gdl/predicates/PredicateTest.java
new file mode 100644
index 0000000..a5eb7e0
--- /dev/null
+++ b/src/test/java/org/s1ck/gdl/predicates/PredicateTest.java
@@ -0,0 +1,413 @@
+package org.s1ck.gdl.predicates;
+
+import org.junit.Test;
+import org.s1ck.gdl.model.comparables.ComparableExpression;
+import org.s1ck.gdl.model.comparables.time.MaxTimePoint;
+import org.s1ck.gdl.model.comparables.time.MinTimePoint;
+import org.s1ck.gdl.model.comparables.time.TimeLiteral;
+import org.s1ck.gdl.model.comparables.time.TimeSelector;
+import org.s1ck.gdl.model.predicates.Predicate;
+import org.s1ck.gdl.model.predicates.booleans.And;
+import org.s1ck.gdl.model.predicates.booleans.Not;
+import org.s1ck.gdl.model.predicates.booleans.Or;
+import org.s1ck.gdl.model.predicates.booleans.Xor;
+import org.s1ck.gdl.model.predicates.expressions.Comparison;
+import org.s1ck.gdl.utils.Comparator;
+
+import java.util.ArrayList;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class PredicateTest {
+
+ @Test
+ // only comparison, only one complex type of depth 1
+ public void testSimpleUnfold(){
+ //--------------------------------------------------
+ // DATA
+ //------------------------------------------------
+ TimeLiteral literal = new TimeLiteral("1970-01-01");
+ TimeSelector m1 = new TimeSelector("p", TimeSelector.TimeField.VAL_FROM);
+ TimeLiteral m2 = new TimeLiteral("1972-01-01");
+ MaxTimePoint mx1 = new MaxTimePoint(m1, m2);
+
+ //---------------------------------------------------
+ // EQ
+ //---------------------------------------------------
+ Comparison c1 = new Comparison(literal, Comparator.EQ, mx1);
+ Comparison c2 = new Comparison(mx1, Comparator.EQ, literal);
+ Or expected1 = new Or(
+ new And(
+ new Comparison(m1, Comparator.EQ, literal),
+ new Comparison(m1, Comparator.GTE, m2)
+ ),
+ new And(
+ new Comparison(m2, Comparator.EQ, literal),
+ new Comparison(m2, Comparator.GTE, m1)
+ )
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c1), expected1);
+ // expected 1 with switched sides
+ Or expected2 = new Or(
+ new And(
+ new Comparison(literal, Comparator.EQ, m1),
+ new Comparison(m2, Comparator.LTE, m1)
+ ),
+ new And(
+ new Comparison(literal, Comparator.EQ, m2),
+ new Comparison(m1, Comparator.LTE, m2)
+ )
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c2), expected2);
+
+ //--------------------------------------------------------------
+ //NEQ
+ //-------------------------------------------------------------
+ Comparison c3 = new Comparison(literal, Comparator.NEQ, mx1);
+ Comparison c4 = new Comparison(mx1, Comparator.NEQ, literal);
+
+ And expected3 = new And(
+ new Or(
+ new Comparison(m1, Comparator.NEQ, literal),
+ new Comparison(m1, Comparator.LT, m2)
+ ),
+ new Or(
+ new Comparison(m2, Comparator.NEQ, literal),
+ new Comparison(m2, Comparator.LT, m1)
+ )
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c3), expected3);
+ //expected3 with switched sides
+ And expected4 = new And(
+ new Or(
+ new Comparison(literal, Comparator.NEQ, m1),
+ new Comparison(m2, Comparator.GT, m1)
+ ),
+ new Or(
+ new Comparison(literal, Comparator.NEQ, m2),
+ new Comparison(m1, Comparator.GT, m2)
+ )
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c4), expected4);
+
+ //--------------------------------------------------------------
+ // GT
+ //-------------------------------------------------------------
+ Comparison c5 = new Comparison(literal, Comparator.GT, mx1);
+ Comparison c6 = new Comparison(mx1, Comparator.GT, literal);
+
+ And expected5= new And(
+ new Comparison(m1, Comparator.LT, literal),
+ new Comparison(m2, Comparator.LT, literal)
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c5), expected5);
+
+ Or expected6 = new Or(
+ new Comparison(literal, Comparator.LT, m1),
+ new Comparison(literal, Comparator.LT, m2)
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c6), expected6);
+
+ //--------------------------------------------------------------
+ // GTE
+ //-------------------------------------------------------------
+ Comparison c7 = new Comparison(literal, Comparator.GTE, mx1);
+ Comparison c8 = new Comparison(mx1, Comparator.GTE, literal);
+
+ And expected7= new And(
+ new Comparison(m1, Comparator.LTE, literal),
+ new Comparison(m2, Comparator.LTE, literal)
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c7), expected7);
+
+ Or expected8 = new Or(
+ new Comparison(literal, Comparator.LTE, m1),
+ new Comparison(literal, Comparator.LTE, m2)
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c8), expected8);
+
+ //--------------------------------------------------------------
+ // LT
+ //-------------------------------------------------------------
+ Comparison c9 = new Comparison(literal, Comparator.LT, mx1);
+ Comparison c10 = new Comparison(mx1, Comparator.LT, literal);
+
+ Or expected9= new Or(
+ new Comparison(m1, Comparator.GT, literal),
+ new Comparison(m2, Comparator.GT, literal)
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c9), expected9);
+
+ And expected10 = new And(
+ new Comparison(literal, Comparator.GT, m1),
+ new Comparison(literal, Comparator.GT, m2)
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c10), expected10);
+
+ //--------------------------------------------------------------
+ // LTE
+ //-------------------------------------------------------------
+ Comparison c11 = new Comparison(literal, Comparator.LTE, mx1);
+ Comparison c12 = new Comparison(mx1, Comparator.LTE, literal);
+
+ Or expected11= new Or(
+ new Comparison(m1, Comparator.GTE, literal),
+ new Comparison(m2, Comparator.GTE, literal)
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c7), expected7);
+
+ And expected12 = new And(
+ new Comparison(literal, Comparator.GTE, m1),
+ new Comparison(literal, Comparator.GTE, m2)
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c8), expected8);
+
+ }
+
+ @Test
+ public void testUnfoldWithTwoTempPredicates(){
+ TimeSelector mx1 = new TimeSelector("mx1", TimeSelector.TimeField.VAL_FROM);
+ TimeSelector mx2 = new TimeSelector("mx2", TimeSelector.TimeField.VAL_TO);
+ MaxTimePoint mx = new MaxTimePoint(mx1, mx2);
+
+ TimeSelector mn1 = new TimeSelector("mn1", TimeSelector.TimeField.TX_FROM);
+ TimeSelector mn2 = new TimeSelector("mn2", TimeSelector.TimeField.TX_TO);
+ MinTimePoint mn = new MinTimePoint(mn1, mn2);
+
+ //-----------------------------------------------
+ // compare max to min
+ //-------------------------------------------------
+ Comparison c1 = new Comparison(mn, Comparator.GT, mx);
+ And expected1 = new And(
+ new And(
+ new Comparison(mx1, Comparator.LT, mn1),
+ new Comparison(mx2, Comparator.LT, mn1)
+ ),
+ new And(
+ new Comparison(mx1, Comparator.LT, mn2),
+ new Comparison(mx2, Comparator.LT, mn2)
+ )
+ );
+ assertEquals(expected1, Predicate.unfoldTemporalComparisons(c1));
+
+ Comparison c2 = new Comparison(mx, Comparator.GT, mn);
+ Or expected2 = new Or(
+ new Or(
+ new Comparison(mn1, Comparator.LT, mx1),
+ new Comparison(mn2, Comparator.LT, mx1)
+ ),
+ new Or(
+ new Comparison(mn1, Comparator.LT, mx2),
+ new Comparison(mn2, Comparator.LT, mx2)
+ )
+ );
+ assertEquals(expected2, Predicate.unfoldTemporalComparisons(c2));
+
+ //---------------------------------------------------------------
+ // compare MAX to MAX
+ //--------------------------------------------------------------
+ Comparison c3 = new Comparison(mx, Comparator.EQ, mx);
+ Or expected3 = new Or(
+ new And(
+ // mx == mx1
+ new Or(
+ new And(
+ new Comparison(mx1, Comparator.EQ, mx1),
+ new Comparison(mx1, Comparator.GTE, mx2)
+ ),
+ new And(
+ new Comparison(mx2, Comparator.EQ, mx1),
+ new Comparison(mx2, Comparator.GTE, mx1)
+ )
+ ),
+ // mx1 >= mx2
+ new Comparison(mx2, Comparator.LTE, mx1)
+ ),
+ new And(
+ // mx == mx2
+ new Or(
+ new And(
+ new Comparison(mx1, Comparator.EQ, mx2),
+ new Comparison(mx1, Comparator.GTE, mx2)
+ ),
+ new And(
+ new Comparison(mx2, Comparator.EQ, mx2),
+ new Comparison(mx2, Comparator.GTE, mx1)
+ )
+ ),
+ new Comparison(mx1, Comparator.LTE, mx2)
+ )
+ );
+ assertEquals(expected3, Predicate.unfoldTemporalComparisons(c3));
+
+ //--------------------------------------------------
+ // compare MIN to MIN
+ //--------------------------------------------------
+ Comparison c4 = new Comparison(mn, Comparator.LTE, mn);
+ Or expected4 = new Or(
+ new And(
+ new Comparison(mn1, Comparator.GTE, mn1),
+ new Comparison(mn2, Comparator.GTE, mn1)
+ ),
+ new And(
+ new Comparison(mn1, Comparator.GTE, mn2),
+ new Comparison(mn2, Comparator.GTE, mn2)
+ )
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c4), expected4);
+ }
+
+ @Test
+ public void testUnfoldWithBooleans(){
+ TimeSelector mx1 = new TimeSelector("mx1", TimeSelector.TimeField.VAL_FROM);
+ TimeSelector mx2 = new TimeSelector("mx2", TimeSelector.TimeField.VAL_TO);
+ MaxTimePoint mx = new MaxTimePoint(mx1, mx2);
+
+ TimeSelector mn1 = new TimeSelector("mn1", TimeSelector.TimeField.TX_FROM);
+ TimeSelector mn2 = new TimeSelector("mn2", TimeSelector.TimeField.TX_TO);
+ MinTimePoint mn = new MinTimePoint(mn1, mn2);
+
+ Comparison c1 = new Comparison(mx, Comparator.NEQ, mn);
+ Comparison c2 = new Comparison(mn1, Comparator.LTE, mx2);
+
+ Predicate expected1 = new And(
+ new Or(
+ // mn neq mx1
+ new And(
+ new Or(
+ new Comparison(mn1, Comparator.NEQ, mx1),
+ new Comparison(mn1, Comparator.GT, mn2)
+ ),
+ new Or(
+ new Comparison(mn2, Comparator.NEQ, mx1),
+ new Comparison(mn2, Comparator.GT, mn1)
+ )
+ ),
+
+ new Comparison(mx2, Comparator.GT, mx1)
+ ),
+ new Or(
+ // mn neq mx2
+ new And(
+ new Or(
+ new Comparison(mn1, Comparator.NEQ, mx2),
+ new Comparison(mn1, Comparator.GT, mn2)
+ ),
+ new Or(
+ new Comparison(mn2, Comparator.NEQ, mx2),
+ new Comparison(mn2, Comparator.GT, mn1)
+ )
+ ),
+ new Comparison(mx1, Comparator.GT, mx2)
+ )
+ );
+
+ Predicate expected2 = new Comparison(mx2, Comparator.GTE, mn1);
+
+ //or
+ Or or = new Or(c1, c2);
+ assertEquals(Predicate.unfoldTemporalComparisons(or), new Or(expected1, expected2));
+
+ //and
+ And and = new And(c1, c2);
+ assertEquals(Predicate.unfoldTemporalComparisons(and), new And(expected1, expected2));
+
+ //xor
+ Xor xor = new Xor(c1, c2);
+ assertEquals(Predicate.unfoldTemporalComparisons(xor), new Xor(expected1, expected2));
+
+ //not
+ Not not = new Not(c1);
+ assertEquals(Predicate.unfoldTemporalComparisons(not), new Not(expected1));
+ }
+
+ @Test
+ public void testOneSideDeepUnfold(){
+ TimeLiteral l1 = new TimeLiteral("1970-02-01");
+ TimeLiteral l2 = new TimeLiteral("2005-04-13");
+ TimeLiteral l3 = new TimeLiteral("1999-12-31T23:59:59");
+ TimeLiteral l4 = new TimeLiteral("2021-04-11");
+ MinTimePoint mn = new MinTimePoint(l1,l2);
+ MaxTimePoint mx = new MaxTimePoint(mn, l3);
+ Comparison c = new Comparison(mx, Comparator.GT, l4);
+
+ Predicate expected = new Or(
+ // mn > l4
+ new And(
+ new Comparison(l4, Comparator.LT, l1),
+ new Comparison(l4, Comparator.LT, l2)
+ ),
+ new Comparison(l4, Comparator.LT, l3)
+ );
+
+ assertEquals(Predicate.unfoldTemporalComparisons(c), expected);
+ }
+
+ @Test
+ public void testBothSideDeepUnfold(){
+ TimeLiteral l1 = new TimeLiteral("1970-02-01");
+ TimeLiteral l2 = new TimeLiteral("2005-04-13");
+ TimeLiteral l3 = new TimeLiteral("1999-12-31T23:59:59");
+ TimeLiteral l4 = new TimeLiteral("2021-04-11");
+
+ TimeLiteral l5 = new TimeLiteral("1970-02-01");
+ TimeLiteral l6 = new TimeLiteral("2005-04-13");
+ TimeLiteral l7 = new TimeLiteral("1999-12-31T23:59:59");
+ TimeLiteral l8 = new TimeLiteral("2021-04-11");
+
+ MaxTimePoint lhs = new MaxTimePoint(new MinTimePoint(l1,l2), new MaxTimePoint(l3,l4));
+ MinTimePoint rhs = new MinTimePoint(new MaxTimePoint(l5, l6), new MinTimePoint(l7, l8));
+ Comparison c = new Comparison(lhs, Comparator.LTE, rhs);
+
+ Predicate expected = new And(
+ new Or(
+ new And(
+ new Or(
+ new Comparison(l5, Comparator.GTE, l1),
+ new Comparison(l6, Comparator.GTE, l1)
+ ),
+ new And(
+ new Comparison(l7, Comparator.GTE, l1),
+ new Comparison(l8, Comparator.GTE, l1)
+ )
+ ),
+ new And(
+ new Or(
+ new Comparison(l5, Comparator.GTE, l2),
+ new Comparison(l6, Comparator.GTE, l2)
+ ),
+ new And(
+ new Comparison(l7, Comparator.GTE, l2),
+ new Comparison(l8, Comparator.GTE, l2)
+ )
+ )
+ ),
+ new And(
+ new And(
+ new Or(
+ new Comparison(l5, Comparator.GTE, l3),
+ new Comparison(l6, Comparator.GTE, l3)
+ ),
+ new And(
+ new Comparison(l7, Comparator.GTE, l3),
+ new Comparison(l8, Comparator.GTE, l3)
+ )
+ ),
+ new And(
+ new Or(
+ new Comparison(l5, Comparator.GTE, l4),
+ new Comparison(l6, Comparator.GTE, l4)
+ ),
+ new And(
+ new Comparison(l7, Comparator.GTE, l4),
+ new Comparison(l8, Comparator.GTE, l4)
+ )
+ )
+ )
+ );
+ assertEquals(Predicate.unfoldTemporalComparisons(c), expected);
+ }
+
+
+}
diff --git a/src/test/java/org/s1ck/gdl/predicates/booleans/AndTest.java b/src/test/java/org/s1ck/gdl/predicates/booleans/AndTest.java
index 22b2eaa..24ca8f9 100644
--- a/src/test/java/org/s1ck/gdl/predicates/booleans/AndTest.java
+++ b/src/test/java/org/s1ck/gdl/predicates/booleans/AndTest.java
@@ -36,4 +36,5 @@ public void extractVariablesTest() {
assertEquals(reference,and.getVariables());
}
+
}