Skip to content

Commit

Permalink
[s1ck#49] implemented remaining Allen predicates
Browse files Browse the repository at this point in the history
  • Loading branch information
lc0197 committed Jun 15, 2020
1 parent a7fc9d6 commit 83f5aae
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 14 deletions.
15 changes: 15 additions & 0 deletions src/main/antlr4/org/s1ck/gdl/GDL.g4
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ intervalFunc
| precedesOperator
| succeedsOperator
| containsOperator
| immediatelyPrecedesOperator
| immediatelySucceedsOperator
| equalsOperator
;
overlapsIntervallOperator
: 'overlaps(' interval ')'
Expand Down Expand Up @@ -228,6 +231,18 @@ containsOperator
| 'contains(' timePoint ')'
;

immediatelyPrecedesOperator
: 'immediatelyPrecedes(' interval ')'
;

immediatelySucceedsOperator
: 'immediatelySucceeds(' interval ')'
;

equalsOperator
: 'equals(' interval ')'
;

stampFunc
: beforePointOperator
| afterPointOperator
Expand Down
57 changes: 43 additions & 14 deletions src/main/java/org/s1ck/gdl/GDLLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@
import java.util.*;
import java.util.stream.Collectors;

import static org.s1ck.gdl.utils.Comparator.GTE;
import static org.s1ck.gdl.utils.Comparator.LTE;
import static org.s1ck.gdl.utils.Comparator.*;

class GDLLoader extends GDLBaseListener {

Expand Down Expand Up @@ -476,27 +475,34 @@ private Predicate buildIntervalFunction(GDLParser.IntvFContext ctx) {
* {@code from} and {@code to}.
*/
private Predicate createIntervalPredicates(TimePoint from, TimePoint to, GDLParser.IntervalFuncContext intervalFunc) {
Predicate predicate = null;
if(intervalFunc.overlapsIntervallOperator()!=null){
predicate = createOverlapsPredicates(from, to, intervalFunc.overlapsIntervallOperator());
return createOverlapsPredicates(from, to, intervalFunc.overlapsIntervallOperator());
}
else if(intervalFunc.fromToOperator()!=null){
predicate = createFromToPredicates(from, to, intervalFunc.fromToOperator());
return createFromToPredicates(from, to, intervalFunc.fromToOperator());
}
else if(intervalFunc.betweenOperator()!=null){
predicate = createBetweenPredicates(from, to, intervalFunc.betweenOperator());
return createBetweenPredicates(from, to, intervalFunc.betweenOperator());
}
else if(intervalFunc.precedesOperator()!=null){
predicate = createPrecedesPredicates(to, intervalFunc.precedesOperator());
return createPrecedesPredicates(to, intervalFunc.precedesOperator());
}
else if(intervalFunc.succeedsOperator()!=null){
predicate = createSucceedsPredicates(from, intervalFunc.succeedsOperator());
return createSucceedsPredicates(from, intervalFunc.succeedsOperator());
}
else if(intervalFunc.containsOperator()!=null){
predicate = createContainsPredicates(from, to, intervalFunc.containsOperator());
return createContainsPredicates(from, to, intervalFunc.containsOperator());
}
// additional constraints added during interval processing?
return predicate;
else if(intervalFunc.immediatelyPrecedesOperator()!=null){
return createImmediatelyPrecedesPredicates(to, intervalFunc.immediatelyPrecedesOperator());
}
else if(intervalFunc.immediatelySucceedsOperator()!=null){
return createImmediatelySucceedsPredicates(from, intervalFunc.immediatelySucceedsOperator());
}
else if(intervalFunc.equalsOperator()!=null){
return createEqualsPredicates(from, to, intervalFunc.equalsOperator());
}
return null;
}

/**
Expand Down Expand Up @@ -552,14 +558,20 @@ private Predicate createBetweenPredicates(TimePoint from, TimePoint to, GDLParse
* Creates a predicate a.precedes(b) = a <= b.
* Function is used for interval and timestamp function {@code precedes}, as they both
* only compare two time stamps
* @param point the time stamp of the caller to compare
* @param to the time stamp of the caller to compare
* @param ctx the context containing the value to be compared
* @return precedes predicate
*/
private Predicate createPrecedesPredicates(TimePoint point, GDLParser.PrecedesOperatorContext ctx){
private Predicate createPrecedesPredicates(TimePoint to, GDLParser.PrecedesOperatorContext ctx){
TimePoint[] arg = buildIntervall(ctx.interval());
TimePoint arg_from = arg[0];
return new Comparison(point, LTE, arg_from);
return new Comparison(to, LTE, arg_from);
}

private Predicate createImmediatelyPrecedesPredicates(TimePoint to, GDLParser.ImmediatelyPrecedesOperatorContext ctx){
TimePoint[] arg = buildIntervall(ctx.interval());
TimePoint arg_from = arg[0];
return new Comparison(to, EQ, arg_from);
}

/**
Expand All @@ -576,6 +588,13 @@ private Predicate createSucceedsPredicates(TimePoint point, GDLParser.SucceedsOp
return new Comparison(point, GTE, arg_to);
}

private Predicate createImmediatelySucceedsPredicates(TimePoint from,
GDLParser.ImmediatelySucceedsOperatorContext ctx){
TimePoint[] arg = buildIntervall(ctx.interval());
TimePoint arg_to = arg[1];
return new Comparison(from, EQ, arg_to);
}

/**
* Creates a predicate a.contains(b) = a.from<=b.from AND a.to>=b.to
* @param from from value of the calling interval
Expand All @@ -602,6 +621,16 @@ private Predicate createContainsPredicates(TimePoint from, TimePoint to, GDLPars
}
}

private Predicate createEqualsPredicates(TimePoint from, TimePoint to, GDLParser.EqualsOperatorContext ctx){
TimePoint[] arg = buildIntervall(ctx.interval());
TimePoint arg_from = arg[0];
TimePoint arg_to = arg[1];
return new And(
new Comparison(from, EQ, arg_from),
new Comparison(to, EQ, arg_to)
);
}

/**
* Creates an array {@code {from, to}} representing an intervall.
* @param ctx context from which to derive {@code from} and {@code to}
Expand Down
31 changes: 31 additions & 0 deletions src/test/java/org/s1ck/gdl/GDLLoaderTemporalTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,37 @@ public void comparisonTest(){
assertPredicateEquals(loader.getPredicates().get(), expected);
}

@Test
public void immediatelyPrecedesTest(){
GDLLoader loader = getLoaderFromGDLString("MATCH (a)-[e]->(b) " +
"WHERE a.tx.immediatelyPrecedes(e.val)");
Predicate expected = new Comparison(
new TimeSelector("a", TX_TO), EQ, new TimeSelector("e", VAL_FROM)
);
assertPredicateEquals(loader.getPredicates().get(), expected);
}

@Test
public void immediatelySucceedsTest(){
GDLLoader loader = getLoaderFromGDLString("MATCH (a)-[e]->(b) " +
"WHERE a.tx.immediatelySucceeds(e.val)");
Predicate expected = new Comparison(
new TimeSelector("a", TX_FROM), EQ, new TimeSelector("e", VAL_TO)
);
assertPredicateEquals(loader.getPredicates().get(), expected);
}

@Test
public void equalsTest(){
GDLLoader loader = getLoaderFromGDLString("MATCH (a)-[e]->(b) " +
"WHERE a.tx.equals(e.val)");
Predicate expected = new And(
new Comparison(new TimeSelector("a", TX_FROM), EQ, new TimeSelector("e", VAL_FROM)),
new Comparison(new TimeSelector("a", TX_TO), EQ, new TimeSelector("e", VAL_TO))
);
assertPredicateEquals(loader.getPredicates().get(), expected);
}

/**
* Does not fail iff {@code result==expected} or {@code result.switchSides()==expected}
* @param result predicate to compare
Expand Down

0 comments on commit 83f5aae

Please sign in to comment.