ALgLang is a DSL, where one can construct and manipulate Abelian groups. ALgLang was initially an alternative of the matrix manipulation language used in Toy, but is now more oriented towards exploring the applicability of MLIR in the symbolic computation domain.
While at first it might seem that Abelian groups only of interest to mathematicians and they are completely irrelevant for any computational applications, I am keen to highlight that the structure of Abelian groups is very similar to that of "glued vector lattices." The following brief discussion justifies this.
- Given generators
$g_1, \ldots, g_n$ of an Abelian group, we can represent the elements of the group as vectors in$\Z^n$ . Addition and subtraction of elements maps exactly to addition and subtraction of their representing vectors. - Since each element belongs to a group, there is extra type-checking to be done compared to simple vector manipulation: only elements that belong to the same group can be added, even if their representation vectors otherwise have compatible sizes. Note also, that this is purely compile time information, so after typechecking
AlgLangcan be lowered to a vector manipulation dialect, and thus to machine code. - The language also exposes another difficulty, where some "vectors" can have multiple representations. For example, consider the group, defined in
AlgLangas:
def G(g, h) {
g - 2 * h
};
The representations of the elements of this language are then linear combinations of the vectors
In AlgLang one can define groups using the def keyword, by specifying the name of the group, its generators, and the relations that hold between the generators.
We use convention that the group operation of every group is denoted by + and n * g is equivalent to writing g + g + ... + g, where g appears n times. Similarly, the inverse of an element is denoted as -n.
For example, one could define the integers modulo 2 as follows:
def G(g) {
2 * g
};
Currently, the only other supported operation in AlgLang's parser is untyped assignment:
# Free group with generator `g`
def G(g);
k = 4 * g;
Here, the fact that k is also an element of the group G is automatically inferred, since g is a member of G. Until the possibility to add typing to expressions is introduced, each expression must be written so that its type is unambigously inferrable. E.g.:
def G(g, h, k);
def H(g, r, s);
a = h + k; // Ok, since both `h` and `k` only make sense in `G`
r = g + h; // OK, since this statement only makes sense if `g`
// refers to an element of `G`
c = g + r; // OK, by the same reason
// c = g + r // NOT OK, since this make sense in both `G` and `H`
The easiest way to get started is using CMake and Ninja. Once both are installed, run the following in the current directory:
mkdir build && cd build
cmake .. -DMLIR_DIR "<YOUR-LLVM-INSTALLATION>/llvm-install/lib/cmake/mlir" \
-DLLVM_DIR "<llvm-project-repo>" \
-DFRONTEND "<ON/OFF>"
ninjaThe frontend flag controls whether the build file created will also compile the interpreter. Without it only the MLIR dialect is compiled.
Afterwards, files can be compiled as follows:
./<path-to-build>/Compiler --input <path to file>Currently, to see the compiler results, one must use either the --dump-ast flag, to dump the parsed AST graph, or the --dump-alg flag, to dump the Alg dialect code generated. See the examples folder for some simple test cases.