From 3572b9b1b9461db3d7c5b2fa41d554a61f39d838 Mon Sep 17 00:00:00 2001 From: lc0197 Date: Mon, 13 Apr 2020 14:55:48 +0200 Subject: [PATCH] [#49] added functionality to convert complex time predicates into simple comparisons --- pom.xml | 1 + src/main/java/org/s1ck/gdl/GDLLoader.java | 1 + .../model/comparables/time/MaxTimePoint.java | 121 ++++- .../model/comparables/time/MinTimePoint.java | 127 +++++- .../model/comparables/time/PlusTimePoint.java | 68 +-- .../gdl/model/comparables/time/TimeAtom.java | 53 +++ .../model/comparables/time/TimeConstant.java | 71 --- .../model/comparables/time/TimeLiteral.java | 10 +- .../gdl/model/comparables/time/TimePoint.java | 80 ++++ .../model/comparables/time/TimeSelector.java | 37 +- .../gdl/model/comparables/time/TimeTerm.java | 6 + .../comparables/time/util/TimeConstant.java | 51 +++ .../s1ck/gdl/model/predicates/Predicate.java | 44 ++ .../gdl/model/predicates/booleans/And.java | 22 + .../gdl/model/predicates/booleans/Not.java | 22 + .../gdl/model/predicates/booleans/Or.java | 22 + .../gdl/model/predicates/booleans/Xor.java | 22 + .../predicates/expressions/Comparison.java | 44 ++ .../gdl/comparables/time/ComparisonTest.java | 49 +++ .../gdl/comparables/time/MaxTimeTest.java | 175 +++++++- .../gdl/comparables/time/MinTimeTest.java | 178 ++++++++ .../gdl/comparables/time/PlusTimeTest.java | 95 ++-- .../comparables/time/TimeConstantTest.java | 16 +- .../gdl/comparables/time/TimeLiteralTest.java | 24 + .../comparables/time/TimeSelectorTest.java | 23 + .../s1ck/gdl/predicates/PredicateTest.java | 413 ++++++++++++++++++ .../s1ck/gdl/predicates/booleans/AndTest.java | 1 + 27 files changed, 1622 insertions(+), 154 deletions(-) create mode 100644 src/main/java/org/s1ck/gdl/model/comparables/time/TimeAtom.java delete mode 100644 src/main/java/org/s1ck/gdl/model/comparables/time/TimeConstant.java create mode 100644 src/main/java/org/s1ck/gdl/model/comparables/time/util/TimeConstant.java create mode 100644 src/test/java/org/s1ck/gdl/comparables/time/ComparisonTest.java create mode 100644 src/test/java/org/s1ck/gdl/predicates/PredicateTest.java diff --git a/pom.xml b/pom.xml index 18a5473..01ea288 100644 --- a/pom.xml +++ b/pom.xml @@ -7,6 +7,7 @@ 0.3.5-SNAPSHOT + GDL - Graph Definition Language ANTLR Grammar for the definition of extended property graphs. http://github.com/s1ck/gdl.git diff --git a/src/main/java/org/s1ck/gdl/GDLLoader.java b/src/main/java/org/s1ck/gdl/GDLLoader.java index 5319a24..fe09c28 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()); } + }