-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce expressions and computed value variables #260
Introduce expressions and computed value variables #260
Conversation
PR Review ChecklistDo not edit the content of this comment. The PR reviewer should simply update this comment by ticking each review item below, as they get completed. Trivial Change
Code
Architecture
|
@@ -27,7 +27,7 @@ | |||
import com.vaticle.typeql.lang.common.TypeQLToken; | |||
import com.vaticle.typeql.lang.common.exception.TypeQLException; | |||
import com.vaticle.typeql.lang.pattern.variable.TypeVariable; | |||
import com.vaticle.typeql.lang.pattern.variable.UnboundVariable; | |||
import com.vaticle.typeql.lang.pattern.variable.UnboundDollarVariable; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only the rename
|
||
private final TypeQLToken.Predicate predicate; | ||
private final T value; | ||
private final com.vaticle.typeql.lang.pattern.expression.Predicate predicate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull predicate out to be common.
public ValueVariable asValueVariable() { | ||
return this; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introduce predicates with ValueVariable on RHS.
Differentiate wrt predicates with Dollar Variable on RHS
java/pattern/variable/Reference.java
Outdated
@Override | ||
public String name() { | ||
return name; | ||
public static abstract class Name extends Referable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make Name abstract, Introduce Name.NamedDollar and Name.NamedValue as nested subclasses
import java.util.List; | ||
|
||
public class UnboundDollarVariable extends UnboundVariable implements | ||
PredicateBuilder<ThingVariable.Attribute>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New class to differentiate b/w UnboundDollarVariable and UnboundValueVariable
import com.vaticle.typeql.lang.pattern.variable.builder.PredicateBuilder; | ||
|
||
import java.util.List; | ||
public class UnboundValueVariable extends UnboundVariable implements PredicateBuilder<ValueVariable> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New class to differentiate b/w UnboundDollarVariable and UnboundValueVariable
return constrain(new ThingConstraint.Relation.RolePlayer(roleTypeVar, playerVar)); | ||
} | ||
|
||
ThingVariable.Relation constrain(ThingConstraint.Relation.RolePlayer rolePlayer); | ||
} | ||
|
||
interface Attribute { | ||
|
||
// Attribute value equality constraint | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move to PredicateBuilder
import static com.vaticle.typeql.lang.common.util.Strings.quoteString; | ||
|
||
public abstract class Predicate<T> { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Predicate class ripped out of ThingConstraint.Value
import static com.vaticle.typeql.lang.common.exception.ErrorMessage.INVALID_CASTING; | ||
|
||
public abstract class Expression { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expression class recursively defines expressions. An expression is one of:
- Operation
$a + ?b
- Function
f($x + ?y, ?z, 2)
- Constant.
5, "foo"
- Variable.
?x, $y
- Bracketed
(expr)
Used (only) in ValueConstraint.Expression
* under the License. | ||
*/ | ||
|
||
package com.vaticle.typeql.lang.pattern.expression; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This package could be named 'subpattern' or something similar.
It contains expressions and predicates.
Could also contain aggregates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
High level comments.
@@ -34,6 +34,6 @@ def vaticle_typedb_common(): | |||
def vaticle_typedb_behaviour(): | |||
git_repository( | |||
name = "vaticle_typedb_behaviour", | |||
remote = "https://github.com/vaticle/typedb-behaviour", | |||
commit = "9ce29c4e2ccf0d34186dbd9c9708153490732d76", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_behaviour | |||
remote = "https://github.com/krishnangovindraj/typedb-behaviour", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will change after review
1b5046c
to
985e365
Compare
java/TypeQL.java
Outdated
@@ -54,7 +59,7 @@ | |||
import static com.vaticle.typeql.lang.common.TypeQLToken.Predicate.SubString.CONTAINS; | |||
import static com.vaticle.typeql.lang.common.TypeQLToken.Predicate.SubString.LIKE; | |||
import static com.vaticle.typeql.lang.common.exception.ErrorMessage.ILLEGAL_CHAR_IN_LABEL; | |||
import static com.vaticle.typeql.lang.pattern.variable.UnboundVariable.hidden; | |||
import static com.vaticle.typeql.lang.pattern.variable.UnboundDollarVariable.hidden; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most changes in this file are a result of
- Replacing UnboundVariable with UnboundDollarVariable
- Renaming ThingConstraint.Value to ThingConstraint.Predicate
Others are pointed out with comments
java/TypeQL.java
Outdated
} | ||
|
||
public static ThingConstraint.Value.Boolean eq(boolean value) { | ||
return new ThingConstraint.Value.Boolean(EQ, value); | ||
public static ThingConstraint.Predicate eq(UnboundDollarVariable variable) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace the single function accepting UnboundVariable
with one each for UnboundDollarVariable
and UnboundValueVariable
java/parser/Parser.java
Outdated
} | ||
|
||
@Override | ||
public Expression visitExpr(TypeQLParser.ExprContext ctx) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expression parsing.
if (ctx.VAR_() != null) unbound = getVar(ctx.VAR_()); | ||
else unbound = hidden(); | ||
|
||
ThingVariable.Attribute attribute = unbound.constrain(visitPredicate(ctx.predicate())); | ||
ThingVariable.Attribute attribute = unbound.constrain(new ThingConstraint.Predicate(visitPredicate(ctx.predicate()))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Effects of making Predicate common for Things & Values
@@ -675,17 +688,21 @@ public Pair<String, String> visitLabel_scoped(TypeQLParser.Label_scopedContext c | |||
// ATTRIBUTE OPERATION CONSTRUCTS ========================================== | |||
|
|||
@Override | |||
public ThingConstraint.Value<?> visitPredicate(TypeQLParser.PredicateContext ctx) { | |||
public Predicate<?> visitPredicate(TypeQLParser.PredicateContext ctx) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Effect of making Predicate common b/w Things & Values
java/pattern/Conjunction.java
Outdated
@@ -72,8 +73,12 @@ public Stream<BoundVariable> variables() { | |||
}); | |||
} | |||
|
|||
public Stream<UnboundVariable> namedVariablesUnbound() { | |||
return variables().filter(Variable::isNamed).map(v -> UnboundVariable.named(v.name())).distinct(); | |||
public Stream<UnboundValueVariable> namedUnboundValueVariables() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Useful to have both, since they're not usable interchangeably
return predicate; | ||
} | ||
|
||
public T value() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ripped out to Predicate class
ff758c5
to
1691194
Compare
WIP: Filling in parser WIP: Filled in all(?) parser functions expand * import Adapt to Variable/Pattern architecture Try to write a test; Exception: Assignment has no namedVariable Use $ for EvaluableVariables too Simplify grammar - Remove atom Add temporary test showing thing-type duality is not handled by the parser Fix grammar & add parser tests Add accessor for EvaluableConstriant.expression Refine EvaluableConstraint constants Add accessors for EvaluableExpression Introduce safe-casting methods for EvaluableVariable and EvaluableConstraint Expressions hold UnboundVariables; EvaluableConstraint inputs are ConceptVariables Fix EvaluableConstraint::variables Make the symbol field for OP enum accessible Remove comment Use '?' for Value variables. Introduce special syntax for value variables; Remove assignment in favour of overloading equality predicate Reintroduce assignment as easy mid-point Some more changes for re-introducing assign Temporarily disable expressions in valueconstraint; tests still fail Make predicate a common construct used by EvaluableVarables and ThingVariables 1/2: Pull up UnboundVariable, Replace with UnboundDollarVariable class 2/2 - Finish & unify predicates so ValueConstraints don't duplicate Add some more EvaluableExpression.Constant builder functions; Fix formatting Fix checkstyle Split Reference.Name into Name.NamedDollar and Name.NamedVal Fix another checkstyle 1/2: Rename {Thing,Evaluable}Constraint.Value to Predicate 2/2 Rename Evaluable -> Value Rename EvaluableExpression -> Expression Rename Predicate.Variable to Predicate.ThingVariable Resolve TODOs Replace NamedVal with NamedValue Small refactor of grammar Update equality check to '=='; assignment to '=' Add static import for pattern.expression.Predicate in TypeQL.java Rename UnboundValueVariable.namedValue -> UnboundValueVariable.named; Static import in ParserTest Static import for pattern.expression.Predicate in ThingVariableBuilder Point typedb-behaviour to myfork Better usages to differentiate between UnboundDollar and UnboundValue Update Match query conjunction bound test to include value variables Improve Named variable methods in TypeQLInsert and TypeQL Delete Allow aggregation on value variables Extend ThingConstraint.has to return attribute identity variables Changes for sorting on value variable Rename grammar symbol from EVAR_ to VALVAR_; Fix formatting Rearrange new grammar rules Fix Formatting till and including pattern.constraint Remove Type Parameter for {Thing,Value}Constraint.Predicate Work through warnings Fix more warnings & formatting Rearrange grammar & parser Introduce modulo-remainder operator; Make POW right-associative; Rearrange grammar; Dissolve pattern.expression package - move predicate up, Expression into ValueConstraint Create ValueVariableBuilder interface; Make UnboundValueVariable implement that simplify a bit Simplify query/ Refactor grammar a bit more Enable grouping on value variables in grammar Refactor grammar a little more Change only the grammar implement changes to parser Revert ThingVariable TypeVariable to not extend ConceptVariable Rename UnboundConceptVariable to UnboundThingTypeVariable Reflect renaming UnboundConceptVariable -> UnboundThingTypeVariable in grammar Unecessary cast in bound contains Remove ThingVariableBuilder.Root, before re-introducing it Rename ThingType to concept; Revert grammar to Concept and value Disable ?y; Explicitly enable has age ?a; Incorporate PR comments in grammar, TypeQLToken Incorporate changes to Parser, builder methods Incorporate more review comments Refactor Reference: Introduce Value class as sibling to Name; Use Variable.isNamed to check if Named or Value Incorporate more PR comments More comments incorporated Incorporate more PR feedback Simplify ThingConstraint.Has.variables() Some more comments Introduce ExpressionBuilder interface; Update builder methods to use them Add license to header in ExpressionBuilder Revert ConceptConstraint to the simpler signature Explicitly declare available functions in the grammar Add license header to ValueVariableBuilder Move PredicateBuilder implementation from ValueVariableBuilder to UnboundValueVariable Make the ParserTest for functions make more sense Incorporate comments Add ExpressionBuilder.plus, .minus, ... methods Rename arglist to args Rename expression function rules reintroduce variable name APIs for modifiers & aggregatables; only to remove them again Remove string api for modifier_vars Spacing in grammar More spacing Rename modifier_vars to var_referable Rename var to cVar and valueVar to vVar Checkstyle Typo in grammar unary operators are no longer handled in lexer, allowing spaceless ?x = 5+2; Move var_referable rule to VAR_* tokens section replace var_referable with VAR_CONCEPT_ | VAR_VALUE_ Align section separator endings (// ... ===) to 80 characters Align (VAR_CONCEPT_ | VAR_REFERABLE_ ) better Replace var_referable to VAR_CONCEPT_|VAR_VALUE_;Expand short rule names - expr*->expression* ; func -> function* Replace PAREN_OPEN/CLOSE in favour literal ( ) Replace rogue replace expresses -> expressionesses Replace redundant Operation enum in AssignmentConstraint with TypeQLToken Operation Use Function Enum in ValueConstraint.Expression PR refactor: remove needless qualifications Collapse all expression non-terminals to a single rule Fix Expression.Constant.String.toString; Introduce TypeQLStep for exceptions containing Backward compatibility for '=' in ThingVariable predicates Update missing var -> cVar Update arithmetic parser tests to reflect new rule synatx Refactor Reference.Refereable into Reference.Name Move Concept and Value into Reference.Name Fix equality function
Add parser test Fix recursion Test and fix variable name clash
Simplifying expressions, rename bracket to parenthesis Predicate constraints extract variables and convert to bound
## What is the goal of this PR? Implement support for expressions and value variables. The user-facing changes that drive this change are outlined in typedb/typeql#260. In particular TypeDB now supports the evaluation and return of Values, which are distinct from the previously existing data instances Entity/Relation/Attribute. Values are never materialised permanently, and only used within the scope of a particular query or rule. They are defined as an actual inner value, plus one of the defined TypeDB value types: `long`, `double`, `boolean`, `string` or `datetime`. Rules also now allow using of value variables to infer new attribute values: ``` define rule computation-cost-dollars-to-pounds: when { $c isa computation, has cost-dollars $c; $_ isa exchange-rate, has name "dollar-pound", has rate $rate; ?pounds = $rate * $c; } then { $c has cost-pounds ?pounds; }; ``` Querying for an attribute `match $x isa thing;` will then also trigger this inference. Note that accidentally creating infinite reasoning is much easier now: if implement `n = n + 1` in a rule, **it will run as long as the transaction is alive** - and likely cause an OOM. Future work will offer more advanced validation to protect against these cases. Closes #6654. ## What are the changes implemented in this PR? Patterns and constraints: Introduce: * Value(Concept) (`concept.value.Value`) * A (virtual) concept defined by a ValueType and a raw value of the said type. * Implemented `ValueImpl` and subclasses for each ValueType. * ValueVariable (`pattern.variable.ValueVariable`) * A new class of variables which unifies with `ValueConcept` and holds `ValueConstraint` * `ValueConstraint` (`pattern.constraint.ValueConstraint) and subclasses: * `AssignmentConstraint`: assigns a ValueVariable with the result of some TypeQL `Expression` * `PredicateConstraint`: Adds a predicate constraint on the ValueVariable - It can be an (inequality) constraint where the value is compared against one of: * A constant of the supported valueTypes * A `ThingVariable` (which has to be an attribute to have a value) * Another `ValueVariable` * A `ValueVertex` similar to Value Concept * An IID definition for `ValueVertex` in `encoding.iid.VertexIID` * Defined by Prefix + ValueType + EncodedValue * `ExpressionCompiler` as a sibling to TypeResolution * Convertes TypeQL expressions into executable traversal expressions with unambiguous value types Refactor: * Introduce a `vertex.Value` interface implemented by ThingVertex and ValueVertex * supports reading the value for comparisons in predicates. * supports reading the as input in expressions * Rename `ThingConstraint.ValueConstraint` to be `ThingConstraint.PredicateConstraint` * Supports comparing a ThingVariable to a ValueVariable . ### Traversal * Introduce the Value subclasses for StructureVertex, PlannerVertex, ProcedureVertex * Introduce `Argument` edge to connect variables on the RHS of an assignment to the variable being assigned to (i.e. on the LHS) * Update the planner to enforce `Argument` edges are always traversed forwards (i.e., all vertices of the RHS are evaluated before the LHS) * Update PredicateEdge to be able to deal with both ValueVertex and ThingVertex * Introduce the implementation of every operator / function in `traversal.expression`
## What is the goal of this PR? Introduce the 'Value' type, which is returned as the result of an expression's computation. This change follows from typedb/typeql#260, which outlines the capabilities of the new expression syntax. Values (representing any of Long, Double, Boolean, String, or DateTime) are returned as part of `ConceptMap` answers and are subtypes of `Concept` for the time being. Their main API is made of the `.getValue()` method and `.getValueType()` method, along with all the standard safe downcasting methods to convert a `Concept` into a `Value`, using `Concept.isValue()` and `Concept.asValue()`. We also move the import location of `ValueType` from being nested in `AttributeType` to `Concept`. ## What are the changes implemented in this PR? * Introduces the `Value` concept and the required `ValueImpl` that implements it * Refactor `ValueType` to no longer live within `AttributeType` - now it exists in `Concept.ValueType` * Updates the test framework for tests involving values, including the new `ExpressionTest` behaviour scenarios, which we also add to CI
## What is the goal of this PR? Introduce the 'Value' type, which is returned as the result of an expression's computation. This change follows from typedb/typeql#260, which outlines the capabilities of the new expression syntax. Values (representing any of Long, Double, Boolean, String, or DateTime) are returned as part of `ConceptMap` answers and are subtypes of `Concept` for the time being. Their main API is made of the `.get_value()` method and `.get_value_vype()` method, along with all the standard safe downcasting methods to convert a `Concept` into a `Value`, using `Concept.is_value()` and `Concept.as_value()`. We also move the import location of `ValueType` from `attribute_type.py` to `concept.py`. ## What are the changes implemented in this PR? * Introduces the `Value` concept and the required `ValueImpl` that implements it * Refactor `ValueType` to no longer live within `AttributeType` - now it exists in `Concept.ValueType` * Updates the test framework for tests involving values, including the new `ExpressionTest` behaviour scenarios, which we also add to CI
## What is the goal of this PR? Introduce the 'Value' type, which is returned as the result of an expression's computation. This change follows from typedb/typeql#260, which outlines the capabilities of the new expression syntax. Values (representing any of Long, Double, Boolean, String, or DateTime) are returned as part of `ConceptMap` answers and are subtypes of `Concept` for the time being. Their main API is made of the `.getValue()` method and `.getValueType()` method, along with all the standard safe downcasting methods to convert a `Concept` into a `Value`, using `Concept.isValue()` and `Concept.asValue()`. We also move the import location of `ValueType` from being nested in `AttributeType` to `Concept`. ## What are the changes implemented in this PR? * Introduces the `Value` concept and the required `ValueImpl` that implements it * Refactor `ValueType` to no longer live within `AttributeType` - now it exists in `Concept.ValueType` * Updates the test framework for tests involving values, including the new `ExpressionTest` behaviour scenarios, which we also add to CI
## What is the goal of this PR? We allow users to interact via Console with the new Value API introduced in typedb/typeql#260. This PR adds pretty printing for value concepts and updates required dependencies to support the change. ## What are the changes implemented in this PR? * Update to a client-java version that supports Values in queries and answers * Update the concept pretty-printer to allow printing Value concepts. * Update ConceptMap printing to first print concept variables (`$`) by alphabetical sorting of the variable name, and then value variables (`?`) by alphabetical sorting.
## What is the goal of this PR? We introduce in `typeql-rust` the ability to perform arithmetic computation and store the results in a "value variable" - denoted by a preceding `?`, the same as introduced in `typeql-java` by #260. All redundant parenthesis from original query will not persist in the string representation of the parsed expression anymore. If we get this query: ``` match $p isa person, has salary $s; ?net = (($s - 12500) * 0.8 + 12500); ``` it will be transformed into ``` match $p isa person, has salary $s; ?net = ($s - 12500) * 0.8 + 12500; ``` ## What are the changes implemented in this PR? In addition to changes implemented in #260: - We removed `Parenthesis` class and do not store parenthesis in the expression tree anymore. When we build a string representation of the expression, we add all necessary parenthesis. Nevertheless, if we get something like `a + (b + c)`, these parenthesis will persist in the resulting string representation.
What is the goal of this PR?
We introduce the ability to perform arithmetic computation and store the results in a 'value variable' - denoted by a preceding
?
. For example:Or through the java api:
Rules now also support value-variable conclusions:
The expression on the right hand side of an assignment can be functions, operations, variables or constants:
+
,-
,*
,/
,^
,%
,min
,max
,floor
,ceil
,round
,abs
(...)
and instantiation of constants eg.12
,0.25
,false
,"abc"
, etc.These constructs are currently defined on double and long valued Attribute instances or Value instances.
The language implements order-of-operations for infix operators in this order:
()
,^
,*
,|
,%
,+
,-
.Deprecation warnings
=
can should no longer be used to denote value-equality.=
now represents value-assignment, with==
representing value equality. For the time being, concept variables$x
will still support the old syntax,=
and the new==
, however expect$x =
to be removed from the language in future releases.Breaking changes
var
is no longer part of the TypeQL builder API, being replaced bycVar
to create concept variables ($x
) andvVar
to create a value variable (?y
).What are the changes implemented in this PR?
Grammar:
?x
instead of$x
.$x
variables are now referred to as "Concept" variables=
from equality test to mean assignment for value variables:?x =
=
for predicates and comparisons becomes==
. ForConcept
variables, we still allow=
and==
to mean comparison. NOTE: the old synta x$x =
is now deprecated and will be removed in 3.0?x =
is anExpression
+
,-
,*
,/
,^
,%
, and wrapper expression(...)
min
,max
,floor
,ceil
,round
,abs
long
anddouble
value typesValue
andConcept
variables can be used in expressions, along with constantsLanguage API:
UnboundValueVariable
(cVar(x)
andUnboundValueVariable
(vVar(x)
), to replacevar(x)
Expression
, which when statically imported can be used to build expressions:Expression.pow(..., ...)
, along with other expression constructsget
,sort
etc:match(...).get("x")
with only the typed versions:match(...).get(cVar("x"))
Pattern:
Unbound
variables may be used as builders for expressions or constraints. However, any variable in aConstraint
must be aBoundVariable
Predicate
class that is held by both Thing and ValuePredicateConstraint
sBoundVariable
:ValueVariable
, which holds the newValueConstraint
sValueConstraint
is the parent class ofValueConstraint.Predicate
andValueConstraint.Assignment
ValueConstraint.Assignment
holds anExpression
ValueVariables
always use aReference.Named.Value
reference type. We refactorReference.Referrable
to be calledReference.Named
and placeReference.Named.Concept
andReference.Named.Value
under it, and moveLabel
toReference.Label
.UnboundValueVariable
analogously toUnboundConceptVariable
. Both are now subtypes ofUnboundVariable
.$x
) and value variables?x
do not re-use the same names