Language Reference
Complete reference for the Quale language. Every keyword, operator, expression form, statement type, built-in function, and comment syntax in one page.
Keywords
Section titled “Keywords”48 reserved keywords. Keyword matching is case-sensitive (lowercase only). All other names (state names, entity types, field names) are contextual identifiers resolved by the parser.
| Keyword | Category | Description |
|---|---|---|
body | Block | Agent state layout and brain interface |
world | Block | Simulation environment with entities |
perception | Block | World/agent state to brain sensor values |
action | Block | Brain actuator outputs to world changes |
dynamics | Block | Per-tick state cascade rules |
fitness | Block | Gates, metrics, and optimization objectives |
evolve | Block | Evolution experiment configuration |
entity | Block | Entity type definition inside a world |
machine | Block | State machine definition |
sensor | Declaration | Brain input node |
actuator | Declaration | Brain output node |
properties | Sub-block | Entity property declarations |
state | Declaration | State variable or machine state |
scope | Machine | Machine scope (agent or world) |
initial | Machine | Initial state of a machine |
transition | Machine | State transition rule |
on_enter | Handler | Fires on entering a state or entity proximity |
on_exit | Handler | Fires on leaving a state |
on_cross | Handler | Fires when agent crosses an entity |
on_pass | Handler | Fires when agent passes an entity without entering |
spawn | Entity | Number of entity instances to place |
query | World | Spatial query declaration |
import | World | External data import |
let | Statement | Local variable binding |
when | Statement | Conditional guard |
else | Statement | Alternative branch of a conditional |
match | Expression | Pattern-matching or condition-based expression |
for | Statement | Loop construct |
in | Statement | Iterable in a for-in expression |
not | Operator | Logical negation (keyword form) |
and | Operator | Logical conjunction (keyword form) |
or | Operator | Logical disjunction (keyword form) |
record | Statement | Emit a typed event record |
consume | Statement | Remove the current entity from the world |
gate | Fitness | Hard prerequisite for fitness scoring |
metric | Fitness | Performance measurement definition |
maximize | Fitness | Higher values produce higher fitness |
reward | Fitness | Accumulative positive contribution |
penalize | Fitness | Value subtracted from fitness |
terminate | Fitness | Early scenario termination condition |
aggregate | Fitness | Aggregation function for per-record/per-tick metrics |
transform | Fitness | Post-processing step on aggregated metric |
mutation | Evolve | Mutation rate configuration sub-block |
speciation | Evolve | Speciation parameters sub-block |
convergence | Evolve | Convergence criteria sub-block |
checkpoint | Evolve | Checkpoint configuration sub-block |
seed_from | Evolve | Seed population from a previous experiment |
topology | World | Spatial structure declaration |
Operators
Section titled “Operators”Operator Precedence
Section titled “Operator Precedence”Listed from lowest to highest precedence. Higher-precedence operators bind tighter.
| Level | Category | Operators | Associativity |
|---|---|---|---|
| 1 | Ternary | ? : | Right |
| 2 | Logical OR | or | Left |
| 3 | Logical AND | and | Left |
| 4 | Comparison | > < >= <= == != | Non-associative |
| 5 | Addition | + - | Left |
| 6 | Multiplication | * / | Left |
| 7 | Unary | -x !x not x | Right (prefix) |
| 8 | Primary | Literals, identifiers, ., (), [], match | Left (postfix) |
Arithmetic Operators
Section titled “Arithmetic Operators”| Operator | Description | Example |
|---|---|---|
+ | Addition | agent.speed + 1.0 |
- | Subtraction | 1.0 - min(chk.distance / 2.0, 1.0) |
* | Multiplication | agent.speed * dt / 1000.0 |
/ | Division (division by zero returns 0) | agent.speed / max_speed_ms |
-x | Unary negation | -5.0 |
Comparison Operators
Section titled “Comparison Operators”| Operator | Description | Example |
|---|---|---|
> | Greater than | actuator.block > 0.5 |
< | Less than | agent.speed < limit_ms |
>= | Greater than or equal | agent.position >= world.length |
<= | Less than or equal | actuator.block <= 0.5 |
== | Equal | chk.index == -1 |
!= | Not equal | chk.index != -1 |
Comparison operators are non-associative. Chaining like a < b < c is not supported; use a < b and b < c.
Logical Operators
Section titled “Logical Operators”| Operator | Description | Example |
|---|---|---|
and | Logical AND (both non-zero) | actuator.block > 0.5 and elapsed_in_state > 1.0 |
or | Logical OR (either non-zero) | actuator.move_n > 0.5 or actuator.move_e > 0.5 |
not | Logical NOT (keyword form) | not agent.warning_acknowledged |
! | Logical NOT (symbol form) | !agent.alive |
Both not and ! perform the same operation: 0.0 becomes 1.0, any non-zero value becomes 0.0.
Assignment Operators
Section titled “Assignment Operators”Used in statements only, not in expressions.
| Operator | Description | Example |
|---|---|---|
= | Direct assignment | agent.accel = -5.0 |
+= | Add and assign | agent.warnings_acknowledged += 1 |
-= | Subtract and assign | agent.hunger -= 0.3 |
*= | Multiply and assign | agent.confidence *= 0.99 |
/= | Divide and assign | agent.score /= 2.0 |
Other Operators
Section titled “Other Operators”| Operator | Description | Context |
|---|---|---|
.. | Range | 0..1 in type annotations |
-> | Transition arrow | transition A -> B in machines, pattern -> value in match |
. | Dot access | agent.speed, world.tick, chk.distance |
Expression Types
Section titled “Expression Types”Literals
Section titled “Literals”| Type | Examples | Storage |
|---|---|---|
| Integer | 0, 42, -1, 300 | float64 |
| Float | 0.5, 1.0, 3.6, -5.0 | float64 |
| Boolean | true, false | float64 (1.0 / 0.0) |
| String | "route-data.csv" | Interned int index |
All numeric values are stored as float64 on the VM stack. true and false are contextual identifiers (not keywords) that resolve to 1.0 and 0.0.
Identifiers
Section titled “Identifiers”hunger -- bare identifier (resolved from scope)dt -- let-bound local variablewaypoint -- entity type nameDot Access
Section titled “Dot Access”agent.speed -- agent stateworld.max_speed -- world constantactuator.brake -- brain output valuechk.distance -- query result field (built-in)chk.position -- query result field (promoted from entity property)sensor.food_nearby.directions -- sensor metadataFunction Calls
Section titled “Function Calls”min(chk.distance / 2.0, 1.0)max(0, agent.speed + agent.accel * dt)abs(agent.accel)clamp((value - 0.5) / 1.5, 0, 1)sqrt(agent.distance)nearest_ahead(waypoint, agent.position)speed_zone_at(agent.position)Index Access
Section titled “Index Access”sensor food_nearby[direction] -- indexed sensor access in for loopsTernary
Section titled “Ternary”agent.warning_active ? 1.0 : 0.0agent.ticks_alive > 0 ? agent.idle_ticks / agent.ticks_alive : 1.0Ternary is right-associative. Nesting is supported: a ? b ? 1 : 2 : 3.
Parenthesized
Section titled “Parenthesized”(agent.speed + agent.accel * dt)(value - 0.5) / 1.5Match (Condition-Based)
Section titled “Match (Condition-Based)”Evaluates conditions top-to-bottom, returns the value of the first matching branch.
match { when stn.distance > 0.16: zone_limit when stn.distance > 0.08: 60.0 when stn.distance > 0.03: 45.0 else: 15.0}Match (Value-Based)
Section titled “Match (Value-Based)”Compares a target expression against patterns. _ is the wildcard default.
match direction { 0 -> "north" 1 -> "east" 2 -> "south" 3 -> "west" _ -> "unknown"}Statement Types
Section titled “Statement Types”Creates a local variable binding. Evaluated once when the line executes. Scoped to the enclosing block.
let dt = world.ticklet max_speed_ms = world.max_speed / 3.6let chk = nearest_ahead(waypoint, agent.position)let moved = actuator.move_n > 0.5 or actuator.move_e > 0.5when (Independent)
Section titled “when (Independent)”Conditional guard. Multiple when blocks at the same level are evaluated independently (not mutually exclusive).
-- Block formwhen actuator.emergency_stop > 0.8 { agent.accel = -5.0 agent.stress += 0.05}
-- Single-line formwhen not moved: agent.idle_ticks += 1when / else when / else (Exclusive Chain)
Section titled “when / else when / else (Exclusive Chain)”Mutually exclusive branches. Evaluates top-to-bottom; only the first matching branch executes.
when actuator.emergency_stop > 0.8 { agent.accel = -5.0} else when actuator.brake > 0.3 { agent.accel = -2.0} else { agent.accel = -0.1}Assignment
Section titled “Assignment”Modifies agent state, world state (in world machines), or entity state.
agent.accel = -5.0 -- direct assignmentagent.hunger -= 0.3 -- subtract and assignagent.warnings_acknowledged += 1 -- add and assignagent.confidence *= 0.99 -- multiply and assignagent.position += agent.speed * dt / 1000.0Deep dot paths are supported for assignment targets:
world.preceding_train.position += 1.0sensor (Assignment)
Section titled “sensor (Assignment)”Writes a value to a brain input node. Only valid inside perception blocks.
sensor current_speed = agent.speed / max_speed_mssensor warning_level = agent.warning_active ? 1.0 : 0.0record
Section titled “record”Emits a typed event record to the scenario event log. Records are consumed by per-record fitness metrics. Fields can use shorthand (bare name) or explicit key-value pairs.
record waypoint_visit { stopped: 1.0, arrival_time: agent.elapsed}
record decision { blocked: 1.0, was_threat: malicious, correct: malicious > 0.5 ? 1.0 : 0.0}consume
Section titled “consume”Removes the current entity from the world. Only valid inside entity interaction handlers (on_cross). For grid worlds, triggers the entity’s respawn timer.
consume()Transition (Inline)
Section titled “Transition (Inline)”Transitions to a named state inside a machine. Only valid inside machine state handlers.
-> monitoringBuilt-in Functions
Section titled “Built-in Functions”| Function | Signature | Description |
|---|---|---|
min(a, b) | (float, float) -> float | Returns the smaller of two values |
max(a, b) | (float, float) -> float | Returns the larger of two values |
abs(x) | (float) -> float | Returns the absolute value |
clamp(val, lo, hi) | (float, float, float) -> float | Clamps val to [lo, hi] |
sqrt(x) | (float) -> float | Returns the square root |
-- From Human Factorssensor waypoint_near = 1.0 - min(chk.distance / 2.0, 1.0)
-- From Human Factorsagent.speed = max(0, agent.speed + agent.accel * dt)Type System
Section titled “Type System”All values are stored as float64 at runtime. Type annotations on state declarations are documentation and optional constraint hints.
| Annotation | Storage | Semantics |
|---|---|---|
float | float64 | General-purpose floating point |
int | float64 | Conceptually integer; no fractional enforcement |
bool | float64 | true = 1.0, false = 0.0 |
0..1 | float64 | Float in [0.0, 1.0]; enforced by dynamics clamp 0..1 |
seconds | float64 | Unit annotation (documentation only) |
m/s | float64 | Unit annotation (documentation only) |
m/s2 | float64 | Unit annotation (documentation only) |
km | float64 | Unit annotation (documentation only) |
km/h | float64 | Unit annotation (documentation only) |
string | int (enum) | Interned at compile time; stored as an enum index |
Unit annotations have no runtime effect. state speed: m/s = 0 and state speed: float = 0 compile to identical bytecode.
Range Types
Section titled “Range Types”The 0..1 range type uses the .. operator to denote a bounded float. The dynamics block’s clamp 0..1 directive enforces this range at the end of each tick for all dynamics-managed states.
Comment Syntax
Section titled “Comment Syntax”| Syntax | Type | Behavior |
|---|---|---|
-- text | Line comment | Discarded by the parser |
--! text | Note comment | Preserved in AST; shown by quale check |
--!! text | Critical comment | Preserved in AST; fails quale check --strict |
--[ text ]-- | Block comment | Multi-line; discarded by the parser |
-- Regular comment (ignored by the compiler)
--! This sensor range was chosen based on grid size--!! Do not exceed 300 ticks without dynamics
--[ Block comment can span multiple lines useful for temporarily disabling code ]--Top-Level Constructs
Section titled “Top-Level Constructs”Every .quale file contains one or more of these seven top-level blocks:
| Construct | Syntax | Required |
|---|---|---|
| Body | body <Name> { ... } | Yes (one per evolve) |
| World | world <Name> { ... } | Yes (one per evolve) |
| Perception | perception <Name> { ... } | Yes (one per evolve) |
| Action | action <Name> { ... } | Yes (one per evolve) |
| Dynamics | dynamics <Name> { ... } | No |
| Fitness | fitness <Name> { ... } | Yes (one per evolve) |
| Evolve | evolve <Name> { ... } | Yes (at least one) |
Multiple evolve blocks are allowed in a project. Select between them with the --run CLI flag.
Dot Access Namespaces
Section titled “Dot Access Namespaces”| Namespace | Access | Description |
|---|---|---|
agent.* | Read/Write | Agent state declared in the body block |
world.* | Read-only (write in world machines) | World constants and state |
actuator.* | Read-only | Brain output values |
sensor.* | Metadata only | Sensor configuration (e.g., .directions) |
engine.* | Read-only (fitness only) | Engine-provided metrics (engine.complexity, engine.nodes) |
<query_result>.* | Read-only | Fields from spatial query results (.distance, .index, plus promoted properties) |
Aggregate Functions
Section titled “Aggregate Functions”Used in per-record and per-tick fitness metrics.
| Function | Description |
|---|---|
avg | Mean of accumulated values |
sum | Sum of accumulated values |
min | Minimum of accumulated values |
max | Maximum of accumulated values |
metric accuracy { per record decision: correct aggregate: avg}Spatial Query Signatures
Section titled “Spatial Query Signatures”Declared in the world block, callable from perception, action, machines, and entity handlers.
Route Topology
Section titled “Route Topology”| Query | Signature | Returns |
|---|---|---|
nearest_ahead(type, pos) | -> distance, index, properties | Next entity of type ahead of position |
speed_zone_at(pos) | -> limit | Speed limit at position (scalar) |
Grid Topology
Section titled “Grid Topology”| Query | Signature | Returns |
|---|---|---|
nearest(type, pos, direction) | -> distance, properties | Nearest entity of type in a direction |
at(type, pos) | -> bool, properties | Entity presence at a grid cell |
No-Match Fallback
Section titled “No-Match Fallback”| Field | Fallback value |
|---|---|
.distance | Positive infinity |
.index | -1 |
| Any property | 0.0 |