Skip to content

Commit

Permalink
[s1ck#49] implemented global valid and tx times
Browse files Browse the repository at this point in the history
  • Loading branch information
lc0197 committed Jun 15, 2020
1 parent 376d2c9 commit 54e6f59
Show file tree
Hide file tree
Showing 15 changed files with 620 additions and 32 deletions.
2 changes: 2 additions & 0 deletions src/main/antlr4/org/s1ck/gdl/GDL.g4
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ interval

intervalSelector
: Identifier '.' IntervalConst
| IntervalConst
;

intervalFromStamps
Expand All @@ -179,6 +180,7 @@ timeLiteral

timeSelector
: Identifier '.' TimeProp
| TimeProp
;

intervalFunc
Expand Down
30 changes: 24 additions & 6 deletions src/main/java/org/s1ck/gdl/GDLLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,7 @@ public void exitGraph(GDLParser.GraphContext ctx) {
*/
@Override
public void exitQuery(GDLParser.QueryContext ctx) {
if(predicates!=null) {
predicates = Predicate.unfoldTemporalComparisons(predicates);
}
postprocessPredicates();
for(Vertex v : vertices) {
addPredicates(Predicate.fromGraphElement(v, getDefaultVertexLabel()));
}
Expand All @@ -323,6 +321,24 @@ public void exitQuery(GDLParser.QueryContext ctx) {
}
}

/**
* Reformulates the predicates when leaving the query. First, complex temporal expressions
* like {@code MIN(t1,t2)<MAX(t2,t3)} are reduced to comparisons of simple timestamps.
* Then, global time comparisons referring to the whole pattern are reduced to comparisons of
* variables.
*/
private void postprocessPredicates(){
if(predicates!=null) {
predicates = Predicate.unfoldTemporalComparisons(predicates);
ArrayList<String> vars = new ArrayList<>();
vars.addAll(userEdgeCache.keySet());
vars.addAll(userVertexCache.keySet());
vars.addAll(autoEdgeCache.keySet());
vars.addAll(autoVertexCache.keySet());
predicates = Predicate.translateGlobalPredicates(predicates, vars, true);
}
}

/**
* Called when parser enters a vertex context.
*
Expand Down Expand Up @@ -537,7 +553,8 @@ 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 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");
Expand Down Expand Up @@ -629,7 +646,8 @@ private TimePoint buildTimePoint(GDLParser.TimePointContext ctx) {
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 var = ts.Identifier()!=null ?
resolveIdentifier(ts.Identifier().getText()) : TimeSelector.GLOBAL_SELECTOR;
String field = ts.TimeProp().getText();
return new TimeSelector(var, field);
}
Expand Down Expand Up @@ -665,7 +683,7 @@ private Predicate createDefaultAsOf(){
vars.addAll(userVertexCache.keySet());
vars.addAll(autoEdgeCache.keySet());
vars.addAll(autoVertexCache.keySet());
if(vars==null){
if(vars.isEmpty()){
return null;
}
else{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package org.s1ck.gdl.model.comparables.time;

import org.s1ck.gdl.model.comparables.ComparableExpression;
import org.s1ck.gdl.model.comparables.time.util.TimeConstant;
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;
import java.util.List;

import static org.s1ck.gdl.utils.Comparator.EQ;

/**
* Represents an addition of a constant to a given TimePoint
Expand Down Expand Up @@ -78,4 +85,9 @@ public boolean equals(Object o) {
}


@Override
public Predicate unfoldGlobal(Comparator comp, ComparableExpression rhs, List<String> variables) {
//TODO implement, if necessary. Practically the same as in TimeSelector
return null;
}
}
15 changes: 15 additions & 0 deletions src/main/java/org/s1ck/gdl/model/comparables/time/TimeAtom.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
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.List;

/**
* Base class for atoms in a {@link TimeTerm}, e.g. simple timestamps
*/
public abstract class TimeAtom extends TimePoint {


/**
* Translates a simple comparison described by {@code this comp rhs} to a equivalent
* comparison that does not contain global time selectors / intervals anymore.
* @param comp the comparator of the comparison
* @param rhs the right hand side of the comparison
* @param variables all the variables in the query
* @return equivalent containing only local selectors/intervals
*/
public abstract Predicate unfoldGlobal(Comparator comp, ComparableExpression rhs, List<String> variables);


@Override
public Predicate unfoldComparison(Comparator comparator, TimePoint arg){
// nothing to unfold here
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
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 java.time.*;
import java.util.ArrayList;
import java.util.List;

import org.s1ck.gdl.utils.Comparator;

Expand Down Expand Up @@ -170,4 +173,8 @@ private String preprocessDateString(String date){
return date;
}

@Override
public Predicate unfoldGlobal(Comparator comp, ComparableExpression rhs, List<String> variables) {
return new Comparison(this, comp, rhs);
}
}
202 changes: 201 additions & 1 deletion src/main/java/org/s1ck/gdl/model/comparables/time/TimeSelector.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

import org.s1ck.gdl.model.comparables.ComparableExpression;
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.List;

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

/**
* Represents a timestamp selection of a graph variable, e.g. v.VAL_FROM selects the VAL_FROM value of a graph element v
Expand All @@ -22,6 +27,11 @@ public class TimeSelector extends TimeAtom{
*/
private TimeField timeProp;

/**
* Variable name that indicates a global time selector, referring to the whole pattern
*/
public final static String GLOBAL_SELECTOR = "___global";

/**
*
* All time properties defined by TPGM
Expand All @@ -43,6 +53,24 @@ public TimeSelector(String variable, TimeField field){
timeProp = field;
}

/**
* Initializes a global TimeSelector given a time property (VAL_FROM, VAL_TO, TX_FROM, TX_TO)
* @param field the time property as defined by the TPGM
*/
public TimeSelector(TimeField field){
this(GLOBAL_SELECTOR, field);
}

/**
* Initializes a global TimeSelector given the string representation of a time property
* (VAL_FROM, VAL_TO, TX_FROM, TX_TO)
* @param field the time property as defined by the TPGM. Must be one of "val_from", "val_to", "tx_from", "tx_to"
* (cases irrelevant)
*/
public TimeSelector(String field){
this(GLOBAL_SELECTOR, field);
}

/**
* Initializes a TimeSelector given a variable and the string representation of a time property
* (VAL_FROM, VAL_TO, TX_FROM, TX_TO)
Expand Down Expand Up @@ -94,9 +122,181 @@ public boolean containsSelectorType(TimeSelector.TimeField type){
return timeProp.equals(type);
}

@Override
public Predicate unfoldGlobal(Comparator comp, ComparableExpression rhs, List<String> variables) {
if(!variable.equals(GLOBAL_SELECTOR)){
return new Comparison(this, comp, rhs);
}
if(comp.equals(EQ)){
return unfoldGlobalEQ(rhs, variables);
}
else if(comp.equals(Comparator.NEQ)){
return unfoldGlobalNEQ(rhs, variables);
}
else if(comp.equals(Comparator.LT)){
return unfoldGlobalLT(rhs, variables);
}
else if(comp.equals(Comparator.LTE)){
return unfoldGlobalLTE(rhs, variables);
}
else if(comp.equals(Comparator.GT)){
return unfoldGlobalGT(rhs, variables);
}
else if(comp.equals(Comparator.GTE)){
return unfoldGlobalGTE(rhs, variables);
}
return null;
}

/**
* Translates a comparison {@code (this == rhs)} into an equivalent predicate that does not contain
* global time selectors/intervals anymore
* @param rhs the right hand side of the comparison to translate
* @param variables all query variables
* @return translated comparison
*/
private Predicate unfoldGlobalEQ(ComparableExpression rhs, List<String> variables){
// exists var: var.from==rhs
Predicate exists = existsVariable(EQ, rhs, variables);

if(timeProp.equals(TimeField.TX_FROM) || timeProp.equals(TimeField.VAL_FROM)){
//globalfrom==rhs <=> (exists var: var.from==rhs) AND (forall var: var.from<=rhs)
return new And(exists,forAllVariables(LTE, rhs, variables));
}

else{
//globalto == rhs <=> (exists var: var.to ==rhs) AND (forall var: var.to>=rhs)
return new And(exists,forAllVariables(GTE, rhs, variables));
}
}

/**
* Translates a comparison {@code (this != rhs)} into an equivalent predicate that does not contain
* global time selectors/intervals anymore.
* @param rhs the right hand side of the comparison to translate
* @param variables all query variables
* @return translated comparison
*/
private Predicate unfoldGlobalNEQ(ComparableExpression rhs, List<String> variables){
return forAllVariables(NEQ, rhs, variables);
}

/**
* Translates a comparison {@code (this < rhs)} into an equivalent predicate that does not contain
* global time selectors/intervals anymore.
* @param rhs the right hand side of the comparison to translate
* @param variables all query variables
* @return translated comparison
*/
private Predicate unfoldGlobalLT(ComparableExpression rhs, List<String> variables){
if(timeProp.equals(TimeField.TX_FROM) || timeProp.equals(TimeField.VAL_FROM)){
// globalfrom < rhs <=> forall var: var.from < rhs
return forAllVariables(LT, rhs, variables);
}
else{
//globalto < rhs <=> exists var: var.to < rhs
return existsVariable(LT, rhs, variables);
}
}

/**
* Translates a comparison {@code (this <= rhs)} into an equivalent predicate that does not contain
* global time selectors/intervals anymore.
* @param rhs the right hand side of the comparison to translate
* @param variables all query variables
* @return translated comparison
*/
private Predicate unfoldGlobalLTE(ComparableExpression rhs, List<String> variables){
if(timeProp.equals(TimeField.TX_FROM) || timeProp.equals(TimeField.VAL_FROM)){
// globalfrom <= rhs <=> forall var: var.from <= rhs
return forAllVariables(LTE, rhs, variables);
}
else{
//globalto <= rhs <=> exists var: var.to <= rhs
return existsVariable(LTE, rhs, variables);
}
}

/**
* Translates a comparison {@code (this > rhs)} into an equivalent predicate that does not contain
* global time selectors/intervals anymore.
* @param rhs the right hand side of the comparison to translate
* @param variables all query variables
* @return translated comparison
*/
private Predicate unfoldGlobalGT(ComparableExpression rhs, List<String> variables){
if(timeProp.equals(TimeField.TX_FROM) || timeProp.equals(TimeField.VAL_FROM)){
// globalfrom > rhs <=> exists var: var.from > rhs
return existsVariable(GT, rhs, variables);
}
else{
//globalto > rhs <=> forall var: var.to > rhs
return forAllVariables(GT, rhs, variables);
}
}

/**
* Translates a comparison {@code (this >= rhs)} into an equivalent predicate that does not contain
* global time selectors/intervals anymore.
* @param rhs the right hand side of the comparison to translate
* @param variables all query variables
* @return translated comparison
*/
private Predicate unfoldGlobalGTE(ComparableExpression rhs, List<String> variables){
if(timeProp.equals(TimeField.TX_FROM) || timeProp.equals(TimeField.VAL_FROM)){
// globalfrom >= rhs <=> exists var: var.from >= rhs
return existsVariable(GTE, rhs, variables);
}
else{
//globalto >= rhs <=> forall var: var.to >= rhs
return forAllVariables(GTE, rhs, variables);
}
}

/**
* Returns a predicate equivalent to {@code exists v in variables s.t. (v comp rhs) holds}
* @param comp the comparator
* @param rhs the rhs in the comparison
* @param variables the query variables to "iterate" over (the domain)
* @return predicate equivalent to {@code exists v in variables s.t. (v comp rhs) holds}
*/
private Predicate existsVariable(Comparator comp, ComparableExpression rhs, List<String> variables){
Comparison c0 = new Comparison(new TimeSelector(variables.get(0),timeProp), comp, rhs);
if(variables.size()==1){
return c0;
}
Or exists = new Or(c0, new Comparison(new TimeSelector(variables.get(1),timeProp), comp, rhs));
for(int i=2; i<variables.size(); i++){
exists = new Or(exists, new Comparison(new TimeSelector(variables.get(i),timeProp), comp, rhs));
}
return exists;
}

/**
* Returns a predicate equivalent to {@code forall v in variables: (v comp rhs) holds}
* @param comp the comparator
* @param rhs the rhs in the comparison
* @param variables the query variables to "iterate" over (the domain)
* @return predicate equivalent to {@code forall v in variables: (v comp rhs) holds}
*/
private Predicate forAllVariables(Comparator comp, ComparableExpression rhs, List<String> variables){
Comparison c0 = new Comparison(new TimeSelector(variables.get(0),timeProp), comp, rhs);
if(variables.size()==1){
return c0;
}

And forall = new And(c0, new Comparison(new TimeSelector(variables.get(1),timeProp), comp, rhs));
for(int i=2; i<variables.size(); i++){
forall = new And(forall,
new Comparison(new TimeSelector(variables.get(i),timeProp),comp,rhs));
}

return forall;
}

@Override
protected Predicate unfoldEQ(TimePoint arg){
return new Comparison(this, Comparator.EQ, arg);
return new Comparison(this, EQ, arg);
}

@Override
Expand Down
Loading

0 comments on commit 54e6f59

Please sign in to comment.