Gödel language
Problems on Project Gödel are solved by writing code in a special language, so that we can enforce certain limits and enable specific execution models.
Values
int is a signed 32-bit integer; uint is an
unsigned 32-bit integer. Arithmetic wraps to 32 bits. Integer division
truncates towards zero. Division by zero stops execution.
bool has the values true and false.
Structs contain named fields. Struct values are references: assigning a struct to another variable shares the same object. Construct a struct with its fields in declaration order.
struct Point {
int x;
int y;
};
Point p = Point(2, 3);
Point q = clone(p);
T[] is a buffer of values of type T. Create one
with buffer<T>(n), index it with a[i], and
read its length with len(a). Indices are bounds-checked.
Integer and Boolean elements start at zero or false; reference elements must
be set before use.
uint[] values = buffer<uint>(4); values[0] = 7u;
clone(x) makes a shallow copy of a struct or buffer. The new
outer object is independent; reference-valued fields or elements remain
shared.
Functions and control flow
Functions declare a return type and typed parameters.
void indicates no return value. A problem specifies the entry
function to implement. Recursion is limited to 100,000 active calls.
int solve(int n) {
return n;
}
Use if and else for branches;
while and for for loops; break to
leave a loop; continue for its next iteration; and
return to leave a function. Braces create a scope.
Operators follow C precedence. Arithmetic, comparisons, bitwise operators,
assignment, and increment or decrement are supported.
&& and || short-circuit. Cast integer
values with int(x) and uint(x). Mixed signed and
unsigned operations require a cast.
Imports
Import a module by name and call its functions with a qualified name. Each problem documents the module it provides.
import p1;
Lifetime
Structs and buffers use automatic reference counting. Variables, including parameters, are released after their last use in a block. Uses in loops or nested statements may retain an outer variable until its block exits. Shared objects remain alive while any reference owns them. References cannot form cycles.