somatize.reasoning
What somebody was trying to find out, read back and drawn.
somatize.record is what happened; this is what was thought about it. Neither
recovers the other: if it can be recalculated it is record, and if somebody
thought it it is reasoning.
It is written from the terminal, one move at a time, while somebody is
thinking — somatize-tree ask, suppose, tried, found, decide — and read
from here:
from somatize import Storefrom somatize import reasoning
store = Store("/scratch/inv")
reasoning.moves(store, tree="inv") # every move, in the order they were madereasoning.standing(store, tree="inv") # how each question and hypothesis standsreasoning.says(store, tree="inv") # what was said, and where it holdsreasoning.folds(store, tree="inv") # what was abandoned, how many and whyreasoning.cites(store, tree="inv") # which moves cite each commitreasoning.covered(store, tree="inv", by=["short"]) # what a scope reachesreasoning.figure(store, tree="inv") # the shape of itEverything cross-references by name, because the store’s slot stops identifying a move the moment nobody is holding it in a variable — and reading one back is exactly that moment.
tree= and never soma-tree.toml: a second reader of that file is how a
--tree said on the command line reaches the journal and not the walk, with
nothing saying so.
Classes
Section titled “Classes”Card(name: str, kind: str, x: float, y: float, w: float, h: float, said: str, prose: str, pruned: bool, hides: int | None = None, why: str | None = None)One move, placed. hides is how many a folded line takes with it, and is
None on a card that is not folded — pruning says how many and why.
Functions
Section titled “Functions”cards(moves: Sequence[Row], says: Sequence[Row] = (), folds: Sequence[Row] = (), *, under: str | None = None) -> tuple[list[Card], list[Edge]]Where every card goes, and the edges between them.
Pure, over the rows somatize.reasoning reads — nothing here touches a
store, which is what makes the layout rules testable on their own.
Folding is what you hand it: the lines in folds come folded, saying how
many they hide and why, and passing none opens everything. An app that folds
what its reader has already read hands its own list and needs nothing from
here.
cites(store: Store, *, tree: str) -> dict[str, dict[str, list[str]]]The way back: {what: {id: [move, …]}} — which moves cite each commit,
trial or configuration.
A commit you cannot ask what was this for is a change without a motive. Derived from the citations here and kept in no index, so it is true the moment somebody cites one and cannot go stale. On real data one commit came back cited by five attempts, told apart only by their configurations.
covered
Section titled “covered”covered(store: Store, *, tree: str, by: list[str]) -> list[str]What a scope with those roots reaches: the roots and everything under them, in the order they were made.
The one walk a reader cannot redo by hand and get right, because under is
multivalued and a scope is a DAG and not a subtree. With it, do these two
scopes touch is set(a) & set(b). Fails if a name is nobody’s here.
figure
Section titled “figure”figure(store: Store, *, tree: str, folded: bool = True, under: str | None = None) -> FigureThe reasoning as a plotly.graph_objects.Figure, drawn from what is
stored with nothing run again.
Hue says which of the five kinds a move is and never whether it went well;
how a question stands is written on it. The one outline that changes is
disputed — edges of opposite sign whose scopes touch — because that is the
one a reader has to go and settle.
folds(store: Store, *, tree: str) -> list[Row]The lines somebody abandoned: root, by, course, why and hides.
One row per move a decision named, with hides naming what folds with it —
so how many is len and why is in words. Pruning never deletes: a line
that did not work is the most reusable thing an investigation produces.
Folding what you have read is not here and never will be. It writes nothing down, because closing what you have read is not a claim about the investigation — it is the reader’s, and so it is an app’s.
moves(store: Store, *, tree: str) -> list[Row]Every move, in the order they were made — which is the order siblings are read and drawn in.
| column | what it is |
|---|---|
name | what its author called it, and how it is reached everywhere else |
id | the store’s slot; what says which of two variants was tried first |
kind | one of KINDS |
prose | what somebody wrote |
under | what it hangs under, multivalued: one move can answer two questions |
about | where it belongs when it hangs nowhere — a decision’s scope names what it abandons |
scope | where it holds, as roots; empty is everywhere |
cites | [{"what": …, "id": …}]; only an attempt and a finding carry one |
course | pursue, abandon, superseded; only a decision |
standing | one of STANDINGS; only a question or a hypothesis, None otherwise |
pruned | whether something abandoned the line it is on — derived, never stored |
who, when | who wrote it down and at what second |
standing is None and not "open" on an attempt: an attempt is not a
question nobody has answered.
says(store: Store, *, tree: str) -> list[Row]Everything anybody said from one move towards another: from, says,
to, scope, partly and withdrawn, all in names.
answers, validates and refutes are what make a standing; combines
says an attempt is the composition of those, which is what lets each
worked alone, together they cancel read as what it is.
withdrawn is an edge whose evidence came from a commit somebody judged
invalid: it no longer counts towards a standing and is still written down,
which is how a standing that moved on its own says what moved it.
standing
Section titled “standing”standing(store: Store, *, tree: str) -> dict[str, str]How each question and hypothesis stands, by name.
A word, and the reason is in says: two edges of opposite sign whose scopes
touch are disputed, and the same two that do not touch are depends —
the answer depending on the case, which is the most informative outcome an
investigation gives. Use covered to tell one from the other.
Derived every time and never read from a field, which is what lets one go
back to open on its own: judge the commit a refutation rested on invalid
and the edge stops counting, with nothing said again and nothing deleted.
Constants
Section titled “Constants”KINDS—question,hypothesis,attempt,finding,decisionSTANDINGS—open,answered,partly,validated,partly-validated,refuted,partly-refuted,disputed,depends