04. The object model
4.1 The 12 kinds
| Kind | It is | Example | Has implementations | Has a Lean part | Has a scene |
|---|---|---|---|---|---|
area |
a node of the area tree (05.2) | Shortest paths | no | no | optional |
concept |
an idea used to design or analyse algorithms | Loop invariant, amortized analysis | no | optional | optional (explorable) |
definition |
a precise term | Stable sort, flow network, topological order | no | yes, a Lean def or structure |
optional |
model |
a model of computation or of cost | Word RAM, comparison model, external memory | no | optional | optional |
problem |
a computational problem with input, output and their relation | Sorting, single-source shortest paths, LCS | no, it has the contract | yes, the spec | optional |
abstract-type |
an abstract data type: operations and their laws | Priority queue, dictionary, disjoint sets | no, it has the contract | yes, the laws | optional |
algorithm |
a method that solves a problem | Merge sort, Dijkstra's algorithm, KMP | yes | yes | yes |
data-structure |
a representation that implements an abstract type | Binary heap, red–black tree, disjoint-set forest | yes | yes | yes |
technique |
a paradigm or a reusable pattern | Divide and conquer, dynamic programming, two pointers | no, it links examples | optional | optional |
theorem |
a result about algorithms or problems | Master theorem, the Ω(n log n) sorting lower bound, max-flow min-cut | no | yes | optional |
exercise |
a practice problem on a public judge or in a public text | CSES 1671 "Shortest Routes I" | no, link and metadata | no | no |
person |
a person who found or named items | Edsger W. Dijkstra | no | no | no |
Notes:
- A variant is an algorithm or a data structure with a
variant_ofedge, for examplemerge-sort-bottom-up→merge-sort. A variant has its own page when it has its own pseudocode, analysis or implementation. A difference of one line is a section of the parent page. - A proof is not a node. A proof belongs to the node that it proves. A node can have several proofs (06.5). Each proof has an id in the node, for example
merge-sort#proof-invariant. - A lemma that only one proof uses lives in that proof. A lemma that many pages use (the harmonic bound, the potential method) is a
theoremor aconcept.
4.2 Tags, slugs and URIs
- Tag. 6 characters of Crockford base32, the alphabet of math2, for example
4MRG7S. A tag is permanent and never reused.registers/tags.reglists each tag and its slug at minting. A new node has the provisional idNEW-<slug>untilalgo mintgives it a tag before the merge.algo mintnever gives a tag that is inregisters/tags.regorregisters/retired.reg. - Slug. Lowercase ASCII words joined by
-, unique over all nodes of all kinds, for exampledijkstra,binary-heap,single-source-shortest-paths. The slug is the URL. It can change; the old slug goes toregisters/aliases.regand the site redirects it. A slug never names a site section (14.2 lists the reserved words). - URI.
al://4MRG7S, andal://4MRG7S@2027.03for the node in a release. Fragments name parts:al://4MRG7S#proof-invariant,al://4MRG7S/impl/rust. - Names.
nameis the common English name.aliaseslists the other names, each with a language when it is not English ({name: "Алгоритм Дейкстры", lang: ru}). Search indexes every alias (15.2).
4.3 The node directory
A node lives at nodes/<top-area>/<sub-area>/<slug>/. The two area levels are the primary area of the node (05.2). They keep each directory under 1,000 entries, which GitHub can list. Moving a node to another area changes its path but not its tag or slug, and algo mv does it.
An algorithm directory has this form. Other kinds use the parts that they need (4.1).
nodes/sorting/comparison/merge-sort/
node.md front matter and the text (06)
proofs/
invariant.md a human proof (06.5)
recurrence.md a second proof, of the running time
impl/
python/merge_sort.py the implementation (08)
python/test_merge_sort.py
cpp/merge_sort.hpp
cpp/merge_sort_test.cpp
rust/merge_sort.rs tests in `mod tests`
go/merge_sort.go
go/merge_sort_test.go
… one directory per language
viz/
scene.ts the scene (10)
presets.yaml named inputs: random, sorted, reversed, worst case
bench.yaml optional: sizes and generators for the complexity check (09.7)
figures/ optional: SVG figures that are not scenes
A problem directory has the contract instead of implementations:
nodes/sorting/sorting-problem/
node.md
contract.yaml the signature, the input and output schemas, the checker (09.1)
cases/
basic.jsonl hand-written cases with names
edge.jsonl empty, one element, duplicates, extremes
generated.yaml generator specs for random and adversarial cases
checker.py the checker, when the output is not unique (09.3)
generators/ generators of inputs (09.4)
The Lean part lives in the Lean package, not in the node directory, because Lean module names cannot have hyphens: lean/Algo/Sorting/MergeSort.lean. The front matter names the module and the declarations, and audit rule L01 checks that each one exists (13.3).
4.4 The front matter
YAML front matter of node.md. The schema is schema/node.v1.json. Fields that do not apply to a kind are absent.
---
tag: 4MRG7S
kind: algorithm
slug: merge-sort
name: Merge sort
aliases: [mergesort, "two-way merge sort"]
area: sorting/comparison # primary area (05.2)
areas: [techniques/divide-and-conquer] # secondary areas
level: intro # intro | core | advanced | research (05.5)
summary: >-
Sort a list by splitting it in half, sorting each half and merging the two sorted halves.
solves: [sorting-problem] # problem slugs; the contract comes from here
techniques: [divide-and-conquer]
uses: [merge-two-sorted-lists] # algorithms and data structures that it calls
variant_of: null
model: comparison # the cost model of the complexity claims
complexity:
vars: {n: "the length of the input"}
time:
worst: "Θ(n log n)"
average: "Θ(n log n)"
best: "Θ(n log n)"
space:
extra: "Θ(n)"
comparisons:
worst: "n⌈lg n⌉ − 2^⌈lg n⌉ + 1"
properties:
stable: true
in_place: false
online: false
deterministic: true
adaptive: false
parallel: "Θ(n) work-efficient merge gives Θ(log³ n) span" # free text, optional
history:
year: 1945
people: [john-von-neumann]
first: {source: "goldstine-von-neumann-1948", note: "described in a 1945 manuscript"}
prereqs: [recursion, asymptotic-notation, loop-invariant] # what to read first
same_as:
wikidata: Q332015
wikipedia: Merge_sort
dads: mergesort
cpalgorithms: null
rosetta: Sorting_algorithms/Merge_sort
math2: null
lean:
module: Algo.Sorting.MergeSort
model: Algo.Sorting.MergeSort.mergeSort # the executable model
spec: Algo.Sorting.SortingProblem.IsSort # from the problem
correct: Algo.Sorting.MergeSort.mergeSort_isSort
cost: Algo.Sorting.MergeSort.mergeSort_time_le # in TimeM
cslib: Cslib.Algorithms.MergeSort # an upstream declaration, when one exists
sources:
- {book: "isbn:9780262046305", locator: "CLRS 4e, Section 2.3"}
- {book: "isbn:9780321573513", locator: "Sedgewick–Wayne 4e, Section 2.2"}
- {url: "https://jeffe.cs.illinois.edu/teaching/algorithms/", locator: "Erickson, Chapter 1.4"}
exercises: [cses-1621, leetcode-912]
---
Rules:
complexityvalues are strings in a small grammar:Θ(...),O(...),Ω(...), exact counts, and the wordsamortized,expected,w.h.p..algo fmtnormalizes them, and audit rule E04 parses them. Each variable is defined invars. Each claim names its case:worst,average(with the input distribution in a note),best,amortizedorexpected(over the random choices of the algorithm).modelis the slug of amodelnode. A claim in another model goes incomplexity_in, a list of{model, time, space}.propertiesuses fixed keys for each kind, listed inschema/properties.v1.yaml. Sorting hasstable,in_place,adaptive,online. Graph algorithms havenegative_weights,directed,weighted. Data structures havepersistent,concurrent,external. The comparison tables of the site (14.5) read these keys.- Status fields do not exist. The build computes the ladders (4.8), and audit rule T05 rejects a status written by hand.
Conditions on solves. The short form solves: [sorting-problem] means "with no condition, under the bounds of complexity". An algorithm that is correct only under conditions, or whose bound depends on them, uses the long form:
# in nodes/graphs/shortest-paths/dijkstra/node.md
solves:
- problem: single-source-shortest-paths
requires: {negative_weights: false}
time: "O((n + m) log n)" # with a binary heap; optional, defaults to complexity.time.worst
- problem: single-source-shortest-paths
requires: {negative_weights: false, integer_weights: true, max_weight: "C"}
time: "O(m + nC)" # Dial's bucket queue
note: "with a bucket queue instead of a heap"
A problem node declares the keys that its algorithms may use, with their types, in constraints:
# in nodes/graphs/shortest-paths/single-source-shortest-paths/node.md
constraints:
weighted: {type: bool, default: true}
negative_weights: {type: bool, default: false}
directed: {type: bool, default: true}
acyclic: {type: bool, default: false}
integer_weights: {type: bool, default: false}
max_weight: {type: var, doc: "the largest absolute weight, C"}
n_max: {type: size}
m_max: {type: size}
- Each key of a
requiresis a key of the problem'sconstraints, or of a problem that itgeneralizes(rule G09 checks the coverage, and E04 parses the bounds). - A family of problems shares keys through
schema/properties.v1.yaml, sonegative_weightsmeans the same thing in every graph problem. - The constraint search of 15.4 reads only these fields.
4.5 Abstract types and data structures
An abstract-type node lists its operations with signatures and laws:
operations:
- {name: insert, sig: "(Q, key) -> Q"}
- {name: find_min, sig: "(Q) -> key?", law: "find_min(Q) = min(keys(Q))"}
- {name: delete_min, sig: "(Q) -> (key?, Q)"}
- {name: decrease_key, sig: "(Q, handle, key) -> Q", optional: true}
A data-structure node names the types it implements (implements: [priority-queue]) and gives the cost of each operation:
implements: [priority-queue]
operations:
insert: {time: "O(log n)"}
find_min: {time: "O(1)"}
delete_min: {time: "O(log n)"}
decrease_key: {time: "O(log n)"}
build: {time: "O(n)"}
The contract of a data structure is the contract of its abstract type: a test case is a sequence of operations with expected results (09.1).
4.6 Edges
Edges are typed fields of the front matter. The build derives the reverse edges. schema/edges.md defines each one.
| Edge | From → to | Meaning |
|---|---|---|
solves |
algorithm → problem | the algorithm meets the contract of the problem |
implements |
data-structure → abstract-type | the structure meets the laws of the type |
uses |
algorithm, data-structure → algorithm, data-structure | it calls or contains the target |
techniques |
algorithm, data-structure → technique | it is an instance of the technique |
variant_of |
algorithm → algorithm | it changes the target in a named way |
generalizes |
problem, algorithm → problem, algorithm | the target is a special case |
reduces_to |
problem → problem | a reduction, with its cost in a note |
lower_bound |
theorem → problem | the theorem bounds every algorithm for the problem in a model |
proves |
theorem → algorithm, problem | the theorem is about the target |
prereqs |
any → any | read the target first; it forms the reading DAG (05.6) |
model |
algorithm, theorem → model | the model of the cost claims |
exercises |
algorithm, technique, data-structure → exercise | practice for the target |
people |
any → person | found, named or improved it |
uses_math |
any → math2 node | a mathematical prerequisite in math2 |
see_also |
any → any | a related page, at most 8 |
Audit rules G01–G08 check the graph: no cycle in prereqs, variant_of or generalizes; each solves target is a problem; each implements target is an abstract type; each node of the core has at least one prereqs path from a foundation node (13.3).
4.7 Provenance
Each file in a node directory has a record in prov/<tag>.jsonl, one line per change: the date, the file, the operation, the author (a person's GitHub login or an agent run id), the reviewer when there is one, and the source ids that the change used. algo prov writes it from the commit and the run record. The page shows it under "History" (14.4), as in math2.
4.8 The computed ladders
The build computes five ladders for each node that can have them. No person and no agent writes them (rule T05).
H. Human proof (for algorithms, data structures and theorems)
| Level | Meaning |
|---|---|
| H0 | no proof |
| H1 | a sketch: the main idea, marked as a sketch |
| H2 | a full proof of correctness and of each complexity claim of the front matter, to the standard of 06.5 |
| H3 | H2, and a person who is not the author reviewed this exact proof hash |
L. Lean (07.8)
| Level | Meaning |
|---|---|
| L0 | no Lean part |
| L1 | the spec and the executable model exist, and the spec is reviewed against the problem text (fidelity) |
| L2 | the correctness theorem is proved: no sorry, only the standard axioms |
| L3 | L2, and each time and space claim of the front matter is proved in the cost model |
| L4 | L3, and an implementation is proved to refine the model (the Rust one through Aeneas, 07.6) |
I. Implementation (for each language, 08.8)
| Level | Meaning |
|---|---|
| I0 | no implementation |
| I1 | it builds with no warnings and passes the shared cases of the contract |
| I2 | I1, and it passes the random and the adversarial differential tests against the oracle, and its tests kill at least 85% of the mutants (09.6) |
| I3 | I2, and lint and format are clean, the complexity check passes (09.7), and the code follows the conventions of 08.3 |
| I4 | I3, and a person reviewed this exact file hash |
V. Visualization (10.9)
| Level | Meaning |
|---|---|
| V0 | none |
| V1 | static figures or frames only |
| V2 | an interactive scene with step back, custom input and code sync, that passes the trace checks |
| V3 | V2, and a person reviewed it for clarity and accessibility |
W. Writing (06.8): W0 stub to W5 complete, as in math2's writing levels.
A node is complete when it has H3, L3, I3 in each tier-1 language, I2 in each tier-2 language, V2 and W4. The badges of the site (13.1) and the coverage levels (16.2) are computed from these ladders.
A review counts only for the hash that it reviewed. When the proof, the Lean statement or the file changes, the review stops counting and the level drops until a new review, as in math2.
4.9 Prohibitions
- No status, level or badge in front matter (T05).
- No copied text or code from a source whose licence forbids it (11.5, rule C01).
- No implementation that imports a package outside the standard library of its language (08.4, rule I07).
- No
sorry,admit,native_decideor new axiom in a module that a node cites as proved (07.5, rule L03). - No complexity claim without a model and defined variables (E04).
- No model-written statement of a problem contract that no person has reviewed, for the core (09.1, rule S06).