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://dke.langsyn.com/source/<name>/, one path per module
dkepy (Python package) The package that writes the facts those modules reason over https://dke.langsyn.com/source/dkepy/

dkekey, the key tool served beside them at https://dke.langsyn.com/source/dkekey/, is not specified here: the store key it issues is specified by MCP Reference §3.1, which dke.keys 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.


2. The shared vocabulary

A reasoning module declares kinds and fields. A producer writes values into them. The names are the interface — there is no registration step, no handshake, and no negotiation: a fact lands where its name says it lands, or it lands somewhere nothing reads.

2.1 Naming

  • A kind name is scoped to its module: code.Function and finance.Function are different kinds and never read each other’s data.
  • Kind names are CapitalizedWords. Field names are lower_snake_case.
  • A producer MUST write the kind name exactly as the module declares it. Case and spelling are the whole of the matching; nothing corrects a near miss. §5.4 names the one check that catches this and the ones that do not.
  • A subject identifies one thing of that kind. Subjects are the producer’s to choose, MUST be stable across loads for the same thing, and MUST be used consistently: §3.3 gives the case where a display name in a subject position silently corrupts every answer.

2.2 Value classes

A field declares one of the writable value classes of the DKE Python language — string, int, bool, and the others given in the Python Specification §5. This document adds no value classes and no coercions. A producer SHOULD write the declared class; a mismatch is not caught by any library-level check (§5.4).

2.3 Three ways a field gets its value

This distinction is load-bearing throughout §3, and getting it wrong is the most common way a store produces confident wrong answers.

Field Written by Read by
Declared field you, or your producer rules and queries
Derived field the engine, kept current as its inputs change rules and queries
Rule conclusion the engine, in force exactly while its condition holds queries

A producer MUST NOT write a derived field or a rule conclusion. They are maintained for you and carry a derived provenance rather than a source, so a conclusion is always distinguishable from something you were told.

2.4 Absence is a value

Several rules in §3 read the absence of a field, not its contents. This is the sharpest edge in the library, so it is stated as a requirement rather than as advice:

A producer MUST write an absence-read field only where the thing it records is actually true, and MUST NOT write a placeholder, an empty string, or a default into one.

Writing such a field everywhere does not make a rule fire everywhere — it silences the rule everywhere, and the store then answers every question with the same list while nothing reports a fault. §3.3 names which fields these are. checkup distinguishes “nothing reaches these” from “nothing was looked for”; §4.4 says how.


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://dke.langsyn.com/source/<name>/ 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.

caller and callee MUST hold the subject of a Function, 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. relation names what is being counted, because it differs per pair; left_covers and right_covers count 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.complexity branches + loops + 1
Counterpart.gap left_covers - right_covers
Counterpart.reverse_gap 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, > 5 select 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. untested and uncalled_fn carry 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.x.y, 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.x.y
same_stated_back Same, Record SameEntity the same statement; concludes SameEntity.y.x
same_further Record SameEntity SameEntity.x.y and SameEntity.y.z; concludes SameEntity.x.z
possibly_stated Possibly, Record PossiblySame a statement’s a names x and its b names y; concludes PossiblySame.x.y
possibly_stated_back Possibly, Record PossiblySame the same statement; concludes PossiblySame.y.x
contradicted Different, Record contradicted the statement’s a and b name x and y, and SameEntity.x.y 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. SameEntity and PossiblySame are read by those bare names in every unit, and are never identity.SameEntity. A unit that declares a class of either name reads its own class by that name.
  • SameEntity is closed; PossiblySame is not. A record in any chain of Same statements is related to every record the chain reaches, itself included. A possibility relates exactly the two records a statement names.
  • A Different statement withdraws nothing. It and every Same statement it contradicts stand together; the contradiction is concluded, not resolved.
  • The closure is quadratic in an entity. An entity of n records holds n² SameEntity conclusions.

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, undefended or reinstated, 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 weakened and 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 argument derives 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 forbidden and violates a constraint; it removes and refuses nothing.
  • late needs both dates. An item with no done_at, or no due, is never late, whatever the time.
  • No relation is concluded. Every field agenda derives 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.quantum.device (§4.5) writes Device, PhysicalQubit and Native; dke.quantum.provenance 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, MustPrecede and CommutesWith relate two gates, the earlier first, and RunsAs relates a gate to the native operation it runs as. Every other conclusion is a field of a Gate or a Result. 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 uncoupled never 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_device and not_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.pqc.cbom (§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.migrate_by horizon - shelf_life
Use.start_by 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 deadline is 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’s year is not among them, and why on the use’s deadline names 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.a.m 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.pc pitch % 12
Note.nextbeat beat + 1
Note.d2 pitch - p2
Note.d3 pitch - p3
Note.i1 (pitch - p1) % 12
Note.i2 (pitch - p2) % 12
Note.i3 (pitch - p3) % 12
Bar.end start + length
Tone.ends onset + duration
Tone.offbeat (onset - barstart) % pulse
Tone.nextpulse 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.place > 1; 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.a.m
fifths_over_2 Note Fifths as fifths_over_1 with a.place > 2, place 2 and i2
fifths_over_3 Note Fifths as fifths_over_1 with a.place > 3, place 3 and i3
octaves_over_1 Note Octaves as fifths_over_1 with a.place > 1 and an i1 of 0. Concludes Octaves.a.m
octaves_over_2 Note Octaves as octaves_over_1 with a.place > 2, place 2 and i2
octaves_over_3 Note Octaves as octaves_over_1 with a.place > 3, 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.a.m
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 duration a second source writes, even the same duration, would be added twice to its bar’s filled; tones and claims count the tones and their claims over the one binding the fold reads, and while the claims are more, the bar is disputed and no filled is concluded for it. A tone with no duration is in neither count, and a tone whose onset holds 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: chromatic holds of a note only when no value of its pc is a degree of its key, and major_open, minor_open and seventh_open read 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.log(ratio, 2.0).
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.si value * factor
Quantity.converted value * (factor / efactor)
Factor.smass power * mass
Factor.slength power * length
Factor.stime power * time
Factor.scurrent power * current
Factor.stemperature power * temperature
Resistor.siemens 1.0 / ohms
Group.parallel 1.0 / siemens

Quantity.si 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 Unit names gets no factor, no dimension and no si; it is marked unknown, and checks() names it. An equation with a factor in such a unit is judged neither consistent nor unbalanced.
  • Consistent is not true. A consistent equation has the same dimensions on both sides. It is not thereby a law: E = m v and E = m v² differ in dimension, but E = m v² and E = 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 ohms a second source writes, even the same ohms, would be added twice, a result no circuit or equation has. The _factors, _resistors and _claims fields 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 whose equation, or a resistor whose group, 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.pi * math.sqrt(length / g), and where length / g passes the range of a real or falls below the smallest normal one, 2.0 * math.pi * (math.sqrt(length) / math.sqrt(g)). 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.cos(theta0 / 2.0)). 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.hypot 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.hydrogens valence - bonds
Atom.mass weight + hydrogens * hweight
Term.contribution 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 no Element, an atom has no valence, no hydrogens and no mass, and weight() 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.hydrogens adds the hydrogens of every atom, and an overbonded atom adds a negative number. overbonded and faults() name it.
  • A reaction’s enthalpy is the sum over the terms the store holds. A term whose species has no formation adds nothing, and the reaction is incomplete: its enthalpy is 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 weight holds two values would be weighed at both, and a bond whose order a second source writes, even the same order, counted twice. The _halves, _atoms, terms and _claims fields 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 no hydrogens or mass, 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 whose molecule, a bond whose a or a term whose reaction holds 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.family 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.c.p for a child c and a parent p, and Ancestor.x.y 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.c.m
parent_father Person Parent the child’s father names a person. Concludes Parent.c.f
ancestor_parent Person Ancestor Parent.x.y holds. Concludes Ancestor.x.y
ancestor_further Person Ancestor Ancestor.x.y and Parent.y.z hold. Concludes Ancestor.x.z
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.c.p 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.c.p 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 reached only 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. runs asks that each substrate be reached and 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 unexplained is where one of those, or the record itself, does not hold. Each of carrier and unexplained is 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 s2 is no longer one with a single substrate, and runs only when that compound is reached as well. A family’s unexplained counts each person once, however many rules or values conclude them unexplained.

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.name.medium 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/dt = rN(1 - N/k), 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/dt = alpha x - beta x y and dy/dt = delta x y - gamma y, 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.s.t 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.circumpolar_above 90 - lat
Site.hidden_below lat - 90
Site.circumpolar_below -90 - lat
Site.hidden_above 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.s.t
circumpolar_south Star, Site Circumpolar the site’s lat < 0 and the star’s dec is below the site’s circumpolar_below; concludes Circumpolar.s.t
hidden_north Star, Site Hidden the site’s lat >= 0 and the star’s dec is below the site’s hidden_below; concludes Hidden.s.t
hidden_south Star, Site Hidden the site’s lat < 0 and the star’s dec is above the site’s hidden_above; concludes Hidden.s.t
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.s.t
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.s.t
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_above is not Circumpolar, and one exactly at hidden_below is not Hidden and is Visible if it is bright enough. The same holds for the southern pair.
  • Visible includes what never sets. A circumpolar star is above the horizon at all times, so it is Visible where it is bright enough. A star that is Hidden is not Visible, and a star fainter than the site’s limit is neither Visible nor kept from being Hidden or Circumpolar. The three relations are independent conclusions.
  • A booking is observable for an overlap. observable holds 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, because up() writes nothing for one, and the rule does not read the star’s magnitude or the site’s limit. A booking at a site with no Night, or for a star with no Up at 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. Call up() 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 dec is given two values is Hidden at a site if either is below hidden_below, and Visible if either is not. unsettled() names the fact. up() and window() are the readers that refuse: up() needs one value of the star’s ra and dec and of the site’s lat and lon, and window() one value of the booking’s starts and ends, 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.fmod, 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.fmod 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.fmod 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.fmod 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.fmod, 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.r.p for a region r and a region p it lies within, Neighbour.x.y and Clash.x.y for two regions, and Inside.p.b 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.r.p
within_further Region Within Within.r.p holds and the region p has a parent that names a region q. Concludes Within.r.q
holds Region holds Within.r.o 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.x.y
neighbour_ba Border, Region Neighbour the same border, the other way. Concludes Neighbour.y.x
clash Region Clash Neighbour.x.y holds and the two regions have the same colour. Concludes Clash.x.y
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. Within runs only between regions that have a field written, so a parent that names a region nobody recorded concludes nothing until that region is recorded, and the readers of §3.44 list only regions recorded with a level. 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 parent replaces the first, and Within and holds follow: 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 lon is at or east of the box’s west, or at or west of its east.
  • A colour clash is between neighbours. Clash.x.y holds for each border whose two regions have the same colour, both ways round. A region with no colour clashes with nothing.
  • holds counts regions, not levels. It is the number of regions within a region at any depth, whatever their level.
  • 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.fmod first. Where the haversine falls below the smallest normal real, its root is the math.hypot 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.fmod 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.fmod 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.frexp 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° + φ/2)). 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.fmod first, and where the square of the sine of the arc falls below the smallest normal real, the sine is a math.hypot.
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.fmod 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.remainder n % k
Triangle.perimeter a + b + c
Triangle.gap a * a + b * b - c * c
Triangle.slack a + b - c
Triangle.heron (a + b + c) * (b + c - a) * (a + c - b) * (a + b - c)
Triangle.valid 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. prime asks that no candidate above 1 divide the number, and the candidates are the facts you or number() wrote, from 1 to half of it. A number written with no candidate and above 1 is concluded prime, and has no divisor_sum. The number 1 is neither prime nor composite, has no divisor_sum and is deficient. Every number above 1 has a divisor_sum, which counts the divisor 1.
  • A property is judged over the table given. closed, commutative and associative hold 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 not closed can still be reported associative; group requires both.
  • An inverse is two-sided and needs an identity. invertible asks that some product of the element with another give the identity from both sides. noninvertible is concluded only where the operation has an identity: an operation with none has no element marked either way, and is not a group.
  • A triangle is judged only when its sides close up. acute, right, obtuse and the three by sides are concluded only for a valid triangle, one whose slack is positive. Three lengths that do not close up, or that lie flat, have no kind. isosceles includes the equilateral.
  • The sides are read in order. gap and slack take c as 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 whose k a second source writes, even the same k, would be added twice; divisor_count and claims count the divisors and their claims over the one binding the sum reads, and while the claims are more the number is disputed and has no divisor_sum, perfect, abundant or deficient. A candidate whose of holds 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.sqrt(heron) / 4; 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.atan(1 / 5) - math.atan(1 / 239)).
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.frexp 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_rate a_yes / a_n
Stratum.b_rate b_yes / b_n
Stratum.a_wins a_rate > b_rate
Stratum.b_wins b_rate > a_rate
Study.a_rate a_yes / a_n
Study.b_rate b_yes / b_n
Study.pooled_a_ahead a_rate > b_rate
Study.pooled_b_ahead b_rate > a_rate
Screen.ppv prevalence * sensitivity / (prevalence * sensitivity + (1.0 - prevalence) * (1.0 - specificity))
Screen.npv (1.0 - prevalence) * specificity / ((1.0 - prevalence) * specificity + prevalence * (1.0 - sensitivity))
Screen.mostly_false ppv < 0.5
Significance.significant 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 study names the study, so a stratum written again with other counts changes the pooled rates and withdraws every conclusion that rested on the old ones, a paradox among 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 _strata and _claims fields 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 whose study holds two values counts in each it names, and each of those pools is one source’s.
  • A paradox is a reversal, and only that. paradox is 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 no wins and does not stand in its way.
  • The two figures a screen is judged by are not the test’s. ppv and npv depend on the prevalence as 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 a ppv of 0.08 at a prevalence of 0.01 and 0.69 at 0.2.
  • A test result is a comparison. significant compares the p you wrote with the alpha you wrote. Nothing computes the p, 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_false by one and not by the other. unsettled() names the fact. pooled() and predictive_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.frexp 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.frexp 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/2 - mu/2) / sigma * 2 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.erfc(-z / sqrt(2)), 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/e)^n), the error of Stirling’s formula, for n from 0: a table of its values to 15, and above it the series (1/12 - (1/360 - (1/1260 - (1/1680 - 1/(1188 n^2)) / n^2) / n^2) / n^2) / n, 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/3 + v^5/5 + ...), 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)^(n - k), 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/1 * ... * lam/k 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.frexp 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.erfc(sqrt(x / 2)): 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.threshold 20.0 * annual_temp + addition
Station.half threshold / 2.0
Station.dry rain < threshold
Station.polar warmest < 10.0
Pair.scratches 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) and continental (D), once all the facts of the station are written. A station is polar when its warmest month is under 10 degrees, tundra where that month is 0 or more and icecap where it is under 0. It is arid when it is not polar and its rain is strictly below its threshold, desert under half of it and steppe from half of it up.
  • The limits fall to one side. A station whose warmest month is exactly 10 is not polar. One whose rain is exactly its threshold is not dry, and one whose rain is exactly its half is steppe. A station whose coldest month is exactly 18 is tropical; one whose coldest month is exactly the boundary is continental.
  • 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. boundary is 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 is continental under the first and temperate under the second; the rules do not choose.
  • The high-sun half of the year is yours to say. summer_share is 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. hurricane is 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 no category, and category() answers 0. major is 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 rain has two values can be in two groups at once, groups() names both, and climate() reads the first of them in the order A, B, C, D, E. unsettled() names the fact. dryness_threshold() and category() 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.log2(1 + ratio). 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.log10(joules) - 4.8) / 1.5; 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.frexp 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.oversubscribed 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_free is 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.
  • complete is concluded, never denied. A code whose Kraft sum is 1 is complete. A code whose sum is anything else has no complete at all rather than a False one, and the same holds of prefix_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 one Word, and its weight counts 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 a weight, so a word whose weight a second source writes, even the same weight, would be added twice; words and claims count the words and their claims over the one binding the sum reads, and while the claims are more the code is disputed and has no kraft, complete or oversubscribed. A word with no weight is in neither count, and one whose code holds 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.log2(p)). 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.r4 number % 4
Year.r100 number % 100
Year.r400 number % 400
Reform.skipped 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_leap and julian_leap are concluded where they hold and absent where they do not, so why_not of 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.
  • differ is 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) is False before 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 ymd and the reform’s last and first as numbers, strictly between them. The day is a valid fact; the relation is the only consequence, and a reform’s first rewritten 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.ratio (fg + 0.05) / (bg + 0.05)
Pair.inverse (bg + 0.05) / (fg + 0.05)
Ray.sin_t 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 True for it; a pair that fails has none, rather than a false one, and why_not names 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 ratio and a pair whose background is the lighter, or equal to the text, uses inverse, 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 n1 above n2, a sin_i of at most 1.0 and a sin_t above 1.0. At a sin_t of 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.fmod first; where n1 times its sine over n2 is not a normal real, that is worked on the mantissas and exponents math.frexp 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/f - 1/u), 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.bmi kg / metres / metres
Person.underweight bmi < 18.5
Person.overweight bmi >= 25.0
Person.obese 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. reacts is the ABO rule: the donor’s red cells carry an antigen the recipient’s lack. sensitises is 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_not of reacts names the two premises that were not met.
  • A band is the narrowest one that holds. An index of 30 or more is overweight and obese both, the WHO bands being cumulative above 25, and normal is 18.5 up to but not including 25, so the four bands cover every index. A person whose bmi is 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.sqrt 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.bmi 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.dose hours / allowed
Segment.dose 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_not says 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; over is 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, and why_not names the premise that failed. A frequency that is not audible has no audible.
  • 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; segments and claims count the segments and their claims over the one binding the sum reads, and while the claims are more the day is disputed and has no total or over. A segment with no dose is in neither count, and one whose worker holds 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_hours is 8 / 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; infrasound and ultrasound are 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. dose and total_of read 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.log10 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/10) + 10^(b/10)); two equal sources add 3.0103 decibels. It is computed as the louder level plus 10 log10(1 + 10^(-d/10)) 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.frexp 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.total payment * months
Offer.interest (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_not of 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_not says 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. total reads 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.frexp 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/n)^(n t), 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/n)^n)^t. Where the sum is not a normal real while P is a real and 1 + r/n above 0, it is P e^(n t log1p(r/n)), log1p(r/n) being ln r - ln n where r/n 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/n)^n - 1, for n above 0, others refused with ValueError. It is taken as expm1(n log1p(r/n)), 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/n passes the largest real, log1p(r/n) 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/100). 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. unknown says that no standard was recorded to conclude from. An empty unsafe means 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 own minimum, 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-venison and fish. A casserole is one with meat or poultry, or meatless: the chart gives both at 165 F. ham-precooked is precooked ham reheated, 165 F, and ham-packaged is 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://www.foodsafety.gov/food-safety-charts/safe-minimum-internal-temperatures), 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.
  • 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.frexp 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.shift offset / 2.0
Tower.radius base / 2.0
Hull.kb draught / 2.0
Hull.bm beam * beam / (12.0 * draught)
Hull.gm (0.5 * kb + 0.5 * bm - 0.5 * kg) * 2.0
Room.rt 0.161 * volume / absorption
Surface.sabins area * coefficient
Channel.gradient 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, and why_not names the feature that is False. A building with no facts has no style, and why_not says 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, so pendentive_dome is 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_building asks 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. undated marks it, and writing its year ranks it.
  • A fall is a correction. fell() writes until, 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 lowers kg withdraws the verdict.
  • A room is judged by its surfaces. absorption is 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 is unmeasured and has no rt, 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() names fall vitruvius minimum. A channel whose standard has no value is no_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, and record_until() refuses while a fact it reads holds two values. A sum reads every value too, so a surface whose sabins holds two values would be added twice to its room’s absorption; surfaces and claims count the surfaces and their claims over the one binding the sum reads, and while the claims are more the room is disputed and has no absorption, rt or verdict. A surface with no sabins is in neither count, and one whose room holds two values lines each room it names, each absorption being one source’s. A conclusion over a group-wise absence names, in why_not, a field of the form <rule>__none1 that 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.atan and math.tan are correctly rounded, and math.degrees and math.radians 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.fmod first; where the product is not a normal real, it is worked on the mantissas and exponents math.frexp 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.gm 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.frexp 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.twice firsts * 2.0
Duel.margin 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. plurality is the candidate the most voters put first, majority the candidate more than half put first, condorcet the candidate who beats every other head to head, and borda_winner the 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_loser is the candidate every other beats.
  • A tie is no win and no loss. A duel with a margin of 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_condorcet is 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, disputed is concluded for the election, no winner is concluded for it, and its readers refuse; why_not on 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_remainder and highest_averages give 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>__none1 that 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. A why on 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.client and dke.keys, whose purposes are to. Nothing else in the package reaches either.
  • No subprocess. The package spawns nothing.
  • Zero runtime dependencies. Nothing beyond the Python standard library, except that dke.keys needs cryptography, the keys extra.
  • 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.put(attr, value) is the one way a target cell is named, and its argument is the Kind.subject.field path of §2.1. A producer that writes through anything else is outside what §5.4’s check can see.

dke.factwriter 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.factwriter and the worked example of §5. dke.ingest.core 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.Class is spelled Klass in Python, because class is a Python keyword. The fact it writes is code.Class. The Python spelling is the producer’s business; the kind name is the contract.

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.factwriter like dke.ingest. 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.quantum.device 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>.json and props_<name>.json 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.quantum.qasm 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/2 is told apart from its decimal.

dke.quantum.provenance 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.pqc.cbom 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.json> --max-bytes N [--source S] [--module M].


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

  1. 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.
  2. A producer MUST NOT write a derived field (§3.4) or a rule conclusion (§3.5).
  3. A producer MUST write absence-read fields only where true (§2.4).
  4. A producer MUST use subjects, not display names, wherever a field holds a reference to another fact (§3.3, Call).
  5. A producer MUST NOT assert an edge it did not resolve; it SHOULD record the unresolved call instead (§3.3, UnresolvedCall).
  6. 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.deprecated. 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: dkepy and 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 dkepy emitter 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 string that a producer writes as an int passes 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. checkup is 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 language parameter 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 a compile given no version records and info_module reports (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: range is a value of its own, walked without being built, so a for over a million numbers runs, and a range keeps its three bounds as .start, .stop and .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.name.endswith(".test") and "admin" in a.role (Specification §14.2), and an addition moves the API’s MINOR. Nothing else changed, and no module did.
  • 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.MINOR. Nothing else changed.
  • rev 145 (2026-11-12) — physics 1.0.3, chemistry 1.0.3, biology 1.0.2, astronomy 1.0.2, geography 1.0.2 and mathematics 1.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 answered inf, nan, 0.0 or a wrong solution past the range of a real. §3.28 defines Quantity.converted as value * (factor / efactor) and states the range of factors over which it is a real. Angles are taken modulo 360 degrees by math.fmod in §3.41 and §3.44; kepler reduces its mean anomaly first and finds E for any M; equilibrium_exact takes its root as 2 k a0 b0 / (p + r), which subtracts nothing; a class chi_square’s ratio gives no share adds nothing where it is empty; pendulum integrates for up to the exact period; and physics.solve reads a system as singular only where a pivot is 0. gmst, kepler, charge_ph, titration, consecutive, consecutive_exact, peak_time, equilibrium_exact, chi_square, logistic, logistic_exact, predator_prey, small_period, agm, period, pendulum, orbit and bridge refuse inputs outside their domain.
  • rev 144 (2026-11-12) — body 1.0.2, food 1.0.3, colour 1.0.1, sound 1.0.4, finance 1.0.2, earthscience 1.0.2 and architecture 1.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 answered inf, nan or 0.0 past the range of a real. §3.70 defines Person.bmi as kg / metres / metres, §3.78 Offer.interest and §3.85 Hull.gm of halves, and §3.85 states the range of beam and draught over which bm is a real. §3.65 states that a refractive index is 1 or more. monthly_payment, effective_annual_rate and continuous_annual_rate are worked through expm1 and log1p, so that 0.12 compounded once gives 0.12; lens_magnification is f / (f - u); an incidence and a lean are taken modulo 360 degrees. level_of_pressure, at_distance, dew_point, monthly_payment, compound_amount and effective_annual_rate refuse inputs outside their domain.
  • rev 143 (2026-11-12) — statistics 1.0.3: §3.52 states how every value script keeps its work in range, so that it answers wherever its value is a real, where binom_pmf, poisson_pmf and the descriptive statistics answered inf, nan or 0.0 from rev 142 when a sum, square or product in their work passed the range. It adds scale_of, stirling_error, deviance and exact_product, states the binomial’s correction for the rounding of 1 - p and the measured accuracy of each probability, and the figures binom_pmf, binom_cdf, poisson_pmf, bayes, chi_square, stirling_error and deviance refuse.
  • rev 142 (2026-11-12) — sound 1.0.3: §3.76 states how add_levels is computed, as the louder level plus 10 log10(1 + 10^(-d/10)), so that no power passes the largest real and any two levels have a sum, where the sum of powers answered inf from this revision for levels past about 3080 decibels.
  • rev 133 (2026-11-10) — The library carries pqc at 1.0.2, harmony 1.0.1, physics 1.0.2, chemistry 1.0.2, biology 1.0.1, geography 1.0.1, mathematics 1.0.1, statistics 1.0.2, computing 1.0.1, sound 1.0.2 and architecture 1.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; chemistry also raises a molecule’s flags from an atom whose bonds are disputed. The queries disputed_rooms, disputed_codes, disputed_days, disputed_equations, disputed_groups, disputed_molecules, disputed_reactions and disputed_studies are new, and a query that answers a disputed sum raises ValueError. chemistry.formula counts each atom once and refuses an atom that holds two elements; unexplained in §3.36 and holds in §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 quantum at 1.3.0, on the source surface. §3.18 gains the step mx, which measures a qubit in the X basis, and the controlled steps x_if, cnot_if, ccx_if, z_if, cz_if, ccz_if, swap_if and cswap_if, and the helpers rev_apply_under and rev_measures. rev_meets holds a circuit over every assignment of the outcomes and answers the count of cases and the lowest failing case; rev_same raises ValueError for a circuit that measures; rev_code answers operation 8 for mx and refuses a controlled step whose qubit no mx measured. A circuit with no mx is answered as 1.2.0 answered it.
  • rev 131 (2026-11-10) — The library carries quantum at 1.2.0, on the source surface. §3.18 gains eight queries: ccx, ccz and cswap, 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 helpers rev_code, rev_apply and lowest_lane. A step of a reversible circuit is x, cnot, ccx, z, cz, ccz, swap or cswap; any other gate is refused. Everything 1.1.0 answered, 1.2.0 answers the same.
  • rev 130 (2026-11-10) — The library carries elections at 1.0.0, on the source surface. §3.2 lists twenty-four modules. §3.88 to §3.91 specify elections: its declared fields, its derived fields, its standing rules and its queries. §3.88 states that elections is 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 architecture at 1.0.0, on the source surface. §3.2 lists twenty-three modules. §3.84 to §3.87 specify architecture: its declared fields, its derived fields, its standing rules and thresholds, and its queries. §3.84 states that architecture is 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, where math.atan, math.tan, math.degrees and math.radians round once.
  • rev 126 (2026-11-09) — §3.82 and §3.83: food is 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. A casserole is one with meat or poultry, or meatless, at 165 F, and chart() writes eleven standards, ham-packaged at 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, earthscience and body are at 1.0.1 and each names the readers that refuse while sources disagree, which the sections had said none did: up() and window(), dryness_threshold() and category(), and bmi().
  • rev 124 (2026-11-09) — §3.75, §3.76, §3.79, §3.80, §3.82 and §3.83: sound, finance and food are at 1.0.1 and each has an unsettled() that names each subject that holds two different values for any field you write, eleven in sound, five in finance and fifteen in food. dose, total_of and total are stated to refuse a cell that holds two values.
  • rev 123 (2026-11-08) — The library carries calendars, colour, body, sound, finance and food at 1.0.0, each on the source surface. §3.2 lists twenty-two modules. §3.61 to §3.64 specify calendars, §3.65 to §3.68 colour, §3.69 to §3.72 body, §3.73 to §3.76 sound, §3.77 to §3.80 finance and §3.81 to §3.83 food: their declared fields, their derived fields, their standing rules and thresholds, and their queries. §3.69 states that body is not medical advice, §3.73 that sound is not occupational-health advice, §3.77 that finance is not financial advice and §3.81 that food is not food-safety or medical advice.
  • rev 122 (2026-11-08) — The library carries statistics, earthscience and computing at 1.0.0, each on the source surface. §3.2 lists sixteen modules. §3.49 to §3.52 specify statistics, §3.53 to §3.56 earthscience and §3.57 to §3.60 computing: their declared fields, their derived fields, their standing rules and thresholds, and their queries.
  • rev 121 (2026-11-08) — The library carries astronomy, geography and mathematics at 1.0.0, each on the source surface. §3.2 lists thirteen modules. §3.38 to §3.41 specify astronomy, §3.42 to §3.44 geography and §3.45 to §3.48 mathematics: 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() in physics and chemistry names 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.34 chemistry and §3.35 to §3.37 biology: 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 harmony rules asking for something to be missing, chromatic and 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 quantum 1.1.0’s generator from a 256-bit key, ChaCha20 as RFC 8439 defines it: chacha_quarter, chacha_block, chacha_unit, chacha_uniform and advance_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 dkepy as 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, which dke.keys 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.
  • rev 24 (2026-10-16) — §3.2 lists six modules. §3.16 to §3.18 specify quantum and §3.19 to §3.22 pqc, and §4.5 their readers in dkepy, dke.quantum and dke.pqc. §4.1 is corrected: dke.keys opens a connection as dke.client does, and needs cryptography, the keys extra, where §4.1 said only dke.client did and that nothing beyond the standard library was needed.
  • rev 22 (2026-10-14) — §1 and §3.2: the modules and dkepy are served from https://dke.langsyn.com/source/. The dke.langsyn.org addresses still lead to the same files.
  • rev 20 (2026-10-14) — §3.6: the sentence on how far impact_of walks 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.