Jump to: navigation, search

VIATRA2/Examples/VTCL/Terms

< VIATRA2‎ | Examples‎ | VTCL

VTCL Terms and Expressions

Constants

The followind types of constants are available in VTCL:

  • Undefined value constant: undef
  • Boolean constants: true, false
  • Integer constants: 1, -1,
  • Double constants: 2.32, -1.9, (as in Java)
  • String constants: "A string." (as in Java)
  • Model element constants: fully qualified names, e.g. uml.metamodel.Classifier, local names: ejbEntity, 'Class' (local names starting with a capital letter should be included within quotes.
  • Multiplicity constants: one_to_one, one_to_many, many_to_one, many_to_many,

In case of model element constants, a corresponding element should be present in the model space (at compile time), otherwise an error message is issued.

 machine vtcl_constants {
  rule main() = seq {
 	// Undefined constant
 	println(undef);
 	// Boolean constants
 	println(true);
 	println(false);
 	// String constants
 	print("Hello VIATRA2 world!");
 	// Integer constants
 	println(4);
 	println(-4);
 	// Double constants
 	print(4.6);
 	print(-4.7);
 	print(6.6e2);
 	print(10e-2);
 	// Model elemenent constants 
 	// (provided that entity testing.models.manager exists in model space)
 	print(fqn(testing.models.manager));
 	print(fqn('testing'));
 	// Multiplicity constant
 	print(one_to_one);
 	print(one_to_many);
 	print(many_to_one);
 	print(many_to_many);
  }
 }


Logical Terms

Logical terms consist of usual binary Boolean operators such as "&&" (and), "||" (or), "xor" (exclusive or), and unary operator "!" (not).

The precedence of Boolean operators are as follows: "!" (highest), "&&", { "||"; "xor" } (lowest). Operator precedence can be overridden by parenthesis. All previous operators tie as usual (to the left)

Equality (and inequality) operators, namely, "==" (equal), and "!=" (not equal), are also allowed for Boolean values.

There are two logical constants: "true" and "false".

 machine logical_operators{
  rule main() = seq {
 	print(!true);
 	print(!false);
 	print(true && false);
 	print(true || false);
 	print(true xor false);
 	print(true == true);
 	print(false != true);
 	// The internal pairs of parenthesis are not needed
 	print((true && false) || (true  && true));
 	print((true == true) != false));
 	// The internal pairs of parenthesis are needed
 	print((true || false) && (true  ||  false));
 	print(true == (true != false));
  }
 }

Arithmetic Terms

Arithmetic terms can be constructed by binary and unary operators in the following way:

Binary operators

  • Additive: + (add), - (subtract)
  • Multiplicative: * (multiply), / (divide), % (remainder, only for integers)

Unary operators:

  • Minus: -

For numerical values, they are treated as in Java, for instance.

 machine arithmetic_terms_1 {
  rule main() = seq {
 	// Add
 	print(3 + 4);
 	print(4.0 + 3); // also 3+4.0 is correct
 	print(5.9 + 4.5);
 	// Subtract
 	print(3 - 4.0);
 	print(4 - 3);
 	print(4.5 - 5.9);
 	// Multiply	
 	print(3 * 4);
 	print(4.0 * 3);
 	print(5.9 * 4.5);
 	// Divide	
 	print(10 / 4.0);		
 	print(6.0 / 3);
 	print(6 / 3);
 	print(9.0 / 4.5);
 	// Remainder: for integers
 	print(14 % 4);
  }
 }

Strings can be added with any other kind of terms, but no other operations are allowed.

 machine arithmetic_terms_2 {
  rule main() = seq {
 	print(3 + "hello");
 	print(3.9 + "hello");
 		
 	print("hello" + 4);
 	print("hello" + 3.4);
 	print("hello" + "test");
 	print("hello" + true);
 	print(false + "hello");
 
 	print("hello" + one_to_many);
 	print(many_to_one + "hello");
  }
 }

Finally, it should be pointed out that any arithmetic operations are allowed for the undef constant regardless of the type of the other operand

Relational operators

The relational operators of the VTCL language are the following:

  • Equal, NotEqual: ==, != (for all kinds of elements provided the left and right values are type compatible)
  • Inequality: <=, >= (only for numerical values, multiplicity constants, and undef)
  • Strict inequality: <, > (only for numerical values, multiplicity constants and undef)

Any numerical types can be compared to

 machine relation_operations_1 {
  rule main() = seq {
 	// Integers and doubles (interchangeably)
 	print(4.0 != 4.0);
 	print(4 == 4);
 	print(4.0 <= 4.0);
 	print(4 >= 4.0);
 	print(4.0 < 4.1);
 	print(4 > 3);
 	// Strings
 	print("apple" == "melon");
 	print("apple" != "melon");
 	// Boolean
 	print(true == false);
 	print(true != false);
 	// Multiplicities
 	print(many_to_one == many_to_many); // false
 	print(many_to_one != many_to_many); // true		
 	print(many_to_one <= many_to_many); // true
 	print(many_to_one >= many_to_many); // false
 	print(many_to_one < many_to_many);  // true
 	print(many_to_one > many_to_many);  // false
 
 	// Undef (in all relational operation 
 	// with all kinds of values)
 	print(undef == 4);
 	print(undef < 4);
  }
 }

Conversion functions

The following conversion functions are available to create different values of a certain type from other elements:

  • toBoolean(X): X can be a string, a numeric value or a boolean
  • toString(X): X can be a string, a numeric value, a boolean, a multiplicity constant, or a model element constant (equals to fqn)
  • toInteger(X): X can be a string, or a numeric value
  • toDouble(X): X can be a string, or a numeric value
  • toMultiplicity(X): X can be a string
  • name(X), fqn(X): X can be a model element; returns the local vs. fully qualified name of a model element
  • ref(X): X can be a string; returns the model element by resolving the string as an FQN (at runtime)

The undefined value can be converted to any other type.


 machine conversion_operations_1 {
  rule main() = seq {
 	// toString()
 	print(toString(true));
 	print(toString("abc"));
 	print(toString("3.14"));
 	print(toString(1));
 	print(toString(1.0));
 	print(toString(one_to_one));
 	print(toString(undef));
 	//toBoolean()
 	print(toBoolean(true));
 	print(toBoolean("viatra"));
 	print(toBoolean(1));
 	print(toBoolean(1.0));
 	print(toBoolean(undef));
 	//toInteger()
 	print(toInteger("1"));
 	print(toInteger(1));
 	print(toInteger(1.5));
 	print(toInteger(undef));
 	//toDouble()
 	print(toDouble("2.2"));
 	print(toDouble(1));
 	print(toDouble(2.2));
 	print(toDouble(undef));
 	//toMultiplicity()
 	print(toMultiplicity("one_to_one"));
 	print(toMultiplicity(undef));
 	//name(), fqn(), ref()
 	print(name(a.b.c)); // Element a.b.c should exist in the model space (at compile time)
 	print(fqn(a.b.c)); // Element a.b.c should exist in the model space (at compile time)
 	print(ref("a.b.c")); // Element a.b.c should exist in the model space (at runtime)
  }
 }