AdaLog
Before there was AdaLogic BASIC, there was AdaLog — and before there was a language to document, there was a workshop's worth of software quietly proving the same thesis that would later drive ALB: that Ada is the right metal to build serious things on, and that programs should be able to prove what they do.
AdaLog is a Prolog-style logic engine written in Ada 2012 with SPARK annotations, built as a utility-AI brain for games — a tiny reasoning machine that stores facts and rules, unifies them, and hands back provable answers one step at a time. It shipped with a small desktop suite built around it: TitaniumWM, a SPARK-annotated tiling window manager for X11; TitaniumRun, a dmenu-style launcher; and TitaniumBG, a procedural animated-wallpaper renderer with its own state machines.[1]
None of it was ever released. All of it survives, source and binaries intact — a complete snapshot of a one-person software workshop in the years before ALB.
== The Titanium workshop ==
The suite shares more than a name. Every program is written in Ada, every core module carries pragma SPARK_Mode (On), every data structure is statically bounded — no heap, no malloc, no allocation after startup — and every piece was built to be understood, in the tradition of the hand-built desktops of the window-manager underground.
The naming runs deeper than branding. AdaLog's own test program announces itself as --- Titanium Engine: Utility AI Test --- — the logic engine was the Titanium Engine. The suite and the language were one project with four faces: a brain (AdaLog), a desktop to run it on (TitaniumWM), a way to launch things (TitaniumRun), and something worth looking at while you thought (TitaniumBG).[2]
== What AdaLog actually is ==
Strip the name away and what's left is a genuine logic-programming kernel — a deliberately small, deliberately provable descendant of Prolog:
see(orc, player).
health(orc, 15).
score(orc, attack, 100) :- see(orc, player).
score(orc, heal, 500) :- health(orc, H), H < 20.
Facts declare the world. Rules derive scores from it. A query — score(orc, Action, Points). — asks the engine to find every action and its score, and the caller picks the best. That is the entire interface between a game and its character's judgement.
The design target is unusual and specific: utility AI for games. Most game AI scores options imperatively — an if ladder, a behavior tree, a hand-rolled scorer. AdaLog instead asks: what if the scoring were logical? A rule only fires when its conditions are provably true against the world state; the engine doesn't just rank actions, it derives them. An orc doesn't get a "heal" score because a programmer wrote if hp < 20 then heal — it gets one because health(orc, 15) unified with health(orc, H), bound H = 15, and the sub-goal H < 20 was proven. The decision carries its own proof.
== Anatomy of a tiny Prolog ==
The whole engine is eight Ada units, each small enough to read in one sitting — and each doing exactly the job its name claims:
Types— the value system. Every term is aTerm_ID(a plain integer); atoms intern from 1,000,000 upward, variables from 2,000,000 upward, leaving small integers free to be literal numbers — the reasonhealth(orc, 15)andH < 20can mix names and arithmetic in one fact. All bounds are constants: 2,048 atoms, 64 variables, 1,024 facts, 256 rules, a 256-entry trail, up to 3 arguments per fact and 16 sub-goals per rule.[3]Atoms— the intern table, mapping names likescoreandorcto their IDs and back.Titanium_Lexer/Titanium_Parser— text to tokens to goals. The parser is what turnsscore(orc, Action, Points).into a machine-usable query.Titanium_Database— the fact base and rule store:Assert_Fact,Assert_Rule, static pools, SPARKAbstract_State.Titanium_Logic— the heart: theEnvironment(variable-to-term bindings), theTrail(the undo log that lets the engine take back every binding it ever made),Deref,Unify, andBacktrack.Titanium_Solver— the driver:Initializea query, then callSteprepeatedly; each step reportsRunning,Found, orDone.
== The SPARK difference ==
Any competent programmer can write a Prolog in a weekend. AdaLog's distinction is that its unification isn't just correct — it's contracted:
procedure Unify (T1, T2 : Term_ID;
Env : in out Environment;
Trail : in out Trail_Array;
T_Ptr : in out Trail_Index;
Success : out Boolean)
with Post => (if not Success then Env = Env'Old
and T_Ptr = T_Ptr'Old);
Read the postcondition aloud: if unification fails, the environment and trail pointer are provably unchanged. A failed match can never leave half-written bindings behind to poison the next attempt — not because the code was reviewed, but because the contract states it and SPARK can prove it. That single line is the difference between a logic engine that probably works and one whose failure behavior is a theorem.[4]
The same discipline runs through everything. Titanium_Database exposes Abstract_State rather than globals; TitaniumRun's launcher buffer carries Pre/Post contracts (Insert_Char requires room, Backspace requires content); TitaniumWM's Layout package is pure logic — Tile_Windows takes screen dimensions and computes positions, provably separated from the X11 event machinery that calls it. The whole suite is built on one pattern: bounded static state, contract-checked behavior, pure logic at the core, impure I/O pushed to the edges.
== The orc test ==
AdaLog's own demo program is the whole pitch in 150 lines of Ada. It interns the atoms, asserts a two-fact world — the orc sees the player, and the orc has 15 hit points — asserts two scoring rules, then runs the query score(orc, Action, Points). one Step at a time.
The solver's first Found is attack at 100 points — the orc sees you, so attacking is provable. The second Found is heal at 500 — health(orc, H) unifies, H binds to 15, 15 < 20 proves, and the wounded orc's self-preservation outscores its aggression. Done ends enumeration, and the harness takes the argmax: the orc heals.[5]
It is a small thing — a toy world, two rules — but it demonstrates the complete claim: a game character whose possible actions are derived from provable facts about its situation, enumerated exhaustively, and selected by score. Behavior trees can imitate this; AdaLog can prove it.
== The desktop trio ==
TitaniumWM (v2.2) is the flagship of the trio — a hybrid tiling window manager for X11, in the tradition of dwm and its kin but written in Ada 2012. Master-plus-stack tiling and full-screen monocle, twelve persistent workspaces, color-coded window decorations for focus state, everything driven from the Alt key — and, critically, a design split the README states plainly: the layout and state logic is SPARK-annotated while the X11 boundary is not (pragma SPARK_Mode (Off) sits honestly atop the event loop, because X event marshalling is a C world). Its stated goal is "minimal memory footprint with no heap allocation after initialization" — a window manager you could, in principle, verify.[6]
TitaniumRun (v0.4) is the launcher — the same idea as dmenu or rofi: type, complete, run. Its Completion package keeps a fixed table of 8,192 candidate names (truncated at 16 characters), returns at most 5 matches, and annotates every buffer operation with contracts. A program whose entire job is to fuzzy-match a string carries formal proof annotations about that string's length. That is the Titanium sensibility in miniature.[7]
TitaniumBG (v0.7) is the surprise — an animated procedural wallpaper engine. Each scene is a tagged object with Render and Update methods, drawn into a bounded pixel buffer sized for up to 4K displays. The desert_mountain scene keeps a coyote at fixed scene coordinates (220, 210) and runs a buzzard through a four-state machine — Circling → Descending → Feasting → Ascending — on its own RNG seed and frame counter. Jungle river, plasma fields, a snowy village round out the set, drawn by a hand-rolled VGPU layer with its own ditherer and fonts. It is a desktop wallpaper that thinks.[8]
== Why Ada, of all languages ==
To the rest of the world, building a logic engine, a window manager, and a wallpaper renderer in Ada is eccentric. To the Titanium workshop it was the obvious choice — Ada is the language industry already trusts where failure isn't an option: avionics, rail, medical. SPARK is its proof subset, where contracts aren't comments but checkable claims. The bet behind the whole suite — and behind ALB after it — is that the same discipline belongs on the desktop, in the game loop, in the wallpaper, and eventually in the language toolchain itself.

And there is a fittingness to it: a language named for the first person to write about programming as a discipline — Lovelace's notes on the Analytical Engine argued the machine could manipulate symbols according to rules, not merely calculate — hosting a system whose entire purpose is symbol manipulation by rule. Prolog's dream, Ada's rigor, one workshop.
== The road to ALB ==
AdaLog answers a question ALB's existence raises: why would anyone build a language? Because they already had. The Titanium suite is the evidence — an author who wrote a Prolog engine when they needed game AI, a window manager when they wanted a desktop, a renderer when they wanted wallpaper. ALB is what happened when the same instinct aimed at the language itself.
The pattern carried over intact: static bounds instead of dynamic allocation, contracts instead of conventions, a compiler pipeline of small honest units (lexer, parser, logic, solver — the same nouns that now structure albt.adb's tokenizer, parser, and emitters). AdaLog v0.9 was the rehearsal. AdaLogic BASIC is the production.
== Quiz ==
- AdaLog is a logic-programming engine in the Prolog family, written in Ada with SPARK annotations.
- Its
Unifyprocedure carries a formal postcondition: failed unification provably leaves the environment unchanged. - AdaLog's solver runs to completion in one call and cannot be interrupted.
- TitaniumBG's desert scene includes a buzzard that cycles through behavioral states.
- The suite was a commercial release competing with mainstream desktop tools.
Show answers — click to check yourself
1. True — facts, rules, unification, a trail for backtracking: a deliberately small, provable Prolog. 2. True — Post => (if not Success then Env = Env'Old and T_Ptr = T_Ptr'Old) in titanium_logic.ads. 3. False — it's stepped on purpose (Step → Running/Found/Done) so a game loop can budget inference per frame. 4. True — Buzzard_State cycles Circling → Descending → Feasting → Ascending in desert_mountain.ads. 5. False — the suite is unreleased open source (BSD-3-Clause bundled), a personal workshop — which is exactly the point.
== Notes ==
- All claims in this article trace to the TitaniumComplete-0.2 source tree itself — the suite is unreleased, so the code is the documentation. Version numbers are the bundled ones: AdaLog v0.9, TitaniumWM v2.2, TitaniumRun v0.4, TitaniumBG v0.7.
- Licensing: TitaniumWM's release bundles a BSD-3-Clause license (© 2026 Rocky L. Oliver); the suite has also been described as Apache-2.0. Both are permissive — the material fact is that the code is open and unshipped.
- The SPARK boundary is reported honestly: core logic packages carry
SPARK_Mode (On); the X11-facing event loop in TitaniumWM'smain.adbis explicitlySPARK_Mode (Off). "SPARK-annotated" is the accurate claim, not "fully verified." - The orc demo's "Chosen Action: heal, Score: 500" is the program's actual designed output — a wounded orc that can see you heals rather than attacks, because the rule set scores it so.
== References ==
AdaLog-v0.9/AdaLog/— atoms, titanium_lexer, titanium_parser, titanium_logic, titanium_solver, titanium_database, types, main (Utility AI test), TitaniumComplete-0.2.titanium_logic.ads— Unify contract and trail-based backtracking.types.ads— Term_ID ranges, atom/variable interning scheme, static pool bounds.TitaniumWM-v2.2/— src/main.adb, layout.ads, wm_state, wm_keys, x11; release README and BSD-3-Clause LICENSE.md.TitaniumRun-v0.4/— src/completion.ads, launcher_core.ads.TitaniumBG-v0.7/— src/desert_mountain.ads, jungle_river, plasma, snowy_village, titanium_bg.ads, vgpu renderer/ditherer/fonts.- Ada Lovelace, notes on the Analytical Engine (1843) — the symbolic-manipulation lineage.
Footnotes
- ↑ TitaniumComplete-0.2 source tree — AdaLog v0.9, TitaniumWM v2.2, TitaniumRun v0.4, TitaniumBG v0.7; the suite's bundled license is BSD-3-Clause, copyright 2026 Rocky L. Oliver.
- ↑ AdaLog main.adb — the test harness prints "Titanium Engine: Utility AI Test", identifying the logic engine as the suite's namesake core.
- ↑ types.ads — Atom_Base 1_000_000, Var_Base 2_000_000, and the fixed pool sizes that bound the whole engine's memory.
- ↑ titanium_logic.ads — Unify's Post aspect: a failed unify restores Env and the trail pointer; backtracking via Trail_Array.
- ↑ main.adb — the utility-AI demo: see/health facts, attack/heal rules, stepped solving, argmax decision; output ends "Chosen Action: heal, Final Score: 500".
- ↑ TitaniumWM README and src/main.adb, layout.ads — SPARK_Mode On for layout/state; the X11 event loop is explicitly non-SPARK by design.
- ↑ TitaniumRun src/completion.ads, launcher_core.ads — Max_Candidates 8192, Max_Results 5, Pre/Post contracts on every buffer operation.
- ↑ TitaniumBG src/desert_mountain.ads, titanium_bg.ads — Buzzard_State machine, Wallpaper_Item tagged type, Pixel_Array bounded to 3840×2160.