DKE Library — Specification
Version: 1.0.5, changed in rev 171 · alpha · API 1.5 · rev 171
Status: Published normative specification of the DKE Library.
Audience: Customers who load facts into a DKE store and reason over them; authors of fact producers, whether they use our package or write their own.
This document as Markdown: dke-library-spec.md — the same text this page is rendered from, for the producer authors above who would rather read the source than the page.
1. Status and scope
This specification is normative for the library — the code LangSyn publishes for you to use, as opposed to the language you write or the wire you send it over. Two artifacts are in scope, and they are two halves of one story:
| Artifact | What it is | Where it is served |
|---|---|---|
Reasoning modules (.dpy) |
DKE Python programs that supply the reasoning — a kind schema, standing rules, and queries | https://, one path per module |
dkepy (Python package) |
The package that writes the facts those modules reason over | https:// |
dkekey, the key tool served beside them at https://, is not specified here: the store key it issues is specified by MCP Reference §3.1, which dke. in dkepy implements too.
A module supplies the reasoning; a producer supplies the facts. Neither is useful without the other, and the thing that binds them — the vocabulary they must agree on — belongs to neither and is specified in §5.
What is normative here and what is not. The Library Reference describes what the published modules and dkepy contain and stands on its own authority as a description. This document states the same surface as a contract: what you may depend on, what may change under you, and what a conformant producer must do. Where the two disagree, this document governs.
Names are English. Every kind name, field name, rule name and query name below is written in English, as the library’s identifiers are. This is a separate question from the language parameter of the wire, which selects the keyword surface of the program you send and is specified in the MCP Reference.
Out of scope. The DKE Python language itself (Python Specification); the wire protocol (MCP Reference); the contents of your store, which are yours.
1.1 Conformance language
MUST / MUST NOT state a requirement; violating one is an error, though not always one a machine catches — §5.4 says exactly which are checked. SHOULD states a strong recommendation with a stated cost for departing. MAY states a permission. A conformant producer is any program that writes facts a published module reasons over, whether or not it uses dkepy.
3. Reasoning modules
3.1 What a module may declare
Five declaration forms, all of which become part of your store the moment you import the module:
| Declaration | Written by | Normative note |
|---|---|---|
| Class | the module | Declares a kind and its fields. |
| Derived field | the module | A field whose value is an expression over other fields of the same kind. |
| Standing rule | the module | Concludes one field about the subjects it binds. |
| Standing constraint | the module | A condition over your facts. checkup reports each subject that breaks it; it refuses no write. |
| Query | the module | A def you call by name, answering over the facts you have loaded. |
A module MUST NOT contain anything else that persists. Module semantics in general — how import resolves, how namespacing works, what re-submitting does — are the language’s, in the Python Reference §9.
Every standing rule in code ranges over one kind. The language allows more — a rule may bind subjects of several kinds and relate them (Python Reference §8.8) — but code asks each of its questions of a field on the subject being asked about. That is why several fields in §3.3 look redundant: an observation another kind also records is recorded again on the side that reads it.
3.2 The published modules
Twenty-four modules are published, each served at https:// under its version, with a latest alias:
| Module | Reasons about | Specified in |
|---|---|---|
code |
a codebase | §3.3 through §3.6 |
identity |
which of your records name the same thing | §3.7 through §3.9 |
argument |
which of your claims stand, given what supports and attacks what | §3.10 through §3.12 |
agenda |
what is overdue, coming up, late or forbidden among your commitments and obligations | §3.13 through §3.15 |
quantum |
quantum circuits: simulating one, which gates a device cannot run as written, and whether a result computed outside the store still holds | §3.16 through §3.18 |
pqc |
which uses of quantum-vulnerable cryptography to move first, and which miss a deadline | §3.19 through §3.22 |
harmony |
four-part writing as a harmony teacher marks it, the rhythm of a melody against its bars, and the arithmetic of tuning, set classes, twelve-tone rows and even rhythms | §3.23 through §3.26 |
physics |
quantities in their units, the dimensions of equations and resistors in series and parallel, and the calculation of classical motion, heat, circuits and a magnet | §3.27 through §3.30 |
chemistry |
the hydrogens, formula, weight and functional groups of a molecule drawn as atoms and bonds, a reaction’s enthalpy by Hess’s law, and the calculation of formulas, balanced equations, pH and kinetics | §3.31 through §3.34 |
biology |
what a metabolic network can make from its medium, ancestry, carriers and what a mode of inheritance cannot explain in a pedigree, and the calculation of the genetic code, crosses, populations, drift and repressor rings | §3.35 through §3.37 |
astronomy |
which stars never set, never rise or can be seen from a site, which bookings an instrument can observe given the night and the star’s time above the horizon, and the calculation of Julian dates, sidereal time, rising and setting, the Sun, day length and orbits | §3.38 through §3.41 |
geography |
regions inside regions, which regions neighbour which and which neighbours share a colour, which places lie in which boxes of latitude and longitude, and the calculation of distances, bearings, projections and areas on the Earth | §3.42 through §3.44 |
mathematics |
whole numbers by their divisors, finite operations by their tables, and triangles by their sides, and the calculation of number theory, counting, continued fractions and numerical methods | §3.45 through §3.48 |
statistics |
the strata of a study and whether pooling them reverses what each shows, screening tests by what a positive result is worth, and significance tests, and the calculation of descriptive statistics, distributions, tests and a seeded generator | §3.49 through §3.52 |
earthscience |
the climate group of a weather station, the category of a storm by its wind and which of two minerals scratches the other, and the calculation of the atmosphere and the solid Earth | §3.53 through §3.56 |
computing |
whether the words of a binary code can be read without a separator, and the calculation of checksums, check digits, number bases, error-correcting codes, entropy, Huffman codes and shortest paths | §3.57 through §3.60 |
calendars |
which years are leap years under the Julian and the Gregorian rule and which the two disagree about, how many days a calendar reform skipped and which days fall in its gap, and the calculation of month lengths, weekdays, Easter, day numbers and spans | §3.61 through §3.64 |
colour |
which contrast levels a colour pair clears and whether a ray is totally reflected, and the calculation of luminance, contrast, hue, refraction, lenses, Wien’s law and frequency | §3.65 through §3.68 |
body |
which antigens a donor’s blood group has that a recipient’s lacks and what that means for a transfusion, the band of a body mass index, and the calculation of the index, resting energy, body surface and maximum heart rate; not medical advice | §3.69 through §3.72 |
sound |
whether a noise exposure or a worker’s day is over a limit and whether a frequency is audible, and the calculation of decibels, distance, the speed of sound, wavelength, the Doppler shift and a time-weighted average; not occupational-health advice | §3.73 through §3.76 |
finance |
which of several loan offers costs the least in total and which carry a payment over a household’s limit, and the calculation of payments, compound interest, effective rates, doubling time, present value and real rates; not financial advice | §3.77 through §3.80 |
food |
whether a dish was cooked to the minimum internal temperature of its kind or held too long in the danger zone and which of the nine major allergens it holds, and the calculation of a recipe’s scale, baker’s percentages, mass of a volume and food energy; not food-safety or medical advice | §3.81 through §3.83 |
architecture |
which style a building’s features make, which structure and which building was the tallest when it was completed, whether a tower tips, a hull is unstable, a room rings too long or too short and a channel falls too little, and the calculation of a lean, Sabine’s reverberation time, a hull’s metacentric height, a gradient and a pendulum; not engineering, naval-architecture, acoustic-design or heritage advice | §3.84 through §3.87 |
elections |
who wins an election under plurality, majority, the Condorcet method and the Borda count, whether no candidate beats every other head to head and whether a count is disputed, an instant-runoff count, and the calculation of the Hare and Droop quotas and of a house’s seats by largest remainders and by the D’Hondt, Sainte-Lague and Huntington-Hill methods; not legal or electoral advice | §3.88 through §3.91 |
code reasons about whatever codebase you load. It describes no particular one, and it ships no facts.
3.3 code — declared fields
A producer writes these. Fields marked absence-read are governed by §2.4.
Function
| Field | Class | Notes |
|---|---|---|
name |
string |
|
module |
string |
A path. It hints at language at best; no query may rely on it for that. |
lines |
int |
|
branches |
int |
What counts as a branch is the producer’s decision, so two producers MAY disagree on scale. |
loops |
int |
|
deprecated |
bool |
Typically supplied by hand rather than by a producer. |
language |
string |
Optional, absent-tolerant. What makes a polyglot store sliceable, and what makes two producers distinguishable. |
test |
string |
Absence-read. A test seen to reach this function. Reaching is not executing: this is not a coverage measurement. |
returns_ignored |
int |
Calls whose return value is not bound, tested, or handed onward. |
called |
bool |
Absence-read. Recorded on the callee’s side as well as in a Call, so uncalled reads a field of the function itself (§3.1). |
callers |
int |
Distinct callers, not call sites. Write it for every function including zero — it is read by comparison, not by absence. |
callees |
int |
Distinct callees. Same rule as callers. |
explained |
bool |
Absence-read. A reason was written down; see Rationale. |
Class — name: string, module: string, methods: int, language: string (optional, as on Function).
Call — caller: string, callee: string, site: string.
callerandcalleeMUST hold the subject of aFunction, never its display name. The queries compare; they cannot tell a name from a subject. A display name here makes every function look uncalled, and nothing reports an error.
UnresolvedCall — caller: string (a Function subject), site: string, text: string (the callee as written).
A call whose target could not be named. No edge is asserted here, and a producer MUST NOT assert one. A missing edge is a known gap; a guessed edge is a wrong answer the queries cannot tell from a fact. Absent-tolerant: record none and everything else works, with
dispatch_sites()returning nothing.
Rationale — subject: string (the Function or Class it explains), marker: string, text: string, site: string.
Stated, never inferred. Which comments count is the producer’s decision. Whatever convention is chosen, it SHOULD be one an author had to type on purpose: a convention wide enough to sweep ordinary comments turns every line into a fact and the query into noise.
Import — importer: string, imported: string, root: string.
Dependency — name: string, version: string, direct: bool, pinned: bool.
Counterpart — name: string, left: string, right: string, relation: string, left_covers: int, right_covers: int.
Two functions that have to agree. Stated, never inferred — agreement is a claim about intent and no call graph can see it.
relationnames what is being counted, because it differs per pair;left_coversandright_coverscount members of that set and are comparable to each other and to nothing else. This is the one kind no producer LangSyn publishes writes (§5.2).
3.4 code — derived fields
Maintained by the engine. A producer MUST NOT write one.
| Field | Definition |
|---|---|
Function. |
branches + loops + 1 |
Counterpart. |
left_covers - right_covers |
Counterpart. |
right_covers - left_covers |
Both directions of the gap are kept, each reading as a positive magnitude where it applies, because a query cannot negate a claim’s value.
3.5 code — standing rules
Each holds continuously: its conclusion is in force exactly while its condition holds over your data, and withdraws itself when the condition stops holding.
| Rule | Over | Concludes | While |
|---|---|---|---|
hotspot |
Function |
hotspot |
complexity > 10 |
oversized |
Function |
oversized |
lines > 200 |
sprawling_class |
Class |
sprawling |
methods > 20 |
hub |
Function |
hub |
callers > 5 |
untested |
Function |
untested |
lines > 0 and test absent |
uncalled_fn |
Function |
uncalled |
lines >= 0 and called absent |
critical_untested |
Function |
critical_untested |
complexity > 10 and test absent |
unexplained_critical |
Function |
unexplained_critical |
complexity > 10, test absent, explained absent |
discards_result |
Function |
discards_result |
returns_ignored > 0 |
left_stricter |
Counterpart |
left_stricter |
gap > 0 |
right_stricter |
Counterpart |
right_stricter |
gap < 0 |
Two notes that are contract rather than commentary:
- The thresholds are values, not percentiles.
> 10,> 200,> 20,> 5select whatever your store has, and select nothing when your store has nothing. A percentile would always name someone, including in a codebase with no hub at all. They are yours to argue with; they are not adaptive. - A rule cannot be all absences.
untestedanduncalled_fncarry a positive premise (lines > 0,lines >= 0) as a range, not a filter — a rule whose every premise is an absence has no set to work over and is refused.
3.6 code — queries
Called by name after import code. Every one answers over the facts you have loaded, and over nothing else.
| Query | Answers |
|---|---|
callers_of(fn) |
Functions that call fn, directly. |
callees_of(fn) |
Functions fn calls, directly. |
impact_of(fn) |
Who breaks if fn changes: callers, and their callers, to depth 3. |
importers_of(mod) |
Modules importing mod. |
functions_in(lang) |
Functions recorded with language = lang. |
hotspots_in(lang) |
Hotspots, narrowed to one language. |
uncalled() |
Functions nothing was seen to call. |
hubs() |
Functions many things depend on. |
rationale_for(fn) |
Reasons recorded against fn. |
unexplained() |
Critical functions carrying no recorded reason. |
dispatch_sites() |
Calls whose target could not be named. |
unused_dependencies() |
Declared dependencies nothing imports. |
unpinned_dependencies() |
Dependencies with no pin. |
asymmetries() |
Counterpart pairs where one side checks more. |
discarded_results() |
Functions throwing a result away. |
critical() |
Complicated and unreached. |
impact_of walks to a fixed depth, not until nothing new is reached. That is a stated bound, not an approximation to be improved: the language guarantees termination and a reachability closure is not something it will run.
An empty answer is an answer. It means no loaded fact satisfies the question — which is different from the question being unanswerable, and different again from the field being empty because nobody wrote it. §4.4.
3.7 identity — declared fields
You write these; no producer in dkepy writes them.
Record
| Field | Class | Notes |
|---|---|---|
name |
string |
For reading. No rule reads it: a name a statement uses is a record whether or not one is recorded here. |
Same, Possibly, Different — each a statement, with a: string and b: string holding the names of the two records it is about. A statement’s own name carries no meaning and only keeps two statements apart.
Names are matched exactly. A name a statement uses and no Record carries is not an error: it is a record to every rule below. unrecorded() (§3.9) lists such names.
3.8 identity — standing rules
Each holds continuously: its conclusion is in force exactly while its condition holds over your data, and withdraws itself when the condition stops holding. Four rules conclude a relation, a three-segment path read as SameEntity., rather than a field.
| Rule | Over | Concludes | While |
|---|---|---|---|
same_stated |
Same, Record |
SameEntity |
a statement’s a names x and its b names y; concludes SameEntity. |
same_stated_back |
Same, Record |
SameEntity |
the same statement; concludes SameEntity. |
same_further |
Record |
SameEntity |
SameEntity. and SameEntity.; concludes SameEntity. |
possibly_stated |
Possibly, Record |
PossiblySame |
a statement’s a names x and its b names y; concludes PossiblySame. |
possibly_stated_back |
Possibly, Record |
PossiblySame |
the same statement; concludes PossiblySame. |
contradicted |
Different, Record |
contradicted |
the statement’s a and b name x and y, and SameEntity. holds |
contested_a |
Different, Record |
contested |
a contradicted statement’s a names the record |
contested_b |
Different, Record |
contested |
a contradicted statement’s b names the record |
Four notes that are contract rather than commentary:
- The relations are not namespaced.
SameEntityandPossiblySameare read by those bare names in every unit, and are neveridentity.. A unit that declares aSameEntity classof either name reads its own class by that name. SameEntityis closed;PossiblySameis not. A record in any chain ofSamestatements is related to every record the chain reaches, itself included. A possibility relates exactly the two records a statement names.- A
Differentstatement withdraws nothing. It and everySamestatement it contradicts stand together; the contradiction is concluded, not resolved. - The closure is quadratic in an entity. An entity of n records holds n²
SameEntityconclusions.
3.9 identity — queries
Called by name after import identity. Every one answers over the facts you have loaded, and over nothing else.
| Query | Answers |
|---|---|
same_as(r) |
Every other record SameEntity relates to r. |
possibly_same_as(r) |
Every other record PossiblySame relates to r. |
contested() |
Records named by a contradicted statement. |
contradictions() |
Different statements concluded contradicted, by name. |
unrecorded() |
Names a statement uses that no Record carries. |
3.10 argument — declared fields
You write these; no producer in dkepy writes them.
Claim
| Field | Class | Notes |
|---|---|---|
text |
string |
For reading. No rule reads it: a name a statement uses is a claim whether or not one is recorded here. |
Support, Attack, Weakening — each a statement, with by: string naming the claim that supports, attacks or weakens, and target: string naming the claim it bears on. A statement’s own name carries no meaning and only keeps two statements apart. A statement bears on nothing until both fields are written.
Names are matched exactly. A name a statement uses and no Claim carries is not an error: it is a claim to every rule below. unrecorded() (§3.12) lists such names.
3.11 argument — standing rules
Each holds continuously: its conclusion is in force exactly while its condition holds over your data, and withdraws itself when the condition stops holding.
| Rule | Over | Concludes | While |
|---|---|---|---|
attack_reaches |
Attack, Claim |
attacked |
an attack’s by names a claim and its target names this one |
weakening_reaches |
Claim, Weakening |
weakened |
a weakening’s by names a claim and its target names this one |
nothing_attacks |
Claim |
unattacked |
no attack with a by names this claim as its target |
attack_stands |
Attack, Claim |
undefended |
an attack targets this claim, and the claim its by names is unattacked |
attack_answered |
Attack, Claim |
answered |
the claim this attack’s by names is undefended; concluded on the attack |
every_attack_answered |
Claim |
reinstated |
this claim is attacked, and every attack with a by that targets it is answered |
premise_attacked |
Claim, Support |
contested |
the claim a support’s by names is attacked, and its target names a claim; concluded on the support |
Four notes that are contract rather than commentary:
- Two steps, then silence. A claim is
unattacked,undefendedorreinstated, or it is named by none of the three: it is open. Claims that attack one another, and the claims such a chain reaches, are open. No answer says an open claim falls. - A weakening decides nothing. It concludes
weakenedand takes part in no other rule. - A support is not a defence. It takes part only in
premise_attacked. - No relation is concluded. Every field
argumentderives is on one of its own kinds.
3.12 argument — queries
Called by name after import argument. Every one answers over the facts you have loaded, and over nothing else. Each answers a sorted list of names.
| Query | Answers |
|---|---|
supporters_of(c) |
The by of every Support whose target is c. |
attackers_of(c) |
The by of every Attack whose target is c. |
weakeners_of(c) |
The by of every Weakening whose target is c. |
unattacked() |
Claims concluded unattacked. |
undefended() |
Claims concluded undefended. |
reinstated() |
Claims concluded reinstated. |
weakened() |
Claims concluded weakened. |
contested_premises() |
The by of every Support concluded contested. |
unrecorded() |
Names a statement uses that no Claim carries. |
3.13 agenda — declared fields
You write these; no producer in dkepy writes them.
Goal
| Field | Class | Notes |
|---|---|---|
text |
string |
For reading. No rule reads it: a name a commitment serves is a goal whether or not one is recorded here. |
Commitment
| Field | Class | Notes |
|---|---|---|
action |
string |
What is undertaken. Compared exactly with a prohibition’s action. |
due |
datetime |
When it is due. A later update from the same source replaces it and keeps the value it replaced. |
serves |
string |
The goal it is for. Optional. |
done_at |
datetime |
When it was done. Absent while it is open. |
Obligation
| Field | Class | Notes |
|---|---|---|
action |
string |
What is owed. Compared exactly with a prohibition’s action. |
due |
datetime |
When it is due, as for a commitment. |
owed_to |
string |
Who it is owed to. For reading; no rule reads it. |
done_at |
datetime |
When it was done. Absent while it is open. |
Prohibition
| Field | Class | Notes |
|---|---|---|
action |
string |
An action that may not be taken. The claim’s validity window, if it has one, is when the prohibition applies. |
Names are matched exactly. A name a commitment serves and no Goal carries is not an error: it is a goal to every rule below. unrecorded() (§3.15) lists such names.
3.14 agenda — standing rules
Each holds continuously: its conclusion is in force exactly while its condition holds over your data, and withdraws itself when the condition stops holding.
| Rule | Over | Concludes | While |
|---|---|---|---|
commitment_forbidden |
Commitment, Prohibition |
forbidden |
the commitment’s action equals a prohibition’s action; valid where the two claims’ windows overlap |
obligation_forbidden |
Obligation, Prohibition |
forbidden |
the obligation’s action equals a prohibition’s action; valid where the two claims’ windows overlap |
commitment_late |
Commitment |
late |
the commitment’s done_at is later than its due |
obligation_late |
Obligation |
late |
the obligation’s done_at is later than its due |
goal_pursued |
Commitment, Goal |
pursued |
a commitment’s serves names the goal |
goal_met |
Goal |
met |
the goal is pursued, and no commitment serving it lacks a done_at |
Two standing constraints are reported by checkup and refuse no write. nothing_forbidden_committed is violated by each Commitment that is forbidden and has no done_at, and nothing_forbidden_owed by each such Obligation.
Four notes that are contract rather than commentary:
- No rule reads the present. Every rule compares recorded values with each other. What depends on the time is a query, and takes the time as
at. - A prohibition is not enforced. It concludes
forbiddenand violates a constraint; it removes and refuses nothing. lateneeds both dates. An item with nodone_at, or nodue, is neverlate, whatever the time.- No relation is concluded. Every field
agendaderives is on one of its own kinds.
3.15 agenda — queries
Called by name after import agenda. Every one answers over the facts you have loaded, and over nothing else. Each answers a sorted list except previous_dues, which keeps the order the dates were given. A commitment is named Commitment.<name> and an obligation Obligation.<name>. An item is open at at when it has no done_at, or its done_at is later than at.
| Query | Answers |
|---|---|
overdue(at) |
Commitments and obligations open at at whose due is earlier than at. |
due_within(at, span) |
Commitments and obligations open at at whose due is at or after at and earlier than at + span. |
unsettled(at) |
Commitments and obligations whose due or done_at holds two values in force at at. overdue and due_within omit these. |
forbidden(at) |
Commitments and obligations open at at and concluded forbidden at at. |
blocked() |
Commitments and obligations with no done_at whose due holds one value, at which they are concluded forbidden. |
late() |
Commitments and obligations concluded late. |
met() |
Goals concluded met, by name. |
serving(g) |
Commitments whose serves is g. |
previous_dues(item) |
The due values item held before the one in force now, oldest first, as RFC 3339 text. Empty when the item’s due holds two values in force. |
unrecorded() |
Names a commitment serves that no Goal carries. |
3.16 quantum — declared fields
quantum has two halves that share nothing but the subject. The simulation half declares one kind, State, and is otherwise functions over values (§3.18). The reasoning half declares the rest. dke. (§4.5) writes Device, PhysicalQubit and Native; dke. writes Result and a circuit’s digest; the module records its own Op facts when it is imported. You write the rest.
State
| Field | Class | Notes |
|---|---|---|
amplitudes |
blob |
A state’s amplitudes in index order, sixteen bytes each: a complex as two little-endian IEEE 754 doubles. Written by save and keep (§3.18). |
Gate
| Field | Class | Notes |
|---|---|---|
op |
string |
The operation, named as an Op subject is: h, cnot, rz. |
a |
string |
The qubit it acts on, by name. A compiled circuit names a qubit by its number, as text. |
b |
string |
The second qubit of a two-qubit gate. Absent for a one-qubit gate. |
step |
int |
Its position. Gates are ordered by step within one circuit. |
circuit |
string |
The Circuit it belongs to. Optional: the gates that name none are one circuit together. |
Qubit
| Field | Class | Notes |
|---|---|---|
label |
string |
For reading. No rule reads it: the rules compare the names gates use. |
Coupler
| Field | Class | Notes |
|---|---|---|
a |
string |
One qubit of a pair the chip can act on together. |
b |
string |
The other. A coupler joins its pair in either order. |
Op
| Field | Class | Notes |
|---|---|---|
qubits |
int |
How many qubits the operation takes. |
diagonal |
bool |
Whether it is diagonal. Diagonal operations commute with one another. |
The module records qubits and diagonal for h, x, y, z, s, t, rx, ry, rz, cnot, cz, sx, id, ecr, swap and rzz when it is imported, under the source quantum. Record another operation the same way.
Device
| Field | Class | Notes |
|---|---|---|
qubits |
int |
How many physical qubits it has. |
snapshot_at |
datetime |
When the calibration snapshot its facts were read from was taken. |
digest |
string |
The snapshot’s digest (§4.5), which names the calibration exactly. |
PhysicalQubit
| Field | Class | Notes |
|---|---|---|
device |
string |
The Device it belongs to. |
index |
string |
Its number, as text, which is how a compiled circuit’s gates name it. |
t1 |
real |
Its relaxation time, in microseconds. |
t2 |
real |
Its dephasing time, in microseconds. |
readout_error |
real |
The probability that reading it out gives the wrong value. |
measured_at |
datetime |
When the latest of those three was measured. |
Native
| Field | Class | Notes |
|---|---|---|
device |
string |
The Device that runs it. |
op |
string |
The operation, as the module names it: cnot where a device says cx. |
a |
string |
The qubit it runs on, or the first of an ordered pair, by index. |
b |
string |
The second of the pair. Absent for a one-qubit operation. The pair is ordered, because a device may run a two-qubit operation one way round only. |
error |
real |
The measured probability that it fails. |
length |
real |
Its duration, in nanoseconds. |
measured_at |
datetime |
When error was measured. Absent when no error is recorded. |
Circuit
| Field | Class | Notes |
|---|---|---|
device |
string |
The Device it was compiled for. Optional: a circuit that names none is judged by no device rule. |
digest |
string |
The digest of the text it was written from (§4.5). The writer keeps it true; the store compares digests and never computes one. |
Result
| Field | Class | Notes |
|---|---|---|
circuit |
string |
The circuit the result is about. |
digest |
string |
That circuit’s digest, as the result’s producer read it. |
source |
string |
The circuit it was derived from, if any. |
source_digest |
string |
That circuit’s digest, as read. |
device |
string |
The device it was computed for, if any. |
device_digest |
string |
That device’s digest, as read. |
producer |
string |
What produced it, with its version. No rule reads it. |
settings |
string |
How the producer was asked. No rule reads it. |
seed |
int |
The seed it drew from. No rule reads it. |
outcome |
string |
The result itself, as text. |
Names are matched exactly. A qubit is compared by its name and is never bound as a subject, since a compiled circuit names its qubits by number.
3.17 quantum — standing rules
Each holds continuously: its conclusion is in force exactly while its condition holds over your data, and withdraws itself when the condition stops holding. The rules over two gates relate only gates of one circuit: a gate’s circuit is its track, and the gates that name no circuit share the empty track.
| Rule | Over | Concludes | While |
|---|---|---|---|
gate_diagonal |
Gate, Op |
diagonal |
the gate’s op names the operation; the gate takes the operation’s diagonal |
track_of_circuit |
Gate |
track |
the gate names a circuit, which is its track |
track_of_none |
Gate |
track |
the gate has a step and names no circuit; its track is the empty string |
shares_earlier_aa |
Gate |
RunsBefore |
two gates on one track, the first’s a equal to the second’s a, and the first’s step earlier |
shares_earlier_ab |
Gate |
RunsBefore |
as shares_earlier_aa, with the first’s a equal to the second’s b |
shares_earlier_ba |
Gate |
RunsBefore |
as shares_earlier_aa, with the first’s b equal to the second’s a |
shares_earlier_bb |
Gate |
RunsBefore |
as shares_earlier_aa, with the first’s b equal to the second’s b |
ordered_first |
Gate |
MustPrecede |
the first gate runs before the second, and the first is not diagonal |
ordered_second |
Gate |
MustPrecede |
the first gate runs before the second, and the second is not diagonal |
commutes |
Gate |
CommutesWith |
the first gate runs before the second, and both are diagonal |
uncoupled |
Gate, Op |
uncoupled |
a two-qubit gate with no device, whose two qubits no Coupler joins in either order |
gate_device |
Gate, Circuit |
device |
the gate’s circuit names the circuit; the gate takes the circuit’s device |
gate_width |
Gate, Op |
width |
the gate’s op names the operation; the gate takes the operation’s qubits |
op_on_device |
Gate, Native |
op_on_device |
the gate’s device runs its op natively on some qubit or pair |
first_on_device |
Gate, PhysicalQubit |
first_on_device |
the gate’s device has a physical qubit whose index is the gate’s a |
second_on_device |
Gate, PhysicalQubit |
second_on_device |
the gate’s device has a physical qubit whose index is the gate’s b |
runs_as_one |
Gate, Native |
RunsAs |
a one-qubit gate, and a native operation of its device with the same op on its a |
runs_as_pair |
Gate, Native |
RunsAs |
a native operation of the gate’s device with the same op on the same ordered pair |
off_device_first |
Gate, Device |
off_device |
the gate’s device has no physical qubit whose index is the gate’s a |
off_device_second |
Gate, Device |
off_device |
a two-qubit gate whose device has no physical qubit whose index is the gate’s b |
not_native |
Gate, Device |
not_native |
the gate’s device runs its op on no qubit at all |
not_here_one |
Gate |
not_here |
a one-qubit gate whose device runs its op and has its qubit, but does not run that operation on that qubit |
not_here_pair |
Gate |
not_here |
a two-qubit gate whose device runs its op and has both its qubits, but runs it on that pair in neither order |
reversed_pair |
Gate, Native |
reversed |
the gate’s device runs its op on its pair the other way round, and not this way |
illegal_off_device |
Gate |
illegal |
the gate is off_device |
illegal_not_native |
Gate |
illegal |
the gate is not_native |
illegal_not_here |
Gate |
illegal |
the gate is not_here |
illegal_reversed |
Gate |
illegal |
the gate is reversed |
circuit_current |
Result, Circuit |
circuit_current |
the result’s digest equals the digest of its circuit |
source_current |
Result, Circuit |
source_current |
the result’s source_digest equals the digest of its source |
source_none |
Result |
source_current |
the result has an outcome and names no source |
device_current |
Result, Device |
device_current |
the result’s device_digest equals the digest of its device |
device_none |
Result |
device_current |
the result has an outcome and names no device |
holds |
Result |
holds |
circuit_current, source_current and device_current all hold and the result is not stopped; concludes the result’s outcome |
unrecorded_circuit |
Result |
unrecorded |
the result has an outcome and no circuit |
unrecorded_outcome |
Result |
unrecorded |
the result names a circuit and has no outcome |
unrecorded_digest |
Result |
unrecorded |
the result names a circuit and has no digest |
unrecorded_source_digest |
Result |
unrecorded |
the result names a source and has no source_digest |
unrecorded_device_digest |
Result |
unrecorded |
the result names a device and has no device_digest |
circuit_unknown |
Result |
circuit_unknown |
no Circuit the result names as its circuit has a digest |
circuit_changed |
Result, Circuit |
circuit_changed |
the result’s digest differs from the digest of its circuit |
source_unknown |
Result |
source_unknown |
no Circuit the result names as its source has a digest |
source_changed |
Result, Circuit |
source_changed |
the result’s source_digest differs from the digest of its source |
device_unknown |
Result |
device_unknown |
no Device the result names has a digest |
recalibrated |
Result, Device |
recalibrated |
the result’s device_digest differs from the digest of its device |
stopped_unrecorded |
Result |
stopped |
the result is unrecorded |
stopped_circuit_unknown |
Result |
stopped |
the result is circuit_unknown |
stopped_circuit_changed |
Result |
stopped |
the result is circuit_changed |
stopped_source_unknown |
Result |
stopped |
the result is source_unknown |
stopped_source_changed |
Result |
stopped |
the result is source_changed |
stopped_device_unknown |
Result |
stopped |
the result is device_unknown |
stopped_recalibrated |
Result |
stopped |
the result is recalibrated |
Two standing constraints are reported by checkup and refuse no write. every_pair_coupled is violated by each Gate that is uncoupled, and every_gate_legal by each Gate that is illegal.
Five notes that are contract rather than commentary:
- Four relations are concluded.
RunsBefore,MustPrecedeandCommutesWithrelate two gates, the earlier first, andRunsAsrelates a gate to the native operation it runs as. Every other conclusion is a field of aGateor aResult. The queries of §3.18 read the relations. - A gate is judged by one set of rules. A gate whose circuit names a device is judged by the device’s own qubits and operations, and
uncouplednever holds for it. A gate whose circuit names no device is judged by the couplers alone. - A device with no facts runs nothing. A circuit naming a device the store holds no facts for has every gate
off_deviceandnot_native, which is also how a misspelt device name shows itself. - A digest holding two values holds the result through neither. When two sources disagree about a digest, every comparison with the other value concludes its reason, and the result does not hold.
- No rule reads the present. What depends on the time is a query, and takes the time as
at.
3.18 quantum — queries
Called by name after import quantum. Qubit q is bit q of an amplitude’s index, so qubit 0 is the lowest bit; a state of n qubits is a list<complex> of 2ⁿ amplitudes. A step, as advance, advance_chacha, overlap, clifford, rev_code, rev_same and rev_meets take one, is a tuple of a gate’s name, the qubits it acts on and an angle that only the rotations read, or ("measure", [q], 0.0); a reversible circuit’s steps are x, cnot, ccx, z, cz, ccz, swap and cswap, with a theta of 0.0, and ("mx", [q], 0.0), which measures q in the X basis and leaves it 0, with the controlled forms x_if, cnot_if, ccx_if, z_if, cz_if, ccz_if, swap_if and cswap_if, which take the measured qubit first and then the gate’s own qubits.
The functions over a state read and write no fact:
| Query | Answers |
|---|---|
zero(n) |
The all-zero state on n qubits. |
phase(theta) |
e raised to i·theta, as cos(theta) + i·sin(theta). |
h(psi, q) |
psi after a Hadamard gate on qubit q. |
x(psi, q) |
psi after an X gate on qubit q. |
y(psi, q) |
psi after a Y gate on qubit q. |
z(psi, q) |
psi after a Z gate on qubit q. |
s(psi, q) |
psi after an S gate on qubit q. |
t(psi, q) |
psi after a T gate on qubit q. |
rx(psi, q, theta) |
psi after a rotation of theta radians about X on qubit q. |
ry(psi, q, theta) |
psi after a rotation of theta radians about Y on qubit q. |
rz(psi, q, theta) |
psi after a rotation of theta radians about Z on qubit q. |
cnot(psi, c, tg) |
psi after a controlled NOT with control c and target tg. |
cz(psi, a, b) |
psi after a controlled Z on a and b. |
sx(psi, q) |
psi after the square root of X on qubit q. |
ecr(psi, a, b) |
psi after an echoed cross-resonance gate, with Qiskit’s matrix and a as its first qubit. |
swap(psi, a, b) |
psi with qubits a and b exchanged. |
ccx(psi, a, b, tg) |
psi after a Toffoli gate: qubit tg flips when a and b are both 1. |
ccz(psi, a, b, c) |
psi after a gate that negates the amplitudes whose qubits a, b and c are all 1. |
cswap(psi, c, a, b) |
psi after a Fredkin gate: qubits a and b exchanged when c is 1. |
probabilities(psi) |
The probability of each basis state, in index order. |
weights(psi, q) |
The probability of qubit q being 0 and of its being 1, each summed in index order. |
collapsed(psi, q, bit, norm) |
The amplitudes whose qubit q is bit, each times norm, and zero elsewhere. |
measure(psi, q, u) |
Qubit q measured: 0 when u is below the probability of 0, and 1 otherwise, with the state that outcome leaves, renormalised. |
tableau(n) |
Aaronson and Gottesman’s stabilizer tableau of the all-zero state on n qubits: 2n + 1 rows of 2n + 1 bits. |
pauli_phase(x1, z1, x2, z2) |
The power of i that multiplying Pauli (x1, z1) into (x2, z2) contributes. |
row_product(hrow, irow, n) |
Row hrow multiplied by row irow, with the sign worked out modulo 4. |
tab_h(tab, a) |
tab after a Hadamard gate on qubit a. |
tab_s(tab, a) |
tab after an S gate on qubit a. |
tab_cnot(tab, a, b) |
tab after a controlled NOT with control a and target b. |
tab_measure(tab, a, u) |
Qubit a measured on tab, with the tableau that leaves. A random outcome is 1 exactly when u is at least one half; a determined one does not read u. |
tab_gate(tab, name, q) |
tab after the Clifford gate name on the qubits q, up to a global phase. |
clifford(n, steps) |
The tableau of a Clifford circuit of steps on n qubits, from the all-zero state. |
lcg_next(state) |
The next state of Park and Miller’s minimal standard generator, multiplier 48271 and modulus 2³¹ − 1. A seed is an int from 1 to 2³¹ − 2. |
lcg_uniform(state) |
The generator state as a value in (0, 1). |
chacha_quarter(w, a, b, c, d) |
w after ChaCha20’s quarter round, RFC 8439, section 2.1, on its words a, b, c and d. w is changed in place, and is the list answered. |
chacha_block(key, counter, nonce) |
The ChaCha20 block of RFC 8439, section 2.3, as its 16 words in order, for a key of 8 words, a block counter and a nonce of 3 words, each from 0 to 0xFFFFFFFF. Raises ValueError for any other. |
chacha_unit(block, i) |
Value i of block: (block[2·i] >> 5) · 2²⁶ + (block[2·i + 1] >> 6), divided by 2⁵³, an exact value in [0, 1). |
chacha_uniform(key, n) |
chacha_unit of value n mod 8 of the block at counter n // 8 with a nonce of three zeros, for a stream position n from 0 to 2³⁵ − 1. Raises ValueError for any other position. |
unitary(name, theta) |
The matrix of gate name; theta is read by rx, ry and rz only. |
adjoint(m) |
The conjugate transpose of m. |
overlap(n, steps, back, j) |
Amplitude j after running steps and then undoing back, on basis state j. Two circuits equal up to a global phase answer the same value for every j. |
rev_code(n, steps) |
The steps of a reversible circuit on n qubits as (operation, a, b, c): operations 0 to 7 for x, cnot, ccx, z, cz, ccz, swap and cswap, with the qubits in the order the gate’s function takes them, and 8 for mx on a, with its number among the mx steps in b. A controlled step <gate>_if is its gate’s operation plus 16·(1 + j), j the number of the latest mx of its first qubit, and the qubits it answers are the gate’s own. Raises ValueError for any other gate, a count of qubits other than the step’s (the measured qubit of a controlled step included), a qubit outside 0 to n − 1, a qubit named twice in one step (the measured one included), and a controlled step whose first qubit no earlier mx measured. |
rev_apply(w, code) |
Runs what rev_code answered on the wires w, one int for each qubit whose bit k is that qubit in input k of 64, changing w in place, and answers the sign of the 64 inputs, bit k set where input k’s is −1. Every outcome of an mx is 0. |
rev_apply_under(w, code, outcomes) |
rev_apply with the outcome of the j-th mx the bit j of outcomes, the same for all 64 inputs. An mx under outcome 1 negates the sign of the inputs where its qubit is 1, and under either sets the qubit to 0; a controlled step runs only where the outcome it names is 1. |
rev_measures(code) |
The number of mx steps in what rev_code answered. |
lowest_lane(m) |
The lowest bit set in the nonzero 64-bit int m, from 0 to 63. |
rev_same(n, a, b) |
Whether reversible circuits a and b on n qubits are equal, on all 2**n inputs, as (holds, 2**n, first, why). They are equal when, on every input, they leave the same bits under one sign shared by every input: the sign of the two at input 0 is the shared one, and first is the lowest input where the bits differ or the sign differs from it, with why "output" or "sign", "output" when both. When they are equal first is −1 and why is "". Raises ValueError when either circuit holds an mx or a controlled step: a circuit that measures is held to a specification with rev_meets, where every qubit but the inputs starts at 0. Input x puts bit q of x on qubit q. |
rev_meets(n, steps, ins, outs, want, signs) |
Whether the reversible circuit steps on n qubits meets a specification, on all 2len(ins) inputs under every assignment of the outcomes of its mx steps, as (holds, the cases, first, why): the cases are 2len(ins) times 2 for each mx, and case i is input i mod 2len(ins) under the outcomes i div 2len(ins), outcome j being the j-th mx. The sign is exact in every case. Input x puts bit j of x on qubit ins[j] and every other qubit starts at 0. At the end the qubits ins hold what they held, no qubit outside ins and outs is 1, the qubits outs hold want[x] with bit j on qubit outs[j], and the sign is −1 exactly when signs[x] is nonzero (an empty signs is +1 for every input). first is the lowest case that fails and why the first of "input", "ancilla", "output" and "sign" that holds there; a circuit that holds answers −1 and "". Raises ValueError when want is not 2len(ins) values, signs is neither empty nor that many, a qubit is outside the circuit or named twice among ins and outs, a value of want does not fit outs, or the cases would be more than 262. |
These read or write a state kept in the store as State.<name>:
| Query | Answers |
|---|---|
save(name, psi) |
Nothing. Keeps psi under name, replacing any state kept there. |
load(name) |
The state kept under name, bit for bit, or an empty list when none is. |
drop(name) |
Nothing. Forgets the state kept under name. |
packed(name) |
The bytes kept under name, or an empty blob when none are. |
keep(name, b) |
Nothing. Keeps the bytes b under name, as save keeps a state. |
advance(name, steps, u) |
Runs steps on the state kept under name and keeps the state it ends with. Each measurement takes lcg_uniform(u), then u becomes lcg_next(u). Answers the generator state it ended with and the bits it measured. |
advance_chacha(name, steps, key, n) |
As advance, with each measurement taking chacha_uniform(key, n), then n becoming n + 1. Answers the position it ended at and the bits it measured. Raises ValueError when n, or a position a measurement would take, is outside 0 to 2³⁵ − 1. |
weigh(name, q) |
weights of the state kept under name. |
collapse(name, q, bit, norm) |
Nothing. Keeps collapsed of the state kept under name. |
These answer over the facts you have loaded, each a sorted list:
| Query | Answers |
|---|---|
after(g) |
The gates gate g MustPrecede. |
commuting(g) |
The gates gate g CommutesWith: later gates sharing a qubit with g that may run before it. |
uncoupled_gates() |
The gates concluded uncoupled. |
illegal_gates(c) |
Each gate of circuit c its device cannot run as written, as "<gate> <reason>", once for each of off_device, not_native, not_here and reversed that holds. |
stale_gates(c, at, max_age) |
Each gate of circuit c that RunsAs a native operation whose measured_at is later than at, earlier than at less max_age, or absent. at is a datetime and max_age a duration. A gate its device cannot run is in illegal_gates and not here. |
results_not_holding() |
Each result a reason holds for, as "<result> <reason>", once for each of unrecorded, circuit_unknown, circuit_changed, source_unknown, source_changed, device_unknown and recalibrated that holds. |
results_of(c) |
The results naming c as their circuit or their source. |
produced(r) |
What result r records, as "<field> <value>", one line for each field it records, in the order of §3.16. Not sorted. |
3.19 pqc — declared fields
dke. (§4.5) writes an algorithm’s quantum and strength and a use’s system and algorithm from a cryptographic bill of materials. You write the rest. Every year is a calendar year, written as an int, and every boundary is the first year WITHOUT something.
Horizon
| Field | Class | Notes |
|---|---|---|
year |
int |
The first year a quantum computer able to break the vulnerable algorithms is assumed to exist. Two horizons are two assumptions held at once, and every use is reasoned about under both. |
Algorithm
| Field | Class | Notes |
|---|---|---|
quantum |
string |
"vulnerable" for an algorithm a quantum computer breaks. Any other value is not vulnerable. |
strength |
int |
Its classical security strength, in bits, which is what a deadline is stated against. |
Data
| Field | Class | Notes |
|---|---|---|
shelf_life |
int |
How many years after it is protected the data must stay protected. |
System
| Field | Class | Notes |
|---|---|---|
migration |
int |
How many years moving the system off a vulnerable algorithm takes. |
Deadline
| Field | Class | Notes |
|---|---|---|
year |
int |
The first year an algorithm the deadline covers may not be used. |
strength |
int |
The deadline covers a vulnerable algorithm of at most this many bits. |
Use
| Field | Class | Notes |
|---|---|---|
system |
string |
The System that uses the algorithm. |
algorithm |
string |
The Algorithm it uses. |
protects |
string |
The Data it protects. |
migrated |
int |
The first year the use no longer relies on its algorithm, planned or done. Absent when there is no plan. |
horizon |
int |
Concluded by a rule (§3.21). Never written. |
shelf_life |
int |
Concluded by a rule (§3.21). Never written. |
migration |
int |
Concluded by a rule (§3.21). Never written. |
3.20 pqc — derived fields
| Field | Definition |
|---|---|
Use. |
horizon - shelf_life |
Use. |
migrate_by - migration |
migrate_by is the first year the use must no longer rely on its algorithm, and start_by the last year to start moving it.
3.21 pqc — standing rules
Each holds continuously, as in §3.17.
| Rule | Over | Concludes | While |
|---|---|---|---|
vulnerable |
Use, Algorithm |
vulnerable |
the use’s algorithm names an algorithm whose quantum is "vulnerable" |
use_horizon |
Use, Horizon |
horizon |
the use is vulnerable; the use takes every horizon’s year |
use_shelf_life |
Use, Data |
shelf_life |
the use is vulnerable and its protects names the data; the use takes the data’s shelf_life |
use_migration |
Use, System |
migration |
the use is vulnerable and its system names the system; the use takes the system’s migration |
late |
Use |
late |
the use’s migrated is later than its migrate_by |
unplanned |
Use |
unplanned |
the use is vulnerable and has no migrated |
deadline |
Use, Algorithm, Deadline |
deadline |
the use’s algorithm is "vulnerable" and its strength is at most a deadline’s strength; concludes the earliest such deadline’s year, under any value of it |
deadline_name |
Use, Algorithm, Deadline |
deadline_name |
as deadline; concludes the name of the deadline with that year, the first in name order when two share it |
misses |
Use |
misses |
the use’s migrated is later than its deadline |
Two standing constraints are reported by checkup and refuse no write. no_late_plan is violated by each Use that is late, and no_missed_deadline by each Use that misses.
Two notes that are contract rather than commentary:
- Disagreement is reasoned about, not resolved. When two sources give a field two values, every value is reasoned about: a use is late or misses a deadline if any value on record makes it so, and its
deadlineis the earliest year of any value of any deadline that covers it, one source’s year.unsettled()names each such use, by its own fields and the horizon, shelf life and migration time it is reasoned about with; a deadline’syearis not among them, andwhyon the use’sdeadlinenames the year that placed it. - No rule reads the present. A question that depends on the year takes it as
at.
3.22 pqc — queries
Called by name after import pqc. Every one answers use names, sorted, except priority, which answers them in order.
| Query | Answers |
|---|---|
priority() |
Every vulnerable use with a start_by, the earliest first, and uses with the same year in name order. A use with two values is placed by the earlier. |
exposed() |
Every use that is late, and every unplanned use with a migrate_by: what it protects from that year on can be recorded now and read at the horizon. |
noncompliant() |
Every use that misses, and every unplanned use with a deadline. |
remaining(at) |
Every vulnerable use still relying on its algorithm in year at: it has no migrated, or its latest migrated is later than at. |
unclassified() |
Every use with no algorithm, or naming an algorithm with no quantum. No rule concludes anything about such a use. |
unassessed() |
Every vulnerable use with no start_by: its data’s shelf life, its system’s migration time or a horizon is not recorded. |
unsettled() |
Every use whose algorithm, migrated, horizon, shelf_life or migration holds more than one value. |
3.23 harmony — declared fields
The five writing scripts of §3.26 write Voice, Key, Degree, Note, Bar and Tone under the source "harmony", and you may write the same fields yourself. A pitch is a MIDI note number: 60 is middle C and each step is a semitone. A pitch class is a pitch taken within the octave, 0 for C up to 11 for B. A beat is one chord, numbered from 1 in order. Rhythm is counted in a unit you choose, such as a sixteenth, from 0 at the start of the piece.
Voice
| Field | Class | Notes |
|---|---|---|
place |
int |
The voice’s order from the bottom, 1 for the bass. Two voices MUST NOT share a place: the rules compare voices by place. |
low |
int |
The lowest pitch of its range. |
high |
int |
The highest pitch of its range. |
Key
| Field | Class | Notes |
|---|---|---|
tonic |
int |
The tonic’s pitch class. |
mode |
string |
"major" or "minor". No rule reads it; key() reads it to choose the degrees it writes. |
Degree
| Field | Class | Notes |
|---|---|---|
key |
string |
The Key the degree belongs to. |
pc |
int |
A pitch class that belongs to that key. |
Note
| Field | Class | Notes |
|---|---|---|
voice |
string |
The Voice that sings it. |
beat |
int |
The chord it belongs to. |
pitch |
int |
Its pitch. |
key |
string |
The Key it is checked against. Absent for a note checked against none. |
place |
int |
Concluded by a rule (§3.25). Never written. |
p1 |
int |
Concluded by a rule (§3.25). Never written. |
p2 |
int |
Concluded by a rule (§3.25). Never written. |
p3 |
int |
Concluded by a rule (§3.25). Never written. |
spacing |
bool |
Concluded by a rule (§3.25). Never written. |
range |
string |
Concluded by a rule (§3.25). Never written. |
chromatic |
bool |
Concluded by a rule (§3.25). Never written. |
chord |
string |
Concluded by a rule (§3.25), on a chord’s bass note. Never written. |
seventh |
string |
Concluded by a rule (§3.25), on a chord’s bass note. Never written. |
Fifths, Octaves and Crossing declare no field. Each is a relation between two notes, Fifths. for notes a and m, concluded by the rules of §3.25 and never written. They are declared so that reading one that does not stand answers empty.
Bar
| Field | Class | Notes |
|---|---|---|
start |
int |
Where the bar starts. |
length |
int |
How long it lasts. Bars of different lengths are a change of metre. |
pulse |
int |
The length of its beat. |
tones |
int |
Concluded by a rule (§3.25): how many tones starting in it have a duration. Never written. |
claims |
int |
Concluded by a rule (§3.25): how many claims of duration they hold. Never written. |
disputed |
bool |
Concluded by a rule (§3.25): claims is greater than tones. Never written. |
filled |
int |
Concluded by a rule (§3.25). Never written. |
miscounted |
bool |
Concluded by a rule (§3.25). Never written. |
Tone
| Field | Class | Notes |
|---|---|---|
onset |
int |
Where the tone starts. A rest is a tone too. |
duration |
int |
How long it lasts. |
barstart |
int |
Concluded by a rule (§3.25). Never written. |
barend |
int |
Concluded by a rule (§3.25). Never written. |
pulse |
int |
Concluded by a rule (§3.25). Never written. |
across |
bool |
Concluded by a rule (§3.25). Never written. |
syncopated |
bool |
Concluded by a rule (§3.25). Never written. |
3.24 harmony — derived fields
| Field | Definition |
|---|---|
Note. |
pitch % 12 |
Note. |
beat + 1 |
Note. |
pitch - p2 |
Note. |
pitch - p3 |
Note. |
(pitch - p1) % 12 |
Note. |
(pitch - p2) % 12 |
Note. |
(pitch - p3) % 12 |
Bar. |
start + length |
Tone. |
onset + duration |
Tone. |
(onset - barstart) % pulse |
Tone. |
onset - (onset - barstart) % pulse + pulse |
% takes the sign of its right side, as in Python, so i1 to i3 are always 0 to 11. That is an interval within the octave, a compound interval counting as its simple form: 7 is a fifth or a twelfth, and 0 a unison or an octave. A note that has crossed below the voice it is compared with reads the interval the other way up.
3.25 harmony — standing rules
Each holds continuously, as in §3.17. A rule over two or three Notes binds them as a, c and m, or as b for a chord’s bass note, in the order the cell names them.
| Rule | Over | Concludes | While |
|---|---|---|---|
place_of |
Note, Voice |
place |
the note’s voice names the voice; the note takes its place |
sounding_1 |
Note |
p1 |
a note on the same beat is at place 1; the note takes its pitch |
sounding_2 |
Note |
p2 |
as sounding_1, for place 2 |
sounding_3 |
Note |
p3 |
as sounding_1, for place 3 |
fifths_over_1 |
Note |
Fifths |
a.; m is at place 1 on a’s beat; a and c, the note of a’s voice on the next beat, both have an i1 of 7; a and c differ in pitch, and so do the notes at place 1 on the two beats. Concludes Fifths. |
fifths_over_2 |
Note |
Fifths |
as fifths_over_1 with a., place 2 and i2 |
fifths_over_3 |
Note |
Fifths |
as fifths_over_1 with a., place 3 and i3 |
octaves_over_1 |
Note |
Octaves |
as fifths_over_1 with a. and an i1 of 0. Concludes Octaves. |
octaves_over_2 |
Note |
Octaves |
as octaves_over_1 with a., place 2 and i2 |
octaves_over_3 |
Note |
Octaves |
as octaves_over_1 with a., place 3 and i3 |
crossing |
Note |
Crossing |
a and m share a beat, a’s place is above m’s, and a’s pitch is below m’s. Concludes Crossing. |
spacing_3 |
Note |
spacing |
the note is at place 3 and d2 > 12 |
spacing_4 |
Note |
spacing |
the note is at place 4 and d3 > 12 |
below_range |
Note, Voice |
range |
the note’s voice names the voice and its pitch is below the voice’s low; concludes "low" |
above_range |
Note, Voice |
range |
the note’s voice names the voice and its pitch is above the voice’s high; concludes "high" |
chromatic |
Note, Key |
chromatic |
the note’s key names a key, and no Degree of that key has the note’s pc |
major_root |
Note |
chord |
b is at place 1, and notes on its beat have an i1 of 4 and of 7; concludes "major" |
minor_root |
Note |
chord |
as major_root, with 3 and 7; concludes "minor" |
diminished_root |
Note |
chord |
as major_root, with 3 and 6; concludes "diminished" |
major_first |
Note |
chord |
as major_root, with 3 and 8; concludes "major, first inversion" |
minor_first |
Note |
chord |
as major_root, with 4 and 9; concludes "minor, first inversion" |
diminished_first |
Note |
chord |
as major_root, with 3 and 9; concludes "diminished, first inversion" |
major_second |
Note |
chord |
as major_root, with 5 and 9; concludes "major, second inversion" |
minor_second |
Note |
chord |
as major_root, with 5 and 8; concludes "minor, second inversion" |
diminished_second |
Note |
chord |
as major_root, with 6 and 9; concludes "diminished, second inversion" |
major_open |
Note |
chord |
b is at place 1, a note on its beat has an i1 of 4, and every note on its beat has an i1 of 0 or 4; concludes "major, fifth omitted" |
minor_open |
Note |
chord |
as major_open, with 3; concludes "minor, fifth omitted" |
seventh_root |
Note |
seventh |
b is at place 1, and notes on its beat have an i1 of 4, of 7 and of 10; concludes "dominant seventh" |
seventh_open |
Note |
seventh |
as seventh_root, with 4 and 10 and no note on the beat with an i1 of 7; concludes "dominant seventh, fifth omitted" |
seventh_first |
Note |
seventh |
as seventh_root, with 3, 6 and 8; concludes "dominant seventh, first inversion" |
seventh_second |
Note |
seventh |
as seventh_root, with 3, 5 and 9; concludes "dominant seventh, second inversion" |
seventh_third |
Note |
seventh |
as seventh_root, with 2, 6 and 9; concludes "dominant seventh, third inversion" |
bar_start |
Tone, Bar |
barstart |
the tone’s onset is at or after the bar’s start and before its end; the tone takes the bar’s start |
bar_end |
Tone, Bar |
barend |
as bar_start; the tone takes the bar’s end |
bar_pulse |
Tone, Bar |
pulse |
as bar_start; the tone takes the bar’s pulse |
bar_claims |
Bar, Tone |
claims |
as bar_start, and the tone’s duration > -1000000000000000000; the bar takes the number of claims of duration such tones hold |
bar_tones |
Bar, Tone |
tones |
as bar_start, and the tone’s duration > -1000000000000000000; the bar takes the number of distinct such tones |
bar_disputed |
Bar |
disputed |
the bar’s claims is greater than its tones; concludes True |
bar_filled |
Bar, Tone |
filled |
as bar_start, and the bar has no disputed; the bar takes the sum of every such tone’s duration |
bar_miscounted |
Bar |
miscounted |
the bar’s filled differs from its length |
across_bar |
Tone |
across |
the tone’s ends is after its barend |
syncopated |
Tone |
syncopated |
offbeat > 0, and the tone’s ends is after its nextpulse |
harmony declares no standing constraint. Four notes that are contract rather than commentary:
- Consecutive means both voices move. A fifth or an octave held by one voice while the other leaps is not marked. Fifths and octaves in contrary motion are marked, and so is a twelfth followed by a fifth.
- A chord takes every reading inside it. Each chord rule reads exactly the intervals it names, so a dominant seventh is also a major triad, a chord with both a major and a minor third above its bass is read as both, and a chord of no shape named here has no reading.
- Disagreement is reasoned about, not resolved. When two sources give a field two values, every value is reasoned about, and a mark stands if any value on record makes it so. A fold reads every value too, so a tone whose
durationa second source writes, even the same duration, would be added twice to its bar’sfilled;tonesandclaimscount the tones and their claims over the one binding the fold reads, and while the claims are more, the bar isdisputedand nofilledis concluded for it. A tone with nodurationis in neither count, and a tone whoseonsetholds two values starts in each bar it names, each of those fills being one source’s. The rules that ask for something to be missing are answered for the note rather than for each value:chromaticholds of a note only when no value of itspcis a degree of its key, andmajor_open,minor_openandseventh_openread a chord only when no value on record supplies the interval they leave out. - No rule hears the music. Every rule compares numbers. What the rules do not check is listed in the Library Reference: hidden fifths and octaves, doubling, resolution, melodic intervals and more than four voices.
3.26 harmony — queries
Called by name after import harmony. Only filled_of refuses because sources disagree, and only a disputed bar: otherwise a reader answers one value by the rule its row states, and unsettled() names what is in disagreement.
| Query | Answers |
|---|---|
satb() |
Nothing. Writes the voices bass, tenor, alto and soprano at places 1 to 4, with the ranges 40 to 60, 48 to 67, 55 to 74 and 60 to 79. |
key(name, tonic, mode) |
Nothing. Writes the key name, and for each pitch class of its scale a Degree named name, _ and the pitch class: the major scale, or for "minor" the natural minor with its raised sixth and seventh. |
chord(beat, k, bass, tenor, alto, soprano) |
Nothing. Writes four notes on beat in key k, named for their voice and beat, bass1 to soprano1 for beat 1. Writing a beat again replaces its notes. |
bars(count, length, pulse) |
Nothing. Writes count bars m1 onward, end to end from 0, then forgets the bars named m and each number from count + 1 up to the number of bars the store held before the call. |
melody(durations) |
Nothing. Writes a tone t1 onward for each duration, end to end from 0, then forgets the tones named t and each number past the new end up to the number of tones the store held before the call. |
voice_of(n) |
The voice of note n, "" when it has none, and every voice in force in name order, joined by " or ", when sources disagree. |
beat_of(n) |
The beat of note n, 0 when it has none, and the least in force when sources disagree. |
filled_of(b) |
The filled of bar b, 0 when it has none, and the least in force when sources disagree. A bar with disputed is refused. |
length_of(b) |
The length of bar b, 0 when it has none, and the least in force when sources disagree. |
pairs(kind) |
For "fifths", "octaves" or "crossing", each pair of notes the relation holds between, as (a, m). |
faults() |
One line for each consecutive fifth or octave, crossed voice, spacing, range and chromatic mark, sorted. A note is named by its voice and beat, each value in force joined by " or ". |
readings(n) |
Every chord and seventh value concluded on note n, sorted. |
rhythm_faults() |
One line for each miscounted bar, each disputed bar (bar b: disputed), each tone across its bar line and each syncopated tone, sorted. A bar’s filled and length are each given with every value in force, joined by " or ". |
unsettled() |
Every voice, note, bar and tone for which a field of §3.23 that is not concluded holds more than one value in force, as its kind in lower case and its name, note tenor1, sorted. |
frequency(midi, a4) |
a4 * 2.0 ** ((midi - 69) / 12), with a4 440.0 when not given. |
cents(ratio) |
1200.0 * math.. |
beating(f1, h1, f2, h2) |
abs(h1 * f1 - h2 * f2). |
pcset(pcs) |
The distinct values of pcs modulo 12, sorted. |
rotations(s) |
Each rotation of the sorted set s, transposed to begin on 0. |
packed_key(r, right) |
What two rotations are compared by: r’s last element, then its elements from the next to last back to the second when right is true, or from the second up to the next to last when it is false. |
most_packed(s, right) |
The rotation of s with the least packed_key, the earlier in order of rotation when two tie. |
prime_form(pcs, right) |
The most packed rotation of pcset(pcs), or of its inversion when that one’s packed_key is less; [] for no pitch classes. right is true when not given. |
interval_vector(pcs) |
Six counts: how many pairs of the set lie each interval class from 1 to 6 apart. |
matrix(row) |
One list for each element of row: element j of list i is (row[j] + row[0] - row[i]) % 12. |
all_interval(row) |
Whether the successive intervals of row, each modulo 12, are all different. |
euclid(k, n) |
n characters, x for each of k onsets and . elsewhere, spread by Bjorklund’s algorithm: all . when k is 0 or less, all x when k is n or more. |
3.27 physics — declared fields
The writing scripts of §3.30 write Quantity, Factor, Resistor and Group under the source "physics", and Unit under the source each is given, and you may write the same fields yourself. A unit is named by letters, digits and underscores, such as "N", "lbf_s" or "m_per_s2". Its dimension is the powers of five base dimensions it is made of: mass, length, time, electric current and temperature. A newton, a kilogram metre per second squared, is mass 1, length 1 and time -2. A unit’s factor is what one of it is in the SI unit of the same dimension. A unit whose zero is not SI’s, such as a degree Celsius, is not a factor and is not written. An equation is checked as a product of powers: write every power on its left side positive and every power on its right side negative, so F = m a is F to the 1, m to the -1 and a to the -1.
Unit
| Field | Class | Notes |
|---|---|---|
mass |
int |
The unit’s power of mass. |
length |
int |
The unit’s power of length. |
time |
int |
The unit’s power of time. |
current |
int |
The unit’s power of electric current. |
temperature |
int |
The unit’s power of temperature. |
factor |
real |
What one of the unit is in the SI unit of the same dimension: 4.4482216152605 for a pound-force, in newtons. |
Quantity
| Field | Class | Notes |
|---|---|---|
value |
real |
The value, in unit. |
unit |
string |
The Unit it is written in. |
expects |
string |
The Unit its reader takes it in, where it is handed from one system to another. Absent for a quantity handed to no one. |
factor |
real |
Concluded by a rule (§3.29). Never written. |
mass |
int |
Concluded by a rule (§3.29). Never written. |
length |
int |
Concluded by a rule (§3.29). Never written. |
time |
int |
Concluded by a rule (§3.29). Never written. |
current |
int |
Concluded by a rule (§3.29). Never written. |
temperature |
int |
Concluded by a rule (§3.29). Never written. |
efactor |
real |
Concluded by a rule (§3.29), from expects. Never written. |
emass |
int |
Concluded by a rule (§3.29), from expects. Never written. |
elength |
int |
Concluded by a rule (§3.29), from expects. Never written. |
etime |
int |
Concluded by a rule (§3.29), from expects. Never written. |
ecurrent |
int |
Concluded by a rule (§3.29), from expects. Never written. |
etemperature |
int |
Concluded by a rule (§3.29), from expects. Never written. |
unknown |
bool |
Concluded by a rule (§3.29). Never written. |
unexpected |
bool |
Concluded by a rule (§3.29). Never written. |
handoff |
string |
Concluded by a rule (§3.29). Never written. |
Factor
| Field | Class | Notes |
|---|---|---|
equation |
string |
The Equation the factor belongs to. |
quantity |
string |
The Quantity it is a power of. |
power |
int |
The power: positive on the left side of the equation, negative on the right. |
mass |
int |
Concluded by a rule (§3.29). Never written. |
length |
int |
Concluded by a rule (§3.29). Never written. |
time |
int |
Concluded by a rule (§3.29). Never written. |
current |
int |
Concluded by a rule (§3.29). Never written. |
temperature |
int |
Concluded by a rule (§3.29). Never written. |
unknown |
bool |
Concluded by a rule (§3.29). Never written. |
Equation
| Field | Class | Notes |
|---|---|---|
mass_factors |
int |
Concluded by a rule (§3.29): how many of its factors hold a share of mass. Never written. |
length_factors |
int |
Concluded by a rule (§3.29): how many of its factors hold a share of length. Never written. |
time_factors |
int |
Concluded by a rule (§3.29): how many of its factors hold a share of time. Never written. |
current_factors |
int |
Concluded by a rule (§3.29): how many of its factors hold a share of current. Never written. |
temperature_factors |
int |
Concluded by a rule (§3.29): how many of its factors hold a share of temperature. Never written. |
mass_claims |
int |
Concluded by a rule (§3.29): how many claims of those shares they hold. Never written. |
length_claims |
int |
Concluded by a rule (§3.29): how many claims of those shares they hold. Never written. |
time_claims |
int |
Concluded by a rule (§3.29): how many claims of those shares they hold. Never written. |
current_claims |
int |
Concluded by a rule (§3.29): how many claims of those shares they hold. Never written. |
temperature_claims |
int |
Concluded by a rule (§3.29): how many claims of those shares they hold. Never written. |
mass_disputed |
bool |
Concluded by a rule (§3.29): mass_claims is greater than mass_factors. Never written. |
length_disputed |
bool |
Concluded by a rule (§3.29): length_claims is greater than length_factors. Never written. |
time_disputed |
bool |
Concluded by a rule (§3.29): time_claims is greater than time_factors. Never written. |
current_disputed |
bool |
Concluded by a rule (§3.29): current_claims is greater than current_factors. Never written. |
temperature_disputed |
bool |
Concluded by a rule (§3.29): temperature_claims is greater than temperature_factors. Never written. |
mass |
int |
Concluded by a rule (§3.29). Never written. |
length |
int |
Concluded by a rule (§3.29). Never written. |
time |
int |
Concluded by a rule (§3.29). Never written. |
current |
int |
Concluded by a rule (§3.29). Never written. |
temperature |
int |
Concluded by a rule (§3.29). Never written. |
consistent |
bool |
Concluded by a rule (§3.29). Never written. |
unbalanced |
bool |
Concluded by a rule (§3.29). Never written. |
Resistor
| Field | Class | Notes |
|---|---|---|
ohms |
real |
Its resistance in ohms. |
group |
string |
The Group it is joined in. Absent for a resistor in none. |
Group
| Field | Class | Notes |
|---|---|---|
joined |
string |
"series" or "parallel". |
ohms_resistors |
int |
Concluded by a rule (§3.29), for a series group: how many resistors carry an ohms into its sum. Never written. |
ohms_claims |
int |
Concluded by a rule (§3.29): how many claims of ohms they hold. Never written. |
ohms_disputed |
bool |
Concluded by a rule (§3.29): ohms_claims is greater than ohms_resistors. Never written. |
siemens_resistors |
int |
Concluded by a rule (§3.29), for a parallel group: how many resistors carry a siemens into its sum. Never written. |
siemens_claims |
int |
Concluded by a rule (§3.29): how many claims of siemens they hold. Never written. |
siemens_disputed |
bool |
Concluded by a rule (§3.29): siemens_claims is greater than siemens_resistors. Never written. |
ohms |
real |
Concluded by a rule (§3.29), for a series group. Never written. |
siemens |
real |
Concluded by a rule (§3.29), for a parallel group. Never written. |
3.28 physics — derived fields
| Field | Definition |
|---|---|
Quantity. |
value * factor |
Quantity. |
value * (factor / efactor) |
Factor. |
power * mass |
Factor. |
power * length |
Factor. |
power * time |
Factor. |
power * current |
Factor. |
power * temperature |
Resistor. |
1.0 / ohms |
Group. |
1.0 / siemens |
Quantity. is the quantity’s value in the SI unit of its dimension, and converted its value in the unit it expects. converted takes the ratio of the two factors first, so a value expected in its own unit comes back as it was, and it is a real wherever the value in the expected unit is one, for any factors from 10^-150 to 10^150. Each is absent until the rules have concluded the fields it reads, so a quantity in a unit the list does not hold has neither. A factor’s s fields are its share of each base dimension, and an equation sums them. A resistor’s siemens is its conductance, and a group’s parallel is the resistance of a parallel group, the reciprocal of the conductances its resistors sum to.
3.29 physics — standing rules
Each holds continuously, as in §3.17. A rule over a Quantity and a Unit binds them as q and u, a rule over a Factor as f, an Equation as e, a Group as g and a Resistor as r.
| Rule | Over | Concludes | While |
|---|---|---|---|
factor_of |
Quantity, Unit |
factor |
the quantity’s unit names the unit; the quantity takes the unit’s factor |
mass_of |
Quantity, Unit |
mass |
as factor_of; the quantity takes the unit’s mass |
length_of |
Quantity, Unit |
length |
as factor_of; the quantity takes the unit’s length |
time_of |
Quantity, Unit |
time |
as factor_of; the quantity takes the unit’s time |
current_of |
Quantity, Unit |
current |
as factor_of; the quantity takes the unit’s current |
temperature_of |
Quantity, Unit |
temperature |
as factor_of; the quantity takes the unit’s temperature |
unknown_unit |
Quantity |
unknown |
the quantity’s unit is not empty and no factor is concluded for it; concludes True |
efactor_of |
Quantity, Unit |
efactor |
the quantity’s expects names the unit; the quantity takes the unit’s factor |
emass_of |
Quantity, Unit |
emass |
as efactor_of; the quantity takes the unit’s mass |
elength_of |
Quantity, Unit |
elength |
as efactor_of; the quantity takes the unit’s length |
etime_of |
Quantity, Unit |
etime |
as efactor_of; the quantity takes the unit’s time |
ecurrent_of |
Quantity, Unit |
ecurrent |
as efactor_of; the quantity takes the unit’s current |
etemperature_of |
Quantity, Unit |
etemperature |
as efactor_of; the quantity takes the unit’s temperature |
unexpected_unit |
Quantity |
unexpected |
the quantity’s expects is not empty and no efactor is concluded for it; concludes True |
handoff_convert |
Quantity |
handoff |
unit differs from expects, and the quantity’s five powers equal the five of the expected unit; concludes "convert" |
handoff_mass |
Quantity |
handoff |
mass differs from emass; concludes "incompatible" |
handoff_length |
Quantity |
handoff |
length differs from elength; concludes "incompatible" |
handoff_time |
Quantity |
handoff |
time differs from etime; concludes "incompatible" |
handoff_current |
Quantity |
handoff |
current differs from ecurrent; concludes "incompatible" |
handoff_temperature |
Quantity |
handoff |
temperature differs from etemperature; concludes "incompatible" |
factor_mass |
Factor, Quantity, Unit |
mass |
the factor’s quantity names the quantity and the quantity’s unit names the unit; the factor takes the unit’s mass |
factor_length |
Factor, Quantity, Unit |
length |
as factor_mass; the factor takes the unit’s length |
factor_time |
Factor, Quantity, Unit |
time |
as factor_mass; the factor takes the unit’s time |
factor_current |
Factor, Quantity, Unit |
current |
as factor_mass; the factor takes the unit’s current |
factor_temperature |
Factor, Quantity, Unit |
temperature |
as factor_mass; the factor takes the unit’s temperature |
factor_unknown |
Factor |
unknown |
the factor’s quantity is not empty and no mass is concluded for it; concludes True |
equation_mass_factors |
Equation, Factor |
mass_factors |
the factor’s equation names the equation and its smass > -1000000000; the equation takes the number of distinct such factors |
equation_length_factors |
Equation, Factor |
length_factors |
the factor’s equation names the equation and its slength > -1000000000; the equation takes the number of distinct such factors |
equation_time_factors |
Equation, Factor |
time_factors |
the factor’s equation names the equation and its stime > -1000000000; the equation takes the number of distinct such factors |
equation_current_factors |
Equation, Factor |
current_factors |
the factor’s equation names the equation and its scurrent > -1000000000; the equation takes the number of distinct such factors |
equation_temperature_factors |
Equation, Factor |
temperature_factors |
the factor’s equation names the equation and its stemperature > -1000000000; the equation takes the number of distinct such factors |
equation_mass_claims |
Equation, Factor |
mass_claims |
the factor’s equation names the equation and its smass > -1000000000; the equation takes the number of claims of smass those factors hold |
equation_length_claims |
Equation, Factor |
length_claims |
the factor’s equation names the equation and its slength > -1000000000; the equation takes the number of claims of slength those factors hold |
equation_time_claims |
Equation, Factor |
time_claims |
the factor’s equation names the equation and its stime > -1000000000; the equation takes the number of claims of stime those factors hold |
equation_current_claims |
Equation, Factor |
current_claims |
the factor’s equation names the equation and its scurrent > -1000000000; the equation takes the number of claims of scurrent those factors hold |
equation_temperature_claims |
Equation, Factor |
temperature_claims |
the factor’s equation names the equation and its stemperature > -1000000000; the equation takes the number of claims of stemperature those factors hold |
equation_mass_disputed |
Equation |
mass_disputed |
the equation’s mass_claims is greater than its mass_factors; concludes True |
equation_length_disputed |
Equation |
length_disputed |
the equation’s length_claims is greater than its length_factors; concludes True |
equation_time_disputed |
Equation |
time_disputed |
the equation’s time_claims is greater than its time_factors; concludes True |
equation_current_disputed |
Equation |
current_disputed |
the equation’s current_claims is greater than its current_factors; concludes True |
equation_temperature_disputed |
Equation |
temperature_disputed |
the equation’s temperature_claims is greater than its temperature_factors; concludes True |
equation_mass |
Equation, Factor |
mass |
the factor’s equation names the equation and the equation has no mass_disputed; the equation takes the sum of its factors’ smass |
equation_length |
Equation, Factor |
length |
as equation_mass, with no length_disputed, summing slength |
equation_time |
Equation, Factor |
time |
as equation_mass, with no time_disputed, summing stime |
equation_current |
Equation, Factor |
current |
as equation_mass, with no current_disputed, summing scurrent |
equation_temperature |
Equation, Factor |
temperature |
as equation_mass, with no temperature_disputed, summing stemperature |
consistent |
Equation |
consistent |
the equation’s mass, length, time, current and temperature are all 0, and no factor of it is unknown; concludes True |
unbalanced_mass |
Equation |
unbalanced |
the equation’s mass is not 0 and no factor of it is unknown; concludes True |
unbalanced_length |
Equation |
unbalanced |
as unbalanced_mass, for length |
unbalanced_time |
Equation |
unbalanced |
as unbalanced_mass, for time |
unbalanced_current |
Equation |
unbalanced |
as unbalanced_mass, for current |
unbalanced_temperature |
Equation |
unbalanced |
as unbalanced_mass, for temperature |
group_ohms_resistors |
Group, Resistor |
ohms_resistors |
the group is joined "series", the resistor’s group names it and its ohms > -1.0e300; the group takes the number of distinct such resistors |
group_siemens_resistors |
Group, Resistor |
siemens_resistors |
the group is joined "parallel", the resistor’s group names it and its siemens > -1.0e300; the group takes the number of distinct such resistors |
group_ohms_claims |
Group, Resistor |
ohms_claims |
the group is joined "series", the resistor’s group names it and its ohms > -1.0e300; the group takes the number of claims of ohms those resistors hold |
group_siemens_claims |
Group, Resistor |
siemens_claims |
the group is joined "parallel", the resistor’s group names it and its siemens > -1.0e300; the group takes the number of claims of siemens those resistors hold |
group_ohms_disputed |
Group |
ohms_disputed |
the group’s ohms_claims is greater than its ohms_resistors; concludes True |
group_siemens_disputed |
Group |
siemens_disputed |
the group’s siemens_claims is greater than its siemens_resistors; concludes True |
series |
Group, Resistor |
ohms |
the group is joined "series", the resistor’s group names it and the group has no ohms_disputed; the group takes the sum of its resistors’ ohms |
parallel |
Group, Resistor |
siemens |
the group is joined "parallel", the resistor’s group names it and the group has no siemens_disputed; the group takes the sum of its resistors’ siemens |
physics declares no standing constraint. Five notes that are contract rather than commentary:
- Only a unit in the list is reasoned about. A quantity in a unit no
Unitnames gets nofactor, no dimension and nosi; it is markedunknown, andchecks()names it. An equation with a factor in such a unit is judged neitherconsistentnorunbalanced. - Consistent is not true. A consistent equation has the same dimensions on both sides. It is not thereby a law:
E = m vandE = m v²differ in dimension, butE = m v²andE = 2 m v²do not. - Disagreement is reasoned about, not resolved. When two sources give a field two values, every value is reasoned about, and
unsettled()names the fact. - A sum is not drawn from a member bound to it twice. A sum reads every value of what it sums, so a factor whose share two values give, or a resistor whose
ohmsa second source writes, even the sameohms, would be added twice, a result no circuit or equation has. The_factors,_resistorsand_claimsfields count the members and their claims over the one binding the sum reads, and while the claims are more, the sum is disputed and not concluded, nor anything that rests on it. A member with no value of the sum is in neither count, so it hides no dispute. A factor whoseequation, or a resistor whosegroup, holds two values counts in each it names, and each of those sums is one source’s. - No rule reads the physics. Every rule compares or adds numbers. Whether an equation is true, whether a quantity is plausible and whether a circuit is built of series and parallel groups are not asked.
3.30 physics — queries
Called by name after import physics. Only resistance refuses because sources disagree, and only a disputed group: otherwise a reader answers one value by the rule its row states, and unsettled() names what is in disagreement. The writers and readers of the first two groups are the interface to the facts; the third group computes values from its arguments and writes nothing.
| Query | Answers |
|---|---|
unit(name, mass, length, time, current, temperature, factor, source) |
Nothing. Writes the unit name with its five powers and its factor, each under source. |
si_units() |
Nothing. Writes the list of units: kg, m, s, A and K, the dimensionless one and rad, g, km, cm, mm, min, h, Hz, m_per_s, km_per_h, m_per_s2, N, N_s, kg_m_per_s, J, W, Pa, C, V, ohm, kWh and eV under the source "SI Brochure 2019", and in, ft, mi, mph, lb, lbf, lbf_s, ft_lbf, psi, atm and cal under the source "NIST SP 811". |
quantity(name, value, unit) |
Nothing. Writes the quantity name with its value and unit. Writing a name again corrects it. |
expect(name, unit) |
Nothing. Writes the unit the quantity name is taken in. |
factor(equation, quantity, power) |
Nothing. Writes the factor named for the equation, - and the quantity, with the equation, the quantity and the power. |
resistor(name, ohms, group) |
Nothing. Writes the resistor name with its ohms and its group. |
group(name, joined) |
Nothing. Writes the group name, "series" or "parallel". |
si(name) |
The si of quantity name, 0.0 when it has none, and the least in force when sources disagree. |
converted(name) |
The converted of quantity name, 0.0 when it has none, and the least in force when sources disagree. |
resistance(name) |
The resistance of group name in ohms: its ohms when joined in series, its parallel when joined in parallel. 0.0 when it has none, and the least in force when sources disagree. A group with ohms_disputed or siemens_disputed is refused. |
disputed_equations() |
The equations with any of the five _disputed fields, sorted. |
disputed_groups() |
The groups with ohms_disputed or siemens_disputed, sorted. |
dimension(name) |
What is left over of equation name’s dimensions, as the powers of M, L, T, I and Θ that are not 0, such as "L1 T-1"; "disputed" when the equation is disputed, "consistent" when none is, "unknown unit" when a factor’s unit is not recorded and "no factors" when the equation has none. |
checks() |
One line for each quantity in a unit the list does not hold (unknown unit: q in u), each quantity expected in one it does not hold (unknown unit: q expected in u), each unbalanced equation that is not disputed (unbalanced: e, D left over), each hand-over (handed over: q in u where x is expected, convert or incompatible), each disputed equation (disputed: equation e) and each disputed group (disputed: group g), sorted. |
unsettled() |
Each unit, quantity, factor, group and resistor that holds two different values in force for a field you write: a unit’s mass, length, time, current, temperature or factor, a quantity’s value, unit or expects, a factor’s equation, quantity or power, a group’s joined, or a resistor’s ohms or group. Given as unit x, quantity x, factor x, group x or resistor x, sorted. |
small_period(length, g) |
2.0 * math., and where length / g passes the range of a real or falls below the smallest normal one, 2.0 * math.. A length below 0 or a g not above 0 is refused with ValueError. |
agm(a, b) |
The arithmetic–geometric mean of a and b, iterated at most 40 times and stopped when the two means differ by at most 1e-15 of the first. A number below 0 is refused with ValueError. Where the sum of the pair passes the range of a real, the mean is the sum of their halves, and where their product passes it or falls below the smallest normal real, the geometric mean is the product of their square roots. |
period(theta0, length, g) |
The exact period of a pendulum released at rest from theta0 radians: small_period(length, g) divided by agm(1.0, math.. An amplitude outside -π to π is refused with ValueError. |
pendulum(theta0, length, g, dt) |
The same period by the fourth-order Runge–Kutta method at steps of dt seconds, four times the time to swing down to the vertical, integrated for up to period(theta0, length, g). An amplitude not above 0 or above π, a length not above 0 or a step not above 0 is refused with ValueError, and so is a step too long to reach the vertical in that time. |
orbit(e, method, periods, steps) |
For a body released at its closest point on a Kepler orbit of eccentricity e, GM 1 and semi-major axis 1, stepped by "euler", "verlet" or any other name for the fourth-order Runge–Kutta method, steps a period for periods periods: the list of the relative error in energy, the relative error in angular momentum, and the distance from the start, a math. where its squares fall below the smallest normal real. An eccentricity outside 0 to below 1 is refused with ValueError. |
heat(cells, r, steps) |
The temperature at the middle of a rod of unit length and diffusivity, held at 0 at both ends and started as a triangle rising to 1, after steps steps of forward differences in time and centred differences in space over cells cells, r the time step over the square of the spacing. |
heat_exact(time) |
The same temperature at time from the sum over odd n, 200 terms, of 8 / (n² π²) times e to the -n² π² time. |
solve(a, b) |
The solution of the linear system a · x = b by Gaussian elimination with partial pivoting, as a list; [] when the system is singular, that is where a pivot is 0. Where x passes the range of a real, or a pivot or a multiplier falls below the smallest normal real, while a and b are reals, it is solved again with each row of a scaled by a power of two that brings its largest entry near 1, and b by another, and x scaled back. |
bridge(volts, r1, r2, r3, r4, rg) |
The current in amperes through the meter of a Wheatstone bridge, r1 above r2 and r3 above r4, the meter rg across their middles. 0 when r1 / r2 = r3 / r4. A resistance not above 0 is refused with ValueError. Where a conductance or a current on the way passes the range of a real, each node’s equation is taken with its resistances scaled by a power of two, and a source past 1 volt with its volts scaled by another, and the current scaled back. |
ising(n, temperature, sweeps, seed) |
The mean of |M| per spin over the second half of sweeps sweeps of an n by n square magnet with wrapped edges, started with every spin up and flipped by the Metropolis rule at temperature, from a seeded generator, so a run is the same every time. |
3.31 chemistry — declared fields
The writing scripts of §3.34 write Element, Atom, Bond, Species and Term under the source "chemistry", except element() and elements(), which write Element under the source "CIAAW"; you may write the same fields yourself. A weight is a standard atomic weight, or a sum of them, in g/mol. A valence is the number of bonds an element usually forms in an organic molecule, and 0 for an element that forms none there. A bond order is 1, 2 or 3. An enthalpy of formation is in kJ/mol at 298.15 K, and a reaction’s enthalpy in kJ. Hydrogens are never written: an atom carries the hydrogens its valence leaves over (§3.33).
Element
| Field | Class | Notes |
|---|---|---|
z |
int |
The element’s atomic number. The element of atomic number 1 is the hydrogen the rules count. |
valence |
int |
The number of bonds it forms, 0 where it forms none here. An element of valence 0 gives its atoms no valence and no hydrogens. |
weight |
real |
Its standard atomic weight. |
An Element is named by its symbol. elements() writes these thirteen:
| Symbol | z |
valence |
weight |
|---|---|---|---|
H |
1 | 1 | 1.008 |
C |
6 | 4 | 12.011 |
N |
7 | 3 | 14.007 |
O |
8 | 2 | 15.999 |
Na |
11 | 0 | 22.990 |
P |
15 | 3 | 30.974 |
S |
16 | 2 | 32.06 |
Cl |
17 | 1 | 35.45 |
K |
19 | 0 | 39.098 |
Ca |
20 | 0 | 40.078 |
Cr |
24 | 0 | 51.996 |
Mn |
25 | 0 | 54.938 |
Fe |
26 | 0 | 55.845 |
Atom
| Field | Class | Notes |
|---|---|---|
element |
string |
The symbol of its Element. |
molecule |
string |
The name of the molecule it belongs to. |
valence |
int |
Concluded by a rule (§3.33). Never written. |
weight |
real |
Concluded by a rule (§3.33). Never written. |
bond_halves |
int |
Concluded by a rule (§3.33): how many halves of its bonds carry an order. Never written. |
bond_claims |
int |
Concluded by a rule (§3.33): how many claims of order they hold. Never written. |
bonds_disputed |
bool |
Concluded by a rule (§3.33): bond_claims is greater than bond_halves. Never written. |
bonds |
int |
Concluded by a rule (§3.33). Never written. |
hweight |
real |
Concluded by a rule (§3.33). Never written. |
overbonded |
bool |
Concluded by a rule (§3.33). Never written. |
carbonyl |
bool |
Concluded by a rule (§3.33). Never written. |
group |
string |
Concluded by a rule (§3.33), on the atom that carries the group. Never written. |
Bond
A Bond is half a bond. bond() writes both halves, named a-b and b-a, so that each atom reaches the other.
| Field | Class | Notes |
|---|---|---|
a |
string |
The atom the half starts from. |
b |
string |
The atom it reaches. |
order |
int |
1, 2 or 3. |
belement |
string |
Concluded by a rule (§3.33). Never written. |
bhydrogens |
int |
Concluded by a rule (§3.33). Never written. |
bcarbonyl |
bool |
Concluded by a rule (§3.33). Never written. |
Molecule
A Molecule is named by the molecule its atoms give, and declares no field you write.
| Field | Class | Notes |
|---|---|---|
weight_atoms |
int |
Concluded by a rule (§3.33): how many of its atoms have a mass. Never written. |
weight_claims |
int |
Concluded by a rule (§3.33): how many claims of mass they hold. Never written. |
weight_disputed |
bool |
Concluded by two rules (§3.33): weight_claims is greater than weight_atoms, or an atom of it has bonds_disputed. Never written. |
hydrogen_atoms |
int |
Concluded by a rule (§3.33): how many of its atoms have hydrogens. Never written. |
hydrogen_claims |
int |
Concluded by a rule (§3.33): how many claims of hydrogens they hold. Never written. |
hydrogens_disputed |
bool |
Concluded by two rules (§3.33): hydrogen_claims is greater than hydrogen_atoms, or an atom of it has bonds_disputed. Never written. |
weight |
real |
Concluded by a rule (§3.33). Never written. |
hydrogens |
int |
Concluded by a rule (§3.33). Never written. |
heavy |
int |
Concluded by a rule (§3.33). Never written. |
Species
| Field | Class | Notes |
|---|---|---|
formation |
real |
The standard enthalpy of formation of the substance in its state, in kJ/mol. A species is named by you, such as "water_l" for liquid water. |
Term
A Term is named by term() for its reaction and species, reaction, - and species.
| Field | Class | Notes |
|---|---|---|
reaction |
string |
The Reaction it belongs to. |
species |
string |
The Species it counts. |
coefficient |
int |
Positive for a product, negative for a reactant. |
formation |
real |
Concluded by a rule (§3.33). Never written. |
missing |
bool |
Concluded by a rule (§3.33). Never written. |
Reaction
A Reaction is named by you, and declares no field you write.
| Field | Class | Notes |
|---|---|---|
terms |
int |
Concluded by a rule (§3.33): how many of its terms have a contribution. Never written. |
claims |
int |
Concluded by a rule (§3.33): how many claims of contribution they hold. Never written. |
disputed |
bool |
Concluded by a rule (§3.33): claims is greater than terms. Never written. |
enthalpy |
real |
Concluded by a rule (§3.33). Never written. |
incomplete |
bool |
Concluded by a rule (§3.33). Never written. |
3.32 chemistry — derived fields
| Field | Definition |
|---|---|
Atom. |
valence - bonds |
Atom. |
weight + hydrogens * hweight |
Term. |
coefficient * formation |
hydrogens is what the atom’s valence leaves over after its bonds: an atom with no bond carries its whole valence, as the oxygen of water and the carbon of methane do. It is negative for an atom bonded past its valence, and overbonded marks that atom (§3.33). mass is the atom’s weight with those hydrogens. An atom of an element that has not been written has no valence, no hydrogens and no mass. An atom of an element of valence 0, a metal, takes its own bonds as its valence (§3.33), so it carries no hydrogens and its mass is its weight.
3.33 chemistry — standing rules
Each holds continuously, as in §3.17. A rule over an Atom and a Bond binds them as a or c, o or n, and x or y, in the order the cell names them. A functional group is concluded on the atom that carries it: the carbonyl carbon of an acid, an ester, an amide, an aldehyde and a ketone, the oxygen of an alcohol, and the nitrogen of an amine.
| Rule | Over | Concludes | While |
|---|---|---|---|
valence_of |
Atom, Element |
valence |
the atom’s element names an element whose valence > 0; the atom takes it |
metal_valence |
Atom, Element |
valence |
the atom’s element names an element whose valence == 0, and the atom’s bonds >= 0; the atom takes its own bonds |
weight_of |
Atom, Element |
weight |
the atom’s element names an element; the atom takes its weight |
hydrogen_weight |
Atom, Element |
hweight |
the atom has an element, and the element of z == 1 has a weight; the atom takes it |
bond_halves |
Atom, Bond |
bond_halves |
a bond’s a names the atom and its order > -1000000000000000000; the atom takes the number of distinct such bonds |
bond_claims |
Atom, Bond |
bond_claims |
a bond’s a names the atom and its order > -1000000000000000000; the atom takes the number of claims of order those bonds hold |
bonds_disputed |
Atom |
bonds_disputed |
the atom’s bond_claims is greater than its bond_halves; concludes True |
bonds_of |
Atom, Bond |
bonds |
a bond’s a names the atom and the atom has no bonds_disputed; the atom takes the sum of every such bond’s order |
unbonded |
Atom |
bonds |
the atom has an element and no bond’s a names it; concludes 0 |
overbonded |
Atom |
overbonded |
the atom’s hydrogens < 0 |
far_element |
Bond, Atom |
belement |
the bond’s b names the atom; the bond takes the atom’s element |
far_hydrogens |
Bond, Atom |
bhydrogens |
the bond’s b names the atom; the bond takes the atom’s hydrogens |
far_carbonyl |
Bond, Atom |
bcarbonyl |
the bond’s b names an atom that is carbonyl |
molecule_weight_atoms |
Molecule, Atom |
weight_atoms |
an atom’s molecule names the molecule and its mass > -1.0e300; the molecule takes the number of distinct such atoms |
molecule_weight_claims |
Molecule, Atom |
weight_claims |
an atom’s molecule names the molecule and its mass > -1.0e300; the molecule takes the number of claims of mass those atoms hold |
molecule_weight_disputed |
Molecule |
weight_disputed |
the molecule’s weight_claims is greater than its weight_atoms; concludes True |
molecule_hydrogen_atoms |
Molecule, Atom |
hydrogen_atoms |
an atom’s molecule names the molecule and its hydrogens > -1000000000000000000; the molecule takes the number of distinct such atoms |
molecule_hydrogen_claims |
Molecule, Atom |
hydrogen_claims |
an atom’s molecule names the molecule and its hydrogens > -1000000000000000000; the molecule takes the number of claims of hydrogens those atoms hold |
molecule_hydrogens_disputed |
Molecule |
hydrogens_disputed |
the molecule’s hydrogen_claims is greater than its hydrogen_atoms; concludes True |
molecule_atom_weight_disputed |
Molecule, Atom |
weight_disputed |
an atom whose molecule names the molecule has bonds_disputed; concludes True |
molecule_atom_hydrogens_disputed |
Molecule, Atom |
hydrogens_disputed |
as molecule_atom_weight_disputed; concludes True |
molecule_weight |
Molecule, Atom |
weight |
an atom’s molecule names the molecule and the molecule has no weight_disputed; the molecule takes the sum of every such atom’s mass |
molecule_hydrogens |
Molecule, Atom |
hydrogens |
an atom’s molecule names the molecule and the molecule has no hydrogens_disputed; the molecule takes the sum of every such atom’s hydrogens |
molecule_heavy |
Molecule, Atom |
heavy |
an atom’s molecule names the molecule; the molecule takes the number of distinct such atoms |
carbonyl |
Atom, Bond |
carbonyl |
the atom’s element is "C", and a bond from it has an order of 2 and a belement of "O" |
carboxylic_acid |
Atom, Bond |
group |
the atom is carbonyl, and a bond from it has an order of 1, a belement of "O" and a bhydrogens of 1; concludes "carboxylic acid" |
ester |
Atom, Bond |
group |
the atom’s carbonyl is True, a bond from it of order 1 reaches an atom whose element is "O" and whose hydrogens are 0, and a bond from that oxygen has a belement of "C" and a b other than the first atom; concludes "ester" |
amide |
Atom, Bond |
group |
the atom is carbonyl, and a bond from it has an order of 1 and a belement of "N"; concludes "amide" |
aldehyde |
Atom |
group |
the atom is carbonyl with hydrogens >= 1, and no bond from it has an order of 1 and a belement of "O" or of "N"; concludes "aldehyde" |
ketone |
Atom, Bond |
group |
the atom is carbonyl, and two bonds from it, each of order 1 and belement "C", reach different atoms; concludes "ketone" |
alcohol |
Atom, Bond |
group |
the atom’s element is "O" and its hydrogens is 1, and a bond from it has a belement of "C" and no bcarbonyl; concludes "alcohol" |
amine |
Atom, Bond |
group |
the atom’s element is "N", a bond from it has a belement of "C", no bond from it has a bcarbonyl, and no bond from it has an order > 1; concludes "amine" |
term_formation |
Term, Species |
formation |
the term’s species names a species; the term takes its formation |
term_missing |
Term |
missing |
the term names a species and has no formation |
reaction_terms |
Reaction, Term |
terms |
a term’s reaction names the reaction and its contribution > -1.0e300; the reaction takes the number of distinct such terms |
reaction_claims |
Reaction, Term |
claims |
a term’s reaction names the reaction and its contribution > -1.0e300; the reaction takes the number of claims of contribution those terms hold |
reaction_disputed |
Reaction |
disputed |
the reaction’s claims is greater than its terms; concludes True |
reaction_enthalpy |
Reaction, Term |
enthalpy |
a term’s reaction names the reaction and the reaction has no disputed; the reaction takes the sum of every such term’s contribution |
reaction_incomplete |
Reaction, Term |
incomplete |
a term of the reaction is missing |
chemistry declares no standing constraint. Six notes that are contract rather than commentary:
- Hydrogens are concluded, not written. The structure is a graph of the heavy atoms and the bonds between them, as a skeletal drawing is. Each atom carries the hydrogens its valence leaves over, and an atom with no bond carries its whole valence. Nothing is concluded until the element is written: before
elements()is called, or for a symbol with noElement, an atom has no valence, no hydrogens and no mass, andweight()answers 0.0 for a molecule none of whose atoms has one. An atom of an element of valence 0 takes its own bonds as its valence, so a metal carries no hydrogens and adds its weight to its molecule’s. - A group takes every reading inside it. Each group rule reads exactly the bonds it names, so an atom that fits two rules carries both groups, and an atom that fits none carries none. A nitrogen is read as an amine only while every bond it has is single, so the nitrogen of a nitrile or an imine carries no group.
- A molecule’s formula and weight are sums over its atoms.
Molecule.adds the hydrogens of every atom, and an overbonded atom adds a negative number.hydrogens overbondedandfaults()name it. - A reaction’s enthalpy is the sum over the terms the store holds. A term whose species has no
formationadds nothing, and the reaction isincomplete: itsenthalpyis the sum of the terms that have one. - Disagreement is reasoned about, not resolved. When two sources give a field two values, every value is reasoned about, and
unsettled()names the fact. - A sum is not drawn from a member bound to it twice. A sum reads every value of what it sums, so a sulfur atom whose element’s
weightholds two values would be weighed at both, and a bond whoseordera second source writes, even the same order, counted twice. The_halves,_atoms,termsand_claimsfields count the members and their claims over the one binding the sum reads, and while the claims are more, the sum is disputed and not concluded, nor anything that rests on it. An atom whose bonds are disputed has nohydrogensormass, so it disputes its molecule’s weight and hydrogens rather than leave them. A member with no value of the sum is in neither count, so it hides no dispute. An atom whosemolecule, a bond whoseaor a term whosereactionholds two values counts in each it names, and each of those sums is one source’s.
3.34 chemistry — queries
Called by name after import chemistry. The first six write facts and answer nothing. The next eight read what the rules concluded; a read refuses only what is disputed, as its cell states, and otherwise answers by the rule its cell states, and unsettled() names what is in disagreement. The last thirteen are value scripts that return a value and write nothing.
| Query | Answers |
|---|---|
element(symbol, z, valence, weight) |
Nothing. Writes the Element named symbol with those three fields, under the source "CIAAW". |
elements() |
Nothing. Writes the thirteen elements of §3.31, each with its abridged standard atomic weight and its usual valence in an organic molecule. |
atom(name, symbol, molecule) |
Nothing. Writes an Atom named name, of the element symbol, in molecule. |
bond(a, b, order) |
Nothing. Writes the bond between atoms a and b as its two halves, a-b and b-a, each of order. Writing a bond again replaces it. |
species(name, formation) |
Nothing. Writes a Species named name with its enthalpy of formation, in kJ/mol. |
term(reaction, species, coefficient) |
Nothing. Writes the Term named reaction, - and species, counting species in reaction with coefficient: positive for a product, negative for a reactant. |
weight(name) |
The weight of molecule name, in g/mol: the least value in force where values disagree, and 0.0 when it has none. A molecule with weight_disputed is refused. |
enthalpy(reaction) |
The enthalpy of reaction, in kJ: the least value in force where values disagree, and 0.0 when it has none. A reaction with disputed is refused. |
formula(name) |
The formula of molecule name in the Hill order: carbon first, then hydrogen, then the other elements alphabetically, or every element alphabetically when there is no carbon. A count of 1 is not written. The hydrogens are the ones the rules concluded, and each atom is counted once. A molecule with hydrogens_disputed, or one of whose atoms holds two different element values, is refused. |
disputed_molecules() |
The molecules with weight_disputed or hydrogens_disputed, sorted. |
disputed_reactions() |
The reactions with disputed, sorted. |
groups(name) |
The functional groups on the atoms of molecule name, each named once, sorted. |
faults() |
One line for each atom bonded past its valence, overbonded: and the atom, for each reaction with a species whose enthalpy of formation is not recorded, incomplete: and the reaction, and for each atom with bonds_disputed, molecule in disputed_molecules() and reaction in disputed_reactions(), disputed: atom, disputed: molecule or disputed: reaction and its name, sorted. |
unsettled() |
Each element, atom, bond, species and term that holds two different values in force for a field you write: an element’s z, valence or weight, an atom’s element or molecule, a bond’s a, b or order, a species’ formation, or a term’s reaction, species or coefficient. Given as its kind in lower case and its name, element S, sorted. |
parse(formula) |
How many atoms of each element formula holds, as a dict: "Ca(OH)2" is one calcium, two oxygens and two hydrogens. Brackets nest. A charge written after a caret is left out. |
charge(formula) |
The charge written after a caret: "^2-" is -2, "^+" is 1, and no caret is 0. |
molar_mass(formula) |
The molar mass of formula in g/mol, from the weight of each element in the store, counted by parse. 0.0 when an element in it has no weight. |
gcd(a, b) |
The greatest common divisor of the absolute values of a and b. |
balance(reactants, products) |
The least whole-number coefficients that balance the equation, reactants first, each element and the charge being the same on both sides. [] unless the equation has exactly one balance up to scale with every coefficient positive. |
charge_ph(acid, base, pkas) |
The pH at which the charges in a solution balance: a weak acid of total concentration acid mol/L with the acid constants pkas, one for each proton it gives up, beside base mol/L of a strong base’s cation. Water’s ion product is taken as 1.0e-14. Found by bisection on the pH between -2 and 16. A concentration below 0 is refused with ValueError. Where an acid constant is so large that a term of the balance passes the largest real, the share of protons given up is taken from the terms’ common logarithms less the largest of them. |
ph(acid, pkas) |
charge_ph(acid, 0.0, pkas): the pH of a weak acid of concentration acid mol/L in water. |
titration(acid, va, base, vb, pkas) |
The pH after vb mL of a strong base of concentration base mol/L is added to va mL of a weak acid of concentration acid: charge_ph of the two concentrations after dilution. A volume below 0 is refused with ValueError. Where the total volume or a concentration after dilution passes the largest real, it is the concentration times the share of the volume, of halves. |
consecutive(k1, k2, t, dt) |
For A to B to C, first order with rate constants k1 and k2, from pure A: the fractions of A, B and C at time t, integrated by the fourth-order Runge-Kutta method in steps of dt. A rate constant or a time below 0, or a step not above 0, is refused with ValueError, and so is a step so long for the rates that the integration diverges past the range of a real. |
consecutive_exact(k1, k2, t) |
The same three fractions in closed form, for k1 different from k2. A rate constant or a time below 0 is refused with ValueError. |
peak_time(k1, k2) |
When B is at its most: ln(k1 / k2) / (k1 - k2), and 1 / k1 when the two are equal; where k1 / k2 is not a normal real, its logarithm is ln k1 - ln k2. A rate constant below 0 is refused with ValueError. |
equilibrium(kf, kr, a0, b0, t, dt) |
For A plus B to C and back, with forward rate constant kf and reverse kr, from a0 and b0 mol/L of A and B and no C: the concentration of C at time t, integrated by the fourth-order Runge-Kutta method in steps of dt. |
equilibrium_exact(k, a0, b0) |
The concentration of C at equilibrium, where C over the product of A and B equals the equilibrium constant k, which is kf / kr: the smaller root of k x^2 - (k (a0 + b0) + 1) x + k a0 b0 = 0, taken as 2 k a0 b0 / (p + r) with p = k a0 + k b0 + 1 and r the root of (k a0 - k b0)^2 + 2 (k a0 + k b0) + 1, which is the same root and subtracts nothing, and where k times the larger concentration is above 1, the same divided through by k and by 8, so that no step passes the range of a real. A constant or a concentration below 0 is refused with ValueError; a constant of 0 gives 0. |
3.35 biology — declared fields
The four writing scripts of §3.37 write Compound, Reaction, Family and Person under the sources "medium", "network" and "pedigree", and you may write the same fields yourself. A compound and a reaction are named by you, and so are a family and a person; a reaction’s s1, s2, p1 and p2, a person’s family, mother and father, and a family’s name in Person. are each the name of another subject. A medium is what a growth medium supplies. A scope is every compound the network can make from it. A mode is how the trait a family is recorded for is inherited: "autosomal dominant", "autosomal recessive" or "X-linked recessive".
Compound
| Field | Class | Notes |
|---|---|---|
medium |
bool |
True for a compound the growth medium supplies. |
reached |
bool |
Concluded by a rule (§3.36). Never written. |
Reaction
| Field | Class | Notes |
|---|---|---|
s1 |
string |
The name of its first substrate, a Compound. |
s2 |
string |
The name of its second substrate. Absent for a reaction with one. |
p1 |
string |
The name of its first product. |
p2 |
string |
The name of its second product. Absent for a reaction with one. |
runs |
bool |
Concluded by a rule (§3.36). Never written. |
Family
| Field | Class | Notes |
|---|---|---|
mode |
string |
"autosomal dominant", "autosomal recessive" or "X-linked recessive". No rule concludes anything for a family with any other mode. |
unexplained |
int |
Concluded by a rule (§3.36). Never written. |
Person
| Field | Class | Notes |
|---|---|---|
family |
string |
The name of the Family the person is recorded in. |
mother |
string |
The name of the person’s mother, a Person. Absent where not recorded. |
father |
string |
The name of the person’s father. Absent where not recorded. |
sex |
string |
"F" or "M". |
affected |
bool |
Whether the person shows the trait. |
inbred |
bool |
Concluded by a rule (§3.36). Never written. |
carrier |
bool |
Concluded by a rule (§3.36). Never written. |
unexplained |
bool |
Concluded by a rule (§3.36). Never written. |
Parent and Ancestor declare no field. Each is a relation between two people, Parent. for a child c and a parent p, and Ancestor. for a person x and an ancestor y, concluded by the rules of §3.36 and never written. They are declared so that reading one that does not stand answers empty.
3.36 biology — standing rules
Each holds continuously, as in §3.17. A rule over several subjects binds them as the cell names them: a compound as a, b or c, a reaction as r, a family as y, and a person as c for a child, m for a mother, f for a father, p for a parent and x, y and z along a line of descent.
| Rule | Over | Concludes | While |
|---|---|---|---|
supplied |
Compound |
reached |
the compound’s medium is True |
runs_one |
Reaction, Compound |
runs |
the reaction’s s1 names the compound, the compound is reached, and the reaction has no s2 |
runs_two |
Reaction, Compound |
runs |
the reaction’s s1 names a compound that is reached and its s2 names a compound that is reached |
makes_first |
Reaction, Compound |
reached |
the reaction runs and its p1 names the compound |
makes_second |
Reaction, Compound |
reached |
the reaction runs and its p2 names the compound |
parent_mother |
Person |
Parent |
the child’s mother names a person. Concludes Parent. |
parent_father |
Person |
Parent |
the child’s father names a person. Concludes Parent. |
ancestor_parent |
Person |
Ancestor |
Parent. holds. Concludes Ancestor. |
ancestor_further |
Person |
Ancestor |
Ancestor. and Parent. hold. Concludes Ancestor. |
inbred_shared |
Person |
inbred |
the child’s mother and father have an ancestor in common |
inbred_father_line |
Person |
inbred |
the child’s father is an ancestor of the child’s mother |
inbred_mother_line |
Person |
inbred |
the child’s mother is an ancestor of the child’s father |
recessive_parent |
Family, Person |
carrier |
the family’s mode is "autosomal recessive", a child in the family is affected, and Parent. holds for a parent who is not affected; the parent is the carrier |
recessive_child |
Family, Person |
carrier |
the family’s mode is "autosomal recessive", a child in the family is not affected, and Parent. holds for a parent who is affected; the child is the carrier |
x_linked_mother |
Family, Person |
carrier |
the family’s mode is "X-linked recessive", a child in the family has sex "M" and is affected, and the child’s mother is not affected; the mother is the carrier |
x_linked_daughter |
Family, Person |
carrier |
the family’s mode is "X-linked recessive", a child in the family has sex "F" and is not affected, and the child’s father is affected; the daughter is the carrier |
dominant_unexplained |
Family, Person |
unexplained |
the family’s mode is "autosomal dominant", a child in the family is affected, and neither the child’s mother nor its father is affected; the child is unexplained |
recessive_unexplained |
Family, Person |
unexplained |
the family’s mode is "autosomal recessive", a child in the family is not affected, and both the child’s mother and its father are affected; the child is unexplained |
x_linked_daughter_unexplained |
Family, Person |
unexplained |
the family’s mode is "X-linked recessive", a child in the family has sex "F" and is affected, and the child’s father is not affected; the daughter is unexplained |
x_linked_son_unexplained |
Family, Person |
unexplained |
the family’s mode is "X-linked recessive", a child in the family has sex "M" and is not affected, and the child’s mother is affected; the son is unexplained |
family_unexplained |
Family, Person |
unexplained |
a person in the family is unexplained; the family takes the number of distinct such people |
biology declares no standing constraint. Five notes that are contract rather than commentary:
- A cycle of reactions does not hold itself up. A compound is
reachedonly through a chain of reactions that begins at the medium. Two reactions that make each other’s substrate from each other’s product reach nothing unless the medium, or another chain from it, supplies one of them; when the medium stops supplying it, the scope withdraws the whole cycle. - A scope assumes every reaction can run.
runsasks that each substrate bereachedand nothing more. The rules do not check energy, balance, direction, enzyme or concentration. - Every pedigree rule assumes the trait shows in everyone who has its genotype, and that no new mutation arose in the family. A person
unexplainedis where one of those, or the record itself, does not hold. Each ofcarrierandunexplainedis concluded only from the generation it names: a carrier is not carried back through a grandparent, and a sister of an affected son is not concluded a carrier. - A person written with no parent has no parent. The scripts of §3.37 pass
""for a parent not recorded, which writes nothing; they do not withdraw a parent an earlier call recorded. Correct a parent by writing the name again. - Disagreement is reasoned about, not resolved. When two sources give a field two values, every value is reasoned about, and a conclusion stands if any value on record supports it. A rule that asks for something to be absent is answered for the subject: a reaction to which another source gives an
s2is no longer one with a single substrate, and runs only when that compound isreachedas well. A family’sunexplainedcounts each person once, however many rules or values conclude themunexplained.
3.37 biology — queries
Called by name after import biology. No query refuses because sources disagree: a reader answers every value in force, and unsettled() names what is in disagreement. The four writers write under the sources "medium", "network" and "pedigree", so writing the same fact again is a correction and a write under another source is a disagreement.
| Query | Answers |
|---|---|
medium(name) |
Nothing. Writes Compound. True under the source "medium". |
reaction(name, s1, s2, p1, p2) |
Nothing. Writes the reaction name’s s1 and p1 under the source "network", and its s2 and p2 only when they are not "". |
family(name, mode) |
Nothing. Writes the family name’s mode under the source "pedigree". |
person(name, family, sex, affected, mother, father) |
Nothing. Writes the person name’s family, sex and affected under the source "pedigree", and its mother and father only when they are not "". |
scope() |
Every compound the network can make from its medium, the medium’s own included, sorted. |
blocked() |
Every reaction with a recorded s1 that does not run, sorted. |
needs(target, candidates) |
Each candidate that, added to the medium alone, would make target reached, in the order given. Each is a hypothesis: nothing is written, and the medium is left as it was. |
people(name) |
Every person recorded in family name, sorted. |
ancestors(name) |
Every recorded ancestor of person name, sorted. |
inbred() |
Every child whose parents are related by descent, sorted. |
carriers(name) |
Every member of family name that the mode requires to carry the allele, sorted. |
unexplained(name) |
Every member of family name whose record the mode cannot explain, sorted. |
unsettled() |
Every compound, reaction, family and person for which a field it writes among medium, s1, s2, p1, p2, mode, family, mother, father, sex and affected holds two different values in force, as its kind in lower case, its name and the field, person nell affected, sorted. |
complement(dna) |
The reverse complement of a strand of A, T, C and G: the other strand, read in its own direction. |
transcribe(dna) |
The messenger RNA a coding strand is copied into: dna with U for each T. |
translate(rna, table) |
The protein rna codes for, in one-letter amino acids, read from the first AUG to the first stop codon, or to the last whole codon when none comes. table 1 is the standard code and 2 the vertebrate mitochondrial code. "" when there is no AUG. |
gc(dna) |
The share of dna’s bases that are G or C, 0.0 for an empty strand. |
gametes(genotype) |
The gametes a genotype written two letters a gene, "AaBb", makes: one allele of each gene, every combination once, in order. |
zygote(a, b) |
The genotype two gametes make, each gene’s letters in character order, so a dominant capital comes first. |
cross(a, b) |
How many of the pairings of the two parents’ gametes give each genotype. |
phenotypes(a, b) |
The same pairings by what they show: each gene’s first letter, so "AB" shows both dominant traits. |
chi_square(observed, ratio) |
The sum over classes of (observed - expected)^2 / expected, where expected is the total of observed shared out in the proportions of ratio. A class ratio gives a share of 0 adds nothing where none were observed in it, and makes the statistic inf where some were. A count or a share below 0 is refused with ValueError. Where a sum or a square on the way passes the range of a real, or falls below the smallest normal one, it is taken again with the counts and the shares each scaled by a power of two and the statistic scaled back. |
hardy_weinberg(aa, ab, bb) |
A list: the first allele’s frequency p from the counts of the three genotypes, and the chi-square of the counts against p^2 : 2pq : q^2; [1.0, 0.0] or [0.0, 0.0] for a sample of one homozygote. |
logistic(r, k, n0, t, dt) |
The population at time t from n0, growing at rate r toward capacity k by dN/, stepped by fourth-order Runge–Kutta in steps of dt. A capacity not above 0 or a population below 0 is refused with ValueError. Where a step passes the range of a real, the steps are taken again with n0 and k scaled by a power of two and the population scaled back. |
logistic_exact(r, k, n0, t) |
The same population from the equation’s solution, k / (1 + (k - n0) / n0 * exp(-r t)); 0 for an n0 of 0 and k for an n0 of k. The same refusals as logistic. Where the factor, the exponential or their product passes the range of a real, or the exponential falls below the smallest normal one, each is carried as a mantissa and a power of two. |
predator_prey(alpha, beta, gamma, delta, x0, y0, t, dt) |
A list: prey x and predators y at time t by fourth-order Runge–Kutta, for dx/ and dy/, and the relative change in delta x - gamma ln x + beta y - alpha ln y, which the exact motion keeps. Where a step passes the range of a real, the steps are taken again with x0 and y0 scaled by powers of two and delta and beta by the same powers the other way, and where the populations pass it even so, they are refused with ValueError. Where that quantity passes the range, it is taken with the four rates scaled by a power of two. |
drift(n, p0, generations, seed) |
A list: the frequency of an allele after generations of a population of n diploid individuals, each generation drawing its 2n gene copies at random from the last, and the generation the allele was fixed or lost in, -1.0 if neither. A seed gives the same run every time. |
fixation(n, p0, runs, generations, seed) |
The share of runs populations, drawn one after another from one stream, in which the allele is fixed within generations. |
ring(start, steps) |
The states of a ring of genes, one character a gene, "1" for on, from start through steps steps, where at each step all at once a gene is on exactly when the gene before it in the ring was off. |
period(start) |
How many steps the ring takes to return to a state it has been in, from start: 1 for a state that stays as it is. |
3.38 astronomy — declared fields
The writing scripts of §3.41 write Site, Star, Night and Booking under the sources "sites", "catalogue", "nights" and "bookings", and up() writes Up under "ephemeris". You may write the same fields yourself. A site, a star, a night, an up and a booking are each named by you, except an Up, which up() names <star>_<site>_<yyyymmdd> after the star, the site and the day of the start it is given. A night’s and a booking’s site, a booking’s star and an up’s star and site are each the name of another subject. Angles are in degrees, latitude and declination positive north, longitude positive east, and right ascension from 0 to 360. A magnitude is the star’s brightness on the astronomers’ scale, on which a smaller number is brighter and a negative one is brighter than zero. All times are UT.
Three facts are written with a window, a stretch of time for which they hold: a night’s site, a booking’s site and star, and an up’s star and site. Each of those windows is also recorded as two facts of its own that hold at all times, so a window can be read when it is not now: opens and closes for a night, starts and ends for a booking, rises and sets for an up.
Site
| Field | Class | Notes |
|---|---|---|
lat |
real |
Latitude in degrees, north positive. |
lon |
real |
Longitude in degrees, east positive. |
limit |
real |
The faintest magnitude the site’s instrument reaches. |
circumpolar_above |
real |
Computed from lat (§3.39). Never written. |
hidden_below |
real |
Computed from lat (§3.39). Never written. |
circumpolar_below |
real |
Computed from lat (§3.39). Never written. |
hidden_above |
real |
Computed from lat (§3.39). Never written. |
Star
| Field | Class | Notes |
|---|---|---|
ra |
real |
Right ascension in degrees. |
dec |
real |
Declination in degrees, north positive. |
mag |
real |
Magnitude. |
Night
| Field | Class | Notes |
|---|---|---|
site |
string |
The name of the Site the night is dark at. Written with the night as its window. |
opens |
datetime |
When the night begins. Valid at all times. |
closes |
datetime |
When the night ends. Valid at all times. |
Up
| Field | Class | Notes |
|---|---|---|
star |
string |
The name of the Star above the horizon. Written with the stretch it is above as its window. |
site |
string |
The name of the Site it is above the horizon of. Written with the same window. |
rises |
datetime |
When the stretch begins. Valid at all times. |
sets |
datetime |
When the stretch ends. Valid at all times. |
Booking
| Field | Class | Notes |
|---|---|---|
site |
string |
The name of the Site the instrument is booked at. Written with the booking as its window. |
star |
string |
The name of the Star it is booked for. Written with the same window. |
starts |
datetime |
When the booking begins. Valid at all times. |
ends |
datetime |
When the booking ends. Valid at all times. |
observable |
bool |
Concluded by a rule (§3.40), and holds for the overlap of the booking, a night and an up alone. Never written. |
Circumpolar, Hidden and Visible declare no field. Each is a relation between a star and a site, Circumpolar. for a star s and a site t, concluded by the rules of §3.40 and never written. They are declared so that reading one that does not stand answers empty.
3.39 astronomy — derived fields
| Field | Definition |
|---|---|
Site. |
90 - lat |
Site. |
lat - 90 |
Site. |
-90 - lat |
Site. |
90 + lat |
Each is a limit of declination, in degrees, set by the site’s latitude alone. At a northern site, a star whose declination is above circumpolar_above never sets, and one whose declination is below hidden_below never rises. At a southern site the limits are the other pair: a star below circumpolar_below never sets and one above hidden_above never rises. All four are absent until the site’s lat is written. A site at latitude 0 is read as a northern site.
3.40 astronomy — standing rules
Each holds continuously, as in §3.17. A rule over a star and a site binds them as s and t; a rule over a booking, a night and an up binds them as b, n and u.
| Rule | Over | Concludes | While |
|---|---|---|---|
circumpolar_north |
Star, Site |
Circumpolar |
the site’s lat >= 0 and the star’s dec is above the site’s circumpolar_above; concludes Circumpolar. |
circumpolar_south |
Star, Site |
Circumpolar |
the site’s lat < 0 and the star’s dec is below the site’s circumpolar_below; concludes Circumpolar. |
hidden_north |
Star, Site |
Hidden |
the site’s lat >= 0 and the star’s dec is below the site’s hidden_below; concludes Hidden. |
hidden_south |
Star, Site |
Hidden |
the site’s lat < 0 and the star’s dec is above the site’s hidden_above; concludes Hidden. |
visible_north |
Star, Site |
Visible |
the site’s lat >= 0, the star’s dec is no lower than the site’s hidden_below, and the star’s mag is no fainter than the site’s limit; concludes Visible. |
visible_south |
Star, Site |
Visible |
the site’s lat < 0, the star’s dec is no higher than the site’s hidden_above, and the star’s mag is no fainter than the site’s limit; concludes Visible. |
observable |
Booking, Night, Up |
observable |
the night’s site and the up’s site both name the booking’s site, and the up’s star names the booking’s star; the booking is observable |
astronomy declares no standing constraint. Six notes that are contract rather than commentary:
- The limits are geometry, not weather. A star never sets where its lowest altitude, the absolute value of the sum of the site’s latitude and the star’s declination, less 90 degrees, is above the horizon, and never rises where its highest, 90 degrees less the absolute value of the difference, is below it. The rules take the horizon to be the geometric one: no refraction, no terrain, no twilight and no cloud.
- A star on a limit is not on its far side. A star whose declination is exactly
circumpolar_aboveis notCircumpolar, and one exactly athidden_belowis notHiddenand isVisibleif it is bright enough. The same holds for the southern pair. Visibleincludes what never sets. A circumpolar star is above the horizon at all times, so it isVisiblewhere it is bright enough. A star that isHiddenis notVisible, and a star fainter than the site’slimitis neitherVisiblenor kept from beingHiddenorCircumpolar. The three relations are independent conclusions.- A booking is observable for an overlap.
observableholds for the stretch where the booking’s window, a night at its site and the star’s time above that site’s horizon all overlap, and for no other. It is not concluded for a star that never rises, becauseup()writes nothing for one, and the rule does not read the star’s magnitude or the site’slimit. A booking at a site with noNight, or for a star with noUpat it, is not observable. - The sky does not write itself. A star’s rising and setting are facts you write with
up()(§3.41); nothing concludes one from the star and the site alone, and a rise is not corrected when a star’s or a site’s coordinates are. Callup()again for the same star, site and day to replace it. - Disagreement is reasoned about, not resolved. When two sources give a field two values, every value is reasoned about, and a conclusion stands if any value on record supports it. A star whose
decis given two values isHiddenat a site if either is belowhidden_below, andVisibleif either is not.unsettled()names the fact.up()andwindow()are the readers that refuse:up()needs one value of the star’sraanddecand of the site’slatandlon, andwindow()one value of the booking’sstartsandends, and each is refused while any of them has two.unsettled()does not name a booking.
3.41 astronomy — queries
Called by name after import astronomy. The first five write facts and answer nothing. The next nine read what the rules concluded or what was written, and two of them take a claim; no read refuses because sources disagree, except window() as §3.40 says: it answers by the rule its cell states, and unsettled() names what is in disagreement about a site or a star. The last fourteen are value scripts that return a value and write nothing. Angles are in degrees, times in UT and Julian dates in days.
| Query | Answers |
|---|---|
site(name, latitude, longitude, faintest) |
Nothing. Writes the Site named name’s lat, lon and limit under the source "sites". |
star(name, right_ascension, declination, magnitude) |
Nothing. Writes the Star named name’s ra, dec and mag under the source "catalogue". |
night(name, where, start, end) |
Nothing. Writes the Night named name’s site as where, with the window from start to end, and its opens and closes as those two instants, under the source "nights". |
book(name, where, target, start, end) |
Nothing. Writes the Booking named name’s site as where and star as target, each with the window from start to end, and its starts and ends as those two instants, under the source "bookings". |
up(target, where, start) |
Nothing. Writes, under the source "ephemeris", the Up named <target>_<where>_<yyyymmdd>, the date being start’s: the star target above the horizon of the site where from its rising to its setting, on the first passage that has not ended by start, that passage included if it began before start. A star that never sets is written above the horizon for the day from start, and one that never rises is written nothing. Rising and setting are for the geometric horizon, from the sidereal rate. Pass a night’s start to get that night’s passage. |
number(c) |
The number the claim c holds: a real as it is, an integer as a real, and 0.0 for any other value. |
stars_in(relation, where) |
The stars in the relation named "circumpolar", "hidden" or "visible" for the site where, sorted. Any other name reads "visible". |
circumpolar(where) |
The stars that never set at the site where, sorted. |
hidden(where) |
The stars that never rise at the site where, sorted. |
visible(where) |
The stars that rise at the site where, or never set, and are no fainter than its limit, sorted. |
observable_at(t) |
The bookings observable at the instant t, sorted. A booking is read at t only where its own window holds it. |
instant_of(c) |
The instant the claim c holds, as a list of one, and [] for any value that is not an instant. |
window(booking) |
The stretch the booking named booking is observable for, as its first and last instants, written as text, or [] where it never is. It opens where the last of the booking, a night and a rising does. The booking must have been written. |
unsettled() |
Each site and star that holds two different values in force for a field you write: a site’s lat, lon or limit, or a star’s ra, dec or mag. Given as site or star, its name and the field, star vega dec, sorted. |
jd(year, month, day) |
The Julian date of a calendar date, day carrying its fraction, by Meeus’s formula 7.1: in the Julian calendar before 1582 October 15 and the Gregorian from then, as astronomers date events. |
jd_of(t) |
The Julian date of the instant t. |
instant(j) |
The instant of the Julian date j, to the nanosecond. A Julian date held as a real steps in about 40 microseconds, so the instant is the real’s and not the decimal written for it. |
gmst(j) |
Greenwich mean sidereal time at the Julian date j, in degrees from 0 to 360, by Meeus’s formula 12.4. A date so far from 2000 that the angle passes the largest real is refused with ValueError. |
lst(j, longitude) |
Local mean sidereal time at a longitude, east positive: gmst(j) plus the longitude taken modulo 360 degrees by math., from 0 to 360. |
hms(degrees) |
An angle of the sky’s rotation as [hours, minutes, seconds], at 15 degrees an hour, each a real; for an angle from 0 to 360. |
altitude(declination, latitude, hour_angle) |
A body’s altitude above the horizon in degrees, from its declination, the observer’s latitude and its hour angle, which is 0 at transit. No refraction is allowed for. Each angle is taken modulo 360 degrees by math. first. |
semi_arc(declination, latitude, horizon) |
The hour angle in degrees at which a body crosses the altitude horizon, rising and setting symmetrically about its transit: 0 for one that never reaches it, 180 for one that never falls below it. Each angle is taken modulo 360 degrees by math. first. |
rise_set(ra, declination, latitude, longitude, day) |
A star’s rising, transit and setting at a site, as [rising, transit, setting], [transit] for a star that never sets and [] for one that never rises. The transit is the first at or after the instant day, and the rising may fall before it. Over the geometric horizon. Each angle is taken modulo 360 degrees by math. first. |
sun(j) |
The Sun’s right ascension and declination at the Julian date j, as [ra, dec], by the Astronomical Almanac’s low-precision formulas, good to about 0.01 degrees from 1950 to 2050. |
day_length(latitude, j) |
The hours from sunrise to sunset at a latitude on the day of the Julian date j: the Sun’s semi-arc to -0.833 degrees, its upper limb at the horizon after refraction, at 15 degrees an hour. 24 where the Sun never sets and 0 where it never rises. |
kepler(mean_anomaly, e) |
The eccentric anomaly E with E - e sin E = M for the mean anomaly M in radians and an eccentricity e from 0 up to 1: [E, steps], found by Newton’s method from M, or from pi where e is above 0.8, stopped when a step changes E by less than 1e-15, in at most 64 steps. An M past pi is taken to within pi of 0 first by math., which is exact, and the turns are added back to E; an M below 0 is solved for its size and E given its sign, as the equation is odd. Another eccentricity is refused with ValueError. |
true_anomaly(eccentric_anomaly, e) |
The true anomaly in radians, the angle from perihelion seen from the focus, from the eccentric anomaly. |
two_body(e, orbits, per_orbit) |
A body on an orbit of eccentricity e, from 0 up to 1, about a mass with GM equal to 1 and a semi-major axis of 1, from perihelion, by fourth-order Runge-Kutta at per_orbit steps an orbit for orbits orbits: [the energy at the start, the energy at the end, the distance from where Kepler's equation puts it then]. The energy is -0.5 for every such orbit, so how far the end differs is the integration’s error. The work grows with the number of steps. |
3.42 geography — declared fields
The scripts of §3.44 write Region, Border, Place and Box under the sources "regions", "map" and "places", and you may write the same fields yourself. A region, a border, a place and a box are each named by you. A region’s parent is the name of another region, and a border’s a and b are the names of the two regions it lies between. A level is any word you use for what kind of region it is, such as "country", "county" or "municipality". Latitude and longitude are in degrees, north and east positive.
Region
| Field | Class | Notes |
|---|---|---|
parent |
string |
The name of the region this one lies in directly. Absent for a region that lies in none you record. |
level |
string |
What kind of region it is, in any word you use. |
colour |
string |
The colour a map gives it. |
holds |
int |
Concluded by a rule (§3.43). Never written. How many regions lie within it at any depth, each counted once. Absent for a region that holds none. |
Border
| Field | Class | Notes |
|---|---|---|
a |
string |
The name of the first region, a Region. |
b |
string |
The name of the second region. A border is named <a>_<b> by the script that writes it. |
Place
| Field | Class | Notes |
|---|---|---|
lat |
real |
Latitude in degrees, from -90 to 90, north positive. |
lon |
real |
Longitude in degrees, from -180 to 180, east positive. |
Box
| Field | Class | Notes |
|---|---|---|
south |
real |
The southern edge, a latitude in degrees. |
north |
real |
The northern edge, a latitude in degrees. A box whose south lies north of its north holds no place. |
west |
real |
The western edge, a longitude in degrees. |
east |
real |
The eastern edge, a longitude in degrees. A box whose west lies east of its east crosses the antimeridian, 180°, and holds the longitudes from west round to east. A box whose two edges are equal is that one meridian. |
Within, Neighbour, Clash and Inside declare no field. Each is a relation between two subjects, concluded by the rules of §3.43 and never written: Within. for a region r and a region p it lies within, Neighbour. and Clash. for two regions, and Inside. for a place p and a box b. They are declared so that reading one that does not stand answers empty.
3.43 geography — standing rules
Each holds continuously, as in §3.17. A rule over several subjects binds them as the cell names them: a region as r, x or y and, above it, as p and q along a line of containment, or as o for the region that holds the others; a border as b; and a place as p and a box as b.
| Rule | Over | Concludes | While |
|---|---|---|---|
within_parent |
Region |
Within |
the region’s parent names a region. Concludes Within. |
within_further |
Region |
Within |
Within. holds and the region p has a parent that names a region q. Concludes Within. |
holds |
Region |
holds |
Within. holds for some regions r; the region o takes the number of distinct such regions |
neighbour_ab |
Border, Region |
Neighbour |
the border’s a names a region x and its b names a region y. Concludes Neighbour. |
neighbour_ba |
Border, Region |
Neighbour |
the same border, the other way. Concludes Neighbour. |
clash |
Region |
Clash |
Neighbour. holds and the two regions have the same colour. Concludes Clash. |
inside |
Place, Box |
Inside |
the box’s west is not east of its east, the place’s lat is from the box’s south to its north, and its lon is from the box’s west to its east, the edges included |
inside_before_antimeridian |
Place, Box |
Inside |
the box’s west lies east of its east, the place’s lat is from the box’s south to its north, and its lon is at or east of the box’s west |
inside_after_antimeridian |
Place, Box |
Inside |
the box’s west lies east of its east, the place’s lat is from the box’s south to its north, and its lon is at or west of the box’s east |
geography declares no standing constraint. Six notes that are contract rather than commentary:
- A region is a name
region()has recorded.Withinruns only between regions that have a field written, so aparentthat names a region nobody recorded concludes nothing until that region is recorded, and the readers of §3.44 list only regions recorded with alevel. Record the outermost region too, with""for its parent. - A move withdraws what it no longer supports. Writing a region under the same source with another
parentreplaces the first, andWithinandholdsfollow: the region leaves every region above its old parent. Passing""for a parent writes nothing, so it does not withdraw a parent an earlier call recorded; write the parent you mean. - A box across the antimeridian is the two ranges it covers. Its longitudes are compared as written, with no wrapping: a place is within when its
lonis at or east of the box’swest, or at or west of itseast. - A colour clash is between neighbours.
Clash.holds for each border whose two regions have the samex. y colour, both ways round. A region with nocolourclashes with nothing. holdscounts regions, not levels. It is the number of regions within a region at any depth, whatever theirlevel.- Disagreement is reasoned about, not resolved. When two sources give a field two values, every value is reasoned about, and a conclusion stands if any value on record supports it. A region two sources place in two parents lies within both of them, and everything above each; a place two sources put at two latitudes lies in every box either latitude falls in, and a region reached by two paths is held once.
unsettled()names what the sources disagree about.
3.44 geography — queries
Called by name after import geography. No query refuses because sources disagree: a reader answers every value in force, and unsettled() names what is in disagreement. The five writers write under the sources "regions", "map" and "places", so writing the same fact again is a correction and a write under another source is a disagreement. The calculations write nothing and return unrounded numbers. Angles that are arguments or results are in degrees, except where a script says radians; distances are in metres.
| Query | Answers |
|---|---|
region(name, parent, level) |
Nothing. Writes the region name’s level under the source "regions", and its parent only when it is not "". |
border(a, b) |
Nothing. Writes a border named <a>_<b> between the regions a and b, its a and b under the source "map". |
colour(name, c) |
Nothing. Writes the region name’s colour under the source "map". |
place(name, lat, lon) |
Nothing. Writes the place name’s lat and lon under the source "places". |
box(name, south, north, west, east) |
Nothing. Writes the box name’s four edges under the source "places". |
paint(palette) |
Nothing. Writes, under the source "map", the colour that dsatur() chooses for each region, colour number k as palette[k]. The palette needs as many colours as the map does; a shorter one is refused part way, after the colours it reached are written. |
regions() |
Every region recorded with a level, sorted. |
within(name) |
Every region the region name lies within, at any depth, sorted. Empty for a name that is not a recorded region. |
regions_in(name, at) |
Every region within the region name whose level is at, or at any level when at is "", sorted. |
neighbours(name) |
Every recorded region that shares a border with the region name, sorted. |
clashes() |
Every pair of neighbours the map gives one colour, as "x y" with x before y, sorted. |
places_in(name) |
Every place within the box name, edges included, sorted. |
unsettled() |
Every region, border, place and box for which a field it writes among parent, level, colour, a, b, lat, lon, south, north, west and east holds two different values in force, as its kind in lower case, its name and the field, place oslo lat, sorted. |
dsatur() |
A colour number, from 0, for every region named in a border, as a dictionary from region to number, chosen by Brélaz’s DSatur: each step colours the region whose neighbours already show the most colours, the most neighbours breaking a tie and then the name, with the lowest number none of them shows. No two neighbours get one number. Not guaranteed to use the fewest. Writes nothing. |
mean_radius() |
The Earth’s mean radius, 6371008.8 metres, which is (2a + b) / 3 of the WGS84 ellipsoid as the IUGG rounds it. |
central_angle(lat1, lon1, lat2, lon2) |
The angle between two points seen from the sphere’s centre, in radians, by the haversine formula, each coordinate taken modulo 360 degrees by math. first. Where the haversine falls below the smallest normal real, its root is the math. of the roots of its two terms. |
haversine(lat1, lon1, lat2, lon2) |
The great-circle distance between two points on the sphere of mean_radius(), in metres. |
bearing(lat1, lon1, lat2, lon2) |
The initial bearing of the great circle from the first point to the second, clockwise from north, from 0 to 360, each coordinate taken modulo 360 degrees by math. first. 0.0 for two points that coincide. |
destination(lat, lon, heading, distance) |
The point reached by setting out from a point on a bearing heading and keeping to the great circle for distance metres on the sphere: a list [lat, lon], lon from -180 to 180. Each angle is taken modulo 360 degrees by math. first. |
spherical_excess(lat1, lon1, lat2, lon2, lat3, lon3) |
The spherical excess of the triangle with the three points as corners, in radians, by L’Huilier’s theorem from its sides: the amount by which its angles sum past π. 0.0 when the three points lie on one great circle or coincide. Where the product of the four tangents L’Huilier multiplies is not a normal real, its root is taken on the mantissas and exponents math. gives. |
triangle_area(lat1, lon1, lat2, lon2, lat3, lon3) |
The area of that triangle on the sphere of mean_radius(), in square metres: the excess times the radius squared. |
mercator(lat) |
The Mercator projection’s northing for a latitude, in units of the sphere’s radius: ln(tan(45° + φ/. Defined strictly between -90 and 90. |
mercator_inverse(y) |
The latitude, in degrees, that a Mercator northing y comes from. |
mercator_scale(lat) |
How much the projection enlarges a short distance at a latitude, 1 / cos φ. |
dms(x) |
An angle as a list [degrees, minutes, seconds], whole degrees and whole minutes and the remainder as seconds, each carrying the angle’s sign. |
vincenty_inverse(lat1, lon1, lat2, lon2) |
The distance between two points on the WGS84 ellipsoid, by Vincenty’s iteration of 1975: a list [metres, the azimuth from the first point to the second, the azimuth from the second point back to the first, rounds], azimuths in degrees from 0 to 360. Two points that coincide answer [0.0, 0.0, 0.0, 1.0]. Near antipodal points the iteration need not converge: after 200 rounds it stops and answers [0.0, 0.0, 0.0, -1.0]. Each coordinate is taken modulo 360 degrees by math. first, and where the square of the sine of the arc falls below the smallest normal real, the sine is a math.. |
vincenty_direct(lat1, lon1, az1, s) |
The point a distance s metres along the geodesic from a point at azimuth az1 degrees, on the WGS84 ellipsoid, by Vincenty’s direct method: a list [lat, lon, the azimuth from there back to the start], lon from -180 to 180. The latitude and the azimuth are taken modulo 360 degrees by math. first. |
The ellipsoid’s constants are those of WGS84: semi-major axis 6378137.0 metres and flattening 1 / 298.257223563.
3.45 mathematics — declared fields
The writing scripts of §3.48 write Number and Candidate under the source "numbers", Operation, Element, Cell and Triple under the source "table", and Triangle under the source "figures", and you may write the same fields yourself. A number is a whole number from 1 up, named n followed by its value, so the number 28 is n28. A candidate is one number tried as a divisor of another, from 1 to half of it, since no proper divisor is larger. An operation is a binary operation on a finite set, given as its table: its elements are named by labels you choose, and its cells are the products of the table, a · b = c. A triple is three elements taken in order, x, y and z, the case that associativity quantifies over. A triangle is three sides in whole units. An element is named <operation>_<label>, a cell <operation>_<a>_<b> and a triple <operation>_<x>_<y>_<z>, and a label that holds an underscore makes those names ambiguous to the readers of §3.48.
Number
| Field | Class | Notes |
|---|---|---|
n |
int |
The value, at least 1. |
divisor_count |
int |
Concluded by a rule (§3.47): how many of its candidates divide it. Never written. |
claims |
int |
Concluded by a rule (§3.47): how many claims of k those candidates hold. Never written. |
disputed |
bool |
Concluded by a rule (§3.47): claims is greater than divisor_count. Never written. |
divisor_sum |
int |
Concluded by a rule (§3.47). The sum of its proper divisors, each divisor but itself. Never written; absent for 1, which has none. |
prime |
bool |
Concluded by a rule (§3.47). Never written. |
composite |
bool |
Concluded by a rule (§3.47). Never written. |
perfect |
bool |
Concluded by a rule (§3.47). Never written. |
abundant |
bool |
Concluded by a rule (§3.47). Never written. |
deficient |
bool |
Concluded by a rule (§3.47). Never written. |
Candidate
| Field | Class | Notes |
|---|---|---|
of |
string |
The Number the candidate is tried against. |
n |
int |
That number’s value. |
k |
int |
The candidate divisor, from 1 to half of n. |
divides |
bool |
Concluded by a rule (§3.47). Never written. |
Operation
| Field | Class | Notes |
|---|---|---|
order |
int |
How many elements the set has. |
identity |
string |
Concluded by a rule (§3.47). The label of the element that leaves every element as it is from either side. Never written; absent where there is none. |
closed |
bool |
Concluded by a rule (§3.47). Never written. |
commutative |
bool |
Concluded by a rule (§3.47). Never written. |
associative |
bool |
Concluded by a rule (§3.47). Never written. |
group |
bool |
Concluded by a rule (§3.47). Never written. |
abelian |
bool |
Concluded by a rule (§3.47). Never written. |
Element
| Field | Class | Notes |
|---|---|---|
op |
string |
The Operation whose set the element belongs to. |
el |
string |
The element’s label. |
identity |
bool |
Concluded by a rule (§3.47). Never written. |
invertible |
bool |
Concluded by a rule (§3.47). Never written. |
noninvertible |
bool |
Concluded by a rule (§3.47). Never written. |
Cell
| Field | Class | Notes |
|---|---|---|
op |
string |
The Operation the cell belongs to. |
a |
string |
The label of the left factor. |
b |
string |
The label of the right factor. |
c |
string |
The label of the product a · b, as the table gives it. A label that is not an element’s is an error of the table, which outside marks. |
left |
string |
The name of the Element that is the left factor. |
right |
string |
The name of the Element that is the right factor. |
outside |
bool |
Concluded by a rule (§3.47). Never written. |
noncommuting |
bool |
Concluded by a rule (§3.47). Never written. |
to_identity |
bool |
Concluded by a rule (§3.47). Never written. |
twosided |
bool |
Concluded by a rule (§3.47). Never written. |
Triple
| Field | Class | Notes |
|---|---|---|
op |
string |
The Operation the triple belongs to. |
x |
string |
The label of the first element. |
z |
string |
The label of the third element. The second is named by xy and yz. |
xy |
string |
The name of the Cell x · y. |
yz |
string |
The name of the Cell y · z. |
left |
string |
Concluded by a rule (§3.47). The label of (x · y) · z. Never written. |
right |
string |
Concluded by a rule (§3.47). The label of x · (y · z). Never written. |
breaks |
bool |
Concluded by a rule (§3.47). Never written. |
Triangle
| Field | Class | Notes |
|---|---|---|
a |
int |
The shortest side, in whole units. |
b |
int |
The middle side. |
c |
int |
The longest side. The rules read c as the longest, so write the three in order. |
acute |
bool |
Concluded by a rule (§3.47). Never written. |
right |
bool |
Concluded by a rule (§3.47). Never written. |
obtuse |
bool |
Concluded by a rule (§3.47). Never written. |
equilateral |
bool |
Concluded by a rule (§3.47). Never written. |
isosceles |
bool |
Concluded by a rule (§3.47). Never written. |
scalene |
bool |
Concluded by a rule (§3.47). Never written. |
A triangle has six further fields that are computed rather than written or concluded, and Candidate one: §3.46 defines them.
3.46 mathematics — derived fields
| Field | Definition |
|---|---|
Candidate. |
n % k |
Triangle. |
a + b + c |
Triangle. |
a * a + b * b - c * c |
Triangle. |
a + b - c |
Triangle. |
(a + b + c) * (b + c - a) * (a + c - b) * (a + b - c) |
Triangle. |
slack > 0 |
remainder is what is left when the candidate k divides n. perimeter is the sum of the three sides. gap is a² + b² − c², whose sign is the sign of the cosine of the angle facing the longest side: positive for an acute angle, 0 for a right one and negative for an obtuse one. slack is a + b − c, which is positive exactly when three lengths close up into a triangle, and valid says so; a degenerate triangle, whose slack is 0, is not valid. heron is sixteen times the square of the triangle’s area, a whole number for whole sides. Each is absent until the fields it reads are present, and heron is also absent when the product passes 9,223,372,036,854,775,807, as for three equal sides of 42,000 units. All six are integers, except valid, which is a bool.
3.47 mathematics — standing rules
Each holds continuously, as in §3.17. A rule over a Number binds it as x and a Candidate as d; over an Operation as t or o, an Element as e or u, a Cell as c, p or q, a Triple as t and a Triangle as t.
| Rule | Over | Concludes | While |
|---|---|---|---|
divides |
Candidate |
divides |
the candidate’s remainder is 0; concludes True |
number_claims |
Number, Candidate |
claims |
the candidate’s of names the number, it divides and its k > -1000000000000000000; the number takes the number of claims of k those candidates hold |
number_divisors |
Number, Candidate |
divisor_count |
the candidate’s of names the number, it divides and its k > -1000000000000000000; the number takes the number of distinct such candidates |
number_disputed |
Number |
disputed |
the number’s claims is greater than its divisor_count; concludes True |
divisor_sum |
Number, Candidate |
divisor_sum |
the candidate’s of names the number, it divides and the number has no disputed; the number takes the sum of those candidates’ k |
composite |
Number, Candidate |
composite |
the candidate’s of names the number, its k > 1 and it divides; concludes True |
prime |
Number |
prime |
the number’s n > 1 and no candidate of it with k > 1 divides; concludes True |
perfect |
Number |
perfect |
the number’s divisor_sum equals its n; concludes True |
abundant |
Number |
abundant |
the number’s divisor_sum exceeds its n; concludes True |
deficient |
Number |
deficient |
the number’s divisor_sum falls short of its n; concludes True |
one_is_deficient |
Number |
deficient |
the number’s n is 1, which has no divisor_sum; concludes True |
identity |
Element |
identity |
no cell whose left names the element has a c other than its b, and no cell whose right names it has a c other than its a; concludes True |
operation_identity |
Operation, Element |
identity |
the element’s op names the operation and it is identity; the operation takes the element’s el |
outside |
Cell |
outside |
no element of the cell’s operation has an el equal to the cell’s c; concludes True |
closed |
Operation |
closed |
no cell of the operation is outside; concludes True |
noncommuting |
Cell |
noncommuting |
a cell of the same operation has its a equal to this cell’s b, its b equal to this cell’s a and a different c; concludes True |
commutative |
Operation |
commutative |
no cell of the operation is noncommuting; concludes True |
bracket_left |
Triple, Cell |
left |
the triple’s xy names a cell p, and a cell q of the same operation has its a equal to the c of p and its b equal to the triple’s z; the triple takes the c of q |
bracket_right |
Triple, Cell |
right |
the triple’s yz names a cell r, and a cell s of the same operation has its a equal to the triple’s x and its b equal to the c of r; the triple takes the c of s |
breaks |
Triple |
breaks |
the triple’s left differs from its right; concludes True |
associative |
Operation |
associative |
no triple of the operation breaks; concludes True |
to_identity |
Cell, Operation |
to_identity |
the cell’s op names the operation and its c equals the operation’s identity; concludes True |
twosided |
Cell |
twosided |
a cell of the same operation has its a equal to this cell’s b and its b equal to this cell’s a, and both cells are to_identity; concludes True |
invertible |
Element, Cell |
invertible |
a cell whose left names the element is twosided; concludes True |
noninvertible |
Element |
noninvertible |
another element u of the same operation is the identity, and no cell whose left names the element is twosided; concludes True |
group |
Operation, Element |
group |
an element of the operation is the identity, the operation is closed and associative, and no element of it is noninvertible; concludes True |
abelian |
Operation |
abelian |
the operation is a group and commutative; concludes True |
acute |
Triangle |
acute |
the triangle is valid and its gap > 0; concludes True |
right |
Triangle |
right |
the triangle is valid and its gap is 0; concludes True |
obtuse |
Triangle |
obtuse |
the triangle is valid and its gap < 0; concludes True |
equilateral |
Triangle |
equilateral |
the triangle is valid and a, b and c are equal; concludes True |
isosceles_base |
Triangle |
isosceles |
the triangle is valid and its a equals its b; concludes True |
isosceles_top |
Triangle |
isosceles |
the triangle is valid and its b equals its c; concludes True |
scalene |
Triangle |
scalene |
the triangle is valid, its a is less than its b and its b is less than its c; concludes True |
mathematics declares no standing constraint. Seven notes that are contract rather than commentary:
- A number is judged by the candidates written for it.
primeasks that no candidate above 1 divide the number, and the candidates are the facts you ornumber()wrote, from 1 to half of it. A number written with no candidate and above 1 is concludedprime, and has nodivisor_sum. The number 1 is neitherprimenorcomposite, has nodivisor_sumand isdeficient. Every number above 1 has adivisor_sum, which counts the divisor 1. - A property is judged over the table given.
closed,commutativeandassociativehold when no cell or triple of the table breaks them, and each withdraws when a cell it rests on is rewritten. A triple whose bracket leaves the set has no result to compare and is not judged, so a table that is notclosedcan still be reportedassociative;grouprequires both. - An inverse is two-sided and needs an identity.
invertibleasks that some product of the element with another give the identity from both sides.noninvertibleis concluded only where the operation has anidentity: an operation with none has no element marked either way, and is not agroup. - A triangle is judged only when its sides close up.
acute,right,obtuseand the three by sides are concluded only for avalidtriangle, one whoseslackis positive. Three lengths that do not close up, or that lie flat, have no kind.isoscelesincludes the equilateral. - The sides are read in order.
gapandslacktakecas the longest side.triangle()writes the three sorted; sides you write yourself must already be. - Disagreement is reasoned about, not resolved. When two sources give a field two values, every value is reasoned about, and a conclusion stands if any value on record supports it. A cell given two products breaks commutativity or associativity if either one does, and a number given two values is classified by both. A divisor sum reads every value of a
k, so a candidate whoseka second source writes, even the samek, would be added twice;divisor_countandclaimscount the divisors and their claims over the one binding the sum reads, and while the claims are more the number isdisputedand has nodivisor_sum,perfect,abundantordeficient. A candidate whoseofholds two values is added to each number it names, each divisor sum being one source’s. - No rule reads the mathematics. Every rule compares or adds whole numbers, or compares labels. That a table is the operation it was meant to be, or that a set of labels is the set the operation acts on, is not asked.
3.48 mathematics — queries
Called by name after import mathematics. No query refuses because sources disagree: a reader answers every value in force, and unsettled() names what is in disagreement. The writers and readers of the first two groups are the interface to the facts; the rest compute values from their arguments and write nothing. An int is 64 bits, and a result past 9,223,372,036,854,775,807 refuses as an overflow rather than wrapping.
| Query | Answers |
|---|---|
number(v) |
Nothing. Writes the number named n followed by v, with its value, and a candidate for each k from 1 to v // 2, each named for the number, _ and k, with its of, n and k, under the source "numbers". |
numbers(lo, hi) |
Nothing. Writes number(v) for every v from lo to hi. The candidates grow as the square of hi, so it is for numbers in the hundreds. |
operation(name, elements, table) |
Nothing. Writes the operation name with its order, an element for each label of elements, a cell for each pair, table[i][j] being elements[i] · elements[j], and a triple for each three elements in order, under the source "table". It writes n² cells and n³ triples for n elements, so it is for tables of a few elements. |
cell(name, a, b, c) |
Nothing. Writes the product of the cell a · b of operation name as c, under the source "table". Writing it again corrects it. |
triangle(name, x, y, z) |
Nothing. Writes the triangle name with its three sides sorted into a, b and c, under the source "figures". |
numbers_that_are(property) |
The values of every number that is "prime", "composite", "perfect", "abundant", "deficient" or "disputed", each once, sorted. Any other property reads as "deficient". |
divisors(v) |
The proper divisors of the number v, sorted: the candidates the rules found to divide it. Empty for a number not written. |
properties(name) |
The properties that hold of operation name, from "closed", "commutative", "associative", "group" and "abelian", in that order. |
identity_of(name) |
The label of the identity of operation name, "" where it has none. |
noncommuting_pairs(name) |
Every pair "a b" of operation name whose products a · b and b · a differ, sorted. |
nonassociative_triples(name) |
Every three elements "x y z" of operation name for which (x · y) · z and x · (y · z) differ, sorted. |
without_inverse(name) |
Every element of operation name, which must have an identity, that has no two-sided inverse, sorted. |
kinds(name) |
What triangle name is, from "acute", "right", "obtuse", "equilateral", "isosceles" and "scalene", in that order; empty where its sides make no triangle. |
area(name) |
The area of triangle name by Heron’s formula, math.; 0.0 where its sides make no triangle. It refuses for a triangle not written, and for one whose heron is absent (§3.46). |
unsettled() |
Each number, candidate, cell and triangle side that holds two different values in force for a field you write: a number’s n, a candidate’s k, a cell’s c, or a triangle’s a, b or c. Given as number x n, candidate x k, cell x c, or triangle x a, triangle x b or triangle x c, sorted. |
gcd(a, b) |
The greatest common divisor of a and b by Euclid’s algorithm, taking their absolute values; no pair of 64-bit numbers needs more than 93 steps. |
lcm(a, b) |
The least common multiple, abs(a) // gcd(a, b) * abs(b); 0 when either is 0. |
extended_gcd(a, b) |
A list [g, x, y] with a * x + b * y = g, the greatest common divisor, by the extended Euclidean algorithm, for a and b at least 0. |
modinv(a, m) |
The inverse of a modulo m, from 1 to m - 1, or 0 where a and m share a factor and there is none. m is at least 2. |
modpow(b, e, m) |
b to the power e modulo m by repeated squaring, for e at least 0 and m from 1 to 3,037,000,499, so that the product of two remainders fits in an int. |
isqrt(n) |
The largest whole number whose square is at most n, for n at least 0, by Newton’s method in whole numbers. |
is_prime(n) |
Whether n is prime, by the Miller–Rabin test to the bases 2, 3, 5 and 7, which decide every n below 3,215,031,751. n is at most 3,037,000,499, the bound of modpow. |
factorize(n) |
The prime factors of n, at least 2, smallest first and each as often as it divides n, by trial division. Its steps grow as the square root of n’s second largest prime factor. |
totient(n) |
Euler’s totient: how many of 1 to n share no factor with n. |
primes(n) |
Every prime up to n, by the sieve of Eratosthenes. The sieve holds n values, so n is for the thousands. |
factorial(n) |
n!, for n from 0 to 20; 21! refuses. |
binomial(n, k) |
n choose k, exactly, 0 for k below 0 or above n. Only a coefficient past 2⁶³ − 1 refuses. |
fibonacci(n) |
The n-th Fibonacci number, F(0) = 0 and F(1) = 1, for n from 0 to 92; F(93) refuses. |
collatz(n) |
How many steps n takes to reach 1, halving an even number and taking 3n + 1 for an odd one; -1 if it has not reached 1 in 1,024 steps. |
continued_fraction(p, q) |
The terms [a0; a1, a2, …] of the fraction p / q, as a list, for q at least 1, by Euclid’s algorithm. |
convergents(terms) |
The convergents [p, q] of a continued fraction, one for each term, as a list of pairs. terms has at least one term. |
sqrt_period(n) |
The continued fraction of the square root of n: [a0, a1, …, ar], where a1 to ar repeat forever and ar is 2 * a0. [a0] alone for a square. |
pell(n) |
The smallest x and y at least 1 with x * x - n * y * y = 1, as [x, y], for n not a square. It refuses only where x itself passes 2⁶³ − 1. |
root(x, k) |
The k-th root of x by Newton’s method from above, stopped when a step no longer brings it down, for x above 0 and k at least 1. |
trapezoid(ys, h) |
The integral of a function sampled at equal steps h by the trapezoidal rule. Where the sum, or the sum times h, passes the largest real while every sample and h are reals, it is summed again with each sample scaled by a power of two and the integral scaled back. |
simpson(ys, h) |
The integral of a function sampled at equal steps h by Simpson’s rule, over an odd number of samples. Where the sum, or the sum times h, passes the largest real, it is taken again as trapezoid does. |
machin() |
π by Machin’s formula of 1706, 4 * (4 * math.. |
determinant(m) |
The determinant of a square matrix by Gaussian elimination with partial pivoting: at each column, the row with the largest entry. 0.0 where a pivot is 0. The product of the pivots is kept as a mantissa and a power of two, as math. gives them. Where an entry passes the largest real on the way, or a multiplier falls below the smallest normal real and loses the row it scales, while every entry is a real, it is taken again with each row scaled by a power of two that brings its largest entry near 1, and the powers added back. |
solve(m, b) |
The x with m · x = b, by Gaussian elimination with partial pivoting and back substitution, as a list; [] where a pivot is 0, that is where m is singular. Where x passes the range of a real, or a pivot or a multiplier falls below the smallest normal real, while m and b are reals, it is solved again with each row of m scaled by a power of two that brings its largest entry near 1, and b by another, and x scaled back. |
hilbert(n) |
The n by n Hilbert matrix, 1 / (i + j + 1) for row i and column j from 0, whose determinant falls toward zero faster than elimination can follow. |
3.49 statistics — declared fields
The writing scripts of §3.52 write Stratum under the source "strata", Screen under "screens" and Significance under "tests", and you may write the same fields yourself. A study is named by you. A stratum is one part of a study in which two arms, A and B, were each tried, and is named <study>_<name>, the study’s name, an underscore and a name of its own. A screen is a screening test and a significance a test result, each named by you. stratum() also writes the Study it belongs to, giving its label the study’s name, under the source "strata". Rates and probabilities are numbers from 0 to 1.
Stratum
| Field | Class | Notes |
|---|---|---|
study |
string |
The name of the Study the stratum is part of. |
a_yes |
int |
Successes among arm A’s trials in the stratum. |
a_n |
int |
Arm A’s trials in the stratum. |
b_yes |
int |
Successes among arm B’s trials in the stratum. |
b_n |
int |
Arm B’s trials in the stratum. |
a_rate |
real |
Computed from a_yes and a_n (§3.50). Never written. |
b_rate |
real |
Computed from b_yes and b_n (§3.50). Never written. |
a_wins |
bool |
Computed from the two rates (§3.50). Never written. |
b_wins |
bool |
Computed from the two rates (§3.50). Never written. |
Study
| Field | Class | Notes |
|---|---|---|
label |
string |
The study’s name. Written by stratum(). |
a_yes_strata |
int |
Concluded by a rule (§3.51): how many of its strata hold a a_yes. Never written. |
a_n_strata |
int |
Concluded by a rule (§3.51): how many of its strata hold a a_n. Never written. |
b_yes_strata |
int |
Concluded by a rule (§3.51): how many of its strata hold a b_yes. Never written. |
b_n_strata |
int |
Concluded by a rule (§3.51): how many of its strata hold a b_n. Never written. |
a_yes_claims |
int |
Concluded by a rule (§3.51): how many claims of a_yes those strata hold. Never written. |
a_n_claims |
int |
Concluded by a rule (§3.51): how many claims of a_n those strata hold. Never written. |
b_yes_claims |
int |
Concluded by a rule (§3.51): how many claims of b_yes those strata hold. Never written. |
b_n_claims |
int |
Concluded by a rule (§3.51): how many claims of b_n those strata hold. Never written. |
a_yes_disputed |
bool |
Concluded by a rule (§3.51): a_yes_claims is greater than a_yes_strata. Never written. |
a_n_disputed |
bool |
Concluded by a rule (§3.51): a_n_claims is greater than a_n_strata. Never written. |
b_yes_disputed |
bool |
Concluded by a rule (§3.51): b_yes_claims is greater than b_yes_strata. Never written. |
b_n_disputed |
bool |
Concluded by a rule (§3.51): b_n_claims is greater than b_n_strata. Never written. |
a_yes |
int |
Concluded by a rule (§3.51): the sum of its strata’s a_yes. Never written. |
a_n |
int |
Concluded by a rule (§3.51): the sum of its strata’s a_n. Never written. |
b_yes |
int |
Concluded by a rule (§3.51): the sum of its strata’s b_yes. Never written. |
b_n |
int |
Concluded by a rule (§3.51): the sum of its strata’s b_n. Never written. |
a_rate |
real |
Computed from the pooled counts (§3.50). Never written. |
b_rate |
real |
Computed from the pooled counts (§3.50). Never written. |
pooled_a_ahead |
bool |
Computed from the pooled rates (§3.50). Never written. |
pooled_b_ahead |
bool |
Computed from the pooled rates (§3.50). Never written. |
paradox |
bool |
Concluded by a rule (§3.51). Never written. |
Screen
| Field | Class | Notes |
|---|---|---|
prevalence |
real |
How common the condition is among those screened. |
sensitivity |
real |
The chance a positive result is given to someone who has the condition. |
specificity |
real |
The chance a negative result is given to someone who does not. |
ppv |
real |
Computed (§3.50). The chance that a positive result is right. Never written. |
npv |
real |
Computed (§3.50). The chance that a negative result is right. Never written. |
mostly_false |
bool |
Computed (§3.50). Never written. |
Significance
| Field | Class | Notes |
|---|---|---|
p |
real |
The test’s p-value. |
alpha |
real |
The level the result is held to. |
significant |
bool |
Computed from the two (§3.50). Never written. |
3.50 statistics — derived fields
| Field | Definition |
|---|---|
Stratum. |
a_yes / a_n |
Stratum. |
b_yes / b_n |
Stratum. |
a_rate > b_rate |
Stratum. |
b_rate > a_rate |
Study. |
a_yes / a_n |
Study. |
b_yes / b_n |
Study. |
a_rate > b_rate |
Study. |
b_rate > a_rate |
Screen. |
prevalence * sensitivity / (prevalence * sensitivity + (1.0 - prevalence) * (1.0 - specificity)) |
Screen. |
(1.0 - prevalence) * specificity / ((1.0 - prevalence) * specificity + prevalence * (1.0 - sensitivity)) |
Screen. |
ppv < 0.5 |
Significance. |
p < alpha |
A stratum’s a_rate is the share of arm A’s trials that succeeded, and a_wins says that arm A’s rate is strictly higher than arm B’s; two equal rates make neither arm win. The Study fields of the same names are the same quantities over the pooled counts. ppv and npv are Bayes’ rule: ppv is the share of positive results that are right, prevalence * sensitivity over all the positive results there would be, and npv the share of negative results that are right. mostly_false is True where ppv is below one half, a positive result more likely wrong than right. significant is True where p is strictly below alpha; a p equal to alpha is not significant. Each is absent until the fields it reads are present. A rate whose trials are 0 is absent, and so are the wins of its stratum; ppv is absent where the prevalence is 0 and the specificity 1, since there are no positive results to value, and npv where the prevalence is 1 and the sensitivity 1. a_yes, a_n, b_yes and b_n are whole numbers, significant, mostly_false and the four wins and ahead fields are bool, and the rest are real.
3.51 statistics — standing rules
Each holds continuously, as in §3.17. A rule over a study and a stratum binds them as t and s.
| Rule | Over | Concludes | While |
|---|---|---|---|
study_a_yes_strata |
Study, Stratum |
a_yes_strata |
the stratum’s study names the study and its a_yes > -1000000000000000000; the study takes the number of distinct such strata |
study_a_n_strata |
Study, Stratum |
a_n_strata |
the stratum’s study names the study and its a_n > -1000000000000000000; the study takes the number of distinct such strata |
study_b_yes_strata |
Study, Stratum |
b_yes_strata |
the stratum’s study names the study and its b_yes > -1000000000000000000; the study takes the number of distinct such strata |
study_b_n_strata |
Study, Stratum |
b_n_strata |
the stratum’s study names the study and its b_n > -1000000000000000000; the study takes the number of distinct such strata |
study_a_yes_claims |
Study, Stratum |
a_yes_claims |
the stratum’s study names the study and its a_yes > -1000000000000000000; the study takes the number of claims of a_yes those strata hold |
study_a_n_claims |
Study, Stratum |
a_n_claims |
the stratum’s study names the study and its a_n > -1000000000000000000; the study takes the number of claims of a_n those strata hold |
study_b_yes_claims |
Study, Stratum |
b_yes_claims |
the stratum’s study names the study and its b_yes > -1000000000000000000; the study takes the number of claims of b_yes those strata hold |
study_b_n_claims |
Study, Stratum |
b_n_claims |
the stratum’s study names the study and its b_n > -1000000000000000000; the study takes the number of claims of b_n those strata hold |
study_a_yes_disputed |
Study |
a_yes_disputed |
the study’s a_yes_claims is greater than its a_yes_strata; concludes True |
study_a_n_disputed |
Study |
a_n_disputed |
the study’s a_n_claims is greater than its a_n_strata; concludes True |
study_b_yes_disputed |
Study |
b_yes_disputed |
the study’s b_yes_claims is greater than its b_yes_strata; concludes True |
study_b_n_disputed |
Study |
b_n_disputed |
the study’s b_n_claims is greater than its b_n_strata; concludes True |
fold_a_yes |
Study, Stratum |
a_yes |
the stratum’s study names the study and the study has no a_yes_disputed; the study takes the sum of those strata’s a_yes |
fold_a_n |
Study, Stratum |
a_n |
the stratum’s study names the study and the study has no a_n_disputed; the study takes the sum of those strata’s a_n |
fold_b_yes |
Study, Stratum |
b_yes |
the stratum’s study names the study and the study has no b_yes_disputed; the study takes the sum of those strata’s b_yes |
fold_b_n |
Study, Stratum |
b_n |
the stratum’s study names the study and the study has no b_n_disputed; the study takes the sum of those strata’s b_n |
paradox_b_ahead_in_the_pool |
Study |
paradox |
the study’s pooled_b_ahead is True and no stratum of it has an a_wins other than True; concludes True |
paradox_a_ahead_in_the_pool |
Study |
paradox |
the study’s pooled_a_ahead is True and no stratum of it has a b_wins other than True; concludes True |
statistics declares no standing constraint. Seven notes that are contract rather than commentary:
- A study is the sum of its strata. The four folds add every stratum whose
studynames the study, so a stratum written again with other counts changes the pooled rates and withdraws every conclusion that rested on the old ones, aparadoxamong them. A study with no stratum written has no pooled counts. - A pooled count is not drawn from a stratum bound to it twice. A fold reads every value of the count it sums, so a stratum whose count a second source writes, even the same number, would be added twice. The
_strataand_claimsfields count the strata and their claims of each count over the one binding its fold reads, and while the claims are more, that count is disputed and not pooled, nor are the rate and the paradox that rest on it; a count both sources agree on is pooled. A stratum with no value of a count is in neither of its counts, so it hides no dispute. A stratum whosestudyholds two values counts in each it names, and each of those pools is one source’s. - A paradox is a reversal, and only that.
paradoxis concluded for a study when one arm is strictly ahead in the pool and the other arm is strictly ahead in every stratum that has rates. It is not concluded for a study in which the two arms are level in some stratum, or in which the arm ahead in the pool is ahead in a stratum too, however far the pooled rate differs from the strata’s. A stratum with no trials has nowinsand does not stand in its way. - The two figures a screen is judged by are not the test’s.
ppvandnpvdepend on theprevalenceas much as on the sensitivity and specificity, and the rules assume the people screened are drawn from the population the prevalence describes. A test of the same sensitivity and specificity can have appvof 0.08 at a prevalence of 0.01 and 0.69 at 0.2. - A test result is a comparison.
significantcompares thepyou wrote with thealphayou wrote. Nothing computes thep, adjusts it for how many tests were run, or says whether the effect it measures matters. - Probabilities are not checked. A figure outside 0 to 1, or a count larger than its trials, is a fact like any other, and the conclusions that follow from it are as meaningful as the figure.
- Disagreement is reasoned about, not resolved. When two sources give a field two values, every value is reasoned about, and a conclusion stands if any value on record supports it. A screen whose prevalence has two values can be
mostly_falseby one and not by the other.unsettled()names the fact.pooled()andpredictive_values()are not readers of that kind: they read one value of each rate, and refuse where it is absent.
3.52 statistics — queries
Called by name after import statistics. The first three write facts and answer nothing. The next six read what the rules concluded or what was written; none refuses because sources disagree, except pooled() and predictive_values() as §3.51 says, and unsettled() names what is in disagreement. The rest are value scripts that return a value and write nothing. Floats are IEEE doubles. A sample variance needs two values, a mean needs one, and a list that is too short is the caller’s to avoid: the script refuses with a division by zero. Where a sum, square or product in a script’s work would pass the largest real, or fall below the smallest normal one, while the value it serves would not, the work is done so that it stays in range, as each row says, and the value is had; the scaling by a power of two that most rows use changes no digit of a value whose work stays in range.
| Query | Answers |
|---|---|
stratum(study, name, a_yes, a_n, b_yes, b_n) |
Nothing. Writes the Stratum named <study>_<name>’s study and four counts, and the Study named study’s label, under the source "strata". |
screen(name, prevalence, sensitivity, specificity) |
Nothing. Writes the Screen named name’s three figures under the source "screens". |
significance(name, p, alpha) |
Nothing. Writes the Significance named name’s p and alpha under the source "tests". |
paradoxes() |
The studies whose paradox holds, sorted. |
pooled(study) |
[A's pooled rate, B's pooled rate] for the study study. It refuses a study with any of the four _disputed fields, and where either rate is absent, a study with no stratum or none with trials. |
disputed_studies() |
The studies with any of the four _disputed fields, sorted. |
predictive_values(name) |
[ppv, npv] for the screen name. It refuses where either is absent. |
significant_tests() |
The tests whose significant is True, sorted. |
unsettled() |
Each stratum count, screen figure and test figure that holds two different values in force for a fact you write, given as stratum and its name and the field, screen and test likewise, stratum stones_small a_yes, sorted. |
scale_of(xs) |
The exponent e of math. of the largest finite value of xs in size, which brings that value to between 1/2 and 1 when scaled by 2^-e, where that value is at least 2^400 or under 2^-400 in size; 0 otherwise, and for a list with no finite value other than 0. |
mean(xs) |
The arithmetic mean, summed from the first value to the last. Where that sum passes the largest real while every value is finite, the values are summed again each scaled by 2^-k, k the exponent of math. of their count, and the mean of those is scaled back. xs is not empty. |
variance(xs) |
The sample variance, dividing by n - 1, by Welford’s single pass over the values scaled by 2^-e, e being scale_of(xs), scaled back by 2^(2e). xs has at least two values. |
std_dev(xs) |
The sample standard deviation: the square root of the variance of the values scaled by 2^-e, e being scale_of(xs), scaled back by 2^e, so it is had wherever it is a real, even where the variance is not. |
median(xs) |
The middle value of the sorted list, or the mean of the two middle ones, taken as the sum of their halves where their sum passes the largest real. |
regression(xs, ys) |
[intercept, slope, r]: the least-squares line y = intercept + slope * x through the points and Pearson’s correlation, computed over xs and ys each scaled by 2^-e for its own scale_of, which does not change r, the intercept scaled back by the ys’ power and the slope by the difference of the two. xs has at least two different values and ys as many values as xs. |
welch_t(xs, ys) |
Welch’s t statistic for two samples of unequal variance, computed over both samples scaled by 2^-e, e being scale_of(xs + ys), which does not change t. |
z_score(x, mu, sigma) |
(x - mu) / sigma, taken as (x/ where x - mu passes the largest real. |
normal_pdf(x, mu, sigma) |
The normal density at x. |
normal_cdf(z) |
The standard normal distribution function, 0.5 * math., so the tails keep their digits: z = -5 gives 2.8665157187919455e-07. |
normal_quantile(p) |
The z whose standard normal distribution function is p, for p strictly between 0 and 1, by 200 halvings of -40 to 40: exact to the last digit of normal_cdf. |
stirling_error(n) |
ln(n!) - ln(sqrt(2 pi n) (n/, the error of Stirling’s formula, for n from 0: a table of its values to 15, and above it the series (1/, so no two large logarithms are subtracted. 0 at n = 0. It refuses a negative n with ValueError. |
deviance(x, mean) |
x ln(x / mean) + mean - x, for a finite x from 0 and a finite mean above 0; mean at x = 0. Where x is within a factor of 3 of mean, where the plain form cancels, it is the series d v + 2 x (v^3/, d = x - mean and v = d / (x + mean), summed until a term changes nothing. It refuses other inputs with ValueError. |
exact_product(a, b) |
[a * b, the part of a * b its rounding lost], which add to a * b exactly, by Dekker’s splitting, for factors and a product under 1e300 in size. It refuses others with ValueError. |
binom_pmf(n, k, p) |
The probability of exactly k successes in n trials at chance p, for n from 0 and p from 0 to 1; 0 for a k outside 0 to n. It is C(n, k) p^k q^(n - k) (1 + r/, q being 1 - p rounded and r the exact (1 - q) - p the rounding lost, the coefficient a running product over the smaller of k and n - k, wherever both powers, the coefficient and the probability are normal reals and the run is under 515 steps, C(1030, 515) being the first coefficient past the largest real. Elsewhere it is Loader’s saddle-point form, e^(stirling_error(n) - stirling_error(k) - stirling_error(n - k) - deviance(k, n p) - deviance(n - k, n q)) / sqrt(2 pi k (n - k) / n), its means n p and n q carried with what their rounding lost by exact_product, and e^(n ln(1 - p)) or e^(n ln p) for a k of 0 or n. The product is within 17 units in its last digit to n = 5000, and Loader’s form within 6 (25 + |ln P|) of them. It refuses an n below 0 and a p outside 0 to 1 with ValueError. |
binom_cdf(n, k, p) |
The probability of at most k successes in n trials, the sum of binom_pmf from no successes. It refuses as binom_pmf does. |
poisson_pmf(k, lam) |
The probability of k events at a mean rate lam, a finite real from 0; 0 for a k below 0. It is the running product e^-lam * lam/ wherever e^-lam and the probability are normal reals, which is for a rate to about 708, stopping where a step falls below the smallest normal real, which happens only past the most likely count. Elsewhere it is Loader’s form, e^(-stirling_error(k) - deviance(k, lam)) / sqrt(2 pi k). The product is within 50 units in its last digit, and Loader’s form within 6 (25 + |ln P|) of them. It refuses a rate below 0 or infinite with ValueError. |
birthday(n) |
The chance that two of n people share a birthday, with 365 equally likely days: 23 people give 0.5072972343239855. |
bayes(prior, likelihood, false_likelihood) |
The posterior chance of a hypothesis with the given prior, after evidence that has likelihood under it and false_likelihood under its negation: prior * likelihood / (prior * likelihood + (1 - prior) * false_likelihood), each factor taken as the mantissa and the exponent math. gives, so a product too small or too large for a real still gives the posterior, and the posterior is the same to the last digit wherever the plain products are normal reals. It refuses a prior outside 0 to 1, and a likelihood below 0, with ValueError. |
chi_square(obs, exp) |
Pearson’s statistic, the sum of (observed - expected)^2 / expected, a term whose square passes the largest real or falls below the smallest normal one being taken as d * (d / expected), d the difference. It refuses an observed count below 0, and an expected count of 0 or below, with ValueError. |
chi_square_p_df1(x) |
The chance of a chi-square statistic of at least x with one degree of freedom, math.: 0.05 at 3.841458820694124. |
chi_square_p_df2(x) |
The same with two degrees of freedom, exp(-x / 2). |
lehmer_next(seed) |
The next state of the Lehmer generator, 48271 * x mod (2^31 - 1), for a seed from 1 to 2^31 - 2. A seed of 0 stays 0. DKE Python has no random module, and a run from the same seed repeats exactly. |
lehmer_uniform(seed) |
A state as a number between 0 and 1, the state over 2^31 - 1. |
monte_carlo_pi(n, seed) |
Four times the share of n points, drawn uniformly in the unit square from the seed, that fall inside the quarter circle. It repeats for the same n and seed: 10,000 points from seed 1 give 3.1344. The points count against the memory one run may hold, so n is for the thousands: a run on the service refuses at 20,000. |
3.53 earthscience — declared fields
The writing scripts of §3.56 write Station under the source "stations", Storm under "storms" and Mineral and Pair under "minerals", and you may write the same fields yourself. A station, a storm and a mineral are each named by you. A pair is two minerals in order, named <first>__<second> with two underscores between the names, so a mineral’s name holds no two underscores in a row. Temperatures are in degrees Celsius, rainfall in millimetres, wind in miles per hour and a hardness is a number on a scale on which a harder mineral scratches a softer one, the Mohs scale or a finer one.
Station
| Field | Class | Notes |
|---|---|---|
coldest |
real |
The mean temperature of the coldest month. |
warmest |
real |
The mean temperature of the warmest month. |
annual_temp |
real |
The annual mean temperature. |
rain |
real |
The annual rainfall. |
summer_share |
real |
The fraction, from 0 to 1, of the rain that falls in the half of the year when the sun is high. |
boundary |
real |
The coldest-month temperature that divides the temperate group from the continental, 0.0 or -3.0 as the version of the system you follow has it. |
addition |
real |
Concluded by a rule (§3.55): 280, 140 or 0 by summer_share. Never written. |
threshold |
real |
Computed (§3.54). The rainfall under which the station is dry. Never written. |
half |
real |
Computed (§3.54). Half the threshold. Never written. |
dry |
bool |
Computed (§3.54). Never written. |
polar |
bool |
Computed (§3.54): group E. Never written. |
tundra |
bool |
Concluded by a rule (§3.55). Never written. |
icecap |
bool |
Concluded by a rule (§3.55). Never written. |
arid |
bool |
Concluded by a rule (§3.55): group B. Never written. |
desert |
bool |
Concluded by a rule (§3.55). Never written. |
steppe |
bool |
Concluded by a rule (§3.55). Never written. |
tropical |
bool |
Concluded by a rule (§3.55): group A. Never written. |
temperate |
bool |
Concluded by a rule (§3.55): group C. Never written. |
continental |
bool |
Concluded by a rule (§3.55): group D. Never written. |
Storm
| Field | Class | Notes |
|---|---|---|
wind_mph |
int |
The sustained wind, in whole miles per hour. |
hurricane |
bool |
Concluded by a rule (§3.55). Never written. |
category |
int |
Concluded by a rule (§3.55): the Saffir-Simpson category, 1 to 5. Never written. |
major |
bool |
Concluded by a rule (§3.55). Never written. |
Mineral
| Field | Class | Notes |
|---|---|---|
hardness |
real |
The mineral’s hardness. |
Pair
| Field | Class | Notes |
|---|---|---|
first |
string |
The name of the first mineral. |
second |
string |
The name of the second. |
h_first |
real |
The first mineral’s hardness. |
h_second |
real |
The second mineral’s hardness. |
scratches |
bool |
Computed from the two hardnesses (§3.54). Never written. |
3.54 earthscience — derived fields
| Field | Definition |
|---|---|
Station. |
20.0 * annual_temp + addition |
Station. |
threshold / 2.0 |
Station. |
rain < threshold |
Station. |
warmest < 10.0 |
Pair. |
h_first > h_second |
threshold is the rainfall in millimetres under which a station is dry: twenty times the annual mean temperature plus addition, which is 280 where 70% or more of the rain falls in the high-sun half of the year, 140 where 30% to 70% does and 0 where under 30% does. half is half of it, the line between desert and steppe. dry is True where the station’s rain is strictly below it, and polar where the warmest month is strictly under 10 degrees. scratches is True where the first mineral is strictly harder than the second; two minerals of equal hardness scratch neither. Each is absent until the fields it reads are present, and threshold, half and dry until the rule that concludes addition has. All are real except dry, polar and scratches, which are bool.
3.55 earthscience — standing rules
Each holds continuously, as in §3.17. A rule over a station binds it as c and a rule over a storm as s.
| Rule | Over | Concludes | While |
|---|---|---|---|
threshold_summer_rain |
Station |
addition |
the station’s summer_share >= 0.7; the station takes 280.0 |
threshold_even_rain |
Station |
addition |
the station’s summer_share >= 0.3 and its summer_share < 0.7; the station takes 140.0 |
threshold_winter_rain |
Station |
addition |
the station’s summer_share < 0.3; the station takes 0.0 |
tundra |
Station |
tundra |
the station is polar and its warmest >= 0.0; concludes True |
icecap |
Station |
icecap |
the station is polar and its warmest < 0.0; concludes True |
arid |
Station |
arid |
the station is not polar and is dry; concludes True |
desert |
Station |
desert |
the station is arid and its rain is under its half; concludes True |
steppe |
Station |
steppe |
the station is arid and its rain is no less than its half; concludes True |
tropical |
Station |
tropical |
the station is not polar and not dry, and its coldest >= 18.0; concludes True |
temperate |
Station |
temperate |
the station is not polar and not dry, its coldest < 18.0 and its coldest is above its boundary; concludes True |
continental |
Station |
continental |
the station is not polar and not dry, and its coldest is no higher than its boundary; concludes True |
hurricane |
Storm |
hurricane |
the storm’s wind_mph >= 74; concludes True |
category_one |
Storm |
category |
the storm’s wind_mph >= 74 and its wind_mph <= 95; the storm takes 1 |
category_two |
Storm |
category |
the storm’s wind_mph >= 96 and its wind_mph <= 110; the storm takes 2 |
category_three |
Storm |
category |
the storm’s wind_mph >= 111 and its wind_mph <= 129; the storm takes 3 |
category_four |
Storm |
category |
the storm’s wind_mph >= 130 and its wind_mph <= 156; the storm takes 4 |
category_five |
Storm |
category |
the storm’s wind_mph >= 157; the storm takes 5 |
major |
Storm |
major |
the storm’s wind_mph >= 111; concludes True |
earthscience declares no standing constraint. Seven notes that are contract rather than commentary:
- Every station is in exactly one of five groups. The rules test the polar group first, then the arid, and only a station that is neither can be tropical, temperate or continental, so the five are
polar(E),arid(B),tropical(A),temperate(C) andcontinental(D), once all the facts of the station are written. A station is polar when its warmest month is under 10 degrees,tundrawhere that month is 0 or more andicecapwhere it is under 0. It is arid when it is not polar and itsrainis strictly below itsthreshold,desertunder half of it andsteppefrom half of it up. - The limits fall to one side. A station whose warmest month is exactly 10 is not polar. One whose
rainis exactly itsthresholdis not dry, and one whoserainis exactly itshalfissteppe. A station whose coldest month is exactly 18 istropical; one whose coldest month is exactly theboundaryiscontinental. - The group is the first letter of a climate and no more. The rules stop at the five groups and the two kinds of arid and polar climate; the finer climates within A, C and D, that depend on which season is dry or how warm the summer is, are not concluded.
- The version of the system is a fact you write.
boundaryis 0.0 for the version of Köppen’s system that puts the temperate group above 0 degrees and -3.0 for the one that puts it above -3. A station whose coldest month falls between the two iscontinentalunder the first andtemperateunder the second; the rules do not choose. - The high-sun half of the year is yours to say.
summer_shareis the fraction of the year’s rain falling in the half of the year when the sun is high, the summer half of whichever hemisphere the station lies in. The rules do not read the hemisphere, and a station whose fraction is written for the wrong half is classified by it. - A storm is judged by its wind alone.
hurricaneis concluded at 74 miles per hour and the category by the five bands of the Saffir-Simpson scale, which cover every wind from 74 up and do not overlap. A wind under 74 has nocategory, andcategory()answers 0.majoris a category of 3 or more. The rules read no pressure, surge, size or rainfall. - Disagreement is reasoned about, not resolved. When two sources give a field two values, every value is reasoned about, and a conclusion stands if any value on record supports it. A station whose
rainhas two values can be in two groups at once,groups()names both, andclimate()reads the first of them in the order A, B, C, D, E.unsettled()names the fact.dryness_threshold()andcategory()read one value and refuse while two are in force, as a station with two annual means or a storm with two winds in two categories gives them.
3.56 earthscience — queries
Called by name after import earthscience. The first three write facts and answer nothing. The next seven read what the rules concluded or what was written; none refuses because sources disagree, except dryness_threshold() and category() as §3.55 says: each answers by the rule its cell states, and unsettled() names what is in disagreement. The last thirteen are value scripts that return a value and write nothing. Temperatures are as each cell says, and each formula holds over a range it does not check.
| Query | Answers |
|---|---|
station(name, coldest, warmest, annual_temp, rain, summer_share, boundary) |
Nothing. Writes the Station named name’s six figures under the source "stations". |
storm(name, wind_mph) |
Nothing. Writes the Storm named name’s wind_mph under the source "storms". |
minerals(names, hardness) |
Nothing. Writes each mineral of names with the hardness at the same position of hardness, and a Pair for each ordered two different minerals, under the source "minerals". The pairs grow as the square of the number of minerals. |
groups(name) |
The Köppen groups the station is in, from "A", "B", "C", "D" and "E", in that order; exactly one for a station whose facts are all written, and [] before they are. |
climate(name) |
The station’s group with its kind where it has one: "A", "BW" (desert), "BS" (steppe), "C", "D", "ET" (tundra) or "EF" (ice cap), and "" before the facts are written. |
dryness_threshold(name) |
The rainfall in millimetres under which the station is dry, 0.0 before its facts are written. |
category(name) |
The storm’s Saffir-Simpson category, 0 below hurricane force. |
scratches(first, second) |
Whether the first mineral is strictly harder than the second. |
scratched_by(name) |
The minerals the named one scratches, sorted. |
unsettled() |
Each station, storm and mineral figure that holds two different values in force for a field you write, given as station, storm or mineral, its name and the field, station cairo rain, sorted. |
dew_point(t, rh) |
The dew point in degrees Celsius of air at t degrees and rh percent humidity, above 0 and up to 100, by the Magnus formula with b = 17.625 and c = 243.04, fitted for -40 to 50 degrees. At 100% it gives the temperature, to within a rounding. Another humidity is refused with ValueError. Where b t passes the largest real, b t / (c + t) is taken as b (t / (c + t)). |
heat_index(t, rh) |
The heat index in degrees Fahrenheit of air at t degrees and rh percent, by the Rothfusz regression, fitted for 80 degrees and 40% or more and within 1.3 degrees there; below that it gives a value that means little. |
wind_chill(t, v) |
The wind chill in degrees Fahrenheit of air at t degrees and a wind of v miles per hour, defined for air at 50 degrees or colder and a wind above 3. |
temperature_at(h) |
The temperature in kelvin at h metres in the standard atmosphere’s troposphere: 288.15 at sea level and 6.5 cooler for each kilometre, to 11,000 metres. |
pressure_at(h) |
The pressure in hectopascals at h metres in the standard atmosphere, 1013.25 * (1 - h / 44307.694) ** 5.2553, holding in the troposphere, to about 11,000 metres, and for h under 44,307. |
potential_temperature(t_kelvin, p_hpa) |
The temperature in kelvin the air would have if brought to 1000 hectopascals without exchanging heat, t * (1000 / p) ** 0.286; 0 for a temperature of 0. Where that is not a normal real while t and p are, it is t e^(0.286 (ln 1000 - ln p)). |
coriolis(lat_deg) |
The Coriolis parameter in 1/s at a latitude in degrees, 2 * 7.2921e-5 * sin(latitude). |
lcl_height(t, td) |
The height in metres at which rising air reaches saturation, 125 * (t - td) for a temperature and a dew point in the same unit, accurate to about 1% in ordinary air. |
radiometric_age(daughter_per_parent, half_life) |
The age of a sample, in the unit of the half-life, from the ratio of daughter atoms to parent atoms now: half_life * math.. It assumes no daughter at the start and none gained or lost since. |
quake_energy_joules(m) |
The energy in joules radiated by an earthquake of surface-wave magnitude m, 10 ** (1.5 * m + 4.8). |
magnitude_from_energy(joules) |
The magnitude whose energy is the given joules, (math.; it inverts quake_energy_joules to within a rounding. |
quake_ratio(m1, m2) |
How many times more energy a magnitude m2 releases than m1, 10 ** (1.5 * (m2 - m1)): one step is 31.6 times and two are 1000. |
sp_distance_km(sp_seconds, vp, vs) |
The distance in kilometres to an earthquake from the interval in seconds between the arrival of its P wave and its S wave, for wave speeds vp and vs in kilometres per second: sp_seconds * vp * vs / (vp - vs), the difference taken of halves where it passes the largest real, and where the distance is then not a normal real, worked on the mantissas and exponents math. gives. |
3.57 computing — declared fields
The writing script of §3.60 writes Code, Word and Pair under the source "code", and you may write the same fields yourself. A code is a set of binary words, each a string of the characters 0 and 1, and is named by you; a code’s name holds no underscore. A word is one of them, named <code>_<bits>, the code’s name, an underscore and the word. A pair is two words of a code in order, named <code>_<first>_<second>.
Code
| Field | Class | Notes |
|---|---|---|
label |
string |
The code’s name. Written by code(). |
words |
int |
Concluded by a rule (§3.59): how many of its words have a weight. Never written. |
claims |
int |
Concluded by a rule (§3.59): how many claims of weight they hold. Never written. |
disputed |
bool |
Concluded by a rule (§3.59): claims is greater than words. Never written. |
kraft |
real |
Concluded by a rule (§3.59): the sum of its words’ weight, the Kraft sum. Never written. |
complete |
bool |
Concluded by a rule (§3.59). Never written. |
oversubscribed |
bool |
Computed from kraft (§3.58). Never written. |
prefix_free |
bool |
Concluded by a rule (§3.59). Never written. |
Word
| Field | Class | Notes |
|---|---|---|
code |
string |
The name of the Code the word belongs to. |
bits |
string |
The word, a string of 0 and 1. |
weight |
real |
2 to the minus the length of bits. Written by code(). |
Pair
| Field | Class | Notes |
|---|---|---|
code |
string |
The name of the Code the pair belongs to. |
first |
string |
The first word. |
second |
string |
The second word. |
prefix |
bool |
True where the first word is the beginning of the second, or the same word. Written by code(). |
3.58 computing — derived fields
| Field | Definition |
|---|---|
Code. |
kraft > 1.0 |
oversubscribed is True where the Kraft sum is over 1, and then no uniquely decodable code has words of those lengths. It is absent until the rule that concludes kraft has. It is a bool.
3.59 computing — standing rules
Each holds continuously, as in §3.17. A rule over a code and a word binds them as c and w; a rule over a code and a pair binds the pair as p.
| Rule | Over | Concludes | While |
|---|---|---|---|
code_claims |
Code, Word |
claims |
the word’s code names the code and its weight > -1.0e300; the code takes the number of claims of weight those words hold |
code_words |
Code, Word |
words |
the word’s code names the code and its weight > -1.0e300; the code takes the number of distinct such words |
code_disputed |
Code |
disputed |
the code’s claims is greater than its words; concludes True |
kraft_of_words |
Code, Word |
kraft |
the word’s code names the code and the code has no disputed; the code takes the sum of those words’ weight |
complete |
Code |
complete |
the code’s kraft is 1.0; concludes True |
prefix_free |
Code |
prefix_free |
no pair of the code has prefix True; concludes True |
computing declares no standing constraint. Five notes that are contract rather than commentary:
- A Kraft sum of 1 does not make a code prefix-free. The Kraft sum is a property of the lengths of the words alone, and
prefix_freeis a property of the words. A code with a Kraft sum of 1 can still have a word that begins another, and one with a Kraft sum of less than 1 can have one too. The sum says whether a code with those lengths could exist: over 1, none could. completeis concluded, never denied. A code whose Kraft sum is 1 iscomplete. A code whose sum is anything else has nocompleteat all rather than a False one, and the same holds ofprefix_free: it is concluded where no pair breaks it, and absent where one does.- A word that begins another is a pair.
code()writes a pair for every two different positions of the list, so a word given twice is a pair with itself and the code is not prefix-free. The two positions are oneWord, and itsweightcounts once in the sum. - A code of no words is prefix-free. Its Kraft sum is 0, and it has no pair to break the rule. A word written again with another string is a different word: nothing withdraws the first, so a corrected code is written under a new name.
- Disagreement is reasoned about, not resolved. When two sources give a field two values, every value is reasoned about, and a conclusion stands if any value on record supports it.
unsettled()names the fact. The Kraft sum reads every value of aweight, so a word whose weight a second source writes, even the same weight, would be added twice;wordsandclaimscount the words and their claims over the one binding the sum reads, and while the claims are more the code isdisputedand has nokraft,completeoroversubscribed. A word with noweightis in neither count, and one whosecodeholds two values counts in each code it names, each Kraft sum being one source’s.
3.60 computing — queries
Called by name after import computing. The first writes facts and answers nothing. The next four read what the rules concluded, and unsettled() names what is in disagreement; kraft_sum refuses a disputed code. The last fourteen are value scripts that return a value and write nothing. An int is 64 bits: the checksums fit, and a 64-bit hash that wraps would not. Every loop is bounded, and the bound is stated where it limits an answer.
| Query | Answers |
|---|---|
code(name, words) |
Nothing. Writes the Code named name’s label, a Word for each word of words with its code, bits and weight, and a Pair for each two different positions of the list, with their code, first, second and prefix, under the source "code". The pairs grow as the square of the number of words. |
prefix_free_codes() |
The codes in which no word begins another, sorted. |
kraft_sum(name) |
The Kraft sum of the code name, 0.0 before its words are written. A code with disputed is refused. |
disputed_codes() |
The codes with disputed, sorted. |
breaking_pairs(name) |
Every pair "first second" of the code in which the first word begins the second, sorted; empty for a prefix-free code. |
unsettled() |
Each word and pair that holds two different values in force for a fact you write, given as word or pair, its name and the field, word good_0 bits, sorted. |
crc32(data) |
CRC-32/ISO-HDLC, bit by bit, of a string whose characters have codes from 0 to 255, each taken as a byte: "123456789" gives 3421780262, which is 0xcbf43926. |
adler32(data) |
Adler-32 of a string whose characters have codes from 0 to 255: "Wikipedia" gives 300286872, which is 0x11e60398. |
luhn_valid(digits) |
Whether a string of digits passes Luhn’s check: every second digit from the right doubled, 9 taken from any above 9, and the sum a multiple of 10. |
isbn13_valid(digits) |
Whether a string of exactly 13 digits, hyphens removed, passes the ISBN-13 check: weights 1 and 3 alternately, and the sum a multiple of 10. |
to_base(n, base) |
n, at least 0, written in a base from 2 to 36 with the digits 0 to 9 and a to z. An int has at most 63 binary digits, so the loop is bounded by 64. |
from_base(text, base) |
A number written in a base from 2 to 36 in lower-case digits, no longer than the 63 binary digits an int holds. |
hamming_distance(a, b) |
How many bits differ between a and b, both at least 0. |
hamming_encode(d) |
Hamming(7,4): four data bits, d from 0 to 15, as a seven-bit word whose bits from the left are p1 p2 d1 p3 d2 d3 d4. Eleven encodes as 51. |
hamming_decode(w) |
The four data bits of a Hamming(7,4) word, w from 0 to 127, after correcting any single flipped bit. Two flipped bits are decoded wrongly; the code cannot tell. |
entropy(counts) |
Shannon’s entropy in bits of a source whose symbols occurred counts[i] times, -sum(p * math.. Two equal counts give 1.0 and four give 2.0. |
huffman_lengths(freqs) |
The length of each symbol’s codeword in a Huffman code for symbols that occurred freqs[i] times, merging the two lightest groups at each step, the lower index first on a tie. Frequencies 45, 13, 12, 16, 9 and 5 give 1, 3, 3, 3, 4 and 4. There are at most len(freqs) - 1 merges. |
binary_search(items, target) |
The index of target in a list sorted ascending, or -1. At most 64 halvings, which any list of an int’s length needs. |
binary_search_steps(n, target) |
How many probes a binary search of the indexes 0 to n - 1 makes to find the index target: 9 for the first of 1,000 and 20 for the last of 1,000,000. When the target is outside, how many it makes before it gives up. |
dijkstra(n, edges, src) |
The shortest distance from node src to each of the nodes 0 to n - 1, over directed edges [from, to, weight] with weights from 0 up. A node not reached keeps 1000000, so a path is shorter than that. It makes n rounds of settling the nearest node. |
3.61 calendars — declared fields
The writing scripts of §3.64 write Year under the source "years", Day under "days" and Reform under the source you pass, and you may write the same fields yourself. A year is named y<number>, the letter y and its number, as years() and year() name it. A reform and a day are named by you; a reform is named for the place that adopted it. A date is one whole number, year * 10000 + month * 100 + day, so 4 October 1582 is 15821004, and two dates compare in order whichever months they fall in. The gap is a relation, Gap.<day>.<reform>, concluded by a rule and never written.
Year
| Field | Class | Notes |
|---|---|---|
number |
int |
The year’s number. Written by years() and year(). |
r4 |
int |
Computed from number (§3.62). Never written. |
r100 |
int |
Computed from number (§3.62). Never written. |
r400 |
int |
Computed from number (§3.62). Never written. |
julian_leap |
bool |
Concluded by a rule (§3.63): the year is a leap year under the Julian rule. Never written. |
gregorian_leap |
bool |
Concluded by a rule (§3.63): the year is a leap year under the Gregorian rule. Never written. |
differ |
bool |
Concluded by a rule (§3.63): the Julian rule makes the year a leap year and the Gregorian rule does not. Never written. |
Reform
| Field | Class | Notes |
|---|---|---|
last |
int |
The last day of the old calendar, as a date. Written by reform(). |
first |
int |
The first day of the new calendar, as a date. Written by reform(). |
last_count |
int |
The day number of last on the Julian calendar, as julian_day_number returns it. Written by reform(). |
first_count |
int |
The day number of first on the Julian calendar. Written by reform(). |
skipped |
int |
Computed from the two counts (§3.62). Never written. |
Day
| Field | Class | Notes |
|---|---|---|
ymd |
int |
The day, as a date. Written by day(). |
Gap declares no field. It is the relation of §3.63: Gap.<day>.<reform> is True for a day that falls after a reform’s last day of the old calendar and before its first day of the new one.
3.62 calendars — derived fields
| Field | Definition |
|---|---|
Year. |
number % 4 |
Year. |
number % 100 |
Year. |
number % 400 |
Reform. |
first_count - last_count - 1 |
The three remainders are those of the year’s number on division by 4, 100 and 400. skipped is the number of days between the reform’s two counts, which are day numbers of one calendar, so it holds across the end of a month: 10 for Rome’s reform of 1582, from Thursday 4 October to Friday 15 October, and 11 for Britain’s of 1752, from 2 September to 14 September. Each is absent until the fields it reads are present, and all are int.
3.63 calendars — standing rules
Each holds continuously, as in §3.17. A rule over a year binds it as y, and the rule over a day and a reform binds them as d and r.
| Rule | Over | Concludes | While |
|---|---|---|---|
julian_leap_year |
Year |
julian_leap |
the year’s r4 is 0; concludes True |
gregorian_leap_ordinary |
Year |
gregorian_leap |
the year’s r4 is 0 and its r100 is not 0; concludes True |
gregorian_leap_fourth_century |
Year |
gregorian_leap |
the year’s r400 is 0; concludes True |
years_differ |
Year |
differ |
the year’s julian_leap is True and it has no gregorian_leap; concludes True |
day_in_the_gap |
Day, Reform |
Gap |
the day’s ymd is above the reform’s last and below its first; concludes Gap.<day>.<reform> is True |
calendars declares no standing constraint. Six notes that are contract rather than commentary:
- A year that is not a leap year has no value, not a false one.
gregorian_leapandjulian_leapare concluded where they hold and absent where they do not, sowhy_notof one names the remainder that failed. The two Gregorian rules are alternatives: a year divisible by 4 and not by 100 qualifies by the first, and a year divisible by 400 by the second. differis a Julian leap year the Gregorian rule refuses. Those are the centuries not divisible by 400: 1700, 1800, 1900 and 2100, and not 1600 or- A year the store does not hold is no year. The rules reach only the years you wrote, so
gregorian_leap(2000)isFalsebefore 2000 is written, which says nothing about the year. The calculations of §3.64 answer for any year. - A day in the gap is marked and kept. The rule reads the day’s
ymdand the reform’slastandfirstas numbers, strictly between them. The day is a valid fact; the relation is the only consequence, and a reform’sfirstrewritten moves the gap and withdraws the marks that rested on it. - A reform rewritten replaces what the same source wrote. Written again under another source it is held beside the first, every value is reasoned about, and a day is in the gap if it is in the gap under any value in force.
unsettled()names the fact two sources disagree about. - The gap is per reform, and the reform is named for the place. A day that is in one place’s gap is not in another’s, and
missing(day, place)asks about the reform written under that name.
3.64 calendars — queries
Called by name after import calendars. The first four write facts and answer nothing. The next eight read what the rules concluded or what was written, and unsettled() names what is in disagreement. The last eleven are value scripts that return a value and write nothing. The calculations count in the proleptic Gregorian calendar, years 1 to 9999, with a day of 86,400 seconds and no leap second. A datetime is a UTC instant written with a trailing Z, and a duration has days, hours, minutes and seconds and no months or years.
| Query | Answers |
|---|---|
years(first_year, last_year) |
Nothing. Writes a Year named y<number> for each year from first_year to last_year inclusive, with its number, under the source "years". |
year(n) |
Nothing. Writes the one Year y<n>. |
reform(name, last_year, last_month, last_day, first_year, first_month, first_day, source) |
Nothing. Writes the Reform named name’s last and first as dates and its last_count and first_count as Julian day numbers, under source. |
day(name, y, m, d) |
Nothing. Writes the Day named name’s ymd, under the source "days". |
true_for(values, name) |
Whether any claim in values, a list as list_values returns, is True for the subject name. The reading below it is built on it. |
julian_leap(n) |
Whether the year n is a Julian leap year, as the rules concluded; False for a year not written. |
gregorian_leap(n) |
Whether the year n is a Gregorian leap year, as the rules concluded; False for a year not written. |
differ(n) |
Whether the year n is one the two rules disagree about. |
years_that_differ() |
The written years the two rules disagree about, sorted. |
skipped(name) |
The days the reform name skipped, one value, or one for each source when the sources disagree, sorted; empty before the reform is written. |
missing(day_name, place) |
Whether the day falls in the gap of the reform written as place, under any value in force for the reform. |
unsettled() |
Each reform or day that holds two different values in force for a fact you write, given as reform or day, its name and the field, reform rome first, sorted. |
is_gregorian_leap(y) |
Whether y is a leap year under the Gregorian rule, for any integer. |
is_julian_leap(y) |
Whether y is a leap year under the Julian rule, every fourth year. |
month_length(y, m) |
The days in month m, 1 to 12, of year y under the Gregorian rule: 28 or 29 for February, 30 or 31 otherwise. The month is not checked. |
julian_month_length(y, m) |
The days in month m of year y under the Julian rule. |
date_exists(y, m, d) |
Whether the Gregorian calendar has this day, in years 1 to 9999; False for 29 February of 2026. |
weekday(y, m, d) |
The weekday of a Gregorian date, 0 for Sunday to 6 for Saturday, by Sakamoto’s method, proleptic. The date is not checked. |
easter(y) |
Easter Sunday of the year y as [month, day] in the Western calendar: [4, 5] for 2026. Defined for years from 1583. |
day_number(y, m, d) |
The Gregorian day number, 1 for 1 January of year 1; the difference of two is the days between them. |
julian_day_number(y, m, d) |
A day number on the Julian calendar, in the same unit; its zero is not day_number’s. |
span(a, b) |
The time from the datetime a to b as a duration, negative when b is earlier. A span of more than about 292 years is refused. |
after(t, days) |
The instant days whole days after t, negative days going back. The result must lie in years 1 to 9999, or it is refused. |
3.65 colour — declared fields
The writing scripts of §3.68 write Pair under the source "pairs" and Ray under "rays", and you may write the same fields yourself. A pair is a colour of text on a colour of background and a ray is a ray meeting a boundary; each is named by you. A luminance is the relative luminance of an sRGB colour, from 0.0 for black to 1.0 for white.
Pair
| Field | Class | Notes |
|---|---|---|
fg |
real |
The relative luminance of the text. |
bg |
real |
The relative luminance of the background. |
ratio |
real |
Computed from the two (§3.66): the contrast ratio when the text is the lighter. Never written. |
inverse |
real |
Computed from the two (§3.66): the contrast ratio when the background is the lighter. Never written. |
aa |
bool |
Concluded by a rule (§3.67): the pair clears WCAG AA, 4.5 to 1. Never written. |
aaa |
bool |
Concluded by a rule (§3.67): the pair clears WCAG AAA, 7 to 1. Never written. |
large_aa |
bool |
Concluded by a rule (§3.67): the pair clears AA for large text, 3 to 1. Never written. |
large_aaa |
bool |
Concluded by a rule (§3.67): the pair clears AAA for large text, 4.5 to 1. Never written. |
Ray
| Field | Class | Notes |
|---|---|---|
n1 |
real |
The refractive index of the medium the ray leaves, 1 or more, as every medium’s is for visible light. |
n2 |
real |
The refractive index of the medium the ray meets, 1 or more. |
sin_i |
real |
The sine of the ray’s angle of incidence, 0.0 to 1.0. |
sin_t |
real |
Computed from the three (§3.66): the sine of the refracted angle that Snell’s law asks for. Never written. |
total |
bool |
Concluded by a rule (§3.67): the ray is totally reflected. Never written. |
3.66 colour — derived fields
| Field | Definition |
|---|---|
Pair. |
(fg + 0.05) / (bg + 0.05) |
Pair. |
(bg + 0.05) / (fg + 0.05) |
Ray. |
n1 * sin_i / n2 |
ratio is the contrast ratio of a pair whose text is the lighter, and inverse that of a pair whose background is the lighter; the one that applies is at least 1.0, and a pair of equal luminance has 1.0 in both. sin_t is the sine of the angle of the refracted ray, and exceeds 1.0 where no such angle exists. Each is absent until the fields it reads are present, and all are real.
3.67 colour — standing rules
Each holds continuously, as in §3.17. A rule over a pair binds it as p and a rule over a ray as r.
| Rule | Over | Concludes | While |
|---|---|---|---|
aa_light_text |
Pair |
aa |
the pair’s fg is above its bg and its ratio >= 4.5; concludes True |
aa_dark_text |
Pair |
aa |
the pair’s bg is no less than its fg and its inverse >= 4.5; concludes True |
aaa_light_text |
Pair |
aaa |
the pair’s fg is above its bg and its ratio >= 7.0; concludes True |
aaa_dark_text |
Pair |
aaa |
the pair’s bg is no less than its fg and its inverse >= 7.0; concludes True |
large_aa_light_text |
Pair |
large_aa |
the pair’s fg is above its bg and its ratio >= 3.0; concludes True |
large_aa_dark_text |
Pair |
large_aa |
the pair’s bg is no less than its fg and its inverse >= 3.0; concludes True |
large_aaa_light_text |
Pair |
large_aaa |
the pair’s fg is above its bg and its ratio >= 4.5; concludes True |
large_aaa_dark_text |
Pair |
large_aaa |
the pair’s bg is no less than its fg and its inverse >= 4.5; concludes True |
total_internal_reflection |
Ray |
total |
the ray’s n1 is above its n2, its sin_i <= 1.0 and its sin_t > 1.0; concludes True |
colour declares no standing constraint. Five notes that are contract rather than commentary:
- A level is concluded, never denied. A pair that clears a level has the value
Truefor it; a pair that fails has none, rather than a false one, andwhy_notnames the premise that failed. A pair that clears no level is kept. - The ratio the pair uses is the one that applies. The two ratios are the same quantity read from either side. A pair whose text is the lighter uses
ratioand a pair whose background is the lighter, or equal to the text, usesinverse, so a light-on-dark pair and a dark-on-light pair of the same two colours clear the same levels. - The thresholds are the guidelines’ and are compared as they are written. 4.5 and 7 are the AA and AAA levels for ordinary text, and 3 and 4.5 for large-scale text, which the guidelines set at 18 point or 14 point bold. A ratio exactly on a threshold clears it.
- A ray is totally reflected only into a rarer medium. The rule needs
n1aboven2, asin_iof at most 1.0 and asin_tabove 1.0. At asin_tof exactly 1.0 the ray runs along the boundary, the critical angle, and refracts. Light entering a denser medium never meets the rule. - Disagreement is reasoned about, not resolved. When two sources give a luminance or an index two values, every value is reasoned about, and a level stands if any value on record clears it.
unsettled()names the fact.
3.68 colour — queries
Called by name after import colour. The first two write facts and answer nothing. The next four read what the rules concluded, and unsettled() names what is in disagreement. The last twelve are value scripts that return a value and write nothing. Floats are IEEE doubles. A colour is a triple of sRGB channels, 0 to 255, or a string #rrggbb.
| Query | Answers |
|---|---|
pair(name, text, background) |
Nothing. Writes the Pair named name’s fg and bg under the source "pairs". |
ray(name, from_index, into_index, sine_of_incidence) |
Nothing. Writes the Ray named name’s n1, n2 and sin_i under the source "rays". |
holds(values, name) |
Whether any claim in values, a list as list_values returns, is True for the subject name. The readings below are built on it. |
levels(name) |
The contrast levels the pair clears, from "AA", "AAA", "large AA" and "large AAA" in that order; empty for a pair that clears none. |
total(name) |
Whether the ray is totally reflected. |
unsettled() |
Each pair or ray that holds two different values in force for a fact you write, given as pair or ray, its name and the field, pair grey fg, sorted. |
srgb_linear(c) |
The linear light of an sRGB channel c, 0 to 255: c / 255 over 12.92 up to 0.04045, and ((c / 255 + 0.055) / 1.055) to the 2.4 above it. |
luminance(r, g, b) |
The relative luminance of an sRGB colour: 0.2126 R + 0.7152 G + 0.0722 B in linear light. |
luminance_hex(text) |
The relative luminance of a colour written #rrggbb; anything else is refused. |
contrast_ratio(l1, l2) |
The contrast ratio of two relative luminances, the lighter plus 0.05 over the darker plus 0.05: 1.0 for equal ones, 21.0 for black and white. |
contrast_hex(a, b) |
The contrast ratio of two colours written #rrggbb. |
hsl(r, g, b) |
[hue, saturation, lightness] of an sRGB colour: hue in degrees from 0.0 up to 360.0, the others from 0.0 to 1.0; a grey has hue 0.0 and saturation 0.0. |
refraction_angle(n1, n2, incidence_deg) |
The angle of the refracted ray in degrees, by Snell’s law, the incidence taken modulo 360 degrees by math. first; where n1 times its sine over n2 is not a normal real, that is worked on the mantissas and exponents math. gives. Refused where the ray is totally reflected. |
critical_angle(n1, n2) |
The critical angle in degrees for light going from index n1 into n2; it exists only into a rarer medium, n2 no larger than n1, and is refused otherwise. |
lens_image(focal_length, object_distance) |
The image distance of a thin converging lens in air, 1 / (1/, in the unit of the two lengths; positive for a real image. Refused with the object at the focus. |
lens_magnification(focal_length, object_distance) |
The magnification of the same lens, the negative of the image distance over the object distance, taken as f / (f - u), which it equals, and of halves where f - u passes the largest real; negative for an inverted image. Refused with the object at the focus. |
wien_peak(temperature_k) |
The wavelength in metres at which a black body at the temperature in kelvin radiates most strongly per unit wavelength, 2.897771955e-3 over the temperature. |
frequency_hz(wavelength_nm) |
The frequency in hertz of light of the wavelength in nanometres in a vacuum, 299792458 over the wavelength in metres. |
3.69 body — declared fields
body is not medical advice. It states rules taught in every introduction to the subject and arithmetic with published formulas. Blood compatibility in practice is decided by laboratory testing, a body mass index is a measure for populations that its own namer judged inappropriate for individual evaluation, and the energy and heart-rate formulas are estimates that may deviate significantly from a person’s actual value. It gives no dose, no diagnosis and no treatment.
The writing scripts of §3.72 write Transfusion under the source you pass and Person under "people", and you may write the same fields yourself. A transfusion is a donor’s blood group given to a recipient’s, and a person a body of a mass and a height; each is named by you. A blood group is held as its three antigens, A, B and D, 1 for present and 0 for absent.
Transfusion
| Field | Class | Notes |
|---|---|---|
da |
int |
1 where the donor’s red cells carry the A antigen. Written by transfusion(). |
db |
int |
1 where they carry the B antigen. Written by transfusion(). |
dd |
int |
1 where they carry the D antigen, the Rh-positive groups. Written by transfusion(). |
ra |
int |
1 where the recipient’s red cells carry the A antigen. Written by transfusion(). |
rb |
int |
1 where they carry the B antigen. Written by transfusion(). |
rd |
int |
1 where they carry the D antigen. Written by transfusion(). |
lacks_a |
bool |
Concluded by a rule (§3.71): the donor’s red cells carry A and the recipient’s do not. Never written. |
lacks_b |
bool |
Concluded by a rule (§3.71): the same for B. Never written. |
lacks_d |
bool |
Concluded by a rule (§3.71): the same for D. Never written. |
reacts |
bool |
Concluded by a rule (§3.71): the red cells would react, from a lacked A or B. Never written. |
sensitises |
bool |
Concluded by a rule (§3.71): the recipient is at risk of sensitisation, from a lacked D. Never written. |
Person
| Field | Class | Notes |
|---|---|---|
kg |
real |
The person’s mass in kilograms. Written by person(). |
metres |
real |
The person’s height in metres. Written by person(). |
bmi |
real |
Computed from the two (§3.70). Never written. |
underweight |
bool |
Computed from bmi (§3.70). Never written. |
overweight |
bool |
Computed from bmi (§3.70). Never written. |
obese |
bool |
Computed from bmi (§3.70). Never written. |
normal |
bool |
Concluded by a rule (§3.71). Never written. |
3.70 body — derived fields
| Field | Definition |
|---|---|
Person. |
kg / metres / metres |
Person. |
bmi < 18.5 |
Person. |
bmi >= 25.0 |
Person. |
bmi >= 30.0 |
bmi is the body mass index, the mass over the square of the height, divided by the height twice so that it is had wherever it is a real. The three bands are the World Health Organization’s: underweight is an index strictly under 18.5, overweight 25 or more, the obese included, and obese 30 or more. They are bands of a population statistic, not a judgement of a person. A height of zero draws no index, so bmi is absent and so are the bands, and why_not says the conclusion computes a division that has none. Each is absent until the fields it reads are present. bmi is real and the bands are bool.
3.71 body — standing rules
Each holds continuously, as in §3.17. A rule over a transfusion binds it as t and a rule over a person as p.
| Rule | Over | Concludes | While |
|---|---|---|---|
lacks_a |
Transfusion |
lacks_a |
the donor’s da is above the recipient’s ra; concludes True |
lacks_b |
Transfusion |
lacks_b |
the donor’s db is above the recipient’s rb; concludes True |
lacks_d |
Transfusion |
lacks_d |
the donor’s dd is above the recipient’s rd; concludes True |
reacts_for_a |
Transfusion |
reacts |
the transfusion’s lacks_a is True; concludes True |
reacts_for_b |
Transfusion |
reacts |
the transfusion’s lacks_b is True; concludes True |
sensitises_for_d |
Transfusion |
sensitises |
the transfusion’s lacks_d is True; concludes True |
normal_weight |
Person |
normal |
the person’s bmi >= 18.5 and bmi < 25.0; concludes True |
body declares no standing constraint. Five notes that are contract rather than commentary:
- A verdict is a stated rule, not advice.
reactsis the ABO rule: the donor’s red cells carry an antigen the recipient’s lack.sensitisesis the D antigen rule, which the sources describe as a risk of sensitisation to the D antigen and not an immediate reaction. Plasma and platelet compatibility, the Kell and other blood systems, a rare group and any dose are outside what the rules say. - A conclusion is positive. A transfusion that lacks nothing has none of the five conclusions rather than false ones, and
why_notofreactsnames the two premises that were not met. - A band is the narrowest one that holds. An index of 30 or more is
overweightandobeseboth, the WHO bands being cumulative above 25, andnormalis 18.5 up to but not including 25, so the four bands cover every index. A person whosebmiis absent has none. - A group is three antigens. O has neither A nor B, A has A, B has B and AB has both, and a plus sign puts D present. The writing script refuses a group written any other way.
- Disagreement is reasoned about, not resolved. When two sources give an antigen, a mass or a height two values, every value is reasoned about, and a conclusion stands if any value on record supports it.
unsettled()names the fact.bmi()reads one value and refuses while two are in force, as a person with two masses or two heights gives it.
3.72 body — queries
Called by name after import body. The first three write facts, and the first returns the antigens it writes; the next five read what the rules concluded or what was written, and unsettled() names what is in disagreement; none refuses because sources disagree, except bmi() as §3.71 says. The last five are value scripts that return a value and write nothing. Floats are IEEE doubles, and math. is correctly rounded, so a result agrees with CPython’s. The formulas are estimates for adults and are no substitute for a clinician.
| Query | Answers |
|---|---|
antigens(group) |
The A, B and D antigens of a blood group written "A+", "B-", "AB+" or "O-" as [a, b, d], each 1 or 0; any other writing is refused. |
transfusion(name, donor, recipient, source) |
Nothing. Writes the Transfusion named name’s six antigens from the two groups, under source. Written again under another source it holds the rival value beside the first. |
person(name, kilograms, height_metres) |
Nothing. Writes the Person named name’s kg and metres under the source "people". |
holds(values, name) |
Whether any claim in values, a list as list_values returns, is True for the subject name. The readings below are built on it. |
verdict(name) |
What the rules conclude for a transfusion: "reacts", "sensitises", both in that order, or empty for neither. |
lacks(name) |
The antigens of the donor the recipient lacks, from "A", "B" and "D", in that order. |
bmi(name) |
A person’s body mass index; 0.0 where none is drawn, as for a height of zero or before the facts are written. |
band(name) |
The narrowest WHO band the rules conclude for a person, "underweight", "normal", "overweight" or "obese"; "" where no index is drawn. |
unsettled() |
Each transfusion or person that holds two different values in force for a fact you write, given as transfusion or person, its name and the field, transfusion t4 rd, sorted. |
body_mass_index(kilograms, height_metres) |
The mass in kilograms over the square of the height in metres, divided by the height twice as Person. is; a height of zero is refused with a division by zero. |
mifflin_st_jeor(kilograms, height_cm, age_years, male) |
The resting energy in kilocalories a day by Mifflin and St Jeor (1990): 10 times the mass plus 6.25 times the height in centimetres minus 5 times the age, then 5 added for a male and 161 taken off for a female. |
body_surface_mosteller(kilograms, height_cm) |
The body surface in square metres by Mosteller (1987), the square root of the height in centimetres times the mass over 3600; where that product passes the largest real or is under 1e-300 in size, the product of the two square roots over 60. |
max_heart_rate_haskell_fox(age_years) |
The maximum heart rate in beats a minute by Haskell and Fox (1971), 220 minus the age; its standard deviation is 12 to 15. |
max_heart_rate_tanaka(age_years) |
The maximum heart rate in beats a minute by Tanaka, Monahan and Seals (2001), 208 minus 0.7 times the age; its standard deviation is about 10. |
3.73 sound — declared fields
sound is not occupational-health advice. It states published limits as data and arithmetic with published formulas. A limit is a figure on a page. Whether a worker is protected is decided by a measurement and a hearing conservation programme, and a dose over a limit is not a finding of hearing loss. It gives no diagnosis and no treatment.
The writing scripts of §3.76 write Exposure under the source "exposure", Segment under "segment", Worker under "segment" and Tone under "tone", and you may write the same fields yourself. An exposure is a sound level held for some hours and judged against a limit, a segment one period of a worker’s day at one level, a worker that day as a whole, and a tone a frequency; each is named by you. A level is in decibels, A-weighted and taken as you give it, never computed from a spectrum. A limit is a pair, a reference level for eight hours and an exchange rate, the decibels by which a level may rise while the permitted time halves: 90 and 5 for the limit OSHA’s Table G-16 tabulates, 85 and 3 for the level NIOSH recommends.
Exposure
| Field | Class | Notes |
|---|---|---|
level |
real |
The level in decibels. Written by exposure(). |
hours |
real |
The hours it is held. Written by exposure(). |
ref |
real |
The limit’s reference level, for eight hours. Written by exposure(). |
rate |
real |
The limit’s exchange rate. Written by exposure(). |
allowed |
real |
The hours the limit permits at the level, from permissible_hours (§3.76). Written by exposure(). |
dose |
real |
Computed from hours and allowed (§3.74). Never written. |
over |
bool |
Concluded by a rule (§3.75): the dose is more than one. Never written. |
Segment
| Field | Class | Notes |
|---|---|---|
worker |
string |
The name of the worker’s day it belongs to. Written by segment(). |
level |
real |
The level in decibels. Written by segment(). |
hours |
real |
The hours it is held. Written by segment(). |
allowed |
real |
The hours the limit permits at the level. Written by segment(). |
dose |
real |
Computed from hours and allowed (§3.74). Never written. |
Worker
| Field | Class | Notes |
|---|---|---|
label |
string |
The worker’s name. Written by segment(), so that the day exists. |
segments |
int |
Concluded by a rule (§3.75): how many of the worker’s segments have a dose. Never written. |
claims |
int |
Concluded by a rule (§3.75): how many claims of dose they hold. Never written. |
disputed |
bool |
Concluded by a rule (§3.75): claims is greater than segments. Never written. |
total |
real |
Concluded by a rule (§3.75): the sum of the doses of the worker’s segments. Never written. |
over |
bool |
Concluded by a rule (§3.75): the total is more than one. Never written. |
Tone
| Field | Class | Notes |
|---|---|---|
hz |
real |
The frequency in hertz. Written by tone(). |
audible |
bool |
Concluded by a rule (§3.75): 20 to 20,000 Hz, both ends inside. Never written. |
infrasound |
bool |
Concluded by a rule (§3.75): below 20 Hz. Never written. |
ultrasound |
bool |
Concluded by a rule (§3.75): above 20,000 Hz. Never written. |
3.74 sound — derived fields
| Field | Definition |
|---|---|
Exposure. |
hours / allowed |
Segment. |
hours / allowed |
The dose is the share of a day’s permitted exposure that the hours use: 1.0 is the whole of it, and 0.5 is half. It is absent until hours and allowed are present, and is real. allowed is a written field and not a derived one, because a power cannot be computed in a derived field; the script that writes it applies permissible_hours (§3.76).
3.75 sound — standing rules
Each holds continuously, as in §3.17. A rule over an exposure binds it as e, a rule over a worker as w and over its segments as s, and a rule over a tone as t.
| Rule | Over | Concludes | While |
|---|---|---|---|
over_limit |
Exposure |
over |
the exposure’s dose > 1.0; concludes True |
day_segments |
Worker, Segment |
segments |
the segment’s worker is the worker and its dose > -1.0e300; concludes the number of distinct such segments |
day_claims |
Worker, Segment |
claims |
the segment’s worker is the worker and its dose > -1.0e300; concludes the number of claims of dose those segments hold |
day_disputed |
Worker |
disputed |
the worker’s claims is greater than its segments; concludes True |
day_total |
Worker, Segment |
total |
the segment’s worker is the worker and the worker has no disputed; concludes the sum of the dose of those segments |
day_over |
Worker |
over |
the worker’s total > 1.0; concludes True |
audible_tone |
Tone |
audible |
the tone’s hz >= 20.0 and hz <= 20000.0; concludes True |
infrasound_tone |
Tone |
infrasound |
the tone’s hz < 20.0; concludes True |
ultrasound_tone |
Tone |
ultrasound |
the tone’s hz > 20000.0; concludes True |
sound declares no standing constraint. Seven notes that are contract rather than commentary:
- A dose of exactly one is at the limit and is not over. An exposure of 4 hours at 95 decibels against a limit of 90 and 5 has a dose of 1.0 and no
over;why_notsays the dose is 1.0. The same holds for a day whose total is exactly one. - An exposure over its limit is marked and kept. The exposure is a valid fact;
overis the only consequence, and rewriting the exposure with fewer hours withdraws it. - A conclusion is positive. An exposure that is not over has no
over, not a false one, andwhy_notnames the premise that failed. A frequency that is not audible has noaudible. - A day is judged by the sum of its segments’ doses. The segments may have different limits, since each carries the hours its own limit permits. A worker with no segment has no day, and a segment name is used once. The sum reads every value of a dose, so a segment whose dose holds two values, or whose hours a second source writes, would be added twice;
segmentsandclaimscount the segments and their claims over the one binding the sum reads, and while the claims are more the day isdisputedand has nototalorover. A segment with nodoseis in neither count, and one whoseworkerholds two values counts in each day it names, each total being one source’s. - The hours a limit permits are this module’s own derivation.
permissible_hoursis8 / 2^((level - ref) / rate), from a reference level, eight hours and an exchange rate. It is not a formula read from NIOSH or from OSHA. It reproduces the table’s 95 decibels for 4 hours and 100 for 2 at 90 and 5, and it gives 6.06 hours at 92 decibels where the table has 6, 3.03 at 97 where it has 3 and 1.52 at 102 where it has 1.5: a published table rounds where the derivation does not. - The range of hearing is a convention. 20 to 20,000 Hz is the commonly stated range, and it shrinks during life;
infrasoundandultrasoundare the names used here for what lies below and above it. - Disagreement is reasoned about by the lists and refused by the single read. When two sources give an exposure’s hours two values, every value is reasoned about, and an exposure is over if any value puts it over; the lists of §3.76 name it, and
unsettled()names the fact.doseandtotal_ofread one value and refuse while two are in force, saying that the cell holds two competing values.
The module does not cover frequency weighting, octave bands, room acoustics and reverberation, sound in water, the action level and the hearing conservation programme of either limit, or any limit of another country.
3.76 sound — queries
Called by name after import sound. The first three write facts and answer nothing. The next eight read what the rules concluded, two of them helpers the others are built on, and unsettled() names what is in disagreement. The last eight are value scripts that return a value and write nothing. Floats are IEEE doubles. Results are not rounded. math. is correctly rounded, and CPython’s can differ from it by one unit in the last place at some arguments: the level of a pressure of 1.4142135623730951 against a reference of 1 is 3.0102999566398125 here and 3.010299956639812 in CPython 3.11. A decibel therefore agrees with CPython’s to that unit, not always to the last bit.
| Query | Answers |
|---|---|
exposure(name, level, hours, ref_level, exchange_rate) |
Nothing. Writes the Exposure named name’s level, hours, ref and rate, and its allowed from permissible_hours, under the source "exposure". Written again with other hours it corrects the first. |
segment(worker, name, level, hours, ref_level, exchange_rate) |
Nothing. Writes the Segment named name for the day of worker, with the hours its limit permits, and the worker’s label, under the source "segment". |
tone(name, hertz) |
Nothing. Writes the Tone named name’s hz under the source "tone". |
holds(values, name) |
Whether any claim in values, a list as list_values returns, is True for the subject name. |
names_of(values) |
The subjects for which any claim in values is True, sorted. |
over_limit_names() |
The exposures whose dose is more than one, sorted. |
days_over() |
The workers whose segments’ doses sum to more than one, sorted. |
dose(name) |
An exposure’s dose; 0.0 before the facts are written. Refuses while two values are in force. |
total_of(name) |
The sum of the doses of a worker’s segments; 0.0 before the rule concludes it. Refuses while two values are in force, and refuses a worker with disputed. |
disputed_days() |
The workers with disputed, sorted. |
range_of(name) |
"audible", "infrasound" or "ultrasound" for a tone; "" before the facts are written. |
unsettled() |
Each exposure, segment, worker and tone that holds two different values in force for a field you write: an exposure’s level, hours, ref, rate or allowed, a segment’s worker, level, hours or allowed, a worker’s label, or a tone’s hz. Given as its kind in lower case, its name and the field, segment s1 hours, sorted. |
permissible_hours(level, ref_level, exchange_rate) |
The hours a day may hold at a level, 8 / 2^((level - ref_level) / exchange_rate), the rise taken of halves where level - ref_level passes the largest real; 8 at the reference level and half for each rise of the exchange rate. |
level_of_pressure(pascals, reference_pascals) |
The sound pressure level in decibels, 20 log10(p / p0); the reference for sound in air is 0.00002 pascal. A pressure or a reference of zero or below has no level and is refused with a math domain error. Where p / p0 is not a normal real, it is 20 (log10 p - log10 p0). |
add_levels(a, b) |
The level of two incoherent sources of a and b decibels, 10 log10(10^(a/; two equal sources add 3.0103 decibels. It is computed as the louder level plus 10 log10(1 + 10^(-d/ for d the difference, so no power passes the largest real and any two levels have a sum. |
at_distance(level_at_r1, r1, r2) |
The level at distance r2 from a point source whose level at r1 is given, in free field: the level less 20 log10(r2 / r1), 6.02 decibels for each doubling, the logarithm taken as log10 r2 - log10 r1 where r2 / r1 is not a normal real. A distance of zero or below is refused with a math domain error. |
speed_of_sound(celsius) |
The speed of sound in dry air in metres a second, 331.32 * sqrt(1 + t / 273.15); 343.2353419474446 at 20. Below -273.15 it is refused with a math domain error. |
wavelength(speed, hertz) |
The wavelength in metres, the speed over the frequency. |
doppler(source_hz, speed, receiver_toward, source_toward) |
The observed frequency, f0 (c + vr) / (c - vs): receiver_toward is the receiver’s speed toward the source and source_toward the source’s toward the receiver, each negative for motion away. The sums are taken of halves where one passes the largest real, and where the frequency is then not a normal real it is worked on the mantissas and exponents math. gives. A source moving at the speed of sound is refused with a division by zero. |
twa_from_dose(dose_percent) |
The 8-hour time-weighted average level of a dose written in percent, 16.61 log10(D / 100) + 90, as OSHA’s Appendix A gives it. |
3.77 finance — declared fields
finance is not financial advice. It states which of several offers costs the least in total and which carry a payment over a limit you give it, and it does arithmetic with published formulas. It does not say which offer to take: the cheapest in total and an offer over a household’s limit can be the same offer, and the module reports both. Every rate, price and income is yours. Ask a financial adviser.
The writing scripts of §3.80 write Offer under the source "offer" and Budget under "budget", and you may write the same fields yourself. An offer is a loan offer named by you, and a budget is a household’s limit, named by the borrower it belongs to. An offer’s borrower and principal together name the group in which it is compared.
Offer
| Field | Class | Notes |
|---|---|---|
borrower |
string |
The borrower’s name, which is also a Budget’s name. Written by offer(). |
principal |
real |
The sum lent. Written by offer(). |
payment |
real |
The monthly payment as the lender states it. Written by offer(). |
months |
real |
The number of payments. Written by offer(). |
total |
real |
Computed from payment and months (§3.78). Never written. |
interest |
real |
Computed from the three (§3.78). Never written. |
cheapest |
bool |
Concluded by a rule (§3.79): no offer of the same borrower and principal has a smaller total. Never written. |
unaffordable |
bool |
Concluded by a rule (§3.79): the payment is over the borrower’s limit. Never written. |
Budget
| Field | Class | Notes |
|---|---|---|
limit |
real |
The largest monthly payment the household can bear. Written by budget(). |
3.78 finance — derived fields
| Field | Definition |
|---|---|
Offer. |
payment * months |
Offer. |
(0.5 * payment * months - 0.5 * principal) * 2.0 |
The total is what the lender is paid and the interest what is paid beyond the sum lent, taken of halves and doubled, which changes no digit of payment * months - principal and keeps a total past the largest real from making the interest one. Each is absent until the fields it reads are present, and both are real. A result is a real number and is not a cent. A bank rounds each payment to the cent and builds a schedule from those; this module does not, so a total is the payment times the months. Use it to compare, not to reproduce a lender’s statement.
3.79 finance — standing rules
Each holds continuously, as in §3.17. A rule over offers binds one as a and b, and the rule over an offer and a budget binds them as o and g.
| Rule | Over | Concludes | While |
|---|---|---|---|
cheapest_offer |
Offer |
cheapest |
no offer b has the same borrower and principal as a and a total less than a’s; concludes True |
unaffordable_offer |
Offer, Budget |
unaffordable |
the offer’s borrower is the budget and its payment is above the budget’s limit; concludes True |
finance declares no standing constraint. Six notes that are contract rather than commentary:
- Cheapest is the absence of a cheaper one. The rule is not “cheaper than some other offer”, which would mark an offer that a third one beats. It holds while no offer of the group has a smaller total and is withdrawn when a cheaper one is written.
why_notof it names the absence it needs and says that a cheaper offer is present. - Offers with equal totals are each cheapest. Neither has a cheaper one, and the module ranks nothing. That was measured, and is the rule’s meaning.
- Offers are compared within a borrower and a principal. An offer of another principal is not compared with them, so every group has a cheapest, and a group of one is its own.
- An offer over a limit is marked and kept. The same offer can be both cheapest and unaffordable, and the module reports both. A borrower with no budget has no offer marked unaffordable: nothing is recorded to be over, and
why_notsays so. A payment exactly at the limit is not over it. - A conclusion is positive. An offer that is not cheapest has no
cheapest, not a false one. - Disagreement is reasoned about by the lists and refused by the single read. When two sources give a payment two values, every value is reasoned about, and a conclusion stands if any value supports it.
unsettled()names the fact.totalreads one value and refuses while two are in force.
The module does not cover fees folded into an annual percentage rate, taxes, a schedule row by row, variable rates, or any statute beyond the words of its sources.
3.80 finance — queries
Called by name after import finance. The first three write facts and answer nothing. The next five read what the rules concluded, and unsettled() names what is in disagreement. The last nine are value scripts that return a value and write nothing. Floats are IEEE doubles. A rate is a fraction, 0.05 for 5 percent, except in the two doubling-time scripts, which take percent as the rule of 72 is written. Results agree with CPython’s except where a logarithm is taken: doubling_exact’s can differ from CPython’s by one unit in the last place.
| Query | Answers |
|---|---|
offer(name, borrower, principal, payment, months) |
Nothing. Writes the Offer named name with its monthly payment as the lender states it, under the source "offer". |
quote(name, borrower, principal, annual_rate, months) |
Nothing. Writes an offer whose payment is monthly_payment(principal, annual_rate, months). |
budget(borrower, limit) |
Nothing. Writes the Budget named borrower’s limit under the source "budget". |
names_of(values) |
The subjects for which any claim in values, a list as list_values returns, is True, sorted. |
cheapest_offers() |
The offers with no cheaper one among those of their borrower and principal, sorted. Equal totals are each in the list. |
unaffordable_offers() |
The offers whose payment is over their borrower’s limit, sorted. |
total(name) |
An offer’s total; 0.0 before the facts are written. Refuses while two values are in force. |
unsettled() |
Each offer and budget that holds two different values in force for a field you write: an offer’s borrower, principal, payment or months, or a budget’s limit. Given as offer or budget, its name and the field, offer a payment, sorted. |
monthly_payment(principal, annual_rate, months) |
The amortised payment, P i / (1 - (1 + i)^-n) with i the annual rate over 12, and P / n for a rate of zero. 1 - (1 + i)^-n is taken as -expm1(-n log1p(i)), which keeps the digits the plain form loses where the power is near 1; where the payment is not a normal real, it is worked on the mantissas and exponents math. gives. Zero months is refused with a division by zero, and fewer with ValueError. Not rounded to the cent. |
compound_amount(present, annual_rate, periods_per_year, years) |
What a sum grows to, P (1 + r/, for n above 0, others refused with ValueError; a sum of 0 stays 0. Where n t is too small for a real, the power is ((1 + r/. Where the sum is not a normal real while P is a real and 1 + r/ above 0, it is P e^(n t log1p(r/, log1p(r/ being ln r - ln n where r/ passes the largest real. |
effective_annual_rate(annual_rate, periods_per_year) |
The annual rate equal to a nominal one compounded n times a year, (1 + r/, for n above 0, others refused with ValueError. It is taken as expm1(n log1p(r/, which never forms the number near 1 that the plain form subtracts 1 from: for n of 1, 0.12 gives 0.12. A rate that loses all of a sum in a period gives -1, and one that loses more is refused with a math domain error. Where r/ passes the largest real, log1p(r/ is ln r - ln n, and where it is below the smallest normal real, the rate is expm1(r). |
continuous_annual_rate(annual_rate) |
The limit as the periods grow without bound, e^r - 1, taken as expm1(r). |
doubling_exact(percent) |
The years to double at a rate in percent, ln(2) / ln(1 + r/. A rate of zero is refused with a division by zero, and -100 percent with a math domain error. |
doubling_rule_of_72(percent) |
The rule of 72, 72 / r for a rate in percent; it suits 6 to 10 percent. |
present_value(future, annual_rate, years) |
A future sum discounted to now, F / (1 + r)^t; where that is not a normal real while F is a real and 1 + r above 0, F e^(-t log1p(r)). |
todays_value(nominal, inflation, years) |
A nominal sum in today’s money after some years of a steady inflation, N / (1 + inflation)^t, kept in range as present_value is. |
real_rate(nominal_rate, inflation) |
The real rate by the exact Fisher form, (1 + i) / (1 + pi) - 1; the approximation i - pi is slightly higher. |
3.81 food — declared fields
food is not food-safety or medical advice. It states published guidance as data and rules over the facts you record, and arithmetic with published conversions. A temperature in it is a figure from a chart: whether a food is safe to eat is decided by the cook, with a thermometer that reads the food, and whether an ingredient is safe for a person with an allergy is decided by that person and their doctor. A dish it does not mark unsafe is not thereby safe, and a dish it does not mark as holding an allergen holds none only of the ingredients you recorded. It gives no diagnosis. Ask a clinician about an allergy.
The writing scripts of §3.83 write Standard under the source "standard", Dish under "dish", Item under "item" and Line under "line", and you may write the same fields yourself. A standard is a minimum internal temperature in Celsius named by a kind of food, a dish a cooked dish named by you, an item an ingredient named by you, and a line an item used in a dish. A dish is judged against the standard whose name is its kind.
Standard
| Field | Class | Notes |
|---|---|---|
minimum |
real |
The minimum internal temperature in Celsius. Written by standard(), which converts the chart’s Fahrenheit exactly. |
Dish
| Field | Class | Notes |
|---|---|---|
kind |
string |
The name of the standard it is judged against. Written by dish(). |
core |
real |
The temperature its core reached, in Celsius. Written by dish(). |
minutes |
real |
The minutes it spent in the danger zone. Written by dish(). |
undercooked |
bool |
Concluded by a rule (§3.82): the kind has a standard and the core is below it. Never written. |
held_too_long |
bool |
Concluded by a rule (§3.82): more than two hours in the danger zone. Never written. |
unsafe |
bool |
Concluded by a rule (§3.82): either cause. Never written. |
unknown |
bool |
Concluded by a rule (§3.82): the kind has no standard recorded. Never written. |
milk, egg, fish, shellfish, tree_nuts, peanuts, wheat, soybeans, sesame |
bool |
Concluded by a rule each (§3.82): a line of the dish uses an item that holds the allergen. Never written. |
Item
| Field | Class | Notes |
|---|---|---|
milk, egg, fish, shellfish, tree_nuts, peanuts, wheat, soybeans, sesame |
bool |
Whether the ingredient holds the allergen. All nine are written by item(): True for those you name and False for the rest. |
Line
| Field | Class | Notes |
|---|---|---|
dish |
string |
The name of the dish. Written by line(). |
item |
string |
The name of the item. Written by line(). |
food declares no derived field. Everything it knows about a dish is concluded by the rules of §3.82, and the chart’s figures are facts that chart() and standard() write.
3.82 food — standing rules
Each holds continuously, as in §3.17. A rule over a dish and a standard binds them as d and s, and a rule over a dish, a line and an item as d, l and i.
| Rule | Over | Concludes | While |
|---|---|---|---|
undercooked_dish |
Dish, Standard |
undercooked |
the dish’s kind is the standard and its core is below the standard’s minimum; concludes True |
held_too_long_dish |
Dish |
held_too_long |
the dish’s minutes > 120.0; concludes True |
unsafe_for_cooking |
Dish |
unsafe |
the dish’s undercooked is True; concludes True |
unsafe_for_holding |
Dish |
unsafe |
the dish’s held_too_long is True; concludes True |
unknown_kind |
Dish |
unknown |
no standard of the dish’s kind has a minimum > -1000.0, which is to say a recorded one; concludes True |
holds_milk |
Dish, Line, Item |
milk |
a line’s dish is the dish, its item is the item, and the item’s milk is True; concludes True |
holds_egg |
Dish, Line, Item |
egg |
a line’s dish is the dish, its item is the item, and the item’s egg is True; concludes True |
holds_fish |
Dish, Line, Item |
fish |
a line’s dish is the dish, its item is the item, and the item’s fish is True; concludes True |
holds_shellfish |
Dish, Line, Item |
shellfish |
a line’s dish is the dish, its item is the item, and the item’s shellfish is True; concludes True |
holds_tree_nuts |
Dish, Line, Item |
tree_nuts |
a line’s dish is the dish, its item is the item, and the item’s tree_nuts is True; concludes True |
holds_peanuts |
Dish, Line, Item |
peanuts |
a line’s dish is the dish, its item is the item, and the item’s peanuts is True; concludes True |
holds_wheat |
Dish, Line, Item |
wheat |
a line’s dish is the dish, its item is the item, and the item’s wheat is True; concludes True |
holds_soybeans |
Dish, Line, Item |
soybeans |
a line’s dish is the dish, its item is the item, and the item’s soybeans is True; concludes True |
holds_sesame |
Dish, Line, Item |
sesame |
a line’s dish is the dish, its item is the item, and the item’s sesame is True; concludes True |
food declares no standing constraint. Eight notes that are contract rather than commentary:
- A kind with no standard is unknown, never safe.
unknownsays that no standard was recorded to conclude from. An emptyunsafemeans that no rule concluded it, and a dish this module does not mark unsafe is not thereby safe. The test that a kind has a standard reads the standard’s ownminimum, so a kind nothing has been recorded for is unknown whether or not the dish names it. - The chart’s rows are the standards
chart()writes. Eleven kinds:steak,ground,poultry,egg-dish,casserole,ham-raw,ham-precooked,ham-packaged,leftovers,rabbit-venisonandfish. Acasseroleis one with meat or poultry, or meatless: the chart gives both at 165 F.ham-precookedis precooked ham reheated, 165 F, andham-packagedis cooked ham packaged in a USDA-inspected plant and reheated, 140 F, the chart’s note to that row; a ham of the second kind recorded under the first kind is judged against 165. The rows that give no temperature (shrimp, lobster, crab and scallops until opaque, clams, oysters and mussels until the shells open, raw eggs until firm) are not in it, and the rest time of three minutes for a steak, a roast or a chop is a second fact that is not a rule here. - The figures are converted exactly and not rounded. A standard is written from the chart’s Fahrenheit by
(f - 32) * 5 / 9, so 145 F is 62.77777777777778 and 165 F is 73.88888888888889, where the chart prints 63 and 74. A core of 63 does not fall below the standard of a steak. - The temperatures are FoodSafety.gov’s. They are the chart “Cook to a Safe Minimum Internal Temperature” (
https://), whose page reads “Date Last Reviewed November 21, 2024”. They were read from a copy of that page downloaded on 2026-11-09, because an automated fetch of the agency’s sites was refused. Check them against the agency that governs your kitchen.www. foodsafety. gov/ food-safety-charts/ safe-minimum-internal-temperatures - The danger zone is held as two ranges.
danger_zone()names the USDA’s, 4 to 60 Celsius, and the United Kingdom’s, 8 to 63; agencies define it differently. The two hours of the rule are the limit of the minutes a dish spent there, and a dish with exactly 120 minutes is not held too long. - An item you never described is unknown, not free.
item()writes all nine allergen facts, so an item described as holding wheat is free from the other eight, and an item with no description holds nothing the rules can see. A dish holds an allergen only of the items recorded, so a dish with a line for an item never described may hold more than the module says. - A dish that exists only through its lines has no kind. The rules conclude its allergens, and it is
unknown, since there is no kind to look up. - A correction withdraws what rested on it, and a disagreement is reasoned about. A core temperature written again above its minimum withdraws
unsafe, and an ingredient replaced withdraws the allergen it brought. When two sources give a core two values, every value is reasoned about, and a dish is unsafe if any value puts it there.unsettled()names the fact.
The module does not cover a cooling curve, a rest, nutrients beyond the four of food_energy, cooking losses or yields.
3.83 food — queries
Called by name after import food. The first five write facts and answer nothing. danger_zone returns a value and writes nothing. The next five read what the rules concluded, two of them helpers, and unsettled() names what is in disagreement. The last six are value scripts that return a value and write nothing. Floats are IEEE doubles, and each result agrees with CPython’s. A density is a number you supply: the module holds none.
| Query | Answers |
|---|---|
standard(kind, minimum_fahrenheit) |
Nothing. Writes the Standard named kind’s minimum from the Fahrenheit figure, converted exactly, under the source "standard". |
chart() |
Nothing. Writes the eleven standards of the chart that give a temperature (§3.82). |
dish(name, kind, core_celsius, minutes_in_zone) |
Nothing. Writes the Dish named name’s kind, core and minutes under the source "dish". Written again it corrects them. |
item(name, allergens) |
Nothing. Writes all nine allergen facts of the Item named name, True for those in the list and False for the rest. A name that is not one of the nine is refused. |
line(name, dish_name, item_name) |
Nothing. Writes the Line named name: the item is used in the dish. |
danger_zone(agency) |
[low, high] in Celsius of the danger zone as the agency defines it: [4.0, 60.0] for "usda" and [8.0, 63.0] for "uk". Any other name is refused. Writes nothing. |
holds(values, name) |
Whether any claim in values, a list as list_values returns, is True for the subject name. |
names_of(values) |
The subjects for which any claim in values is True, sorted. |
unsafe_dishes() |
The dishes the rules conclude unsafe, for either cause, sorted. |
unknown_dishes() |
The dishes whose kind has no standard recorded, sorted. |
allergens_of(name) |
The allergens the rules conclude a dish holds, in the order milk, egg, fish, shellfish, tree_nuts, peanuts, wheat, soybeans, sesame; empty for a dish with none. |
unsettled() |
Each standard, dish, item and line that holds two different values in force for a field you write: a standard’s minimum, a dish’s kind, core or minutes, an item’s nine allergens, or a line’s dish or item. Given as its kind in lower case, its name and the field, dish d1 core, sorted. |
fahrenheit_to_celsius(fahrenheit) |
(f - 32) * 5 / 9, in that order; (f - 32) / 9 * 5 where (f - 32) * 5 passes the largest real. |
scale_by_servings(quantity, from_servings, to_servings) |
A quantity for one number of servings, for another: quantity * to / from; where that is not a normal real, the same worked on the mantissas and exponents math. gives. |
bakers_percentage(part, flour) |
An ingredient’s weight as a percentage of the flour’s, 100 * part / flour; the flour is 100 and the water’s is the hydration, kept in range as scale_by_servings is. A flour of zero is refused with a division by zero. |
volume_to_mass(cups, density_grams_per_ml) |
Grams for a volume in US customary cups of 236.5882365 millilitres, by a density in grams per millilitre that you supply, kept in range as scale_by_servings is. |
food_energy(protein_g, carbohydrate_g, fat_g, alcohol_g) |
Kilocalories by the labelling table’s approximate factors: 4 for protein, 4 for carbohydrate, 9 for fat and 7 for alcohol. |
kilocalories_to_kilojoules(kilocalories) |
One kilocalorie is 4.184 kilojoules. |
3.84 architecture — declared fields
architecture is not engineering, naval-architecture, acoustic-design or heritage advice. It states published definitions and simple models as rules over the facts you record. A tower in it is a straight column of even weight, a hull is a box, and a room is Sabine’s equation: whether a real structure is safe, a real ship stable or a real hall good for music is decided by those who survey, test and certify it. A style is a family resemblance that a rule makes strict, and a record of height is a verdict over the records you wrote.
The writing scripts of §3.87 write Building under the source "building", Structure under "structure", Tower under "tower", Hull under "hull", Room under "room", Surface under "surface" and Channel under "channel", and Fall under the source you name; you may write the same fields yourself. A building is a building with the features recorded for it, a structure anything with a height and a year of completion, a tower a column with a lean, a hull a ship’s hull taken as a box, a room a volume with a range of reverberation times wanted, a surface an area lining a room, and a channel a watercourse with a fall; each is named by you. A fall is a standard, a minimum gradient, named by its name, and a channel is judged against the fall whose name is its standard. Lengths are in metres, except a channel’s, which are in any one unit.
Building
| Field | Class | Notes |
|---|---|---|
pointed_arch, rib_vault, flying_buttress, round_arch, thick_walls, barrel_vault, groin_vault, dome, pendentives |
bool |
Whether the building has the feature. All nine are written by building(): True for those you name and False for the rest. |
gothic |
bool |
Concluded by a rule (§3.86): pointed arches, rib vaults and flying buttresses. Never written. |
romanesque |
bool |
Concluded by two rules (§3.86): round arches and thick walls, with a barrel vault or a groin vault. Never written. |
pendentive_dome |
bool |
Concluded by a rule (§3.86): a dome and pendentives. Never written. |
Structure
| Field | Class | Notes |
|---|---|---|
height |
real |
Its height in metres. Written by structure(). |
completed |
real |
The year it was completed, negative before the common era. Written by structure(). |
until |
real |
The year it fell, or the part of it that made its height. structure() writes 10000.0, standing, and fell() writes the year. |
building |
bool |
Whether it is a building. Written by structure(). |
tallest_structure |
bool |
Concluded by a rule (§3.86): it was the tallest structure recorded when it was completed. Never written. |
tallest_building |
bool |
Concluded by a rule (§3.86): it was the tallest building recorded when it was completed. Never written. |
undated |
bool |
Concluded by a rule (§3.86): it has a height and no year of completion. Never written. |
Tower
| Field | Class | Notes |
|---|---|---|
height |
real |
Its height in metres. Written by tower(). |
offset |
real |
Its top’s distance from the vertical, in metres. Written by tower(). |
base |
real |
Its base’s outer diameter, in metres. Written by tower(). |
shift |
real |
Computed from offset (§3.85). Never written. |
radius |
real |
Computed from base (§3.85). Never written. |
tips |
bool |
Concluded by a rule (§3.86): the shift passes the radius. Never written. |
Hull
| Field | Class | Notes |
|---|---|---|
beam |
real |
Its breadth, in metres. Written by hull(). |
draught |
real |
Its depth in the water, in metres. Written by hull(). |
kg |
real |
The height of its centre of gravity above the keel, in metres. Written by hull(). |
kb, bm, gm |
real |
Computed (§3.85). Never written. |
unstable |
bool |
Concluded by a rule (§3.86): the metacentric height is not positive. Never written. |
Room
| Field | Class | Notes |
|---|---|---|
volume |
real |
Its volume in cubic metres. Written by room(). |
low |
real |
The shortest reverberation time wanted, in seconds. Written by room(). |
high |
real |
The longest reverberation time wanted, in seconds. Written by room(). |
surfaces |
int |
Concluded by a rule (§3.86): how many of the room’s surfaces have sabins. Never written. |
claims |
int |
Concluded by a rule (§3.86): how many claims of sabins they hold. Never written. |
disputed |
bool |
Concluded by a rule (§3.86): claims is greater than surfaces. Never written. |
absorption |
real |
Concluded by a rule (§3.86): the sum of the sabins of the room’s surfaces. Never written. |
rt |
real |
Computed from volume and absorption (§3.85). Never written. |
too_live |
bool |
Concluded by a rule (§3.86): the time is longer than high. Never written. |
too_dead |
bool |
Concluded by a rule (§3.86): the time is shorter than low. Never written. |
unmeasured |
bool |
Concluded by a rule (§3.86): the room has a volume and no surface. Never written. |
Surface
| Field | Class | Notes |
|---|---|---|
room |
string |
The name of the room it lines. Written by surface(). |
area |
real |
Its area in square metres. Written by surface(). |
coefficient |
real |
Its absorption coefficient, as you give it. Written by surface(). |
sabins |
real |
Computed from area and coefficient (§3.85). Never written. |
Fall
| Field | Class | Notes |
|---|---|---|
minimum |
real |
The minimum gradient, a drop over a length. Written by fall() under the source you name; vitruvius() writes two values of it. |
Channel
| Field | Class | Notes |
|---|---|---|
length |
real |
Its length. Written by channel(). |
drop |
real |
Its drop over that length, in the same unit. Written by channel(). |
standard |
string |
The name of the fall it is held to. Written by channel(). |
gradient |
real |
Computed from drop and length (§3.85). Never written. |
too_flat |
bool |
Concluded by a rule (§3.86): the gradient is below the standard’s minimum. Never written. |
no_standard |
bool |
Concluded by a rule (§3.86): no fall of that name has a minimum recorded. Never written. |
3.85 architecture — derived fields
| Field | Definition |
|---|---|
Tower. |
offset / 2.0 |
Tower. |
base / 2.0 |
Hull. |
draught / 2.0 |
Hull. |
beam * beam / (12.0 * draught) |
Hull. |
(0.5 * kb + 0.5 * bm - 0.5 * kg) * 2.0 |
Room. |
0.161 * volume / absorption |
Surface. |
area * coefficient |
Channel. |
drop / length |
shift is the distance of a tower’s centre of mass from the vertical, on the model of a straight tower of even weight: half the top’s. radius is half the base’s outer diameter. kb is the height of a hull’s centre of buoyancy above the keel, bm the distance from it to the metacentre, and gm the metacentric height, the distance from the centre of gravity to the metacentre. For a box the centre of buoyancy is half the draught and BM is the beam squared over twelve times the draught; those two forms are this module’s derivation from KM = KB + BM and BM = I/V, not a published formula. gm is kb + bm - kg taken of halves and doubled, which changes no digit of it and keeps a sum past the largest real from making it one. bm is a real for any beam and draught from 10^-150 to 10^150 metres, which is the range the class states. rt is Sabine’s reverberation time, 0.161 V / A in seconds; the constant is given as about 0.1611 elsewhere, and the module uses 0.161. sabins is a surface’s absorption in square metres, and gradient a channel’s drop over its length.
Each is absent until the fields it reads are present, and all are real. rt reads absorption, which a rule concludes, so it follows the surfaces: a surface added or corrected moves it. A zero divisor draws no value: a hull of zero draught has no bm and no gm, a channel of zero length no gradient, and a room whose surfaces absorb nothing no rt. No rule concludes from a field with no value, and why_not says that nothing is recorded there.
3.86 architecture — standing rules
Each holds continuously, as in §3.17. A rule over a building binds it as b, a structure as s and those it is compared with as o, a tower as t, a hull as h, a room as r and its surfaces as s, and a channel as c and its standard as f.
| Rule | Over | Concludes | While |
|---|---|---|---|
gothic_building |
Building |
gothic |
the building’s pointed_arch, rib_vault and flying_buttress are True; concludes True |
romanesque_barrel_vault |
Building |
romanesque |
the building’s round_arch, thick_walls and barrel_vault are True; concludes True |
romanesque_groin_vault |
Building |
romanesque |
the building’s round_arch, thick_walls and groin_vault are True; concludes True |
dome_on_pendentives |
Building |
pendentive_dome |
the building’s dome and pendentives are True; concludes True |
tallest_structure_when_completed |
Structure |
tallest_structure |
the structure’s height > 0.0 and completed > -1000000.0, which is to say a recorded one, and no structure completed in that year or before it still stood after it and is taller; concludes True |
tallest_building_when_completed |
Structure |
tallest_building |
the structure’s building is True, its height > 0.0 and completed > -1000000.0, and no building completed in that year or before it still stood after it and is taller; concludes True |
undated_structure |
Structure |
undated |
the structure’s height > 0.0 and it has no completed; concludes True |
tower_tips |
Tower |
tips |
the tower’s shift is greater than its radius; concludes True |
unstable_hull |
Hull |
unstable |
the hull’s gm <= 0.0; concludes True |
room_claims |
Room, Surface |
claims |
a surface’s room is the room and its sabins > -1.0e300; concludes the number of claims of sabins those surfaces hold |
room_surfaces |
Room, Surface |
surfaces |
a surface’s room is the room and its sabins > -1.0e300; concludes the number of distinct such surfaces |
room_disputed |
Room |
disputed |
the room’s claims is greater than its surfaces; concludes True |
room_absorption |
Room, Surface |
absorption |
a surface’s room is the room and the room has no disputed; concludes the sum of the sabins of those surfaces |
room_too_live |
Room |
too_live |
the room’s rt is greater than its high; concludes True |
room_too_dead |
Room |
too_dead |
the room’s rt is less than its low; concludes True |
room_unmeasured |
Room |
unmeasured |
the room’s volume > 0.0 and no surface whose room is the room has an area > -1.0, which is to say a recorded one; concludes True |
channel_too_flat |
Channel, Fall |
too_flat |
the channel’s standard is the fall, the fall’s minimum > -1.0, which is to say a recorded one, and the channel’s gradient is less than it; concludes True |
channel_without_standard |
Channel |
no_standard |
no fall named by the channel’s standard has a minimum > -1.0; concludes True |
architecture declares no standing constraint. Nine notes that are contract rather than commentary:
- A style is three features, and a building never described is unknown.
building()writes all nine features, so a building you described lacks what you did not name, andwhy_notnames the feature that isFalse. A building with no facts has no style, andwhy_notsays that nothing is recorded there. Gothic’s definition names four features, and the rule takes the three that are parts of the structure; the fourth is its windows. A pendentive is a device and not a period, sopendentive_domeis a form and not a style, and a building may have both. - A record is judged over the records you wrote. A structure is the tallest when it was completed if no structure you recorded was completed in that year or before it, still stood after it and was taller; one that is not recorded cannot end a record. A structure stands in every year before its
until. A year before the common era is written negative, as -2570 for 2570 BC, and is compared like any other.tallest_buildingasks the same among buildings only, so a monument or a tower that is not a building ends a structure’s record and not a building’s. The rules ask which structure was the tallest when it was completed: one that became the tallest later, when taller ones fell, is not concluded. Recorded as the list of the tallest structures built before the twentieth century gives them, Cologne Cathedral is the tallest structure until the Washington Monument of 1884 and the tallest building until Ulm Minster of 1890. - A record with no year is undated and never ranked. With no year, nothing could be completed before it, so it would be concluded the tallest, and nothing could be ended by it.
undatedmarks it, and writing its year ranks it. - A fall is a correction.
fell()writesuntil, and a record that a taller structure ended only while it stood is concluded once the fall is written. A fall in the year another structure was completed does not end that structure’s record. - The tower model sees the structure and not the ground. On the model, a straight tower of even weight tips when its centre of mass, half the top’s offset, passes the edge of its base; a shift exactly at the radius does not tip. Whether a real tower stands depends also on the ground under it, which the model does not see.
- GM is initial stability. It measures how a hull resists heel at small angles, where the metacentre can be taken as fixed; stability at large angles is not modelled here. A hull with a GM of exactly zero is
unstable, and ballast that lowerskgwithdraws the verdict. - A room is judged by its surfaces.
absorptionis the exact sum of its surfaces’ sabins, rounded once, so the order in which the surfaces were written does not move it. A room with no surface isunmeasuredand has nort, so it is neither too live nor too dead. A time exactly at an end of the range is inside it. Sabine’s equation is the module’s whole acoustics; Eyring’s, which the literature gives for small rooms with much absorption, is not here. - Vitruvius’s minimum is held as two values.
vitruvius()writes the two readings the sources give, half a foot in a hundred and one in 4,800, as two values of one fact. A channel is too flat if any value in force puts it there, so a channel marked too flat is too flat under at least one reading, and a channel not marked is within all of them.unsettled()namesfall vitruvius minimum. A channel whose standard has no value isno_standard, never within it. - A correction withdraws what rested on it, and a disagreement is reasoned about. A fact written again withdraws the conclusions that rested on its old value. When two sources give a fact two values, every value is reasoned about. A verdict a rule concludes from what it finds holds under any of them, as a style, an unstable hull or a flat channel does. A verdict a rule concludes from what it does not find holds only if nothing is found under any of them: a taller value of any height ends a record, and a structure whose own height holds two values is never the tallest, since under one of them it is taller than under the other.
unsettled()names the fact, andrecord_until()refuses while a fact it reads holds two values. A sum reads every value too, so a surface whosesabinsholds two values would be added twice to its room’sabsorption;surfacesandclaimscount the surfaces and their claims over the one binding the sum reads, and while the claims are more the room isdisputedand has noabsorption,rtor verdict. A surface with nosabinsis in neither count, and one whoseroomholds two values lines each room it names, each absorption being one source’s. A conclusion over a group-wise absence names, inwhy_not, a field of the form<rule>__none1that is “to be absent, and it is present”: it means that something the rule asks to be missing was found, as the Python Specification §14.2 defines it.
The module does not cover loads, materials or foundations, wind or earthquakes, stability at large angles of heel, hull forms other than a box, Eyring’s or any other reverberation formula, the frequency of a reverberation time, or the flow of water in a channel.
3.87 architecture — queries
Called by name after import architecture. The first ten write facts and answer nothing. The next seventeen read what the rules concluded, three of them helpers, and unsettled() names what is in disagreement. The last eight are value scripts that return a value and write nothing. Floats are IEEE doubles. Results are not rounded. Each step is rounded once: math. and math. are correctly rounded, and math. and math. give a·180/π and a·π/180 rounded once. A lean or an offset can therefore differ from CPython’s in the last place, where CPython rounds twice or its library misses the correctly rounded value: lean_degrees(1.0, 14.0) is 4.085616779974876 here and 4.085616779974877 in CPython 3.11. Every other script gives CPython’s digits.
| Query | Answers |
|---|---|
building(name, features) |
Nothing. Writes all nine features of the Building named name, True for those in the list and False for the rest, under the source "building". A name that is not one of the nine is refused. |
structure(name, height, completed, is_building) |
Nothing. Writes the Structure named name’s height, completed and building, and its until as 10000.0, standing, under the source "structure". Written again it corrects them and writes the structure standing, so fell() comes after it. |
fell(name, year) |
Nothing. Writes the Structure named name’s until, the year it fell, under the source "structure". |
tower(name, height, offset, base) |
Nothing. Writes the Tower named name’s height, offset and base under the source "tower". |
hull(name, beam, draught, kg) |
Nothing. Writes the Hull named name’s beam, draught and kg under the source "hull". |
room(name, volume, low, high) |
Nothing. Writes the Room named name’s volume, low and high under the source "room". |
surface(name, room_name, area, coefficient) |
Nothing. Writes the Surface named name’s room, area and coefficient under the source "surface". |
fall(standard, minimum, source) |
Nothing. Writes the Fall named standard’s minimum under the source you name. A second source that gives another value writes a second value of the same fact. |
vitruvius() |
Nothing. Writes the Fall named "vitruvius" twice: 0.5 / 100.0 under the source "half-a-foot-in-a-hundred" and 1.0 / 4800.0 under "one-in-4800". |
channel(name, length, drop, standard) |
Nothing. Writes the Channel named name’s length, drop and standard under the source "channel". |
names_of(values) |
The subjects for which any claim in values, a list as list_values returns, is True, sorted. |
styles_of(name) |
The styles and forms the rules conclude for a building, in the order gothic, romanesque, pendentive_dome; empty for a building with none. |
tallest_structures() |
The structures that were the tallest when they were completed, sorted. |
tallest_buildings() |
The buildings that were the tallest building when they were completed, sorted. |
undated_structures() |
The structures with a height and no year of completion, sorted. |
reals(values) |
A dict from each subject in values to its number. A subject that holds two different values is refused, and so is a value that is not a number. |
record_until(name, buildings_only) |
The year a record passed: the earlier of the year the structure fell and the year a taller one was completed after it, over all structures, or over buildings when buildings_only is True. 10000.0 when nothing you recorded passed it and it stands: passed by nothing recorded, not held for ever. A structure that was not the tallest when it was completed is refused, and so is any call while a structure’s height, year of completion, year of falling or building flag holds two values, since any of them can move the year. |
tipping_towers() |
The towers whose shift passes their radius, sorted. |
unstable_hulls() |
The hulls whose gm is not positive, sorted. |
live_rooms() |
The rooms whose rt is longer than their high, sorted. |
dead_rooms() |
The rooms whose rt is shorter than their low, sorted. |
disputed_rooms() |
The rooms with disputed, sorted. |
unmeasured_rooms() |
The rooms with a volume and no surface, sorted. |
flat_channels() |
The channels whose gradient is below their standard’s minimum under at least one of its values, sorted. |
channels_without_standard() |
The channels whose standard has no minimum recorded, sorted. |
disputes(values, noun) |
The facts in values that hold two different values, each as noun, the subject and the field; the helper unsettled() is built on. |
unsettled() |
Each building, structure, tower, hull, room, surface, fall and channel that holds two different values in force for a field you write: a building’s nine features, a structure’s height, completed, until or building, a tower’s height, offset or base, a hull’s beam, draught or kg, a room’s volume, low or high, a surface’s room, area or coefficient, a fall’s minimum, or a channel’s length, drop or standard. Given as its kind in lower case, its name and the field, fall vitruvius minimum, sorted. |
lean_degrees(offset, height) |
A lean in degrees from the top’s offset and the height, degrees(atan(offset / height)). A height of zero is refused with a division by zero. |
top_offset(height, degrees) |
The top’s offset for a height and a lean in degrees, height * tan(radians(degrees)), the lean taken modulo 360 degrees by math. first; where the product is not a normal real, it is worked on the mantissas and exponents math. gives. |
reverberation_time(volume, absorption) |
Sabine’s time in seconds, 0.161 * volume / absorption, the volume in cubic metres and the absorption in sabins. An absorption of zero is refused with a division by zero. |
metacentric_height(beam, draught, kg) |
A box hull’s GM, draught / 2 + beam * beam / (12 * draught) - kg, taken of halves and doubled as Hull. is, so that it is that field to the last digit; where beam * beam / (12 * draught) is not a normal real, its half is worked on the mantissas and exponents math. gives. A draught of zero is refused with a division by zero. |
gradient(length, drop) |
A channel’s gradient, drop / length. A length of zero is refused with a division by zero. |
one_in(length, drop) |
The gradient as one in N, length / drop: a drop of 0.025 in 456 is one in 18240.0. A drop of zero is refused with a division by zero. |
pendulum_period(length) |
A pendulum’s period in seconds for a length in metres, at standard gravity and for a small swing, 2 pi sqrt(length / 9.80665). A negative length is refused with a math domain error. |
pendulum_length(period) |
The length in metres of a pendulum with a period in seconds, at standard gravity and for a small swing, 9.80665 * (period / (2 pi))^2. |
3.88 elections — declared fields
elections is not legal or electoral advice. It states published counting methods as rules and calculations over the ballots and populations you record. It certifies no election and counts no real ballot for anyone: which method an election uses, who may vote and what a ballot says are decided by the law and the officials who run it. A winner in it is a verdict over the numbers you wrote, under the method named.
The writing scripts of §3.91 write Election, Candidate and Duel under the source "election" and Ballot and Pref under "ballot"; recount() writes a ballot’s count under the source you name. You may write the same fields yourself. An election is named by you and has two candidates or more; a candidate is named by you and stands in one election, and a candidate’s name is its own across all your elections; a ballot is the ranking of every candidate of one election, first to last, with the number of voters who cast it; a preference records, for one ballot and one pair of candidates, which of the two the ballot ranks higher; a duel is one ordered pair of the candidates of an election, a against b. election() also writes, for each election, a ballot named by the election’s name and __baseline, of no voters, so that an election has a total and a tally for every duel before its first ballot is written. Counts are numbers of voters.
Election
| Field | Class | Notes |
|---|---|---|
candidates |
real |
How many candidates it has. Written by election(). |
total |
real |
Concluded by a rule (§3.90): the voters over all its ballots. Never written. |
matches, firstclaims, rankclaims, ballots |
real |
Concluded by rules (§3.90): the counts that disputed compares. Never written. |
disputed |
bool |
Concluded by three rules (§3.90): a ballot holds a second claim on its count, ranking or first choice. Never written. |
no_condorcet |
bool |
Concluded by a rule (§3.90): no candidate beats every other head to head. Never written. |
Candidate
| Field | Class | Notes |
|---|---|---|
election |
string |
The name of the election it stands in. Written by election(). |
firsts |
real |
Concluded by a rule (§3.90): the voters who put it first. Never written. |
twice |
real |
Computed from firsts (§3.89). Never written. |
borda |
real |
Concluded by a rule (§3.90): its Borda score. Never written. |
plurality, majority, condorcet, condorcet_loser, borda_winner |
bool |
Concluded by rules (§3.90). Never written. |
Ballot
| Field | Class | Notes |
|---|---|---|
election |
string |
The name of the election it is cast in. Written by ballot(). |
first |
string |
Its first choice. Written by ballot(). |
ranking |
string |
The candidates’ names joined by >, first to last. Written by ballot(). |
count |
real |
The number of voters who cast it. Written by ballot(), and by recount() under another source. |
Pref
| Field | Class | Notes |
|---|---|---|
ballot |
string |
The name of the ballot. Written by ballot(). |
over |
string |
The candidate the ballot ranks higher of the pair. Written by ballot(). |
under |
string |
The candidate it ranks lower. Written by ballot(). |
Duel
| Field | Class | Notes |
|---|---|---|
election |
string |
The name of the election. Written by election(). |
a, b |
string |
The two candidates, a against b. Written by election(). |
ab |
real |
Concluded by a rule (§3.90): the voters ranking a over b. Never written. |
ba |
real |
Concluded by a rule (§3.90): the voters ranking b over a. Never written. |
margin |
real |
Computed from ab and ba (§3.89). Never written. |
3.89 elections — derived fields
| Field | Definition |
|---|---|
Candidate. |
firsts * 2.0 |
Duel. |
ab - ba |
twice is twice the voters who put a candidate first, so that a majority, which is more than half of the voters, is a comparison of two numbers with no division. margin is the voters who rank a over b less those who rank b over a, positive where a wins the duel. Each is absent until the fields it reads are present, and both are real. No rule concludes from a field with no value, and why_not says that nothing is recorded there.
3.90 elections — standing rules
Each holds continuously, as in §3.17. A rule binds an election as e, a candidate as c and the candidates it is compared with as o, a ballot as b, a duel as d and a preference as p.
| Rule | Over | Concludes | While |
|---|---|---|---|
first_preferences |
Candidate, Ballot |
firsts |
a ballot’s first is the candidate; concludes the sum of those ballots’ count |
election_total |
Election, Ballot |
total |
a ballot’s election is the election; concludes the sum of those ballots’ count |
duel_for |
Duel, Pref, Ballot |
ab |
a preference’s over is the duel’s a, its under is the duel’s b and its ballot is the ballot; concludes the sum of those ballots’ count |
duel_against |
Duel, Pref, Ballot |
ba |
a preference’s over is the duel’s b, its under is the duel’s a and its ballot is the ballot; concludes the sum of those ballots’ count |
borda_score |
Candidate, Duel |
borda |
a duel’s a is the candidate; concludes the sum of those duels’ ab |
election_matches |
Election, Ballot |
matches |
a ballot’s election is the election and it has a count > -1.0, which is to say a recorded one; concludes how many such claims there are |
election_first_matches |
Election, Ballot |
firstclaims |
a ballot’s election is the election and its first is not ">"; concludes how many such claims there are |
election_rank_matches |
Election, Ballot |
rankclaims |
a ballot’s election is the election and its ranking is not ">"; concludes how many such claims there are |
election_ballots |
Election, Ballot |
ballots |
a ballot’s election is the election; concludes how many distinct ballots there are |
election_disputed |
Election |
disputed |
the election’s matches is greater than its ballots; concludes True |
election_disputed_first |
Election |
disputed |
the election’s firstclaims is greater than its ballots; concludes True |
election_disputed_ranking |
Election |
disputed |
the election’s rankclaims is greater than its ballots; concludes True |
plurality_winner |
Candidate, Election |
plurality |
the election has no disputed, the candidate’s firsts > 0.0 and no other candidate of the election has more firsts; concludes True |
majority_winner |
Candidate, Election |
majority |
the election has no disputed and the candidate’s twice is greater than the election’s total; concludes True |
condorcet_winner |
Candidate, Election |
condorcet |
the election has no disputed and no duel with the candidate as a has a margin <= 0.0; concludes True |
condorcet_loser |
Candidate, Election |
condorcet_loser |
the election has no disputed and no duel with the candidate as a has a margin >= 0.0; concludes True |
borda_winner |
Candidate, Election |
borda_winner |
the election has no disputed, the candidate’s borda > 0.0 and no other candidate of the election has a higher borda; concludes True |
no_condorcet_winner |
Election |
no_condorcet |
the election’s total > 0.0, it has no disputed and no candidate of it has condorcet True; concludes True |
elections declares no standing constraint. Seven notes that are contract rather than commentary:
- Each method concludes its own winner, and they may differ.
pluralityis the candidate the most voters put first,majoritythe candidate more than half put first,condorcetthe candidate who beats every other head to head, andborda_winnerthe candidate with the highest Borda score. A candidate’s Borda score is the sum of its head-to-head tallies: over every ballot and every other candidate, the voters who rank it higher, which is the Borda count of n - 1 points for a first place down to 0 for a last. With the four cities of the Tennessee example the sources share, the most voters put Memphis first, and Nashville beats every other city head to head and has the highest Borda score.condorcet_loseris the candidate every other beats. - A tie is no win and no loss. A duel with a
marginof zero is neither, so a candidate who ties another head to head is not a Condorcet winner or loser. A tie for the most first choices, or for the highest Borda score, concludes the verdict for each candidate in it. - A cycle leaves no Condorcet winner. Where the head-to-head counts run in a cycle, A over B, B over C and C over A, no candidate beats every other and
no_condorcetis concluded for the election.without_condorcet_winner()names it. - A count in dispute decides nothing. A rule that adds up a fact adds every value it holds, so a second count of a ballot, from a second source, would be added to the first, and a winner concluded from the total would be the winner under neither count.
recount()writes such a second count. While any ballot of an election holds a second claim on its count, its ranking or its first choice,disputedis concluded for the election, no winner is concluded for it, and its readers refuse;why_noton a candidate’s verdict names the dispute. Forgetting the claim that is not to stand settles it, and every verdict returns. - A ballot ranks every candidate once, and writing it again replaces it. A tied or partial ranking cannot be written. The candidates of an election are fixed once it is written, and a ballot written again under its name with another ranking withdraws what rested on the first.
- The seat methods compare in whole numbers.
largest_remainderandhighest_averagesgive seats from populations that are whole numbers, and compare only whole numbers, so a tie is found exactly. A tie that more states share than there are seats left to give refuses rather than be broken, as does an instant-runoff tie for last place, since the methods name no way to break one. Huntington-Hill gives every state one seat first, and its comparison of squared populations is exact only up to a population of 3,037,000,499, which larger populations are refused. - A conclusion over a group-wise absence names, in
why_not, a field of the form<rule>__none1that is “to be absent, and it is present”: it means that something the rule asks to be missing was found, as the Python Specification §14.2 defines it. Awhyon that cell names the head-to-head count that beats the candidate, and under it each ballot’s preference and count.
The module does not cover the law of any election, who may vote, what a ballot says, ballots that tie or leave candidates out, write-in or spoiled ballots, runoffs between two rounds of voting, systems that transfer votes beyond the instant-runoff count, or the allocation of seats from ballots rather than from populations.
3.91 elections — queries
Called by name after import elections. The first three write facts and answer nothing. The next thirteen read what the rules concluded, five of them helpers, and runoff counts the ballots round by round. The last nine write nothing and, but for checked, return a value: the quotas, the two seat methods, a priority and four helpers of the seat methods. Floats are IEEE doubles and results are not rounded.
| Query | Answers |
|---|---|
election(name, roster) |
Nothing. Writes the Election named name and its candidates, two or more, each named once, under the source "election", with every duel and preference of the pairs and the election’s ballot of no voters. A name that holds __ or > is refused, and so is a candidate named twice, one already standing in another election and an election already written. |
ballot(name, poll, voters, order) |
Nothing. Writes the Ballot named name in election poll, ranking every candidate of it once in order, first to last, cast by voters, with the preferences of every pair, under the source "ballot". Written again it replaces. A negative count, an election not written, a candidate not of it and a candidate ranked twice or left out are refused. |
recount(name, voters, reason) |
Nothing. Writes a second count of the ballot name under the source reason, which is not "ballot", and so puts its election in dispute until one of the two claims is forgotten. |
strings(values) |
A dict from each subject in values, a list as list_values returns, to its string; a value that is not a string is refused. |
candidates_of(name) |
The candidates of the election name, sorted; empty for one not written. |
names_of(values) |
The subjects for which any claim in values is True, sorted. |
disputed_elections() |
The elections whose count is in dispute, sorted. |
without_condorcet_winner() |
The elections in which no candidate beats every other head to head, sorted. |
settled(name) |
The candidates of the election name, sorted. An election not written, and one whose count is disputed, are refused. |
chosen(values, names) |
The subjects of names for which any claim in values is True, sorted. |
winners(name) |
A dict with the keys plurality, majority, condorcet, condorcet_loser and borda, each the list of the election’s candidates the rules conclude it for, sorted. A list is empty where no candidate wins and holds more than one where candidates tie. A disputed election is refused. |
tallies(values, names) |
A dict from each of names to its number in values, 0.0 where it has none; a value that is not a number is refused. |
first_choices(name) |
A dict from each candidate of the election to the voters who put it first. |
borda_scores(name) |
A dict from each candidate of the election to its Borda score. |
head_to_head(name) |
A dict from each ordered pair "a>b" of the election’s candidates to the voters who rank a over b. |
runoff(name) |
An instant-runoff count: a list of dicts, one tally per round. Each round every ballot counts for the highest candidate on it still standing, and the candidate with the fewest votes is eliminated, until one stands. A tie for last place is refused. |
hare_quota(votes, seats) |
The Hare quota, float(votes) / float(seats). Fewer than one seat is refused. |
droop_quota(votes, seats) |
The exact Droop quota, float(votes) / float(seats + 1). Fewer than one seat is refused. |
checked(populations, seats) |
Nothing. Refuses a dict with no state, a negative number of seats and a population that is not positive; the helper the seat scripts begin with. |
largest_remainder(populations, seats) |
Hamilton’s method: a dict from each state to its seats. Each state takes the whole part of its share, and the seats left go one each to the largest remainders. A tie for the last seat is refused. |
wide(x, p) |
x times p as a list of two ints, the high and the low half of 31 bits each; the helper of wide_compare. |
wide_compare(x, p, y, q) |
1, 0 or -1 as x * p is greater than, equal to or less than y * q, compared exactly; the helper of ahead. |
ahead(a, na, b, nb, method) |
1, 0 or -1 as a state of population a holding na seats has a higher, an equal or a lower priority for the next seat than one of population b holding nb, under method; the helper of highest_averages. |
highest_averages(populations, seats, method) |
A dict from each state to its seats, given one at a time to the state with the highest priority: its population over 1, 2, 3 and on by "dhondt", over 1, 3, 5 and on by "sainte_lague", and over the square root of n (n + 1) by "huntington_hill", which first gives every state one seat. Any other method, fewer seats than states under Huntington-Hill and a tie for the last seat are refused. |
priority_value(population, held) |
Huntington-Hill’s priority for a state’s next seat, population / sqrt(held * (held + 1)). A state holding fewer than one seat is refused. |
4. dkepy
The Python package a customer installs to write facts. Distribution name dkepy; import name dke. They differ because dke is taken on PyPI, and neither may change casually — both appear in customer code.
dkepy is not required. It is one conformant producer, published so that you have a worked example and do not have to write the boring half yourself. A producer in any language that satisfies §5 is equally conformant.
4.1 What the package guarantees about itself
These are properties a caller may depend on. LangSyn’s tests assert each one before a release is published; the tests are not part of the release, and each property can be checked against the source it describes:
- No network. No module in the package opens a connection, except
dke.andclient dke., whose purposes are to. Nothing else in the package reaches either.keys - No subprocess. The package spawns nothing.
- Zero runtime dependencies. Nothing beyond the Python standard library, except that
dke.needskeys cryptography, thekeysextra. - Python 3.10 or later, a hard floor with a named cause.
- No engine code. The package contains none and never will.
4.2 dke.factwriter — domain-free
The layer that knows how to write a fact-loading program and nothing about what the facts mean. Public surface:
| Name | Contract |
|---|---|
sanitize(name) -> str |
Make a name safe to use as an identifier. |
Ids |
Stable subject allocation. get(qual) returns the same subject for the same qualified name, for the life of the instance. |
FactProgram |
Builds one DKE Python program. comment, open, q, put, table, load_marker, render. |
FactProgram. is the one way a target cell is named, and its argument is the Kind. path of §2.1. A producer that writes through anything else is outside what §5.4’s check can see.
dke. is re-exported at the package root: from dke import FactProgram, Ids, sanitize.
4.3 dke.ingest — the code readers
Readers for one domain — source code — that are both consumers of dke. and the worked example of §5. dke. holds the domain-shared layer and MODULE = "code", which names the module these facts are for, and one reader submodule per source language sits beside it.
Naming asymmetry, stated because it will otherwise look like a bug. The reader class for
code.is spelledClass Klassin Python, becauseclassis a Python keyword. The fact it writes iscode.. The Python spelling is the producer’s business; the kind name is the contract.Class
Exit statuses are part of the contract: EXIT_OK, EXIT_NO_SUCH_PATH, EXIT_NOTHING_TO_READ. A reader that read nothing MUST NOT exit zero — an empty load and a successful one are the two outcomes it exists to distinguish.
4.4 dke.client — reaching the service
The wire client. DEFAULT_ENDPOINT and PROTOCOL_VERSION name what it talks to. Its error hierarchy is a contract: DkeError is the base, TransportError carries an HTTP status, ProtocolError carries a wire code, and PaymentRequired is a ProtocolError a caller SHOULD handle distinctly.
On telling an empty answer from an empty store. When a query returns nothing and you cannot tell which it is, checkup reports unmet <Kind>.<field> for a cell a standing rule reads that holds nothing — including the case where a field is absent-read and was never recorded anywhere. That is the difference between no test reaches these and no test was looked for, and it is the intended instrument for §2.4 going wrong.
4.5 dke.quantum and dke.pqc — the quantum and pqc readers
Readers for two more modules, built on dke. like dke.. Each splits its load over as many programs as the size it is given needs, through FactLoad, and each program records a load marker. That size is the caller’s to pass, because it is a setting of the store.
dke. writes a device’s calibration snapshot as the Device, PhysicalQubit and Native facts of §3.16. A snapshot is a directory named for the device, holding conf_<name>. and props_<name>. as Qiskit’s fake backends ship them. An operation keeps the device’s name for it, except cx, which is written cnot. reset, measure and delay are not written, and a value the snapshot lacks is not written at all. Its command is dke-quantum-device <dir> --max-bytes N [--module M].
dke. reads OpenQASM 2.0 into the gate lists the module runs, and writes one back. An angle keeps an exact rational multiple of pi when the text makes it one, so a quarter turn written pi/ is told apart from its decimal.
dke. computes the digests the rules of §3.17 compare, and writes a Result:
| Name | Contract |
|---|---|
text_digest(text) |
sha256: and the SHA-256 of text as UTF-8. |
snapshot_digest(dir) |
sha256: and the SHA-256 of one line per .json file in dir, in name order, each the file’s name, a space and its own SHA-256. |
digest_name(digest) |
c_ and the first 16 hex digits of digest: the subject of a circuit the store knows only by its digest. |
lines(module, name, result, writer) |
The update lines that record result as Result.<name>. A field left None is not written. |
circuit_line(module, circuit, digest, writer) |
The update line that records a circuit’s digest. |
dke. reads a CycloneDX document of version 1.6 or later and writes the facts of §3.19 it states: an algorithm’s quantum, "vulnerable" when its nistQuantumSecurityLevel is 0 and "resistant" when it is 1 or more, and its strength, its classicalSecurityLevel; and one Use for each dependsOn edge from a component that is not a cryptographic asset to an algorithm. A provides edge is not a use. What the document holds and the reader does not read is counted in each program’s header. Its command is dke-pqc-cbom <cbom..
5. The fact-writing contract
The vocabulary of §2 and §3 is what a producer and a module must agree on. There is no negotiation and no error at load time for disagreeing: a fact whose field the module does not declare is written, stored, and read by nothing.
5.1 Requirements on a producer
- A producer MUST write only into fields the module declares (§3.3). A field the module does not declare is a fact that lands where nothing reads.
- A producer MUST NOT write a derived field (§3.4) or a rule conclusion (§3.5).
- A producer MUST write absence-read fields only where true (§2.4).
- A producer MUST use subjects, not display names, wherever a field holds a reference to another fact (§3.3,
Call). - A producer MUST NOT assert an edge it did not resolve; it SHOULD record the unresolved call instead (§3.3,
UnresolvedCall). - A producer SHOULD write every field it can determine. Writing fewer narrows what the module can conclude; it does not make anything wrong.
5.2 What is normal and not an error
A field the module declares that no producer writes is fine, and expected. Several exist. Some a customer supplies by hand — Function.. One whole kind, Counterpart, is written by nothing LangSyn publishes, because it records a claim about intent that only a reader can make.
This asymmetry is deliberate: the contract is one-way. A module may declare more than any producer writes. A producer may not write more than the module declares.
5.3 Compatibility
- Adding a class, a field, a rule or a query to a module is a compatible change. Existing producers keep working; the new field is simply unwritten.
- Removing or renaming a class or field a producer writes is a breaking change, and the module’s version reflects it.
- Changing a rule’s threshold changes what your store concludes without changing any name. It is a semantic change, and it is checked: the thresholds in §3.5 and the module’s own must agree, so a threshold cannot move without this document moving with it.
- Changing a rule’s condition in any other way — which fields it reads, how they combine — is a semantic change that no mechanical check sees (§5.4). It is visible in the module’s version and in §3.5’s prose, and nowhere else.
- The two artifacts version independently:
dkepyand each module carry their own versions, and this specification carries its own. Read a version from the artifact it belongs to, never from prose.
5.4 What is mechanically checked, and what is not
Stated plainly, because the gap is where a producer author will otherwise assume protection that does not exist.
Checked.
- One direction of §5.1(1): a field written by any
dkepyemitter that the module does not declare fails a gate before release. The check spans every generation of the emitter the published surface has ever held, not just the current one, because a customer may hold any of them. - This document against the module it specifies, in both directions: every kind, field, derived field, rule and query the module declares is named here, and every rule, query and derived field this document promises exists there. Rule thresholds, the kind a rule ranges over, the field it concludes, and a derived field’s definition are compared as values, not merely as names.
Not checked, and each of these is real:
- Types. A field declared
stringthat a producer writes as anintpasses every check here. - What a rule reads. Thresholds are compared, but the rest of a condition is not: a module can keep every field name and every threshold and still change which fields a rule combines, or how.
- Producers we do not publish. A producer you wrote is bound by §5.1 and measured by nothing.
checkupis the instrument that answers from your own store. - Absence discipline. §2.4 is a requirement no gate enforces. Its failure mode is a plausible answer rather than an error, which is exactly why it is written as a MUST.
6. What this specification does not cover
- The DKE Python language — Python Specification.
- The wire — MCP Reference, including the
languageparameter and its accepted values. - How to use a module — Library Tutorial.
- Your store’s contents, which are yours, and which this document deliberately says nothing about.
Revision history
Newest first. The revision is the surface’s — one number stated by every published document, the web pages and the service wire, moving whenever any document changes. This list records the revisions at which this document changed and what changed in it; a revision absent here left this document as it was. The Version line at the top states this document’s version, the revision it last changed in and the current revision; from rev 148 each entry opens with the version that revision gave this document. The history starts at rev 1. What a revision promises is stated in the Python Specification, its section 11.1.
- 1.0.5 · rev 171 (2026-11-15) — The Version line states API 1.5: a module may state its version on a top-level
__version__line, which acompilegiven noversionrecords andinfo_modulereports (Python Reference §9.1), and an addition moves the API’s MINOR. - 1.0.4 · rev 163 (2026-11-14) — The Version line states API 1.4:
rangeis a value of its own, walked without being built, so aforover a million numbers runs, and a range keeps its three bounds as.start,.stopand.step(Specification §8.6), and an addition moves the API’s MINOR. - 1.0.3 · rev 151 (2026-11-13) — The Version line states API 1.3: a rule premise may test part of a text, as
r.,path. startswith("/ srv/") t.andname. endswith(". test") "admin" in a.(Specification §14.2), and an addition moves the API’s MINOR. Nothing else changed, and no module did.role - 1.0.2 · rev 150 (2026-11-13) — The Version line states API 1.2: calls made with keys that may only read run on one store together, where every call on a store ran alone (MCP §9.8), and an addition moves the API’s MINOR. Nothing else changed, and no module did.
- 1.0.1 · rev 149 (2026-11-13) — The Version line states API 1.1: DKE Python gained a form a rule’s conclusion may take, a text written from values the rule read (Python Specification §14.3), and an addition moves the API’s MINOR. Nothing else changed, and no module did.
- 1.0.0 · rev 148 (2026-11-12) — This document states a version of its own, 1.0.0, first on the Version line and followed by the revision it last changed in, and from this revision each entry here opens with the version it made (Python Specification §11.1). Nothing else changed.
- rev 147 (2026-11-12) — The Version line states API 1.0: the API version is
MAJOR.. Nothing else changed.MINOR - rev 145 (2026-11-12) —
physics1.0.3,chemistry1.0.3,biology1.0.2,astronomy1.0.2,geography1.0.2 andmathematics1.0.2: each section states how its value scripts keep their work in range, so that each answers wherever its value is a real, where a sum, square, product, ratio or multiplier in the work answeredinf,nan,0.0or a wrong solution past the range of a real. §3.28 definesQuantity.asconverted value * (factor / efactor)and states the range of factors over which it is a real. Angles are taken modulo 360 degrees bymath.in §3.41 and §3.44;fmod keplerreduces its mean anomaly first and findsEfor anyM;equilibrium_exacttakes its root as2 k a0 b0 / (p + r), which subtracts nothing; a classchi_square’s ratio gives no share adds nothing where it is empty;pendulumintegrates for up to the exact period; andphysics.reads a system as singular only where a pivot is 0.solve gmst,kepler,charge_ph,titration,consecutive,consecutive_exact,peak_time,equilibrium_exact,chi_square,logistic,logistic_exact,predator_prey,small_period,agm,period,pendulum,orbitandbridgerefuse inputs outside their domain. - rev 144 (2026-11-12) —
body1.0.2,food1.0.3,colour1.0.1,sound1.0.4,finance1.0.2,earthscience1.0.2 andarchitecture1.0.2: each section states how its value scripts and computed fields keep their work in range, so that each answers wherever its value is a real, where a sum, square, product or ratio in the work answeredinf,nanor0.0past the range of a real. §3.70 definesPerson.asbmi kg / metres / metres, §3.78Offer.and §3.85interest Hull.of halves, and §3.85 states the range of beam and draught over whichgm bmis a real. §3.65 states that a refractive index is 1 or more.monthly_payment,effective_annual_rateandcontinuous_annual_rateare worked throughexpm1andlog1p, so that 0.12 compounded once gives 0.12;lens_magnificationisf / (f - u); an incidence and a lean are taken modulo 360 degrees.level_of_pressure,at_distance,dew_point,monthly_payment,compound_amountandeffective_annual_raterefuse inputs outside their domain. - rev 143 (2026-11-12) —
statistics1.0.3: §3.52 states how every value script keeps its work in range, so that it answers wherever its value is a real, wherebinom_pmf,poisson_pmfand the descriptive statistics answeredinf,nanor0.0from rev 142 when a sum, square or product in their work passed the range. It addsscale_of,stirling_error,devianceandexact_product, states the binomial’s correction for the rounding of1 - pand the measured accuracy of each probability, and the figuresbinom_pmf,binom_cdf,poisson_pmf,bayes,chi_square,stirling_erroranddeviancerefuse. - rev 142 (2026-11-12) —
sound1.0.3: §3.76 states howadd_levelsis computed, as the louder level plus10 log10(1 + 10^(-d/, so that no power passes the largest real and any two levels have a sum, where the sum of powers answered10)) inffrom this revision for levels past about 3080 decibels. - rev 133 (2026-11-10) — The library carries
pqcat 1.0.2,harmony1.0.1,physics1.0.2,chemistry1.0.2,biology1.0.1,geography1.0.1,mathematics1.0.1,statistics1.0.2,computing1.0.1,sound1.0.2 andarchitecture1.0.1, on the source surface. Every sum in §3.23–§3.34, §3.45–§3.52, §3.57–§3.60, §3.73–§3.76 and §3.84–§3.87 gains derived fields over the sum’s own binding: a count of the members that carry a value into it, a count of the claims they hold, and a flag where the claims outnumber the members. The sum is concluded only where the flag is absent, and so are the rules that rest on it;chemistryalso raises a molecule’s flags from an atom whose bonds are disputed. The queriesdisputed_rooms,disputed_codes,disputed_days,disputed_equations,disputed_groups,disputed_molecules,disputed_reactionsanddisputed_studiesare new, and a query that answers a disputed sum raisesValueError.chemistry.counts each atom once and refuses an atom that holds two elements;formula unexplainedin §3.36 andholdsin §3.43 count each member once; §3.21 states that a use’s deadline is the earliest year of any value of any deadline. Where each fact is written once, every module answers as before. - rev 132 (2026-11-10) — The library carries
quantumat 1.3.0, on the source surface. §3.18 gains the stepmx, which measures a qubit in the X basis, and the controlled stepsx_if,cnot_if,ccx_if,z_if,cz_if,ccz_if,swap_ifandcswap_if, and the helpersrev_apply_underandrev_measures.rev_meetsholds a circuit over every assignment of the outcomes and answers the count of cases and the lowest failing case;rev_sameraisesValueErrorfor a circuit that measures;rev_codeanswers operation 8 formxand refuses a controlled step whose qubit nomxmeasured. A circuit with nomxis answered as 1.2.0 answered it. - rev 131 (2026-11-10) — The library carries
quantumat 1.2.0, on the source surface. §3.18 gains eight queries:ccx,cczandcswap, the Toffoli, CCZ and Fredkin gates;rev_same, which holds two reversible circuits equal when, on every input, they give the same output bits under one sign shared by all inputs;rev_meets, which holds a reversible circuit to a specification of its inputs, outputs, zeroed qubits and sign; and the helpersrev_code,rev_applyandlowest_lane. A step of a reversible circuit isx,cnot,ccx,z,cz,ccz,swaporcswap; any other gate is refused. Everything 1.1.0 answered, 1.2.0 answers the same. - rev 130 (2026-11-10) — The library carries
electionsat 1.0.0, on the source surface. §3.2 lists twenty-four modules. §3.88 to §3.91 specifyelections: its declared fields, its derived fields, its standing rules and its queries. §3.88 states thatelectionsis not legal or electoral advice, and §3.90 that a count in dispute decides nothing and a tie for the last seat is refused rather than broken. - rev 129 (2026-11-09) — The library carries
architectureat 1.0.0, on the source surface. §3.2 lists twenty-three modules. §3.84 to §3.87 specifyarchitecture: its declared fields, its derived fields, its standing rules and thresholds, and its queries. §3.84 states thatarchitectureis not engineering, naval-architecture, acoustic-design or heritage advice, and §3.87 that a lean or an offset can differ from CPython’s in the last place, wheremath.,atan math.,tan math.anddegrees math.round once.radians - rev 126 (2026-11-09) — §3.82 and §3.83:
foodis at 1.0.2 and credits FoodSafety.gov’s chart “Cook to a Safe Minimum Internal Temperature”, reviewed November 21, 2024, read from a copy downloaded on 2026-11-09. Acasseroleis one with meat or poultry, or meatless, at 165 F, andchart()writes eleven standards,ham-packagedat 140 F, the chart’s note on cooked ham packaged in a USDA-inspected plant, among them. - rev 125 (2026-11-09) — §3.40, §3.41, §3.55, §3.56, §3.71 and §3.72:
astronomy,earthscienceandbodyare at 1.0.1 and each names the readers that refuse while sources disagree, which the sections had said none did:up()andwindow(),dryness_threshold()andcategory(), andbmi(). - rev 124 (2026-11-09) — §3.75, §3.76, §3.79, §3.80, §3.82 and §3.83:
sound,financeandfoodare at 1.0.1 and each has anunsettled()that names each subject that holds two different values for any field you write, eleven insound, five infinanceand fifteen infood.dose,total_ofandtotalare stated to refuse a cell that holds two values. - rev 123 (2026-11-08) — The library carries
calendars,colour,body,sound,financeandfoodat 1.0.0, each on the source surface. §3.2 lists twenty-two modules. §3.61 to §3.64 specifycalendars, §3.65 to §3.68colour, §3.69 to §3.72body, §3.73 to §3.76sound, §3.77 to §3.80financeand §3.81 to §3.83food: their declared fields, their derived fields, their standing rules and thresholds, and their queries. §3.69 states thatbodyis not medical advice, §3.73 thatsoundis not occupational-health advice, §3.77 thatfinanceis not financial advice and §3.81 thatfoodis not food-safety or medical advice. - rev 122 (2026-11-08) — The library carries
statistics,earthscienceandcomputingat 1.0.0, each on the source surface. §3.2 lists sixteen modules. §3.49 to §3.52 specifystatistics, §3.53 to §3.56earthscienceand §3.57 to §3.60computing: their declared fields, their derived fields, their standing rules and thresholds, and their queries. - rev 121 (2026-11-08) — The library carries
astronomy,geographyandmathematicsat 1.0.0, each on the source surface. §3.2 lists thirteen modules. §3.38 to §3.41 specifyastronomy, §3.42 to §3.44geographyand §3.45 to §3.48mathematics: their declared fields, the derived fields of the two that have them, their standing rules and thresholds, and their queries. - rev 119 (2026-11-08) — §3.30 and §3.34:
unsettled()inphysicsandchemistrynames each subject that holds two different values for any field you write, where it named a dispute over five fields of each. - rev 118 (2026-11-08) — §3.2 lists ten modules. §3.27 to §3.30 specify
physics, §3.31 to §3.34chemistryand §3.35 to §3.37biology: their declared fields, the derived fields of the two that have them, their standing rules and their thresholds, and their queries. - rev 117 (2026-11-08) — §3.25 states that the
harmonyrules asking for something to be missing,chromaticand the three open readings, are answered for the note rather than for each of its values. - rev 116 (2026-11-08) — §3.2 lists seven modules. §3.23 to §3.26 specify
harmony: its declared fields, its derived fields, its standing rules and their thresholds, and its queries. - rev 114 (2026-11-06) — §3.18 specifies
quantum1.1.0’s generator from a 256-bit key, ChaCha20 as RFC 8439 defines it:chacha_quarter,chacha_block,chacha_unit,chacha_uniformandadvance_chacha. - rev 33 (2026-10-23) — §1: every kind, field, rule and query name is written in English.
- rev 31 (2026-10-19) — The DKE Library’s three documents are one family. Cross-references name the Library Reference and the Library Tutorial at their new addresses, and §1 says the Reference describes
dkepyas well as the modules. - rev 26 (2026-10-17) — The header states Version, Status, Audience and the Markdown copy, one field to a line. §1 places
dkekey: the store key it issues is specified by MCP Reference §3.1, whichdke.implements too. §3.1’s citation of the Python Reference links to §8.8. §4.1: the properties the package guarantees are asserted by LangSyn’s tests, which are not part of the release, and each can be checked against the source it describes.keys - rev 24 (2026-10-16) — §3.2 lists six modules. §3.16 to §3.18 specify
quantumand §3.19 to §3.22pqc, and §4.5 their readers indkepy,dke.andquantum dke.. §4.1 is corrected:pqc dke.opens a connection askeys dke.does, and needsclient cryptography, thekeysextra, where §4.1 said onlydke.did and that nothing beyond the standard library was needed.client - rev 22 (2026-10-14) — §1 and §3.2: the modules and
dkepyare served fromhttps://. Thedke. langsyn. com/ source/ dke.addresses still lead to the same files.langsyn. org - rev 20 (2026-10-14) — §3.6: the sentence on how far
impact_ofwalks is reworded. What it answers is unchanged. - rev 4 (2026-10-11) — Cross-references take the published documents’ short names, the ones the footer uses — MCP Reference, Python Specification, Python Reference, Modules Reference, Modules Tutorial. Nothing else changed.
- rev 3 (2026-10-11) — The revision is the surface’s: one number shared by every published document, the web pages and the service wire. This section says so, and the Version line moves from rev 1 to it. Nothing else changed.
- rev 1 (2026-10-11) — The Version line states the document’s revision and this section is added. Nothing else changed.