This is an old revision of the document!


Connections

When two nodes are connected to each other by wires, they effectively become one electrical node. This connection operation is part of the ACT language, and is denoted by the = sign. The = operation is also overloaded for meta-language variables to denote assignment. Multiple connections can be specified in a single statement by repeatedly using the = operator. This section describes the different connection statements supported by ACT.

Simple connections

The simplest possible connection statement is the connection of two variables of type bool.

bool x, y;
x=y;

The effect of this operation is to alias the two nodes. After this operation is performed, both x and y refer to the same value. Meta-language types can also be 'connected' to expressions. The result of such a 'connection' is that the right hand side of the = sign is evaluated, and assigned to the variable on the left. Such connections are only meant to initialize the values of parameters.

pint x, y;
x=5;
y=x*1+2;         // success

Whereas connecting nodes is a symmetric operation, connecting meta-language variables is not symmetric, as illustrated below.

pint x, y;
x=5;
x=y*1+2;
-[ERROR]-> id: y
           FATAL: Uninitialized identifier

Meta-language parameter connections correspond to assignment statements. ACT permits assigning floating-point values to integer-valued variables, and vice versa. However, there are some restrictions on meta-language variable assignments.

pint x;
x=5;
x=8;
-[ERROR]-> Id: x
           FATAL: Setting immutable parameter that has already been set

In this example, x has been declared and then defined twice at the top-level of the ACT file. This makes x a global variable, which means x can be used in types defined later in the ACT file. This potentially makes x an implicit parameter for all types, even though x does not appear in the template parameter list for any of them. To prevent the situation where x might have different values depending on when a type is used, global parameters can only be defined once in ACT. This constraint also applies to template parameters for the same reason.

However, for parameters defined within the body of a type, they can be defined multiple types since they are not in the scope of any other type. ACT defines global parameter variables and template parameter variables as immutable types—they can only be defined once.

Array and subrange connections

Array connections in ACT are extremely flexible. In general, if two arrays have the same basic type and have the same number of elements, they can be connected with a simple connect directive. In the example below, nodes x[0], …, x[9] are connected to nodes y[10], …, y[19] respectively.

bool x[10];
bool y[10..19];
x=y;

Connecting two arrays of differing sizes is an error.

bool x[10];
bool y[10..20];
x=y;
-[ERROR]-> Connection: x = y
             LHS: bool[10]
             RHS: bool[10..20]
          FATAL: Type-checking failed on connection
             Types `bool[10]' and `bool[10..20]' are not compatible

ACT provides a subrange mechanism for connecting parts of arrays to one another. The example below shows a connection between elements x[3], …, x[7] to y[12], …, y[16].

x[3..7] = y[12..16];

Connections between two arrays with differing numbers of dimensions is not permitted.

Array shapes

When a connection between multidimensional arrays is specified where the shape of the two arrays is not identical, this is also reported as an error. However, it is possible that two arrays have the same shape but where the elements have differing indices. In this case, the ranges to be connected are sorted in lexicographic order (with indices closer to the variable having higher weight) and the corresponding array elements are connected. For example, in the example below x[3][5] would be connected to y[0][0] and so on.

bool x[3..4][5..6];
bool y[2][2];
x = y;         

When two arrays are connected by name as in the example above, they become aliases for each other. So while the connection statement

x[3..4][5..6] = y[0..1][0..1];

is the same as x=y earlier, the two are actually logically different. The first one says that the two arrays are the same, while the second is an element-by-element connection. This difference is visible in the case of sparse arrays.

bool x[3..4][5..6];
bool y[2][2];
x = y;
bool x[5..5][5..5];
-[ERROR]-> Array being extended after it has participated in a connection
             Type: bool[ [3..4][5..6]+[5..5][5..5] ]

In the example above, the arrays x and y are connected to each other. After the connection, the array x is being extended in size using the sparse array functionality. This is not allowed, because this would also make y a sparse array—except, the way y is to be extended is unspecifed. On the other hand, the same sparse array extension is valid if instead the element-by-element connection is performed. This is because array y has fewer elements compared to x, and only a subset of x is connected to the elements of y.

Performance note: Extending an array after it has connections can be expensive as the array connections have to be moved. If you have an array of size N with internal connections that is extended by a constant amount M times, the current implementation can take time complexity MN.

Finally, two sparse arrays can be connected to each other as long as they have the same shape. The shape is determined by viewing a sparse array as an ordered collection of dense sub-arrays. Two sparse arrays have the same shape if they have the same number of dense sub-arrays, and the corresponding dense sub-arrays have the same shape.

Finally, arrays can be re-shaped. The most common example of this is that a list of variables can be treated as a single array by enclosing it in braces.

bool x[3];
bool x0,x1,x2;
x = {x0,x1,x2};

This is a special case of a more general mechanism for array expressions, described next.

Array expressions

There are times when it is convenient to ``reshape an array, or only connect part of an array to other instances. ACT provides flexible syntax to construct arrays from other arrays and instances. If two arrays have the same dimension, then they can be concatenated together to form a larger array using the # operator. In order to do this, the size of (n-1) dimensions of the arrays must match (excluding the left-most dimension). <code> bool x[5]; bool y[3]; bool z[8]; z = x # y; success! </code> Sometimes it is useful to be able to connect arrays that have different numbers of dimensions to each other. To change the dimensionality of an array, the { … } construct can be used. A higher-dimensional array can be created by providing a comma-separated list of lower dimensional arrays enclosed in braces. <code> bool x[2]; bool y[2]; bool z[2][2]; z = {x,y}; success! </code> In this example, the construct {x,y}'' is used to create a two-dimensional array from two one-dimensional arrays. The size and number of dimensions of all the arrays specified in the list must be the same. The most common use of this construct is to connect a one-dimensional array to a list of instances.

A final syntax that is supported for arrays is a mechanism to extract a sub-array from an array instance. The following example extracts one row and one column from a two-dimensional array.

bool row[4],col[4];
bool y[4][4];
y[1][0..3]=row;   // connect row
y[0..3][1]=col;   // connect column

In general, array expressions can appear on either the left hand side or the right hand side of a connection statement. This means that the following is a valid connection statement:

bool a[2][4];
bool b[4..4][4..7];
bool c0[4],c1[4],c2[4];

{c0,c1,c2} = a # b; // success, both sides are bool[3][4]