Sets are first-class
Set-builder notation, comprehensions, and the full algebra of sets — straight from the page into the runtime.
nums: [1, 2, 3, 4, 5, 6] { n | n <- nums, n mod 2 == 0 } ⇒ {2, 4, 6}
State what is true. Let the language reason.
A cognitive programming language for knowledge representation and reasoning — sets, logic, and many-valued truth, with a natural-language syntax that runs entirely in your browser.
Most languages compute with numbers. Axioma computes with truth.
Axioma reads like mathematics and runs like a program. Each construct below is real, executable syntax — try any of it in the playground.
Set-builder notation, comprehensions, and the full algebra of sets — straight from the page into the runtime.
nums: [1, 2, 3, 4, 5, 6] { n | n <- nums, n mod 2 == 0 } ⇒ {2, 4, 6}
Universal and existential quantifiers range over sets and evaluate to a truth value — ∀ and ∃, as code.
forall x in {2, 4, 6} | x mod 2 == 0 ⇒ true exists x in {1, 2, 3} | x > 2 ⇒ true
Declare facts and Horn-clause rules; recursion computes the full transitive closure, Datalog-style. The relation and assert keywords are even optional in the obvious cases.
ancestor(X, Z) <== parent(X, Z) ancestor(X, Z) <== parent(X, Y) and ancestor(Y, Z)
Boolean, Kleene K3, Łukasiewicz L3, Belnap B4, and Gödel G3 — first-class logics for the unknown and the contradictory.
belnap("both") ⇒ ⊤⊥ om or true ⇒ true # unknown ∨ true
Russell's copula, made precise: identity, predication, and existence — with concepts, instances, and classification.
concept Stock { price: 0 } aapl: a Stock { price: 150 } aapl is Stock ⇒ true
The whole interpreter compiles to WebAssembly — no install, no server. It also speaks Forth-style stacks and prose-like definitions.
# a function, REBOL-style binding sq: func(n) [n * n] map(sq, [1, 2, 3]) ⇒ [1, 4, 9]
Before the logic, the everyday shape of the language. Axioma's surface is inspired by a lineage of expressive languages: you bind a name with a colon, group expressions in [ ] blocks, and treat functions as ordinary values you can pass and compose. Every snippet here runs in the interactive tutorial →
No let and no var — just bind a name with a colon (and several at once). = reassigns an existing binding; it doesn't create one.
answer: 42 greeting: "hello" x, y, z: 1, 2, 3 # multi-bind
Square brackets group a sequence of expressions; the block's value is its last line — which is exactly how a function body is written.
r: [ a: 3 b: 4 a * a + b * b ] ⇒ 25
A function is a value too — bound with :, its body a [ ] block. A lightweight lambda exists for short ones.
square: func(x) [x * x] double: lambda x => x * 2 square(9) ⇒ 81
Because functions are values, they pass straight into map / filter / reduce — and compose into pipelines.
nums: [1, 2, 3, 4, 5] map(func(x) [x * x], nums) ⇒ [1, 4, 9, 16, 25]
A concept is more than a class. It can hold its own purpose, the mode by which it was formed, a defining boundary, and the cases that test it — then validate itself to a four-valued truth. The everyday parts read like English; the philosophical parts are executable.
# A concept is a class — declared in plain English, with a doc string concept Vehicle "anything that moves people or goods" # Fields: add with `has`, remove with `had` Vehicle has wheels Vehicle has speed Vehicle has cargo Vehicle had cargo # …dropped again # Inheritance: extends declares Car ⊆ Vehicle (auto-creates Car) Car extends Vehicle Car has doors # An instance — the indefinite article `a` tesla: a Car { wheels: 4, speed: 250, doors: 2 } # Classify it with the copula `is` (Russell's ∈ and ⊆) tesla is Car → true (membership ∈) tesla is Vehicle → true (inherited) Car is Vehicle → true (class inclusion ⊆) # Auto-classification — a rule decides membership SportsCar defines { is Car and speed > 200 } tesla is SportsCar → true # Lifecycle: suspend, revive, or destroy a concept concept Draft "scratch" Draft suspend # frozen Draft unsuspend # live again Draft destroy # gone for good is Draft → false
The everyday surface: declare a concept and its fields in plain English (has adds a field, had removes one), inherit with extends, instantiate with a, classify with is, and manage a concept's whole life — suspend · unsuspend · destroy. Every → is the interpreter's real output.
concept Man Man has age Man has married alex: a Man { age: 30, married: false } sam: a Man { age: 28, married: true } # A concept carries its own epistemology — not just fields: concept Bachelor { purpose: "an unmarried adult male — Quine's analytic example" formed_by: "stipulation" # 1 of 5 formation modes boundary: is Man and age >= 18 and married == false # the intension examples: [alex] # must fall inside counterexamples: [sam] # must fall outside } alex is Bachelor → true (boundary derives the extension) sam is Bachelor → false (married) check(Bachelor) → ⊤ᵇ (Belnap: examples in, counterexamples out) examine(Bachelor) → {meaningful: true, pseudo: false, …} grounding("isa", alex, Bachelor) → "axiom" (stipulated ⇒ axiomatic)
The philosophical surface: a concept carries its purpose, the formed_by mode it came from (abstraction · combination · distinction · stipulation · metaphor), a boundary that turns intension into extension, and examples / counterexamples it must honour. check grades that contract in Belnap four-valued logic; examine runs a Carnap pseudo-statement test; and because Bachelor was stipulated, its memberships are graded axiom.
| Epictetus' dichotomy of control“some things are up to us, some are not” | Thing partition UpToUs, NotUpToUs |
is_partitioned → true |
| Stoic adiaphorawealth is judged indifferent, not unvalued | value_indifferent("wealth", …) |
value_kind_of → "indifferent" |
| Russell's definite descriptionsa class named by a property | the Stock where price > 1000 |
luxury is it → true |
| Frege's sense vs. referenceone fact under two framings | departed("estate") qua "lost" |
framings_of → {…} |
The full concept vocabulary
Beyond running your program, Axioma reasons about its own knowledge — where a fact came from, how sure it is, and how to explain it. The [ model | … ] lens even charts your code on the knowledge lifecycle as you write it.
[ model | relation mortal(x) axiom mortal("socrates") human(X) <== mortal(X) { X | X <- human(X) } ] ┌─ model · epistemic lifecycle ───────────────────────────────────── │ ✓ represented │ ✓ grounded │ ✓ inferred │ ✗ proved → why <conclusion> · proof(rel, args…) chains back to axioms · prove / derive / refute (automated reasoning) │ ✗ truth-valued → set_truth(rel, args…, "both") · truth(rel, args…) (T / F / Both / Neither) │ ✗ applied → check Concept / examine Concept (→ B4) · examples / counterexamples · reconcile against KB / Cascade · understand X runs the whole arc └─ 3/6 phases present · advisory only — your code runs exactly as written. ⇒ {"socrates"}
Wrap any block in [ model | … ] and Axioma runs it untouched — returning {"socrates"} — then charts how far that knowledge has travelled: represented → grounded → inferred → proved → truth-valued → applied. Here three of six phases are present, and every unreached phase (✗) names the exact next step. It's Calculemus turned on the program itself: computing a result is one thing — knowing what you've actually established is another.
understand · examine · abduce — Peirce's inference-to-the-best-explanation as a built-in (the "fifth paradigm").
flies(X) <~~ bird(X) abduce("flies", "tweety") ⇒ ("bird(tweety)", defeasible)
Ask why a conclusion holds and get a prose proof traced back to its founding axioms.
why mortal("socrates") # ⇒ a theorem, from # human("socrates") [axiom]
Axioma is named for the axiom — you don't just assert facts, you grade them (axiom > postulate > theorem > conjecture > hypothesis), and the grade propagates through every proof.
axiom mortal("socrates") # foundational grounding("mortal", "socrates") ⇒ axiom
Defeasible rules (<~~) hold by default and retract for exceptions — non-monotonic logic, provenance kept.
flies(X) <~~ bird(X) cancel("flies", "pingu") # penguins excepted; tweety still flies
No stack unwinding — a fault becomes an inspectable value that auto-classifies into a concept you can match on.
e: try(10 / 0) e is DivByZero ⇒ true parse_int("x") otherwise 0 ⇒ 0
Homoiconic to the core: quote ASTs, write hygienic macros, even build a symbolic differentiator in user code.
macro double(x) quasiquote(unquote(x) * 2) double(21) ⇒ 42
Set theory and intensional logic, the geometry of meaning, prime-number taxonomy, the opacity of belief — each is a chip in the playground, one click from running.
Leibniz's 1666 dream: encode primitive concepts as primes, so that subsumption becomes plain divisibility.
human: 2*3*7*13*19 # a prime fingerprint is_subtype_of(human, 2*3*7) ⇒ true
Russell's the X where … — name a class by a property, then test membership or iterate its extent.
big: the Stock where price > 1000 luxury is big ⇒ true
Write the symbols mathematicians use — quantifiers ∀ ∃, membership ∈, set difference \, proper subset ⊊.
∀ x in {2,4,6} | x mod 2 == 0 ⇒ true {1,2,3,4} \ {2,4} ⇒ {1, 3} {1,2} ⊊ {1,2,3} ⇒ true
Gärdenfors conceptual spaces — concepts as convex regions, categorization by the nearest prototype.
add_prototype(fruit, "apple", [7,5]) nearest_prototype(fruit, [6,5]) ⇒ "apple"
Intensionality made executable — the same fact under divergent value-laden descriptions (Epictetus, Ench. 11).
departed("estate") qua "lost" departed("estate") qua "given_back" framings_of("departed", "estate") ⇒ {"lost", "given_back"}
Real knowledge is incomplete and sometimes contradictory. Axioma builds that in: Belnap's four-valued bilattice treats missing and conflicting information as first-class truth values.
Contradiction propagates through rules instead of crashing — and every derived fact carries its epistemic grounding, from axiom down to hypothesis.
Axioma is a cognitive programming language — built for knowledge representation, symbolic reasoning, and explainable AI. After procedural, object-oriented, functional, and logic programming comes a fifth paradigm, whose defining act is to understand: to model a thing into a model of everything. Seventeen logics and eight knowledge-representation systems, unified under a single old dream.
“Calculemus. Let us calculate.”— G. W. Leibniz, on settling every dispute by computation
characteristica universalis + calculus ratiocinator — a universal language of thought, and a calculus to reason in it.
The Laws of Thought — the algebra of logic.
Begriffsschrift — the first formal logic; quantifiers, sense & reference.
Types, definite descriptions, and the three meanings of “is.”
Incompleteness — and numbering a formal system within itself.
Programs with common sense.
The relational model — data as sets of tuples, queried in first-order logic.
The cognitive language — 17 logics and 8 knowledge-representation systems, executable in your browser.
Declare a relation and assert facts into it, and you have built exactly what Codd called a relation — a table whose rows are tuples. So SQL is not a separate engine bolted on: it is a second notation for the set-comprehensions you already write, over the very same facts. Same question, same answer, compiled to the same Axioma set.
relation teaches(teacher, student) # a table — two columns assert teaches("Socrates", "Plato") # a row / tuple assert teaches("Socrates", "Xenophon") assert teaches("Plato", "Aristotle")
Three facts asserted into one relation — three rows in the table teaches(teacher, student). Now ask who did Socrates teach? two ways:
The mathematician's set-builder — bind a variable over the relation, keep what matches.
{ S | S <- teaches("Socrates", S) }
⇒ {"Plato", "Xenophon"}The same projection and filter, in the language every analyst already knows.
[sql | SELECT student FROM teaches WHERE teacher = 'Socrates'] ⇒ {"Plato", "Xenophon"}
# Axioma compiles your SQL back to the formalisms it was built to hide: [sql -> calculus | SELECT student FROM teaches WHERE teacher = 'Socrates'] ⇒ { t.student | teaches(t) ∧ t.teacher = 'Socrates' } # Codd's tuple calculus — a set-builder [sql -> algebra | SELECT student FROM teaches WHERE teacher = 'Socrates'] ⇒ π_{student}(σ_{teacher='Socrates'}(teaches)) # selection σ + projection π
A SELECT is selection (σ) and projection (π) over a set — Codd's 1970 relational algebra and tuple calculus, which rest in turn on set theory and first-order logic: the same ancestry as the rest of the language. Joins, GROUP BY and aggregates compile the same way, and hand back sets of tuples — GROUP BY region yields {("east", 7), ("west", 15)}. None of this leaves Axioma, so it all runs in the browser: open the “SQL = sets” example in the playground →
A surface, not a database. And not read-only — INSERT, UPDATE and DELETE compile too, writing to the very same relations, so you can search and edit your facts in SQL if that is the interface you prefer. Those relations live in memory for the session — in the browser, that is the whole story — and you can keep them: Axioma persists your concepts, relations and assertions to a SQLite knowledge base, so the same tables survive across sessions. Either way there is no separate database to load or sync. It stays one set of tuples — under whichever notation suits you.
One bracket form, more than one runtime: translate Axioma to Python, run Python inline, or symbolize plain English into runnable Axioma. These reach beyond the interpreter — to a Python runtime, to an LLM — so they need the native axioma binary, and are shown here rather than in the browser playground. (SQL is different — it never leaves Axioma; see above.)
Compile a comprehension to idiomatic Python source — deterministic and offline.
[axioma -> python | [n*n | n <- range(10)]] ⇒ "[n * n for n in range(10)]"
Run Python inline, or pull a Python function into Axioma scope and call it.
[python --> axioma | def double(x): return x*2] double(5) ⇒ 10
Describe what you want in plain English; an LLM emits Axioma you can run.
[nl --> axioma | the empty list] ⇒ []
The interpreter runs in your browser — write a comprehension, prove a theorem, watch a rule reach its fixpoint.
▶ Open the Playground