Grok operators

*  These operators are available in QL only.


[top]

Assignment Operator

The assignment operator has the following syntax in Grok:

 id := expression 
There is no semicolon at the end of the statement. The assignment operator := is like Pascal or Algol (not like the = in C and Java).

The assignment operator evaluates a value of expression and assigns it to id. It does not return a value. Assignment always is always "by value", i.e. if A is being assigned to B, a copy of A is created and placed in B. Future changes to A do not affect the value of B.

There is an alternate form:

$ expression1 := expression2 
This form assigns expression2 to the variable whose name is expression1.



[top]

Regular Expression Matching

This family of operators is unique to QL. They are not available in Grok. Grok has some matching operators (see their description --- when running Grok, type '?' for their description).

[top]

Relational operators

Grok has a fairly standard set of relational operators. The table below gives a complete list.

Operator Meaning
== equal
~= not equal
<strictly less than
>strictly greater than
<=less than or equal to
>=greater than or equal to

Applying relational operators to scalars. When used to compare scalar types (int, float, string, boolean), the types of both operands must be compatible, i.e. both operands must be numbers (int, float), or strings, or booleans. (Note that int, real and boolean are actually implemented as simply strings.)

Applying relational operators to sets and relations. Sets can be only compared to sets, and relations can only be compared to relations.

The equality and inequality operators function exactly as you would expect. Two sets or relations are found equal if they contain the same elements.

Operators >, <, >=, <= can be applied to sets and relations.

[top]

Arithmetic operators

Four standard arithmetic operators are supported: addition (+), substraction (-), multiplication (*) and division (/). Arithmetic operators can only be applied to numeric scalars (to strings that are integers and floats).

[top]

Logical operators

Three logical operators are available: and, or and not.

and returns true only if both its operands are true.

or returns true if at least one of its operands is true.

not (or ~) is a prefix operator and returns true if its sole operand is false.

Logical values (true and false) are simply string values.

[top]

Concatenation operator

QL provides a concatenation operator cat. Concatenation operates on two strings and returns a string that is produced by concatenating the two strings together.

The union operator (+) operates on sets or relations, and returns a set or relation composed of tuples that occur in either one of its operands. Duplicates are eliminated. The two operands must be compatible with each other; it is impossible to take a union of a set and a relation, or of two relations with different column counts.

[top]

Difference operator

The difference operator (-) operates on sets or relations, and returns the difference between its operands, i.e. a set (or relation) consisting of all elements in the first operand that are not in the second operand. The two operands must be compatible with each other; it is impossible to take a union of a set and a relation.

An example below illustrates the use of the difference operator to compute, given sets of carnivores and herbivores, a list of animals which are pure carnivores (i.e. do not eat plants as well as meant):

>> carnivores = {"wolf", "lion", "bear"}
>> herbivores = {"cow", "deer", "bear", "elk"}
>> not_omnivores = carnivores - herbivores
>> not_omnivores
wolf
lion


[top]

Composition operator

The composition operator, denoted o, can be used to join two relations. The join is always performed on the rightmost column of the first operand and the leftmost column of the second operand. The result of such operation is a relation made of tuples from the first operand "joined" to the tuples of the left operand that match them in the field the join is performed on. Tuples that do not have a match do not appear in the result. The column on which the join was performed is discarded and does not appear in the result. (###This needs an example.)

[top]

Intersection operator

The intersection operator (^) can be applied to two sets or relations to determine their intersection, i.e. common components. The result of execution would be a set or relation composed of tuples that exist in both operands. The two operands to the operator must be compatible: you cannot take an intersection of a relation and a set, or two relations with different column counts.

[top]

Projection operator

The projection operator (.) is used for projecting a set through a relation. The result of such an operation is a set, containing such tuples from the original relation that their entries in the projection column are equal to one of the members of the set being projected. (###This needs examples.)

[top]

Transitive closure and reflective transitive closure

The transitive closure operator (+) computes transitive closure on a relation. The reflective transitive closure operator (*) is identical to the transitive closure in application, but the results of reflective transitive closure include self-loops. The examples below illustrate the use of the transitive closure operators.

The example below shows the creation of a relation which compares relative speeds of different modes of transportation:

>> faster = {"rocket"} X {"car"} + {"car"} X {"bicycle"} + {"bicycle"} X {"pedestrian"}
>> faster
rocket car
car bicycle
bicycle pedestrian
Using transitive closure, from this relation we can obtain speed comparisons between all transportation modes listed:
>> faster+
rocket car
rocket bicycle
rocket pedestrian
car bicycle
car pedestrian
bicycle pedestrian
The resulting relation gives us, for a given transportation mode, all modes that are slower than it. If, on the other hand, we want a list of transportation modes that are not faster than a give one, we would use the reflective transitive closure:
>> faster*
rocket rocket
rocket car
rocket bicycle
rocket pedestrian
car car
car bicycle
car pedestrian
bicycle bicycle
bicycle pedestrian
pedestrian pedestrian
You will notice that the result of the reflective transitive closure operator is augmented with self-loops (e.g "car car"), but is otherwise the same as the result of ordinary transitive closure.

(###Should explain that in Grok, but not JGrok, the self loops are on all nodes that appear in any relations.)



[top]

Domain operator

The domain operator (dom) computes the domain of its operand, which must be a relations. What this operator really returns is the set of all entities contained in the first column (column zero) of a relation; duplicates are eliminated.

The example below illustrates how to use the domain operator.

>> map = {1} X {"one"} + {2} X {"two"} + {3} X {"three"}
>> map
1 one
2 two
3 three
>> dom map
1
2
3


[top]

Range operator

The range operator (rng) computes the range of its operand, which must be a relation. What is actually returned is the set of all entities contained in the last column of a relation, with duplicates (if any) eliminated.

The example below illustrates how to use the range operator.

>> map = {1} X {"one"} + {2} X {"two"} + {3} X {"three"}
>> map
1 one
2 two
3 three
>> rng map
one
two
three


[top]

Entities operator

The entities operator (ent) is a prefix operator (like dom and rng above) that returns a set containing all the entities in its operand, which must be a relations.

[top]

Inverse operator

The inverse operator (inv) is a prefix operator that inverses the order of columns in its operand, which can be a set or a relation.

[top]

Identity operator

The identity operator (id) returns a binary relation in which the first column consists of all entities in the operand (which must be a set). The entries in the second column of each tuple of the result are equal to the entries in the first column. The example below illustrates:

 

>> numbers = {1,2,3}
>> id numbers
1 1
2 2
3 3


[top]

Cross product operator

The cross product operator (X) returns the cross-product of its two operands, which must be sets. The result is a binary relation. For example:

>> {"one", "two", "three"} X {1,2,3}
one 1
one 2
one 3
two 1
two 2
two 3
three 1
three 2
three 3


[top]

Cardinality operator

The cardinality operator (#) returns the number of tuples or entries in a set or relation. For example:

>> map = {1} X {"one"} + {2} X {"two"} + {3} X {"three"}
>> #map
3
>> strings = {"foo", "bar", "buzz", "lightyear"}
>> #strings
4