Knowledge representation + programming

Axioma.

Represent knowledge.
Compute its consequences.

Express concepts, facts and rules. Inspect what follows from your assumptions. Build programs that use those results, in the same language.

An open-source language with a native interpreter and a browser playground.

Follow the example ↓
Premise → conclusion → revisionRun in Playground ↗
relation human(name)
assert/axiom human("socrates")
mortal(X) whenever human(X)

count_mortals() = len({ X | X <- mortal(X) })
println(count_mortals())
why mortal("socrates")

forget_cascade("human", "socrates")
println(count_mortals())
Output
1
Explanation for: mortal(socrates)
This is a theorem derived by strict inference from:
  - human("socrates")  [axiom]

0

Explore the language

Follow the reasoning

A conclusion with a reason.

The example above combines a rule, a query and an ordinary function. Changing the knowledge changes the function’s result.

  1. 01

    State the premise

    We take Socrates’ humanity as an axiom of this example and declare the rule that humans are mortal.

  2. 02

    Derive and explain

    The query derives Socrates’ mortality. why traces the conclusion to its supporting premise.

  3. 03

    Use it in a program

    A function counts the query’s results. Knowledge queries and ordinary computation share one environment.

  4. 04

    Revise the knowledge

    Withdrawing the sole supporting fact removes its dependent conclusion. The count becomes zero.

What this establishes: a consequence of the declared premises and rule, followed by a dependency-aware revision. Zero means the query now derives no members. Grounding records the role and derivation of a claim; the truth of a real-world premise still needs evidence.

One language, connected capabilities

Model. Reason. Program.

Readable, mathematical forms for knowledge work, together with the functions, data structures and numerical tools that turn a model into a working program.

I · Representation

Concepts, relations and sets

Describe a domain with concepts, fields, inheritance and classification rules. Query relations with set-builder notation. Concepts can also carry their purpose, defining boundary, examples and counterexamples.

A definition that classifiesRun in Playground ↗
concept Person
Person has age
ada: a Person { age: 36 }
Adult defines { is Person and age >= 18 }
println(ada is Adult)
println({ n | n <- 1..6, n mod 2 == 0 })
Output
true
{2, 4, 6}
Explore the language tutorial →

II · Logic

Make uncertainty explicit

Use classical logic, quantifiers and typed many-valued truth. Belnap’s four values distinguish support, denial, conflicting information and missing information. Strict rules derive conclusions; defeasible rules express defaults with exceptions.

Unknown, conflicting, and quantifiedRun in Playground ↗
println(?ᵇ)
println(⊤⊥ᵇ)
println(⊤ᵇ and ⊤⊥ᵇ)
println(forall x in {2, 4, 6} | x mod 2 == 0)
Output
?ᵇ
⊤⊥ᵇ
⊤⊥ᵇ
true

The first two lines distinguish an information gap from a conflict. Each logic gives its operators a defined meaning.

Explore missing and conflicting information →

III · Programming

Functions that work with data

Compose functions, match patterns, build pipelines and call collection methods. Dotted calls broadcast across data; connected dotted expressions fuse. Type annotations, contracts, modules and errors as values support larger programs.

Broadcast, transform, reduceRun in Playground ↗
double(x) = 2*x
next_value(x) = x+1
let xs = [1, 2, 3]
println(next_value.(double.(xs)))
println(xs.map(double) |> sum)
println(xs.length())
Output
[3, 5, 7]
12
3

let declares a fresh immutable binding; var declares a mutable one. : and = bind or update. The first printed expression fuses; a pipe between stages is a materialization boundary.

Learn functions and broadcasting →

IV · Computation

Exact numbers and matrices

Compute with arbitrary-precision integers and rational values, including exact matrix operations. Use explicit Float conversion when approximation is intended. Matrices have a shape; their linear indexing and cell iteration follow row-major order.

Exact arithmetic, explicit approximationRun in Playground ↗
m = matrix([[1, 2], [3, 4]])
println(inv(m)[:])
println(1 / 8)
println(fdiv(1, 8))
for cell in m
    println(cell)
end
Output
[-2, 1, 3/2, -1/2]
1/8
0.125
1
2
3
4

Matrix inversion preserves the fractions here. fdiv requests a Float result. The loop visits cells in the same order as linear indexing.

Read the numeric and collection reference →

V · Reflection

Programs can inspect programs

Functions are values. Quotation, AST inspection and hygienic macros make code available to code. Ask the runtime for a function’s documentation, signature or source, and compose functions in either direction.

A macro and a compositionRun in Playground ↗
macro double(x) quasiquote(unquote(x) * 2)
println(double(21))
square(x) = x*x
println((square << (x -> x+1))(3))
Output
42
16

<< composes right to left, like . >> composes left to right. ASCII forms keep the same operations easy to type.

Explore function composition →

VI · Data

Query the same facts in SQL

A relation is a set of tuples. Axioma’s SQL surface queries and updates those relations; a set comprehension can ask the same question. Native knowledge-base persistence can retain supported knowledge across sessions.

Two notations, one relationRun in Playground ↗
relation teaches(teacher, student)
assert teaches("Socrates", "Plato")
assert teaches("Socrates", "Xenophon")
println({ S | S <- teaches("Socrates", S) })
println([sql | SELECT student FROM teaches
               WHERE teacher = 'Socrates'])
Output
{"Plato", "Xenophon"}
{"Plato", "Xenophon"}

These two queries return the same set. The SQL surface has a defined subset and its own documented limits.

Read the SQL reference →
More tools for everyday programs

Collections and control flow

Arrays, dictionaries, tuples, sets, bags and stacks; lazy ranges, generators and streams; comprehensions, loops and recursion. Choose the data structure and traversal that express your problem.

Values and structure

Strings and Unicode, enumerations and algebraic data types, complex and monetary values, dates, times and durations. Modules, closures, pattern matching and contracts help organize the program around them.

Browse data types, control flow and modules →
The language, in six axioms

What you can say

Axioma reads like mathematics and runs like a program. The examples below run in the Playground except the explicitly labeled native SMT example.

I.

Sets are first-class

Set-builder notation, comprehensions, union, intersection, difference and subset tests — mathematical notation evaluated directly by the runtime.

Sets are first-classRun in Playground ↗
nums: [1, 2, 3, 4, 5, 6]
println({ n | n <- nums, n mod 2 == 0 })
Output
{2, 4, 6}
II.

Logic is executable

Quantifiers range over collections and evaluate: (“for all”) and (“there exists”). A separate [logic/…] solver portfolio includes SAT for Boolean satisfiability, SMT for supported arithmetic and equality theories, answer-set programming for rules and defaults, chase-style database inference, and quantified reasoning. Read the returned engine and regime metadata: these engines have different supported fragments and limits.

Logic is executableNative · requires Z3
println(forall x in {2, 4, 6} | x mod 2 == 0)
println([logic/smt | x + 0 == x])
Output
true
«engine=smt regime=decidable (quantifier-free linear integer) grounding=theorem result=true»

The quantified expression runs in the browser; the SMT block requires the native interpreter and Z3 on PATH, or a compatible solver configured with AXIOMA_SMT. The result shown is for the supported quantifier-free linear-integer fragment.

III.

Rules reason for you

Horn-clause rules that read as English: head whenever body derives theorems, typically head whenever body defeasible conjectures (also head if body / rule~) — with operator twins when you want arrows (strict <== / ==>, defeasible <~~ / ~~>, Prolog :-). Recursive rules can compute transitive closure over finite relations, Datalog-style; relation / assert are optional in the obvious cases.

Rules reason for youRun in Playground ↗
relation edge(x, y)
assert edge("a", "b")
assert edge("b", "c")
path(X, Y) whenever edge(X, Y)
path(X, Y) whenever edge(X, Z) and path(Z, Y)
println({ Y | Y <- path("a", Y) })

# Bare declarations and facts also work.
parent(X, Y)
parent("bob", "ann")
parent("ann", "pat")
ancestor(X, Z) whenever parent(X, Z)
ancestor(X, Z) whenever parent(X, Y) and ancestor(Y, Z)
println({ Z | Z <- ancestor("bob", Z) })
Output
{"b", "c"}
{"ann", "pat"}
IV.

Truth needn't stop at two values

Plain booleans are fully classical — two values, all the classical laws. When a problem calls for more, opt in per value: Kleene K3 and Łukasiewicz Ł3 add an unknown, Gödel G3 uses a three-valued intuitionistic truth algebra (excluded middle is not generally valid), and Belnap B4 adds a value for contradictory evidence. The values are literals — what Axioma prints is valid source — and one such value in an expression makes the operators follow that logic.

Truth needn't stop at two valuesRun in Playground ↗
println(true and not true)
println(om or true)
println(⊤ᵇ and ⊤⊥ᵇ)
Output
false
true
⊤⊥ᵇ
V.

“is” means three things

Russell's copula, made precise — one English word, three relations kept distinct: predication (, membership in a concept), identity (=, spelled is/same so bare is never conflates it), and existence (, there is …).

“is” means three thingsRun in Playground ↗
concept Planet {}
hesperus: a Planet {}        # the Evening Star…
phosphorus: hesperus          # …is the Morning Star
println(hesperus is Planet)
println(hesperus is/same phosphorus)
println(there is hesperus)
Output
true
true
true
VI.

Reasoning runs anywhere

The core evaluator compiles to WebAssembly and runs locally in your browser. Stacks, prose-like definitions and the examples here need no server. Host I/O, external runtimes, native persistence and AI providers require the native application.

Reasoning runs anywhereRun in Playground ↗
# a function, colon binding
sq: func(n) [n * n]
println(map(sq, [1, 2, 3]))
Output
[1, 4, 9]
A cognitive paradigm

A cognitive approach to computing

Axioma’s cognitive approach brings knowledge representation, symbolic reasoning and explanations into an ordinary programming environment. It proposes a fifth, cognitive paradigm alongside procedural, object-oriented, functional and logic programming: make concepts, assumptions, evidence and revision explicit, and work through the knowledge lifecycle with understand. This is Axioma’s design position rather than an established classification of all programming languages. The logic and representation families below put that ambition into practice, with different levels of execution support.

Calculemus. Let us calculate.”— Leibniz’s aspiration to make reasoning calculable

17th century
Leibniz

characteristica universalis + calculus ratiocinator — a universal language of thought, and a calculus to reason in it.

1854
Boole

The Laws of Thought — the algebra of logic.

1879
Frege

Begriffsschrift — a foundational modern predicate calculus with quantified expressions. His later work distinguished sense and reference.

1903–1905
Russell

Types, definite descriptions, and the three meanings of “is.”

1931
Gödel

Incompleteness — and numbering a formal system within itself.

1959
McCarthy

Programs with common sense.

1970
Codd

The relational model — data as sets of tuples, queried in first-order logic.

today
Axioma

Knowledge representation and programming together — a native interpreter and browser core, with executable studies that test the language against actual arguments.

Logic: a family of reasoning tools

Axioma exposes the following seventeen overlapping logic families and representations. For typed truth values, and, or, not and implies dispatch according to the operands. Modal models, rule engines and solver blocks have their own contracts: sharing notation does not make a proof valid across logics. Classical and typed truth examples are shown above; advanced KR families remain experimental. Read the maturity and compatibility policy.

Propositionalclassical two-valued logic
First-order · FOLbounded quantifiers and supported rule / prover fragments
Second-order · SOLpredicate and set representations; experimental inference
Modal · alethicnecessity □, possibility ◇ (Kripke)
Modal · temporalalways · eventually · next · until
Modal · epistemicknows / believes, per agent
Modal · deonticobligation · permission · prohibition
Intuitionistic · G3three-valued truth algebra; excluded middle can fail
Paraconsistenttolerates contradiction, no explosion
Fuzzydegrees of truth across [0, 1]
Description logic · DLconcepts, roles, subsumption
Probabilisticuncertainty quantified as probability
Free logicnon-denoting terms ("the round square")
Default logicnon-monotonic defaults & exceptions
Kleene K3true / false / unknown
Łukasiewicz Ł3three-valued, graded implication
Belnap B4true / false / both / neither

Eight ways to represent knowledge

From symbolic AI to geometric and linguistic semantics, these systems offer different ways to structure a domain. Working constructors or a demonstrated query do not imply complete inference support. Core concepts and rules have executable examples here; the advanced graph, semantic and geometric systems have experimental contracts.

Frames & conceptsMinsky — slots, defaults, inheritance
Relations & rulesDatalog facts + Horn-clause rules
Semantic networksQuillian — typed links, spreading activation
Conceptual graphsSowa — concept/relation bipartite graphs
Existential graphsPeirce — diagrammatic logic of cuts
Conceptual spacesGärdenfors — geometric quality dimensions
Semantic primes · NSMWierzbicka — universal meaning primitives
Conceptual dependencySchank — primitive ACTs (ATRANS…)
Many-valued logic

Beyond true and false

Real knowledge can be incomplete or contradictory. Belnap’s four-valued bilattice represents missing and conflicting information separately: ⊤⊥ᵇ and ?ᵇ are literals and match patterns. Branching uses the value’s logic-specific designated set; in B4, both is designated and neither is not. A designated value satisfies that branching rule, not a general claim that acting on conflicting evidence is appropriate.

  • ⊤ true asserted, no conflict
  • ⊥ false denied, no conflict
  • ⊤⊥ both asserted and denied — a paraconsistent contradiction
  • ? neither no information either way

The diamond shows the information order: neither below true and false, both above them. The separate truth order puts false below neither and both, and true above them. B4 can retain a conflict without making every unrelated proposition true. Typed truth operations and stored fact annotations are separate from grounding and from the behavior of a particular inference engine.

Belnap B4: neither below true and false, both above them in the information order ⊤⊥ ? more info ↑
Knowledge representation

Concepts that carry their philosophy

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.

Concepts that carry their philosophyRun in Playground ↗
# A concept is MORE than a class — it starts as one, but also carries
# actions, a defining boundary and a grounding (below). Plain English + doc:
concept Vehicle "anything that moves people or goods"

# Fields: add several at once with `has`, drop one with `had`
Vehicle has wheels: 4, speed, cargo   # wheels carries a default
Vehicle had cargo                 # …dropped again

# Actions (methods) — `it` is the receiving instance
Vehicle action summary() [ str(it.wheels) + " wheels @ " + str(it.speed) ]

# Inheritance: extends declares Car ⊆ Vehicle (auto-creates Car)
Car extends Vehicle
Car has doors

# Instances — the indefinite article `a` (consonant) / `an` (vowel)
tesla: a Car { wheels: 4, speed: 250, doors: 2 }
Aircraft extends Vehicle
jet: an Aircraft { wheels: 3, speed: 900 }
println(tesla.summary())

# Read a field by dot — or with the 's possessive (Russell's genitive)
println(tesla's speed)
println(Vehicle's wheels)

# Classify it with the copula `is` (Russell's ∈ and ⊆)
println(tesla is Car)
println(tesla is Vehicle)
println(Car is Vehicle)

# Auto-classification — a rule decides membership
SportsCar defines { is Car and speed > 200 }
println(tesla is SportsCar)

# Lifecycle: suspend, revive, or destroy a concept
concept Draft "scratch"
Draft suspend                     # frozen
Draft unsuspend                   # live again
Draft destroy                     # gone for good
println(is Draft)
Output
4 wheels @ 250
250
4
true
true
true
true
false

The everyday surface: declare a concept and several fields at once with has (had removes one), attach actions — methods where it is the instance — inherit with extends, instantiate with a / an, read a field by dot or the 's possessive (on an instance or a concept), classify with is, and manage a concept's whole life — suspend · unsuspend · destroy. The Output panel shows what this complete program prints.

Concepts that carry their philosophyRun in Playground ↗
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
}

println(alex is Bachelor)
println(sam  is Bachelor)
println(check(Bachelor))
println(examine(Bachelor))
println(grounding("isa", alex, Bachelor))
Output
true
false
⊤ᵇ
{contract: ⊤ᵇ, formed_by: "stipulation", kind: "concept", meaningful: true, pseudo: false, target: "Bachelor", verdict: "meaningful concept"}
axiom

The philosophical surface: a concept carries its purpose, a formed_by mode (abstraction · combination · distinction · stipulation · metaphor), a defining boundary, and examples / counterexamples. check evaluates that contract in Belnap four-valued logic; examine supplies a Carnap-inspired diagnostic. Here “meaningful” reports the model’s checks, not a philosophical proof of meaningfulness. Stipulated membership receives axiom grounding within the model.

Philosophical modeling forms — see the complete examples and studies for their premises.
IdeaAxioma formWhat it lets you inspect
Epictetus’ dichotomy of controlThing partition UpToUs, NotUpToUsThe declared partition; unknown cases still need an explicit policy.
Stoic adiaphoravalue_indifferent / value_kind_ofA stipulated value classification, not a measurement of human concern.
Descriptions by a propertythe Stock where price > 1000A class description and its members; this form does not itself assert unique existence.
Sense and reference; different framingsdeparted("estate") qua "lost"An event under a named description and the rules attached to it.

The concept vocabulary

Lifecycleconcept · has · had · suspend · unsuspend · destroy
Structureextends · implements · action · defines / defines~ · partition · enumerates · ranges · identified by · unify / unify~ · classify · subsumes
Formation fieldspurpose · formed_by · boundary / boundary~ · examples · counterexamples · default_grounding
Slot metadatahas slot/cumulative · inverse_slot · transitive_slot · find_or_create · cardinality
Diagnosticscheck · examine · why · grounding · proof
Facts & grounding

Assert a fact — record its grounding

A relation is a named predicate; an assert drops a fact into it. In the obvious case both keywords fall away. And every fact carries an epistemic grounding — how it is introduced or derived in the model — kept strictly apart from its truth.

Assert a fact — record its groundingRun in Playground ↗
# Explicit — the keywords spell out the intent
relation edge(x, y)
assert edge("a", "b")
assert edge("b", "c")

# Optional — a bare UPPERCASE-arg header declares the relation,
# and a bare call asserts a fact. Same result, less ceremony:
near(X, Y)                 # ≡ relation near(x, y)
near("a", "b")            # ≡ assert near("a", "b")
near("b", "c")

println({ (P, Q) | (P, Q) <- near(P, Q) })
Output
{("a", "b"), ("b", "c")}

The keyword form is for clarity, the bare form for speed. The rule: a header with uppercase arguments (logic variables) reads as a declaration, a call with concrete values reads as a fact — so near(X, Y) declares while near("a", "b") asserts.

Assert a fact — record its groundingRun in Playground ↗
# Grounding records how a claim entered the model.
assert/axiom mortal("socrates")
assert/postulate rain("tuesday")
assert/hypothesis dark_matter("halo")
assert barks("rex")
println(grounding("mortal", "socrates"))
println(grounding("rain", "tuesday"))
println(grounding("barks", "rex"))

# Strict and defeasible rules give different derived grades.
assert man("socrates")
assert wise("socrates")
human(X) <== man(X)
sage(X) <~~ wise(X)
println({ X | X <- human(X) })
println({ X | X <- sage(X) })
println(grounding("human", "socrates"))
println(grounding("sage", "socrates"))

# Truth is a separate dimension from grounding.
println(truth("mortal", "socrates"))
set_truth("barks", "rex", "both")
println(truth("barks", "rex"))
Output
axiom
postulate
datum
{"socrates"}
{"socrates"}
theorem
conjecture
⊤ᵇ
⊤⊥ᵇ

Six grounding grades have a defined internal ordering: axiom > postulate > theorem > conjecture > hypothesis > datum. Four describe asserted premises; strict inference derives a theorem and defeasible inference a conjecture. This is a record of epistemic role and derivation, not a numerical confidence score or certification of empirical truth. Grounding is separate from true / false / both / neither: an asserted axiom can also carry conflicting information.

Reasoning about reasoning

It knows what it knows

Beyond running your program, Axioma reasons about its own knowledge — where a fact came from, how it is grounded, and how to explain it. The [ model | … ] lens even charts your code on the knowledge lifecycle as you write it.

It knows what it knowsRun in Playground ↗
[ model |
  relation human(x)
  axiom human("socrates")
  mortal(X) <== human(X)
  println({ X | X <- mortal(X) })
]
Output
{"socrates"}
Advisory report (stderr)

┌─ 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.

The [model | …] lens runs the block and reports which knowledge-lifecycle phases its syntax uses: represented → grounded → inferred → proved → truth-valued → applied. Here three of six are present. The report suggests relevant operations for missing phases. It is advisory: detecting a proof-related operation is not verification that a theory is true or complete. The example’s rule runs from humanity to mortality, and the result remains available to ordinary code.

A cognitive kernel

understand, examine and abduce connect representation with inspection and candidate explanations. In the spirit of Peircean abduction, the example identifies a premise that could support the goal. A candidate explanation is not automatically the best explanation, an established fact or a causal finding.

A cognitive kernelRun in Playground ↗
flies(X) <~~ bird(X)
println(abduce("flies", "tweety"))
Output
[("bird(\"tweety\")", "defeasible")]

It solves problems

Pólya-inspired blocks can find an unknown in a finite domain, attempt to prove a supported goal, or plan using Newell–Simon-style means–ends analysis (gps). This example searches 1 through 20 and rechecks the condition for 13. Search bounds and the supported problem form matter; this is not an unrestricted problem solver.

It solves problemsRun in Playground ↗
r: [solver/polya |
  find d in [1..20]
  condition d * d == 169 ]
println(r.answer)
Output
13
Advisory report (stderr)

┌─ solver · Pólya · four phases ────────────────────────────────────
│ 1 understand  unknown d ; data (none) ; condition d * d == 169
│ 2 devise      finite search over [1..20], filtered by the condition
│ 3 carry out   { d | d <- [1..20], … } → answer 13
│ 4 look back   ✓ condition re-checked — holds
└─ the engine PRODUCED the answer; it was not given in the source.

Self-explaining proofs

Ask why a supported conclusion holds and inspect its premises and rule-based justification. The explanation shows what follows inside the model; the premises still need their own justification.

Self-explaining proofsRun in Playground ↗
relation human(name)
assert/axiom human("socrates")
mortal(X) <== human(X)
why mortal("socrates")
Output
Explanation for: mortal(socrates)
This is a theorem derived by strict inference from:
  - human("socrates")  [axiom]

Knowledge has grades

Axioma is named for the axiom. Grounding distinguishes adopted starting points, observations and derived claims. A plain assert receives datum; axiom records an adopted premise. See the full grounding example above for strict and defeasible derivations.

Knowledge has gradesRun in Playground ↗
axiom mortal("socrates")      # top of the ladder
assert barks("rex")           # the floor
println(grounding("barks", "rex"))
Output
datum

Defaults & exceptions

Defeasible rules (<~~) hold by default and retract for exceptions — non-monotonic logic, provenance kept.

Defaults & exceptionsRun in Playground ↗
relation bird(name)
assert bird("pingu")
assert bird("tweety")
flies(X) <~~ bird(X)
println({ X | X <- flies(X) })
cancel("flies", "pingu")
println({ X | X <- flies(X) })
Output
{"pingu", "tweety"}
{"tweety"}

Errors are values

try turns a fault into an inspectable value that auto-classifies into a concept you can match on.

Errors are valuesRun in Playground ↗
e: try(10 / 0)
println(e is DivByZero)
println(parse_int("x") otherwise 0)
Output
true
0
λ

Code is data

Code can be represented and inspected: parse strings to ASTs, quote code, write hygienic macros, and introspect with fullform / treeform / tableform / graphform.

Code is dataRun in Playground ↗
macro double(x) quasiquote(unquote(x) * 2)
println(double(21))
Output
42
?

It describes itself

Local help is available in the runtime: doc looks up names, keywords and operators; describe inspects a value; apropos searches names and documentation. functions(Integer) lists associated functions. source(f) and ast("src") expose definitions and parsed code. REPL :manual (short alias :man) searches the embedded Manual; oracle provides local hints. The online Textbook offers This Book and All Docs search. Reserved and experimental entries are labeled.

It describes itselfRun in Playground ↗
double(x) = x*2
println(signature(round))
println(source(double))
println(eval(source(double))(21))
Output
round(x, [digits])
double: func(x) [(x * 2)]
42
/

Refinements adapt a word

A /word refinement tunes one keyword instead of multiplying keywords. The copula is tests membership; is/same tests identity. The same dialect controls persistence — /persist vs /transient.

Refinements adapt a wordRun in Playground ↗
concept Dog
rex: a Dog {}
fido: rex
println(rex is Dog)
println(rex is/same fido)
concept/transient Scratch
println(is Scratch)
Output
true
true
true

Orthogonal axes & the bilattice

One fact carries independent dimensions at once — its Belnap truth, its epistemic grounding, and its kind (empirical, logical, …). The four truth values form a bilattice — ordered by truth and by information.

Orthogonal axes & the bilatticeRun in Playground ↗
axiom/empirical color("apple", "red")   # grounding + kind
set_truth("color", "apple", "red", "both")
println(grounding("color", "apple", "red"))
println(truth("color", "apple", "red"))
Output
axiom
⊤⊥ᵇ

Meaning, made executable

Model meaning directly: NSM semantic primes and Schank Conceptual Dependency on cognitive words, Lojban-style selbri places on relations, plus natural-language dialects (<<Lojban| … >>) and cross-language translate.

Meaning, made executableRun in Playground ↗
# each place carries a semantic role
relation gives(g -> "giver", x -> "gift", r -> "recipient")
gives("John", "book", "Mary")
println({X | X <- gives(X, "book", _)})
Output
{"John"}
A wider vocabulary

Three centuries of ideas, runnable

Set theory and intensional descriptions, the geometry of meaning, prime-number taxonomy and belief-sensitive viewpoints provide different modeling tools. The examples below are complete programs; the studies connect these forms to their philosophical sources and explain what each model establishes.

Concepts as numbers

A Leibniz-inspired finite encoding assigns primes to primitive attributes and combines them by multiplication. In this representation, divisibility tests whether one bundle includes another. It illustrates a chosen taxonomy, not an encoding of every possible concept.

Concepts as numbersRun in Playground ↗
human: 2*3*7*13*19   # a prime fingerprint
println(is_subtype_of(human, 2*3*7))
Output
true

Definite descriptions

The description the X where … forms a class satisfying a property. You can test membership or inspect its extent. Inspired by the logical analysis of descriptions, this class form does not on its own impose Russell’s unique-existence condition.

Definite descriptionsRun in Playground ↗
concept Stock
Stock has price
luxury: a Stock { price: 1500 }
ordinary: a Stock { price: 100 }
big: the Stock where price > 1000
println(luxury is big)
println(ordinary is big)
Output
true
false

Textbook notation

Write the symbols mathematicians use — quantifiers ∀ ∃, membership ∈, order ≤ ≥ (they chain), set difference \, proper subset ⊊.

Textbook notationRun in Playground ↗
x: 5
println(∀ x in {2,4,6} | x mod 2 == 0)
println(0 ≤ x < 10)
println({1,2,3,4} \ {2,4})
println({1,2} ⊊ {1,2,3})
Output
true
true
{1, 3}
true

The geometry of meaning

Gärdenfors-inspired conceptual spaces represent quality dimensions, prototypes and regions. Here categorization selects a nearby prototype in two specified dimensions. The dimensions, distance and examples determine the result; they do not establish a universal geometry of meaning.

The geometry of meaningRun in Playground ↗
fruit: conceptual_space("Fruit", "Two illustrative quality dimensions")
add_dimension(fruit, "sweetness", 0, 10)
add_dimension(fruit, "crunch", 0, 10)
add_prototype(fruit, "apple", [7, 5])
add_prototype(fruit, "pear", [9, 2])
println(nearest_prototype(fruit, [6, 5]))
Output
apple

One fact, two framings

Represent the same event under divergent value-laden descriptions, as in Epictetus’ Enchiridion 11. qua records the framings and can distinguish their rule consequences. Changing a description in the model does not itself establish a psychological change in a person.

One fact, two framingsRun in Playground ↗
relation departed(item)
departed("estate") qua "lost"
departed("estate") qua "given_back"
println(framings_of("departed", "estate"))
Output
{"given_back", "lost"}
How it's written

Bindings, blocks & functions

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. Each example below has its own runnable Playground link; the interactive tutorial develops these ideas further.

:

Bindings

Use : or = to bind or update a name, including multiple bindings. Use let for a fresh immutable declaration and var for a mutable one. These forms make declaration and later updates explicit when that distinction matters.

BindingsRun in Playground ↗
answer: 42
greeting: "hello"
x, y, z: 1, 2, 3      # multi-bind
B = {2, 4, 6}            # = also binds (textbook math)
let fixed = 7
var counter = 0
counter = counter + 1
println(answer)
println(greeting)
println([x, y, z])
println(B)
println([fixed, counter])
Output
42
hello
[1, 2, 3]
{2, 4, 6}
[7, 1]
[ ]

Blocks

In a function body or a statement block, square brackets group a sequence of expressions; its value is the last expression. Brackets also form arrays in value positions. Multiline control-flow bodies can instead end with end; see the loop examples below.

BlocksRun in Playground ↗
r: [
  a: 3
  b: 4
  a * a + b * b
]
println(r)
Output
25
λ

Functions

A function is a value too — bound with :, its body a [ ] block (or a lightweight lambda). Being values, they recurse, form closures, and compose.

FunctionsRun in Playground ↗
square: func(x) [x * x]
double: lambda x => x * 2
println(square(9))
Output
81

Composition

Functions pass into map, filter and reduce, and compose with or its ASCII spelling << (right to left). >> composes left to right. A pipeline |> applies a value to the next call; _ selects an argument position when needed.

CompositionRun in Playground ↗
square(x) = x*x
double(x) = 2*x
println((square << double)(3))
println((double >> square)(3))
println(map(square, [1, 2, 3, 4, 5]))
Output
36
36
[1, 4, 9, 16, 25]
±

Prefix · infix · postfix

Operators are values, so arithmetic reads three ways: infix by default, prefix as a function you can pass to map / reduce, and a stack for postfix / RPN.

Prefix · infix · postfixRun in Playground ↗
println(2 + 3)
println(+(2, 3))
println(reduce(*, 1, [1,2,3,4]))
Output
5
5
24
Everyday breadth

The tools for everyday programs

The philosophy is the headline — but ordinary programming tools belong here too. Pattern matching, errors-as-values, strings, enums, lazy streams, stacks, higher-order functions, loops. Explore them further in the tutorial and the worked algorithms.

Pattern matching

ML-style match … with, with when guards and a _ catch-all. An unmatched match returns om; this fallback does not make arbitrary programs total.

Pattern matchingRun in Playground ↗
grade: func(n) [
  match n with
  | n when n > 90 => "A"
  | n when n > 60 => "pass"
  | _ => "fail" ]
println(grade(95))
Output
A
!

Errors are values

Handle evaluation failures explicitly: try hands back the fault as an inspectable value that auto-classifies, and otherwise gives a fallback.

Errors are valuesRun in Playground ↗
e: try(10 / 0)
println(e is DivByZero)
println((10 / 0) otherwise 99)
Output
true
99
"

Strings & interpolation

${…} interpolation and \u{…} escapes that reach the whole of Unicode — a string can carry ∃ or 😀 directly.

Strings & interpolationRun in Playground ↗
name: "Ada"
println("hello ${name}")
println("sum ${2 + 3}")
println("exists \u{2203}")
Output
hello Ada
sum 5
exists ∃

Enumerated types

Ada/Pascal-style enums with ordinals, membership and iteration — sum types that read like a list.

Enumerated typesRun in Playground ↗
Day enumerates Mon, Tue, Wed, Thu, Fri
println(len(Day))
println(Wed.ord)
println(Mon is Day)
Output
5
2
true

Algebraic data types

ML/Haskell-style sum types — constructor patterns in match, and --typecheck catches a missing arm. Option/Result ship seeded, with railway composition via |?>.

Algebraic data typesRun in Playground ↗
data Shape = Circle(Float) | Dot
area(s) = match s with
  | Circle(r) => 3.14159 * r*r
  | Dot => 0
println(area(Circle(2.0)))
double(n) = n * 2
println(Some(5) |?> double)
Output
12.56636
10

Lazy generators

Parenthesise a comprehension and it streams instead of materialising — pull with first or force.

Lazy generatorsRun in Playground ↗
squares: (x * x | x <- [1,2,3,4,5])
println(first(squares, 3))
Output
[1, 4, 9]

Stack programming

A first-class Stack that reads like prose — mutate with message verbs push · pop · dup · swap, read with the possessive 's top · 's depth.

Stack programmingRun in Playground ↗
s: a Stack
s push 10
s push 20
println(s's top)
s pop
println(s's depth)
Output
20
1
λ

Higher-order functions

Three familiar operations over supported collections — functions are ordinary values you pass, return and compose.

Higher-order functionsRun in Playground ↗
nums: [1, 2, 3, 4, 5]
println(map(lambda x => x*x, nums))
println(filter(lambda x => x>2, nums))
println(reduce(lambda (a,x) => a+x, 0, nums))
Output
[1, 4, 9, 16, 25]
[3, 4, 5]
15

Loops, when you want them

Comprehensions and recursion sit alongside imperative for/foreach, while, repeat and loop. Use bracket bodies or multiline end forms. The last loop here demonstrates the end-terminated spelling.

Loops, when you want themRun in Playground ↗
n: 1
while n <= 3 [ println(n)  n: n + 1 ]
# prints 1, 2, 3
repeat 3 [ println("hello axioma") ]
# prints hello axioma ×3
for value in [4, 5, 6]
  println(value)
end
Output
1
2
3
hello axioma
hello axioma
hello axioma
4
5
6
The relational model

A relation is a set of tuples

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.

A relation is a set of tuplesRun in Playground ↗
relation teaches(teacher, student)        # a table — two columns
assert teaches("Socrates", "Plato")         # a row / tuple
assert teaches("Socrates", "Xenophon")
assert teaches("Plato", "Aristotle")
println({ (T, S) | (T, S) <- teaches(T, S) })
Output
{("Plato", "Aristotle"), ("Socrates", "Plato"), ("Socrates", "Xenophon")}

Three facts asserted into one relation — three rows in the table teaches(teacher, student). Now ask who did Socrates teach? two ways:

as a set

Set-comprehension

The mathematician's set-builder — bind a variable over the relation, keep what matches.

Set-comprehensionRun in Playground ↗
relation teaches(teacher, student)        # a table — two columns
assert teaches("Socrates", "Plato")         # a row / tuple
assert teaches("Socrates", "Xenophon")
assert teaches("Plato", "Aristotle")
println({ S | S <- teaches("Socrates", S) })
Output
{"Plato", "Xenophon"}
as SQL

SELECT

The same projection and filter, in the language every analyst already knows.

SELECTRun in Playground ↗
relation teaches(teacher, student)        # a table — two columns
assert teaches("Socrates", "Plato")         # a row / tuple
assert teaches("Socrates", "Xenophon")
assert teaches("Plato", "Aristotle")
println([sql | SELECT student FROM teaches
WHERE teacher = 'Socrates'])
Output
{"Plato", "Xenophon"}
SELECTRun in Playground ↗
println([sql -> calculus | SELECT student FROM teaches WHERE teacher = 'Socrates'])
println([sql -> algebra | SELECT student FROM teaches WHERE teacher = 'Socrates'])
Output
{ t.student | teaches(t) ∧ t.teacher = 'Socrates' }
π_{student}(σ_{teacher='Socrates'}(teaches))

SQL projection and selection correspond to familiar relational operations: selection σ and projection π, with tuple calculus expressing the same query through predicates. Axioma also supports documented joins, grouping, aggregates and SQL mutations. These are a defined subset with operation-specific limits; the example demonstrates the simple projection and filter, not every SQL construct. Read the SQL chapter.

A surface over the same knowledge. INSERT, UPDATE and DELETE update the in-memory relations. With native KB persistence enabled, supported concepts, relations and assertions can be retained in SQLite across sessions. Browser execution keeps session data in memory. Persistence and SQL have beta contracts; check supported operations instead of assuming compatibility with a general SQL database.

Interop

It speaks other languages

One bracket form connects several language surfaces: translate a supported Axioma expression to Python source offline, or use the native runtime to execute Python and import functions. Natural-language symbolization uses a configured AI provider. Translation to source and executing that source are distinct operations; generated code needs review. The core SQL example above runs without either external runtime or AI.

axioma → python

Translate

Compile a comprehension to idiomatic Python source — deterministic and offline.

TranslateRun in Playground ↗
println([axioma -> python | [n*n | n <- range(10)]])
Output
[n * n for n in range(10)]
python → axioma

Embed & call

Execute a Python definition with [python | …] and call it through python.call. Separately, [python --> axioma | …] asks an AI provider to translate the definition and execute the generated Axioma in the surrounding scope. Direct foreign execution and translation are different routes.

Call Python directlyNative · requires Python
[python | def double(x): return x * 2]
println(python.call("double", 5))
Output
10

Run with the native interpreter, Python installed and the default persistent Python worker enabled. This calls Python directly and does not need an AI provider.

Translate Python into Axioma
[python --> axioma | def double(x): return x*2]
println(double(5))

Provider-backed translation: generates and executes an Axioma definition from Python source. This is not a direct Python import. It requires a configured AI provider; review the generated definition and its result.

english → axioma

Symbolize

Describe an expression in English and request an Axioma symbolization from a configured model. Treat the result as a proposed interpretation: inspect its assumptions and validate it before using it for inference. Provider output is not deterministic.

Symbolize
[nl --> axioma | the empty list]

Provider-backed example: requires a configured AI provider. Generated code must be reviewed; output is not fixed.

Try the core in your browser

Try it. No install.

Write a comprehension, inspect an inference or run a recursive rule over finite facts. The Playground runs the core evaluator locally. Native persistence, external solvers and runtimes, host file/process access and configured AI providers need the native application.

Open the Playground
Beyond the playground

A full toolchain

The native application adds learning modes, knowledge persistence, external runtimes and AI integrations to the browser core. Each is available through a documented command or API; native host access and configured dependencies determine what can run. The broader VM, persistence, education and integration surfaces retain their published beta or experimental boundaries.

#

Teaching subsets

A #language directive selects a learning dialect. axioma/beginner narrows allowed forms; this example uses its canonical func(args) [body] spelling. lambda is rejected there with a migration hint. axioma/knowledge-core selects a restricted monotonic Horn-rule surface. Restrictions apply to the chosen dialect, not to the full language.

Teaching subsetsRun in Playground ↗
#language axioma/beginner
double: func(x) [x * 2]
println(double(5))
Output
10

Guided wizards native

Learn by doing in the terminal — --learn walks a dozen checked tasks; --recipe is an HtDP "design-recipe" tutor in six stages.

Guided wizards native
axioma --learn
axioma --recipe

Terminal commands: open interactive native teaching wizards.

Knowledge base native

Opt in with --kb and select a store with --kb-path. Native persistence retains supported knowledge in SQLite. why explains a derivation even without persistence, as in the example below. Cascade is a related graph application; shared-storage or federation behavior must be checked against its own version and repository, rather than assumed from a working Axioma example.

Knowledge base nativeRun in Playground ↗
relation human(name)
assert/axiom human("socrates")
mortal(X) <== human(X)
why mortal("socrates")
Output
Explanation for: mortal(socrates)
This is a theorem derived by strict inference from:
  - human("socrates")  [axiom]

AI & translation native

The supported Axioma-to-Python source translator is deterministic and offline. Other translation and symbolization routes can use configured providers such as OpenRouter, Grok, Gemini, Ollama and Claude; authentication depends on the provider. axioma --mcp exposes supported tools to compatible clients. AI-generated formalizations are proposals to inspect, not automatically verified conclusions.

AI & translation nativeRun in Playground ↗
println([axioma -> python | [n*n | n <- range(10)]])
Output
[n * n for n in range(10)]

The command line

Run--vm bytecode VM · -e eval inline · --ast show the AST · --repl interactive
Check--typecheck / --strict static analysis · --doctest run example fences · --language teaching subset · --mode paradigm overlay
Learn--learn · --recipe guided wizards · --annotate literate docs (Markdown / HTML)
Knowledge--kb SQLite KB (off by default) · --kb-path · --mcp Model Context Protocol server
Sibling toolsaxiomadoc documentation generator · axioma-test-runner parallel test sweep

Ideas put to the test

Read the source. Inspect the model.

The studies use Axioma to examine arguments and models. Source passages, interpretation choices and executable examples make it possible to ask what a formalization preserves and what its conclusions depend on.

Philosophy · Epictetus

Symbolization

The Enchiridion beside its Axioma models: control, judgment, different viewpoints and revision. See where the interpretation adds an assumption and what each example establishes.

Read the Handbook study →

Psychology · ACT

Acceptance and action

Represent central claims of Acceptance and Commitment Therapy. Separate definitions and adopted premises from empirical hypotheses, then compute their conditional consequences.

Read the ACT study →

Learn, build and connect

From a first expression to a knowledge program.

Learn at your own pace

Start with the Textbook for a guided introduction to designing programs. Already programming? Explore the interactive tutorial and keep the Manual beside your code.

Work in your editor

The native REPL, Unicode completion, VS Code/Cursor language support, formatter and debugger support everyday work. Static checks and runtime contracts help you inspect a program before and while it runs.

Editor setup →

Connect tools and agents

The MCP server exposes execution, knowledge queries and inspection to compatible clients. Native integrations include Python execution and translation; configured AI providers can assist with symbolization. Review the resulting formalization against its source.

Native setup and integrations →

Implementation status

Choose the surface for your task.

Interpreter & browser

The native interpreter is the reference runtime. The examples on this page can be opened in the browser playground. Browser execution excludes host file/process access, external runtimes, native persistence and provider-backed AI features.

Tools still developing

The bytecode VM, persistence, modules, MCP and SQL have beta contracts. VM coverage differs from the interpreter; unsupported paths should report a refusal. The Manual and maturity reference describe the relevant boundaries.

Research surfaces

Advanced modal, epistemic, probabilistic and other knowledge-representation systems include experimental work. A representation, a working example and a general proof procedure are different levels of support.

Read the feature maturity and compatibility policy →
Explore the logic and representation families

Truth and inference

Classical propositions and quantified expressions; Kleene K3, Łukasiewicz Ł3, Gödel G3 and Belnap B4 values; strict and defeasible rules. Typed truth operations dispatch by their operands. Solver blocks provide separate SAT, SMT, answer-set, chase and quantified-reasoning surfaces with result metadata.

Worlds and viewpoints

Modal, temporal, epistemic and deontic representations; description, free, fuzzy and probabilistic logic; higher-order representations. Their semantics and execution coverage vary. Sharing notation does not automatically establish a proof across different logics.

Representing meaning

Frames and concepts, relations and rules, semantic networks, conceptual and existential graphs, conceptual spaces, semantic primes and conceptual dependency. These offer different ways to structure a domain, with different maturity levels.

Explaining and revising

Grounding and justifications, assumptions and conjectures, defaults and exceptions, aspectual descriptions with qua, and stored belief attributions. Inspect how a conclusion was obtained and revise supported dependencies when premises change.

Explore the complete language reference →

The idea behind Axioma

Calculemus.
Let us calculate.

Axioma takes inspiration from Leibniz’s characteristica universalis and calculus ratiocinator: a language for expressing ideas and a calculus for reasoning with them.

That ambition guides its cognitive approach to programming: make concepts, assumptions and explanations explicit, then study them through computation. Executable philosophy is one application; knowledge models and ordinary software belong in the same environment.

Explore the philosophical foundations →