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
, andint32
supported by Matlab, but typesintN
anduintN
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
.