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.