CAL Language Reference - Hexcore/HxCAS GitHub Wiki

Overview

The Cellular Automata Language (CAL) is a domain specific imperative programming language designed for quick, easy and intuitive specification of cellular automata programs. HxCAS has a built-in editor in which users may write CAL programs. Users are also welcome to use a 3rd party text editor but must just be aware that HxCAS will only open files named with the .cal extension. The language currently supports basic features including user defined scalar variables, mathematical expressions, boolean expressions and evaluations, and deterministic loops. Functions for rounding, generating random numbers, and logarithmic operations form part of the CAL standard library. All of these features are discussed in this reference.

Compiled CAL

In the interest of completeness this section describes the CAL compilation process. This section is intended for those who wish to extend or otherwise modify the CAL language. The CAL language is specified in CoCoL and a basic scanner is then generated from the CoCoL specification using CoCo/R. Code generation is worked into the scanner allowing for single pass compilation. The code generator generates a single Java class (Rule) by outputting Java Byte Code as per the JVM 1.7 specification. The details of the byte code construction are handled by the ASM library. Once the byte code is generated it is loaded by the Java Class Loader during run-time and each cell in the CA grid is passed to the Rule class and updated.

CAL Program Structure

CAL programs have the following structure:

ruleset MyRuleSet
{
    types{MyType1, MyType2};
    property alive;

    type MyType1
    {
        //Rule code
    }

    type MyType2
    {
        //Rule Code
    }
}

Each CAL program begins with the compulsory ruleset block which is given a unique name. CAL supports heterogeneous CA worlds and so allows for multiple cell type declarations with their respective rules enclosed. Thus we must fist declare how many cell types our program has with a types specifier that specifies the name of each cell type. Finally we need to declare the properties that each cell will have. A CAL program must have at least one property. Each property is declared and named with the property declaration. Now the rules can be specified with type blocks. **Important: Each type decalared in the types specification must have a corresponding type block **

CAL language features

Rule code is written within the type blocks. The features and constructs that rules can be made up of are discussed in this section.

Variables

Variables are dynamically typed and are currently either a double floating point value or a boolean value. Variables are declared using the var statement and can also be immediately initialized. Thus the following code is valid:

var MyVar1;
var MyVar2 = 22.3;

If Statements

The regular C-structured if and if-else statements exist:

if(x == 10 && y < 5)
{
    z = 5;
}
else
{
    z = 0;
}

Loops

Currently a single deterministic looping structure exists. The loop is guaranteed to run for the specified amount of times. The loop variable cannot be changed and exists only within the loop.

loop i from 0 to 10
{
    x = x + i;
}

N-Step Engine

The N-Step engine is a feature that was initially built into the simulator and was moved into the CAL language as of HxCAS v1.1. The N-Step engine allows for blocks of code to be run only on certain generations. Thus if a CAL program has 3 steps, then the Step 0 code will run for generation 1, the step 1 code will run for generation 2, and the step 2 code will run for generation 3 and then the step 0 code will run again. This pattern continues throughout the simulation. The N-Step engine can be used by making use of the optional step blocks in each type specification. An example program with 3 steps is illustrated as follows:

ruleset MyRules
{
    types{Fire,Earth,Water};
    property p1;

    type Fire
    {
        step 0
        {
        }

        step 1
        {
        }

        step 2
        {
        }
    }

    type Earth
    {
        step 0
        {
        }

        step 1
        {
        }

        step 2
        {
        }
    }

    type Water
    {
        step 0
        {
        }

        step 1
        {
        }

        step 2
        {
        }
    }
}

It is important to note the following:

  1. All code must be within the step blocks.
  2. Each type must have the same amount of steps.
  3. Steps must be in ascending order, starting from 0.

CA World Variables

A set of variables exists for querying and updating the CA world. These include the self variable which refers to the current cell. Each of the declared properties of self can be accessed. The neighbours of the current cell may be accessed using the neighbours array. The first neighbour of a cell is accessed using neighbours[0], the second neighbour using neighbours[1] and so forth. Thus we can specify the evolution of a CA world with code like this

if(neighbours[0].prop1 == 1 && neighbours[1].prop1 == 0)
{
    self.prop2 = self.prop1 + 1;
}

CAL Standard Library

The CAL standard library contains a set of useful mathematical functions that can be used within CAL rules. This section briefly details the contents of the library. A note to developers: Currently the standard library is implemented in com.hexcore.cas.rulesystems.StdLib as a host of Java functions. A more plugin like way that makes extension of the standard easier is planned The following is an exhaustive list of all functions in the standard library:

Array Manipulation

The following functions take as input an array of double values and gives a single value as output.

  • max - Returns the maximum value in the array.
  • min - Returns the minimum value in the array.
  • sum - Returns the sum of all the values in the array.
  • count - Returns the size of the array.

Currently user defined arrays are not supported. Typically these functions would be used with the properties of neighbours. When a cell property of neighbours is accessed without specifying the exact neighbour then an array of values is returned with each value representing the value of the specified property for one of the neighbours. Thus a typical example of the usage of one of the these functions would be

var x = max(neighbours.prop1);
var c = count(neighbours.prop1);
loop i from 0 to c-1
{
    self.prop1 = neighbours[i].prop1 + x;
}

Mathematical Functions

The following functions take as a parameter a single value and return the output of the relevant mathematical function:

  • log - Returns the base 10 logarithmic of the given value.
  • ln - Returns the natural logarithm of the given value.
  • sin - Returns the sine of the given angle (specified in radians).
  • cos - Returns the cosine of the given angle (specified in radians).
  • random - Returns a double value between 0.0 and the given parameter.
  • round - Returns the given number naturally rounded.

Cell Functions

The following functions work directly with the Cell type of CA worlds:

  • exists - Given a specific neighbour, returns if that neighbour exists for this world or not. Usage example:
var x = 0;
loop i from 0 to 8
{
    if(exists(neighbours[i]))
        x = x + neighbours[i].prop1;
}

This allows for the user to write a program that is compatible with multiple grid types that have varying amount of neighbours.