# Language Reference¶

Grackle supports a significant portion of MATLAB syntax. This allows engineers familiar with MATLAB to start formal analysis without having to learn a new language. This documentation assume that readers are familiar with MATLAB, and focuses on differences between Grackle and MATLAB.

## Symbolic Computation¶

The fundamental difference between MATLAB and Grackle is that MATLAB evaluates the program in a context where expressions appearing in the program are bound to values such as a floating point numbers, while Grackle uses a context where expressions are bound to mathematical formulas. This is more general, as every value can be treated as a constant formula, but formulas may denote an arbitrary number of values.

When executing over values, Grackle is similiar to MATLAB; the primary difference is that Grackle encodes numerical values as arbitrary precision rationals whereas MATLAB uses floating point. By encoding numerical values as rationals, one does not lose precision in basic operations like adding, subtracting, multiplying or dividing numbers. The computation may take longer, but numerical accuracy is not lost. Grackle will only switch to floating point when evaluating functions that cannot be computed over rationals. This includes trigometric functions such as `sin` and `cos` (see API Reference for details about specific functions).

The key focus of Grackle though is manipulating formulas, and Grackle provides a variety of functions for working with formulas. This include the symbolic function for creating formulas that are new symbolic variables, performing satisfiability checks to find satisfying assignments to symbolic variables, and writing formulas out to different formats such as SMTLIB. See Symbolic Simulator Operations for a description of each function.

Most MATLAB functions supported by Grackle have been generalized to operate over formulas. For adding two numbers `x + y` where either `x` or `y` are formulas and not values, the plus function will return a formula denoting the sum of the two formulas bound to `x` and `y`.

## Functions¶

Functions that are globally visible are defined in separate files ending with the `.m` extension. The filename must match the name of the function. For example, a function `foo` should be defined in `foo.m`.

In addition to global functions, Grackle source files may contain both anonymous functions and local functions. These functions are only visible within the function that defined them, but other code may be able to call them if they are passed out of a function via a return value. Grackle does not support nested functions, so code containing them will be rewritten.

## Statements¶

The simulator supports the majority of MATLAB control flow statements. This includes `if`, `elseif`, `else`, `for`, `switch`, `case`, `otherwise`, `while`, `break`, `continue`, `end`, and `return`. Parallel for loops (i.e., `parfor`) have limited support, as they will just be interpreted as ordinary `for` loops.

Grackle does not support exception handling including `try` and `catch`. Grackle also does not support classes and object oriented MATLAB.

Grackle allows global variables to be introduced and used. It does not currently support persistent variables.

## Data types¶

The simulator supports many of the primtive data types in Matlab, including all of the types below:

• Numeric arrays of real and complex numbers.
• Fixed precision integers including not just the types such as `int8`, `int16`, and `int32` supported by Matlab, but types `intN` and `uintN` for any positive number of bits N.
• Character arrays and strings.
• Logical arrays.
• Structures
• Cell arrays
• Function handles

One major difference between Matlab and `grackle` is that real and complex values in Matlab are typically treated as arbitrary precision values, and are not floating point values as in Matlab. This is one source of performance overhead when evaluating Matlab code symbolically, but has the side effect of making symbolic analysis much more tractable and accurate on typical problems. `grackle` does currently revert to double precision on some operations, such as trigonometric functions, but this restriction may be relaxed once `grackle` develops full support for computational real numbers.

During symbolic simulation, the simulator currently makes a few restrictions on what types of values may be symbolic. In particular, the simulator requires that the type of values is not symbolic, and the number of elements in array must be a concrete value. Furthermore, only numeric and logical values may be symbolic: if one, for example, attempts to convert a symbolic array of numbers to characters, the simulator will throw an error. It should be possible to relax these restrictions in a later release, but the resulting problems may be more difficult to formally analyze.

For arrays, the simulator allows values within arrays to be symbolic, but does not allow the size of the array itself to be symbolic. This can pose an issue when calling functions that interpret an expression as the size of an array, such as, `zeros(x)`. In this expression, the simulator will report an error unless `x` is a concrete value.

## Object Oriented Programming¶

Grackle supports a subset of the object oriented programming features of MATLAB. In the following subsections, the features supported by Grackle and simple examples are given. For detailed syntax and semantics, see the MATLAB reference above.

### User defined classes¶

Classes may be defined using the `classdef` keyword. Grackle currently only supports `properties` and `methods` blocks inside `classdef` definitions. For example, the most trivial class definition is:

```classdef Flicker
end
```

Class definitions may be a) self-contained in one file, or b) spread across multiple files using a class folder. Class folders start with an `@` character and contain a classdef file of the same name, e.g. `@MyClass/MyClass.m`. All other function files inside the class folder are interpreted as class methods, whether they are declared in the class file or not.

### Properties¶

Class properties may be specified using one or more `properties` blocks:

```classdef Flicker
properties
x = 0
end
end
```

Both static and dynamic property references are supported, e.g. `obj.x` and `obj.('x')`. Object properties can be “get” and “set” like normal variables:

```In [1]: obj = Flicker;
In [2]: obj.x
ans =

0

In [3]: obj.x = 6.022e23
obj =

Flicker with properties
x: 6.0220e23
```

### Methods¶

Class methods are specified using one or more `methods` blocks, for example:

```classdef Flicker
properties
x = 0
end
methods
function r = xsq(obj)
r = obj.x^2;
end
end
end
```

Ordinary class methods must accept an initial “self” argument (above called `obj`) as there is no implicitly bound “this” or “self” object in MATLAB.

Static class methods are specified using the `Static` attribute in a `methods` block, for example:

```classdef Flicker
methods (Static)
function r = tau()
r = 2*pi;
end
end
end
```

Note that static methods can be called from the class, e.g. `Flicker.sayHello()` or from an instance, e.g. ```obj = Flicker; obj.sayHello()```.

### Constructors¶

User defined constructors are supported, for example:

```classdef Flicker
properties
x  % initialized by the constructor
end
methods
% object constructor that initializes property 'x'
function obj = Flicker(v)
obj.x = v;
end
end
end
```

Objects are constructed using the class name, e.g. `obj = Flicker(6)`. A class may have only one constructor. Overloading can nonetheless be achieved using `varargs` and `nargin`, just as for ordinary functions.

### Getters and Setters¶

User defined property getters and setters may be defined by declaring methods with the `get.` and `set.` prefix, for example:

```classdef Flicker
properties
x = 0
end
methods
% return the internal value 'x' plus one
function r = get.x(obj)
r = obj.x + 1;
end
% set the internal value 'x' to 'v-1'
function obj = set.x(obj, v)
obj.x = v - 1;
end
end
end
```

### Inheritance¶

Grackle supports single inheritance, including method overriding, for example consider a base class `Ptarmigan`:

```classdef Ptarmigan
properties
y = 0
end
methods
function r = ptMethod(obj)
r = obj.y*obj.y + 1;
end
function r = doubley(obj)
r = 2*obj.y
end
end
end
```

and a subclass `Flicker` that overrides `ptMethod`:

```classdef Flicker < Ptarmigan
methods
function r = ptMethod(obj, z)
r = z*z + 1;
end
end
end
```

In the example, class `Flicker` inherits whatever properties `Ptarmigan` defines, including their default values. It also inherits all of `Ptarmigan`‘s methods, except for `ptMethod` which is overridden. The inheritance chain is allowed to by arbitrarily long.

Note that Grackle currently does not support calling methods of superclasses directly.

### Handle Classes¶

Grackle supports the Matlab built-in class handle. A subclass of handle does not inherit any methods or properties from its parent, rather it inherits reference semantics. The semantics of updates, method calls, and functions calls for handle class are different than that of value classes, cf. Comparing MATLAB handle and value classes. Moreover, classes that inherit from handle indirectly through a superclass also use reference semantics.

Some caveats:

• Note that class property default values are constructed once, and only once, for each class. Each instance of a class shares the default value specific to each property. This is important if the property is a handle class itself since all instances of this default value will alias.
• The delete method is not supported. It may be defined as part of a classdef, but it will never be called by the simulator, unless it is explicitly called.
• Object references (i.e. instances of a handle class) must not depend on symbolic values. This feature is not supported by Grackle.

### Unsupported Features¶

Grackle does not support several of the object oriented features of MATLAB. These include:

• class attributes, e.g. `Abstract`, `Sealed`, `Hidden`, etc. See MATLAB class attributes.
• property attributes, e.g. `Access`, `Constant`, etc. See MATLAB property attributes.
• methods attributes (except `Static`). See MATLAB method attributes.
• superclass method calls, e.g. `MethodName@SuperclassName(...)`
• class and method metadata, e.g. `meta.class`, `meta.method`, etc. See MATLAB class metadata.
• enumeration classes
• events and listeners
• multiple inheritance
• MATLAB built-in mixin classes
• exceptions, in particular the built-in class `MException`.