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.