Expressions¶
This chapter describes all expressions of SMOL. Informally, expressions are the language elements that can occur on the right hand side of an assignment (even though they can be written on their own, see The Expression Statement).
Expressions are divided syntactially into two categories: Simple Expressions, which can be nested, and Top Level Expressions, which cannot be sub-expressions of other expressions. This slight notational inconvenience makes it easier to develop tools for SMOL.
Expression ::= SimpleExpression
| TopLevelExpression
SimpleExpression ::= LiteralExpression
| OperatorExpression
| NullExpression
| ThisExpression
| VariableExpression
| FieldExpression
| FmuFieldExpression
TopLevelExpression ::= NewExpression
| NewFmuExpression
| MethodCallExpression
| SuperExpression
| QueryExpression
| ConstructExpression
| ConceptExpression
| ShapeExpression
Literal Expressions¶
All literals, as defined in Literals, can be used as simple expressions.
LiteralExpression ::= Literal
Example:
"This is a string"
5.13
false
Unary and Binary Operator Expressions¶
SMOL has a range of unary and binary operators working on pre-defined datatypes. Additionally, there are conversion operators between strings, integers, and doubles.
OperatorExpression ::= UnaryOperatorExpression | ConversionExpression | BinaryOperatorExpression
ConversionExpression ::= Conversion '(' Expression ')'
Conversion ::= 'intToString' | 'doubleToString' | 'intToDouble' | 'doubleToInt'
UnaryOperatorExpression ::= UnaryOperator Expression
UnaryOperator ::= '!'
BinaryOperatorExpression ::= Expression BinaryOperator Expression
BinaryOperator ::= '/' | '%' | '*' | '+' | '-' | '==' | '!=' | '>=' | '<=' | '>' | '<' | '&&' | '||' | '++'
Example:
1 / 2
bid > price || customer == "VIP"
The following table describes the meaning as well as the associativity and the precedence of the different operators. The list is sorted from low precedence to high precedence.
Expression |
Meaning |
Argument types |
Result type |
---|---|---|---|
|
logical negation |
Boolean |
Boolean |
|
logical or |
Boolean |
Boolean |
|
logical and |
Boolean |
Boolean |
|
less than |
numeric |
Boolean |
|
greater than |
numeric |
Boolean |
|
less or equal than |
numeric |
Boolean |
|
greater or equal than |
numeric |
Boolean |
|
not equal to |
compatible |
Boolean |
|
equal to |
compatible |
Boolean |
|
subtraction |
numeric |
numeric |
|
addition |
numeric |
numeric |
|
multiplication |
numeric |
numeric |
|
modulus |
numeric |
numeric |
|
division |
numeric |
numeric |
|
concatenation |
String |
String |
Semantics of Comparison Operators¶
Equality and inequality comparison is standard: by value for datatypes and by
reference for objects. I.e., two strings “Hello” compare as identical via
==
, as do two numbers. Two references to objects compare as identical via
==
if they point to the same object or future. The inequality operator
!=
evaluates to True
for any two values that compare to False
under ==
and vice versa.
The less-than operator <
and the other comparison operators compare
numbers of different types (integers vs floats) in the expected way.
The Null Expression¶
The null expression evaluates to a value denoting an invalid object. It can be used, e.g., to initialize a variable that will be assigned another value later in the program.
NullExpression ::= 'null'
Example:
null
The This Expression¶
This expression evaluates to the current object. This expression cannot be used in the main block, since the main block does not execute within the scope of an object.
ThisExpression ::= 'this'
Example:
this
The Variable Expression¶
Variable expressions evaluate to the current content of the named variable.
VariableExpression ::= Identifier
Example:
x
a_long_variable_name
The Field Expression¶
Field expressions evaluate to the current content of the named field in the
given object. The object can be this
, another object, or an FMO.
Note that fields of the current object cannot be accessed without the this.
prefix.
FieldExpression ::= SimpleExpression '.' Identifier
Example:
this.x
an_object.a_long_field_name
The New Expression¶
The New expression creates a new object of the given class. Values for the class’s constructor parameters are given as simple expressions inside parentheses. All generic type parameters of a class must be instantiated.
The optional models
clause adds to an eventual models
clause of the new object’s class declarations (see
Class Declarations).
NewExpression ::= 'new' Type '(' ( SimpleExpression ( ',' SimpleExpression)* )? ')' ( 'models' SimpleExpression )
Example:
new Person("Name", 35) models "a :person."
The New FMU Expression¶
This expression creates a new instance of the given FMU. The expression takes
first a literal string containing the path to the FMU file, followed by zero
or more initializer terms for the FMU’s parameters. All parameters specified
by the FMU in its modelDescription.xml
file must be initialized.
NewFmuExpression ::= 'simulate' '(' StringLiteral (',' Identifier ':=' SimpleExpression)* ')'
Example:
simulate("../Sim.fmu", iValue = 0.0, slope = 1.5)
The Method Call Expression¶
This expression invokes the named method on the given object instance.
MethodCallExpression ::= Expression '.' Identifier '(' ( SimpleExpression ( ',' SimpleExpression)* )? ')'
Example:
this.doWork();
worker.processRequest();
The super
Expression¶
This expression invokes the method as defined in a superclass of the current
object’s class from within the overriding method. The super
expression is
only valid inside a method that overrides a superclass’s method.
SuperExpression ::= 'super' '(' ( SimpleExpression ( ',' SimpleExpression)* )? ')'
Example:
super.doWork()
The Query Expression¶
The access
top-level expression retrieves a list of literals or lifted objects using a query mode SPARQL
to access the semantically lifted state or INFLUXDB
to access an external InfluxDB database. If no query mode is given, SPARQL
is the default.
QueryMode ::= 'SPARQL' | ('INFLUXDB' '(' StringLiteral ')')
QueryExpression ::= 'access' '(' SimpleExpression (',' QueryMode)? ( ',' SimpleExpression)* ')'
In SPARQL
mode, it takes as its first parameter a String
-literal containing an extended SPARQL query, which additionally may contain non-answer variables of the form %i
for some strictly positive number i
. The set of numbers for the non-answer variables must form an interval [1,n] for some n.
Additionally, the top-level expression takes a list of expressions of the length n.
At runtime, these expressions are evaluated and the result is syntactically substituted for the corresponding non-answer variable.
The SPARQL query must contain a ?obj
variable.
Example: The following retrieves all objects o
of type C
with o.b.c == this.x
.
List<C> l = access("SELECT ?obj WHERE {?obj prog:C_b ?b. ?b prog:D_c %1 }", this.x);
In INFLUXDB
mode, the first parameter is an InfluxDB query with a single answer variable. Non-answer variables are not supported and the query mode has a parameter itself, which is
a String
-literal containing a path to a YAML configuration to connect to the InfluxDB endpoint.
The result is always a List
of Double
values.
Example:
main
List<Double> list := access(
"from(bucket: \"petwin\")
|> range(start: -1h, stop: -1m)
|> filter(fn: (r) => r[\"_measurement\"] == \"chili\")
|> filter(fn: (r) => r[\"_field\"] == \"temperature\")
|> filter(fn: (r) => r[\"name\"] == \"faarikaal1\")
|> aggregateWindow(every: 5m, fn: mean, createEmpty: false)
|> yield(name: \"mean\")",
INFLUXDB("petwin.yml"));
print(list.content);
end
The Construct Expression¶
The construct
top-level expression constructs a list of new objects from a SPARQL query.
Its parameters are as the one of the access
top-level expression, but the variables are handled differently:
ConstructExpression ::= 'construct' '(' Expression ( ',' SimpleExpression)* ')'
Each variable must have the name of a field of the type of the target location. For each field there must be one variable. All fields must be of primitive data type.
Example:
class C(Int j1, Int j2) end
...
List<C> v = construct("SELECT ?j1 ?j2 WHERE { ?y a prog:B. ?y prog:B_i2 ?j2.?y prog:B_a ?x.?x a prog:A. ?x prog:A_i1 ?j1 }");
The Concept Expression¶
The member
top-level expression retrieves the list of objects described by an OWL concept.
The parameter must be a String
-literal containing a concept in Manchester syntax.
ConceptExpression ::= 'member' '(' Expression ')'
Example: The following retrieves all members of class C
that model some domain concept domain:D
.
List<C> list := member("<domain:models> some <domain:D>");
The execution fails if the concept is either mal-formed or contains elements that are not IRIs of lifted objects.
The Shape Expression¶
Shape access validates the correctness of the lifted knowledge graph with respect to a graph shape using the top-level expression validate(Literal)
.
The parameter must be a String
-literal containing a path to SHACL shapes in turtle syntax.
ShapeExpression ::= 'validate' '(' Expression ')'
Example:
Boolean b = validate("examples/double.ttl");
The execution fails if the file does not accessable or the SHACL shapes are mal-formed.