Skip to content

Commit

Permalink
[s1ck#49] implemented merge and join for intervals
Browse files Browse the repository at this point in the history
  • Loading branch information
lc0197 committed Jun 15, 2020
1 parent 54e6f59 commit 7266a30
Show file tree
Hide file tree
Showing 3 changed files with 262 additions and 46 deletions.
11 changes: 9 additions & 2 deletions src/main/antlr4/org/s1ck/gdl/GDL.g4
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ timeFunc
interval
: intervalSelector
| intervalFromStamps
| complexInterval
;


Expand All @@ -161,8 +162,14 @@ intervalFromStamps
;

// TODO: change (only placeholder yet)
complexIntervall
: Identifier '.' IntervalConst
complexInterval
: complexIntervalArgument '.merge(' complexIntervalArgument ')'
| complexIntervalArgument '.join(' complexIntervalArgument ')'
;

complexIntervalArgument
: intervalSelector
| intervalFromStamps
;

// TODO: add functions that yield timePoint
Expand Down
93 changes: 77 additions & 16 deletions src/main/java/org/s1ck/gdl/GDLLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -433,10 +433,17 @@ public void enterIntvF(GDLParser.IntvFContext ctx){
* @return complex predicate that encodes the interval function. Atoms are time stamp comparisons
*/
private Predicate buildIntervalFunction(GDLParser.IntvFContext ctx) {
int predicateSizeBefore = currentPredicates.size();
TimePoint[] intv = buildIntervall(ctx.interval());
TimePoint from = intv[0];
TimePoint to = intv[1];
return createIntervalPredicates(from, to, ctx.intervalFunc());
Predicate predicate = createIntervalPredicates(from, to, ctx.intervalFunc());
// additional constraints?
int countConstraints = currentPredicates.size() - predicateSizeBefore;
for(int i = 0; i<countConstraints; i++){
predicate = new And(predicate, currentPredicates.removeFirst());
}
return predicate;
}

/**
Expand All @@ -449,22 +456,24 @@ 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){
return createOverlapsPredicates(from, to, intervalFunc.overlapsIntervallOperator());
predicate = createOverlapsPredicates(from, to, intervalFunc.overlapsIntervallOperator());
}
else if(intervalFunc.fromToOperator()!=null){
return createFromToPredicates(from, to, intervalFunc.fromToOperator());
predicate = createFromToPredicates(from, to, intervalFunc.fromToOperator());
}
else if(intervalFunc.betweenOperator()!=null){
return createBetweenPredicates(from, to, intervalFunc.betweenOperator());
predicate = createBetweenPredicates(from, to, intervalFunc.betweenOperator());
}
else if(intervalFunc.precedesOperator()!=null){
return createPrecedesPredicates(to, intervalFunc.precedesOperator());
predicate = createPrecedesPredicates(to, intervalFunc.precedesOperator());
}
else if(intervalFunc.succeedsOperator()!=null){
return createSucceedsPredicates(from, intervalFunc.succeedsOperator());
predicate = createSucceedsPredicates(from, intervalFunc.succeedsOperator());
}
return null;
// additional constraints added during interval processing?
return predicate;
}

/**
Expand Down Expand Up @@ -553,22 +562,74 @@ private TimePoint[] buildIntervall(GDLParser.IntervalContext ctx) {
if (ctx.intervalSelector()!=null){
GDLParser.IntervalSelectorContext selector = ctx.intervalSelector();
// throws exception, if variable invalid
String var = selector.Identifier()!=null ?
resolveIdentifier(selector.Identifier().getText()) : TimeSelector.GLOBAL_SELECTOR;
String intId = selector.IntervalConst().getText();
TimePoint from = new TimeSelector(var, intId+"_from");
TimePoint to = new TimeSelector(var, intId+"_to");
return new TimePoint[]{from, to};
return buildIntervalFromSelector(selector);
}
else if(ctx.intervalFromStamps()!=null){
GDLParser.IntervalFromStampsContext fs = ctx.intervalFromStamps();
TimePoint from = buildTimePoint(fs.timePoint(0));
TimePoint to = buildTimePoint(fs.timePoint(1));
return new TimePoint[]{from,to};
return buildIntervalFromStamps(fs);
}
else if(ctx.complexInterval()!=null){
GDLParser.ComplexIntervalArgumentContext arg1 = ctx.complexInterval()
.complexIntervalArgument(0);
GDLParser.ComplexIntervalArgumentContext arg2 = ctx.complexInterval()
.complexIntervalArgument(1);
boolean join = ctx.getText().contains(".join(");
return buildIntervalFromComplex(arg1, arg2, join);
}
return null;
}

private TimePoint[] buildIntervalFromSelector(GDLParser.IntervalSelectorContext ctx){
String var = ctx.Identifier()!=null ?
resolveIdentifier(ctx.Identifier().getText()) : TimeSelector.GLOBAL_SELECTOR;
String intId = ctx.IntervalConst().getText();
TimePoint from = new TimeSelector(var, intId+"_from");
TimePoint to = new TimeSelector(var, intId+"_to");
return new TimePoint[]{from, to};
}

private TimePoint[] buildIntervalFromStamps(GDLParser.IntervalFromStampsContext ctx){
TimePoint from = buildTimePoint(ctx.timePoint(0));
TimePoint to = buildTimePoint(ctx.timePoint(1));
return new TimePoint[]{from,to};
}

private TimePoint[] buildIntervalFromComplex(GDLParser.ComplexIntervalArgumentContext arg1,
GDLParser.ComplexIntervalArgumentContext arg2,
boolean join){
TimePoint[] i1 = null;
TimePoint[] i2 = null;
if(arg1.intervalFromStamps()!=null){
i1 = buildIntervalFromStamps(arg1.intervalFromStamps());
}
else{
i1 = buildIntervalFromSelector(arg1.intervalSelector());
}
if(arg2.intervalFromStamps()!=null){
i2 = buildIntervalFromStamps(arg2.intervalFromStamps());
}
else{
i2 = buildIntervalFromSelector(arg2.intervalSelector());
}
// constraint: merge and join only when overlapping or meeting
Comparison constraint = new Comparison(
new MaxTimePoint(i1[0], i2[0]), LTE, new MinTimePoint(i1[1], i2[1])
);
currentPredicates.addFirst(constraint);
// now build complex intervall from i1, i2
if(join){
TimePoint start = new MinTimePoint(i1[0],i2[0]);
TimePoint end = new MaxTimePoint(i1[1],i2[1]);
return new TimePoint[]{start, end};
}
// merge
else{
TimePoint start = new MaxTimePoint(i1[0],i2[0]);
TimePoint end = new MinTimePoint(i1[1],i2[1]);
return new TimePoint[]{start, end};
}
}

/**
* Builds a {@code Predicate} from the given TimeStamp-Function (caller is a timestamp)
* time stamp functions are e.g. succeeds(x), before(x),...
Expand Down
Loading

0 comments on commit 7266a30

Please sign in to comment.