Skip to content

Commit

Permalink
[s1ck#49] implemented simple timestamp and interval predicates
Browse files Browse the repository at this point in the history
  • Loading branch information
lc0197 committed Jun 15, 2020
1 parent 4fd9e41 commit 046afff
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 42 deletions.
31 changes: 14 additions & 17 deletions src/main/antlr4/org/s1ck/gdl/GDL.g4
Original file line number Diff line number Diff line change
Expand Up @@ -140,30 +140,27 @@ literal
// time-related
//________________________
timeFunc
: intervall '.' intervallFunc #intvFunc
| timePoint '.' stampFunc #stmpFunc
: interval '.' intervalFunc #intvF
| timePoint '.' stampFunc #stmpF
;

intervall : intervallAtom #intvAtom
| complexIntervall #cmplxIntv
;

intervallAtom
: intervallSelector
interval
: intervalSelector
| intervalFromStamps
;

intervallSelector
: Identifier '.' Interval

intervalSelector
: Identifier '.' IntervalConst
;

intervalFromStamps
: 'Interval('('['|'(') timePoint (')'|']') ')'
: 'Interval([' timePoint ',' timePoint '])'
;

// TODO: change (only placeholder yet)
complexIntervall
: Identifier '.' Interval
: Identifier '.' IntervalConst
;

// TODO: add functions that yield timePoint
Expand All @@ -182,12 +179,12 @@ timeSelector
: Identifier '.' TimeProp
;

intervallFunc
: overlapsIntervallOperator #intvOverl
| asOfOperator #intvAsOf
intervalFunc
: overlapsIntervallOperator
| asOfOperator
;
overlapsIntervallOperator
: 'overlaps' '(' intervall ')'
: 'overlaps(' interval ')'
;

asOfOperator
Expand Down Expand Up @@ -309,7 +306,7 @@ TimeProp
| 'val_to'
;

Interval
IntervalConst
: 'tx'
| 'val'
;
Expand Down
178 changes: 173 additions & 5 deletions src/main/java/org/s1ck/gdl/GDLLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.s1ck.gdl.exceptions.InvalidReferenceException;
import org.s1ck.gdl.model.*;
import org.s1ck.gdl.model.comparables.ElementSelector;
import org.s1ck.gdl.model.comparables.time.*;
import org.s1ck.gdl.model.predicates.booleans.And;
import org.s1ck.gdl.model.predicates.expressions.Comparison;
import org.s1ck.gdl.model.predicates.Predicate;
Expand All @@ -42,6 +43,9 @@ class GDLLoader extends GDLBaseListener {
private final Map<String, Vertex> userVertexCache;
private final Map<String, Edge> userEdgeCache;

// used to map graphs to their elements
private Map<Long, ArrayList<GraphElement>> graphElements;

// used to cache elements which are assigned to auto-generated variables
private final Map<String, Graph> autoGraphCache;
private final Map<String, Vertex> autoVertexCache;
Expand Down Expand Up @@ -122,6 +126,8 @@ class GDLLoader extends GDLBaseListener {
userVertexCache = new HashMap<>();
userEdgeCache = new HashMap<>();

graphElements = new HashMap<>();

autoGraphCache = new HashMap<>();
autoVertexCache = new HashMap<>();
autoEdgeCache = new HashMap<>();
Expand Down Expand Up @@ -385,6 +391,163 @@ public void enterComparisonExpression(GDLParser.ComparisonExpressionContext ctx)
currentPredicates.add(buildComparison(ctx));
}

/**
* Builds a {@code Predicate} from the given Intervall-Function (caller is a interval)
* interval functions are e.g. asOf(x), between(x,y)....
*
* @param ctx interval function context
*/
@Override
public void enterIntvF(GDLParser.IntvFContext ctx){
currentPredicates.add(buildIntervalFunction(ctx));
}

/**
* Converts an interval function into a (complex) predicate
* For example, i.between(x,y) would be translated to a predicate ((i.from<= y) AND (i.to>x))
* @param ctx interval function context
* @return complex predicate that encodes the interval function. Atoms are time stamp comparisons
*/
private Predicate buildIntervalFunction(GDLParser.IntvFContext ctx) {
TimePoint[] intv = buildIntervall(ctx.interval());
TimePoint from = intv[0];
TimePoint to = intv[1];
return createIntervalPredicates(from, to, ctx.intervalFunc());
}


private Predicate createIntervalPredicates(TimePoint from, TimePoint to, GDLParser.IntervalFuncContext intervalFunc) {
if(intervalFunc.overlapsIntervallOperator()!=null){
return createOverlapsPredicates(from, to, intervalFunc.overlapsIntervallOperator());
}
else if(intervalFunc.asOfOperator()!=null){
return createAsOfPredicates(from, to, intervalFunc.asOfOperator());
}
return null;
}

private Predicate createOverlapsPredicates(TimePoint from, TimePoint to, GDLParser.OverlapsIntervallOperatorContext ctx) {
TimePoint[] arg = buildIntervall(ctx.interval());
TimePoint arg_from = arg[0];
TimePoint arg_to = arg[1];
TimePoint mx = new MaxTimePoint(from, arg_from);
TimePoint mn = new MinTimePoint(to, arg_to);
// TODO unzip comparison
return new Comparison(mx, Comparator.LT, mn);
}

private Predicate createAsOfPredicates(TimePoint from, TimePoint to, GDLParser.AsOfOperatorContext ctx){
TimePoint x = buildTimePoint(ctx.timePoint());
return new And(new Comparison(from, Comparator.LTE, x), new Comparison(to, Comparator.GTE, x));
}


private TimePoint[] buildIntervall(GDLParser.IntervalContext ctx) {
if (ctx.intervalSelector()!=null){
GDLParser.IntervalSelectorContext selector = ctx.intervalSelector();
// throws exception, if variable invalid
String var = resolveIdentifier(selector.Identifier().getText());
String intId = selector.IntervalConst().getText();
TimePoint from = new TimeSelector(var, intId+"_from");
TimePoint to = new TimeSelector(var, intId+"_to");
return new TimePoint[]{from, to};
}
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 null;
}

/**
* Builds a {@code Predicate} from the given TimeStamp-Function (caller is a timestamp)
* time stamp functions are e.g. asOf(x), before(x),...
*
* @param ctx stamp function context
*/
@Override
public void enterStmpF(GDLParser.StmpFContext ctx){
currentPredicates.add(buildStampFunction(ctx));
}

/**
* Converts a time stamp function into a (potentially complex) {@code Predicate}
* For example, i.asOf(x) would be translated to a {@code Predicate} i<=x
*
* @param ctx time stamp function context
* @return (potentially complex) {@code Predicate} that encodes the time stamp function. Atoms are time stamp comparisons
*/
private Predicate buildStampFunction(GDLParser.StmpFContext ctx) {
TimePoint tp = buildTimePoint(ctx.timePoint());
return createStampPredicates(tp, ctx.stampFunc());
}

/**
* Returns time stamp {@code Predicate} given the caller (a time stamp) and its context
*
* @param tp the caller
* @param stampFunc context including the operator (e.g. asOf, before,...) and its argument(s)
* @return (potentially complex) {@code Predicate} that encodes the time stamp function. Atoms are time stamp comparisons
*/
private Predicate createStampPredicates(TimePoint tp, GDLParser.StampFuncContext stampFunc) {
if(stampFunc.asOfOperator()!=null){
return createAsOfPredicates(tp, stampFunc.asOfOperator());
}
else if(stampFunc.beforePointOperator()!=null){
return createBeforePredicates(tp, stampFunc.beforePointOperator());
}
return null;
}


/**
* Creates an asOf-{@code Predicate} given the caller (a timestamp) and its context
*
* @param from the caller
* @param ctx its context including the argument
* @return a {@code Predicate} encoding the asOf function: from<=x
*/
private Predicate createAsOfPredicates(TimePoint from, GDLParser.AsOfOperatorContext ctx) {
TimePoint x = buildTimePoint(ctx.timePoint());
// TODO hier schon Abschätzung reinbringen?
return new Comparison(from, Comparator.LTE, x);
}

/**
* Creates a before {@code Predicate} given the caller (a timestamp) and its context
*
* @param from the caller
* @param ctx its context including the argument
* @return a {@code Predicate} encoding the before function: from<x
*/
private Predicate createBeforePredicates(TimePoint from, GDLParser.BeforePointOperatorContext ctx){
TimePoint x = buildTimePoint(ctx.timePoint());
return new Comparison(from, Comparator.LT, x);
}

/**
* Builds a {@code TimePoint} (can be {@code TimeLiteral}, {@code TimeSelector}, {@code MIN},...) given its context
*
* @param ctx timepoint context
* @return the {@code TimePoint} described by the context
*/
private TimePoint buildTimePoint(GDLParser.TimePointContext ctx) {
if (ctx.timeLiteral() != null){
return new TimeLiteral(ctx.getText());
}
else if (ctx.timeSelector()!=null){
GDLParser.TimeSelectorContext ts = ctx.timeSelector();
// checks whether ID is even there (is a vertex or edge) and returns its variable
String var = resolveIdentifier(ts.Identifier().getText());
String field = ts.TimeProp().getText();
return new TimeSelector(var, field);
}
return null;
}


/**
* Called when we leave an NotExpression.
*
Expand Down Expand Up @@ -579,6 +742,10 @@ private Edge initNewEdge(GDLParser.EdgeBodyContext edgeBodyContext, boolean isIn
private void updateGraphElement(GraphElement graphElement) {
if (inGraph) {
graphElement.addToGraph(getNextGraphId());
if(! graphElements.containsKey(getNextGraphId())){
graphElements.put(getNextGraphId(), new ArrayList<>());
}
graphElements.get(getNextGraphId()).add(graphElement);
}
}

Expand Down Expand Up @@ -736,20 +903,21 @@ private ComparableExpression extractComparableExpression(GDLParser.ComparisonEle
* @return parsed property selector expression
*/
private PropertySelector buildPropertySelector(GDLParser.PropertyLookupContext ctx) {
GraphElement element;

String identifier = ctx.Identifier(0).getText();
String identifier = resolveIdentifier(ctx.Identifier(0).getText());
String property = ctx.Identifier(1).getText();
return new PropertySelector(identifier,property);
}

private String resolveIdentifier(String identifier){
GraphElement element;
if(userVertexCache.containsKey(identifier)) {
element = userVertexCache.get(identifier);
}
else if(userEdgeCache.containsKey(identifier)) {
element = userEdgeCache.get(identifier);
}
else { throw new InvalidReferenceException(identifier);}

return new PropertySelector(element.getVariable(),property);
return element.getVariable();
}

// --------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,19 @@
* Represents a MAX(p1,...,pn) term, where p1...pn are TimePoints
*/
public class MaxTimePoint extends TimeTerm{
/**
* Operator name
*/
private final static String operator = "MAX";

/**
* Creates a MAX(args[0],...,args[args.length-1]) term
* @param args the arguments for the MAX term (TimePoints)
*/
public MaxTimePoint(TimePoint...args){
super(args);
operator = "MAX";
}




@Override
public long evaluate(){
long mn = Long.MIN_VALUE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@
* Represents a MAX(p1,...,pn) term, where p1...pn are TimePoints
*/
public class MinTimePoint extends TimeTerm {
/**
* Operator name
*/
private final static String operator = "MIN";

/**
* Creates a MIN(args[0],...,args[args.length-1]) term
* @param args the arguments for the MIN term (TimePoints)
*/
public MinTimePoint(TimePoint...args){
super(args);
operator = "MIN";
}

@Override
Expand Down
24 changes: 12 additions & 12 deletions src/main/java/org/s1ck/gdl/model/comparables/time/TimeTerm.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
public abstract class TimeTerm extends TimePoint {

/**
* Operator name (e.g. "MIN", "MAX",...)
* List of arguments (i.g. more than one)
*/
private final static String operator="";
protected ArrayList<TimePoint> args;

/**
* List of arguments (i.g. more than one)
* String representation of the operator, e.g. "MIN", "MAX", ...
*/
ArrayList<TimePoint> args;
protected String operator = "";

/**
* Initialize a complex expression by its arguments (TimePoints)
Expand All @@ -29,14 +29,6 @@ protected TimeTerm(TimePoint...args){
Collections.addAll(this.args, args);
}

/**
* Get the operator name
* @return operator name
*/
public String getOperator() {
return operator;
}

/**
* Get the arguments list
* @return list of arguments
Expand Down Expand Up @@ -65,6 +57,14 @@ public ArrayList<String> getVariables(){
return vars;
}

/**
* String representation of the operator (e.g. "MIN", "MAX",...)
* @return operator string
*/
public String getOperator(){
return operator;
}

@Override
public String toString(){
StringBuilder sb = new StringBuilder(operator+"(");
Expand Down
Loading

0 comments on commit 046afff

Please sign in to comment.