@lapxo/obligations 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  # @lapxo/obligations
4
4
 
5
- ![version 0.2.0](https://img.shields.io/badge/version-0.2.0-8c959f) ![license MIT](https://img.shields.io/badge/license-MIT-8c959f) ![node >=22.12](https://img.shields.io/badge/node-%3E%3D22.12-8c959f) ![dependencies 0](https://img.shields.io/badge/dependencies-0-2da44e) ![cases 178 hold](https://img.shields.io/badge/cases-178_hold-2da44e) ![verify agrees](https://img.shields.io/badge/verify-agrees-8c959f) [![DOI 10.5281/zenodo.21858428](https://img.shields.io/badge/DOI-10.5281%2Fzenodo.21858428-8c959f)](https://doi.org/10.5281/zenodo.21858428)
5
+ ![version 0.3.0](https://img.shields.io/badge/version-0.3.0-8c959f) ![license MIT](https://img.shields.io/badge/license-MIT-8c959f) ![node >=22.12](https://img.shields.io/badge/node-%3E%3D22.12-8c959f) ![dependencies 0](https://img.shields.io/badge/dependencies-0-2da44e) ![cases 203 hold](https://img.shields.io/badge/cases-203_hold-2da44e) ![verify agrees](https://img.shields.io/badge/verify-agrees-8c959f) [![DOI 10.5281/zenodo.21858428](https://img.shields.io/badge/DOI-10.5281%2Fzenodo.21858428-8c959f)](https://doi.org/10.5281/zenodo.21858428)
6
6
 
7
- The algebra of a cell: two poles, origins with phase, six operations.
7
+ The algebra of a cell: two poles, origins with phase, eight acts.
8
8
 
9
9
  ## The idea
10
10
 
@@ -19,20 +19,23 @@ A cell is drawn as bars on one scale: a grey bar is what one origin claims, pote
19
19
  ## The object
20
20
 
21
21
  ```text
22
- c = ⟨⊥, ⊤, O, r, ⊑⟩ ⊥, ⊤ ∈ L with ≤ O = {(o, φ, s)} r ∈ ℕ ⊑ the order of rest
23
- meet(c) = ⊤ ∧ ⋀_{o∈O} span_o
24
- info(c) ⟺ |ext(O)| ≥ 2 ∧ meet(c) ≠ ∅
25
- F(c) = log₂ |{x ∈ L : ⊥ ≤ x ≤ ⊤}|
26
- sign : ⊤(c′) ← ⊤(c′) ∧ s ∀ c′ ⊒ c
27
- join : ⊤(c) ← ⊤(c) ∨ s for c alone, witnessed
28
- state(c) ∈ {FREE, REQUIRED, FORBIDDEN, CONFLICT}
22
+ c = ⟨⊥, ⊤, O, ⊑⟩ over L at r
23
+ ⊥(c) = ⋁ required ∨ ⋁_{o∈O} lo_o
24
+ ⊤(c) = ⋀ signed ∧ ⋀_{o∈O} hi_o
25
+ info(c) ⟺ |ext(O)| ≥ 2 ∧ meet(c) ≠ ∅
26
+ F(C) = Σ_{c∈C} F(c), F(a(c)) ≤ F(c) for every act a that narrows
27
+ A(c) = |Σ_{o∈O} s_o w_o e^{iφ_o}|²
28
+ ⊤(c) = ⋀_{b ⊑ c} signed(b) ∧ ⋀_{o∈O} hi_o, one line per act
29
+ |e^{ia} + e^{ib}|² < 2 ⟺ |a − b| > π/2
30
+ state(c) ∈ {FREE, REQUIRED, FORBIDDEN, CONFLICT}
29
31
  ```
30
32
 
31
33
  ```text
32
- one origin REQUIRED ○
33
- two or more, they meet, within the ceiling FREE ●
34
- two or more, they meet, outside the ceiling FORBIDDEN ✕
35
- two or more, they do not meet CONFLICT ⋔
34
+ bounds that cross CONFLICT ⋔
35
+ one origin REQUIRED ○
36
+ claims that do not meet CONFLICT ⋔
37
+ claims that meet and fit the bounds FREE ●
38
+ claims that meet outside the bounds FORBIDDEN ✕
36
39
  ```
37
40
 
38
41
  ## What holds
@@ -41,9 +44,9 @@ The theory of this package is ten axioms and what follows from them. Three of th
41
44
 
42
45
  A claim from one origin is potential; a cell is information only where two independent origins touch it and their intervals meet. That is encounter, and 28 lines of the lock rest on it.
43
46
 
44
- Every quantity has two poles, a floor that is required and a ceiling that is permitted, and a cell is the pair. That is carrier, and 17 lines of the lock rest on it.
47
+ Two bounds on one cell fold by the meet of their form; the order they arrive in never decides. That is meet, and 19 lines of the lock rest on it.
45
48
 
46
- Two bounds on one cell fold by the meet of their form; the order they arrive in never decides. That is meet, and 13 lines of the lock rest on it.
49
+ Every quantity has two poles, a floor that is required and a ceiling that is permitted, and a cell is the pair. That is carrier, and 17 lines of the lock rest on it.
47
50
 
48
51
  <details><summary>The other seven, each one line of the lock with a sample that shows it and one that would break it</summary>
49
52
 
@@ -134,36 +137,31 @@ Five readings:
134
137
  - **A distant signature moves a cell that did not move** — a hint, never a claim. *Breaks if one act is both local and non-local.*
135
138
  - **Amplitudes without an origin** — what is left of a cell when who, ceiling, resolution and band are dropped. *Breaks if the arithmetic forbids what the restored fields predict.*
136
139
  - **Measurement** — a thermometer, a survey, an interferometer and a headcount fill the same five fields. *Breaks if one instrument cannot.*
137
- - **The medium of encounters** — what carries an encounter is a medium, and a medium is what two origins can both reach. *Breaks if two origins meet with nothing they both reach.*
138
- - **Refereed game** — a field of cells with origins and signatures is a game whose referee is inside it. *Breaks if a player can suspend the rule that two origins are needed.*
140
+ - **The medium of encounters** — what carries an encounter is a medium, and a medium is what two origins can both reach: in each instrument the medium can be named and the encounter happens where two origins touch it and nowhere else, so two origins at one cell make information and the same two at two cells make none; structural resemblance, one origin, not a claim about the world. *Breaks if two origins meet with nothing they both reach.*
141
+ - **Refereed game** — a field of cells with origins and signatures is a game whose referee is inside it: a move is a claim, a claim alone is potential, two that meet are information, a signature moves every cell that rests on it, and no player may suspend the rule that makes the first four; the claim is that each of five readings of the field matches all five properties; structural resemblance, one origin, not a claim about the world. *Breaks if a player can suspend the rule that two origins are needed.*
139
142
 
140
143
  <details><summary>Every conjecture in full</summary>
141
144
 
142
- Resolution times independent encounters per cell stays above a floor c; the sufficient resolution is where the product saturates. It is falsified by a cell read at four resolutions whose product of resolution and independent encounters comes out above the floor while the encounters fall away with the sharpening. A product that rises as the reading sharpens would say the floor is not a floor but an accident of how coarsely the cell was read.
145
+ Resolution times independent encounters per cell stays above a floor c; the sufficient resolution is where the product saturates. The falsifier: a cell read at four resolutions whose product of resolution and independent encounters comes out above the floor while the encounters fall away with the sharpening. A product that rises as the reading sharpens would say the floor is not a floor but an accident of how coarsely the cell was read.
143
146
 
144
- Where reading already is, the next reading lands: over eight epochs of placement in proportion to the origins a cell already carries, the ratio between the densest tenth and the sparsest rises at every epoch and the deserts stay empty, while the same budget placed blind to density holds that ratio near two and touches three times as many cells. It is falsified by encounters that land independently of the density already there. Then the ratio does not rise with the epochs and the cells touched grow with the budget, which is what the blind placement in the yes sample shows.
147
+ Where reading already is, the next reading lands: over eight epochs of placement in proportion to the origins a cell already carries, the ratio between the densest tenth and the sparsest rises at every epoch and the deserts stay empty, while the same budget placed blind to density holds that ratio near two and touches three times as many cells. The falsifier: encounters that land independently of the density already there. Then the ratio does not rise with the epochs and the cells touched grow with the budget, which is what the blind placement in the yes sample shows.
145
148
 
146
- Stated as a hint and never as a claim about the world: if what is is a field of floors and ceilings, a distant signature changes a cell whose own record never moved, and in two hundred trials of one cell holding one value the verdict came out both ways, so nothing stored at the cell explains the difference and what explains it is the bound the cell rests on; the resemblance is structural and never arithmetic, with no continuous amplitudes and no inequality violated by number; structural resemblance, one origin, not a claim about the world. It is falsified by one act that is both local and non-local — a change that travels a distance and also reaches a cell that does not rest on its bound. The two poles would then be one, and this would be a claim about the world rather than a hint.
149
+ Stated as a hint and never as a claim about the world: if what is is a field of floors and ceilings, a distant signature changes a cell whose own record never moved, and in two hundred trials of one cell holding one value the verdict came out both ways, so nothing stored at the cell explains the difference and what explains it is the bound the cell rests on; the resemblance is structural and never arithmetic, with no continuous amplitudes and no inequality violated by number; structural resemblance, one origin, not a claim about the world. The falsifier: one act that is both local and non-local — a change that travels a distance and also reaches a cell that does not rest on its bound. The two poles would then be one, and this would be a claim about the world rather than a hint.
147
150
 
148
- The cells under the order of rest, with signatures as meets and the phase each origin carries as what they are enriched over, look like an enriched meet-semilattice, and what this library proves would be its representation theory; identity, composition, associativity, commuting and naturality hold for the operations as vectors, while observation is not one of them — it moves the metric and can split a cell no signature could, so it is a functor out of the category and not an arrow inside it, and the join, which does not travel, is a second kind of arrow this conjecture does not name. It is falsified by a pair of the five operations whose composition the axioms do not determine. The join is already known to be absent from them: it does not travel, and naming what it is would be a second kind of arrow this conjecture does not have.
151
+ The cells under the order of rest, with signatures as meets and the phase each origin carries as what they are enriched over, look like an enriched meet-semilattice, and what this library proves would be its representation theory; identity, composition, associativity, commuting and naturality hold for the operations as vectors, while observation is not one of them — it moves the metric and can split a cell no signature could, so it is a functor out of the category and not an arrow inside it, and the join, which does not travel, is a second kind of arrow this conjecture does not name. The falsifier: a pair of the five operations whose composition the axioms do not determine. The join is already known to be absent from them: it does not travel, and naming what it is would be a second kind of arrow this conjecture does not have.
149
152
 
150
- Amplitudes with a phase and no origin, no signed ceiling, no resolution and no epoch band are what is left of a cell when those four fields are dropped, so the measurement problem is the absence of who, imposed symmetries the absence of a signed ceiling, the classical limit the absence of resolution and universal interference the absence of bands; restored, four claims in phase keep exactly the share of the whole their number leaves them against an environment spread over the period, and six origins around one value are six objects read finely and one read coarsely, so how many things there are is a reading; structural resemblance, one origin, not a claim about the world. It is falsified by a result of the usual formalism that cannot be stated with the four fields, or a prediction the restored fields make that the arithmetic forbids. This conjecture is about which structure is missing, not about numbers the arithmetic already gives.
153
+ Amplitudes with a phase and no origin, no signed ceiling, no resolution and no epoch band are what is left of a cell when those four fields are dropped, so the measurement problem is the absence of who, imposed symmetries the absence of a signed ceiling, the classical limit the absence of resolution and universal interference the absence of bands; restored, four claims in phase keep exactly the share of the whole their number leaves them against an environment spread over the period, and six origins around one value are six objects read finely and one read coarsely, so how many things there are is a reading; structural resemblance, one origin, not a claim about the world. The falsifier: a result of the usual formalism that cannot be stated with the four fields, or a prediction the restored fields make that the arithmetic forbids. This conjecture is about which structure is missing, not about numbers the arithmetic already gives.
151
154
 
152
- Four instruments that share no mechanism fold the same way because a measurement is a cell: for a thermometer, a survey, an interferometer and a headcount the five fields are named without strain and the same five operations answer for all four; no number is claimed, only that the table can be filled in every row. It is falsified by an instrument whose reading cannot be written as a floor and a ceiling held by an origin at an epoch and a resolution, without straining any of the five.
155
+ Four instruments that share no mechanism fold the same way because a measurement is a cell: for a thermometer, a survey, an interferometer and a headcount the five fields are named without strain and the same five operations answer for all four; no number is claimed, only that the table can be filled in every row. The falsifier: an instrument whose reading cannot be written as a floor and a ceiling held by an origin at an epoch and a resolution, without straining any of the five.
153
156
 
154
- What carries an encounter is a medium, and a medium is what two origins can both reach: in each instrument the medium can be named and the encounter happens where two origins touch it and nowhere else, so two origins at one cell make information and the same two at two cells make none; structural resemblance, one origin, not a claim about the world. It is falsified by an encounter between two origins with nothing they both reach. Then information would appear where nothing was shared.
157
+ What carries an encounter is a medium, and a medium is what two origins can both reach: in each instrument the medium can be named and the encounter happens where two origins touch it and nowhere else, so two origins at one cell make information and the same two at two cells make none; structural resemblance, one origin, not a claim about the world. The falsifier: an encounter between two origins with nothing they both reach. Then information would appear where nothing was shared.
155
158
 
156
- A field of cells with origins and signatures is a game whose referee is inside it: a move is a claim, a claim alone is potential, two that meet are information, a signature moves every cell that rests on it, and no player may suspend the rule that makes the first four; the claim is that each of five readings of the field matches all five properties; structural resemblance, one origin, not a claim about the world. It is falsified by a reading of the field where a player can suspend the rule that two origins are needed, or where one claim is information. Then the referee would be outside the game.
159
+ A field of cells with origins and signatures is a game whose referee is inside it: a move is a claim, a claim alone is potential, two that meet are information, a signature moves every cell that rests on it, and no player may suspend the rule that makes the first four; the claim is that each of five readings of the field matches all five properties; structural resemblance, one origin, not a claim about the world. The falsifier: a reading of the field where a player can suspend the rule that two origins are needed, or where one claim is information. Then the referee would be outside the game.
157
160
 
158
- The obligatory is maximal: take away any one of its seven parts and what is left is an object already known, and anything added to it is either already inside it or breaks the four states. It is falsified by a part the obligatory lacks that keeps the four states and the six operations and is not a reading of one of them.
161
+ The obligatory is maximal: take away any one of its seven parts and what is left is an object already known, and anything added to it is either already inside it or breaks the four states. The falsifier: a part the obligatory lacks that keeps the four states and the six operations and is not a reading of one of them.
159
162
 
160
163
  </details>
161
164
 
162
165
  ## Check
163
166
 
164
- ● 178 cases hold
165
-
166
- ## Pointers
167
-
168
- - [Reference](docs/reference.md)
169
- - Learn from an example: [in phase](docs/learn/in-phase.md), [price](docs/learn/price.md), [signature](docs/learn/signature.md), [thermometer](docs/learn/thermometer.md), [withdrawal](docs/learn/withdrawal.md)
167
+ ● 203 cases hold
@@ -0,0 +1,6 @@
1
+ import type { Interval } from '../lattice/forms.ts';
2
+ import type { Lattice } from '../lattice/lattice.ts';
3
+ import type { World } from '../lattice/obligatory.ts';
4
+ export declare function price<T>(bits: (held: T) => number, before: T, after: T): number;
5
+ export declare function looksLeft(L: Lattice<Interval>, world: World<Interval>, origin: string): number;
6
+ export declare function pay(L: Lattice<Interval>, world: World<Interval>, origin: string): World<Interval>;
@@ -0,0 +1,15 @@
1
+ import { sign } from "../field/sign.js";
2
+ import { UnitError } from "../lattice/errors.js";
3
+ import { cell, parts } from "../lattice/obligatory.js";
4
+ export function price(bits, before, after) {
5
+ return bits(before) - bits(after);
6
+ }
7
+ export function looksLeft(L, world, origin) {
8
+ return parts(L, world.get(origin) ?? cell(origin), world).ceiling.hi;
9
+ }
10
+ export function pay(L, world, origin) {
11
+ const held = parts(L, world.get(origin) ?? cell(origin), world);
12
+ if (held.ceiling.hi - 1 < held.floor.lo)
13
+ throw new UnitError('attention-spent', `obligations: REFUSE·attention ${origin} has no look left: an act nobody pays for is not taken`);
14
+ return sign(L, world, origin, { lo: L.top.lo, hi: held.ceiling.hi - 1 });
15
+ }
@@ -1,5 +1,7 @@
1
1
  import type { Point, Sighting } from './field.ts';
2
2
  import type { Interval } from '../lattice/forms.ts';
3
+ import type { Lattice } from '../lattice/lattice.ts';
4
+ import type { Obligatory, Origin, World } from '../lattice/obligatory.ts';
3
5
  export declare function origins(place: Point): number;
4
6
  export declare function potential(place: Point): boolean;
5
7
  export declare function disagree(place: Point): readonly [Sighting, Sighting] | null;
@@ -7,3 +9,13 @@ export declare function meetAt(place: Point): Interval;
7
9
  export declare function latest(places: readonly Point[]): Point | null;
8
10
  export declare function verdict(place: Point): string;
9
11
  export declare function turned(before: readonly Point[], after: readonly Point[]): readonly Point[];
12
+ export declare function encounter<T>(L: Lattice<T>, c: Obligatory<T>, world?: World<T>): {
13
+ readonly origins: number;
14
+ readonly held: T;
15
+ };
16
+ export declare const cancels: (a: Origin, b: Origin) => boolean;
17
+ export declare function pairs(origins: readonly Origin[]): {
18
+ readonly forks: number;
19
+ readonly closes: number;
20
+ };
21
+ export declare function laminar(origins: readonly Origin[]): boolean;
@@ -1,6 +1,8 @@
1
1
  import { witnessesIn } from "../debit/debit.js";
2
2
  import { key } from "./field.js";
3
+ import { meet } from "./meet.js";
3
4
  import { intervals } from "../lattice/forms.js";
5
+ import { live } from "../lattice/obligatory.js";
4
6
  const spanning = (spans) => intervals(Math.min(...spans.map((one) => one.lo)), Math.max(...spans.map((one) => one.hi)));
5
7
  export function origins(place) {
6
8
  return new Set(place.seen.map((s) => s.origin)).size;
@@ -34,3 +36,23 @@ export function turned(before, after) {
34
36
  const held = new Map(before.map((p) => [key([{ at: p.at }]), verdict(p)]));
35
37
  return after.filter((p) => held.get(key([{ at: p.at }])) !== verdict(p));
36
38
  }
39
+ export function encounter(L, c, world = new Map()) {
40
+ return { origins: new Set(live(c.seen).map((claim) => claim.origin)).size, held: meet(L, c, world) };
41
+ }
42
+ export const cancels = (a, b) => Math.cos(a.phase - b.phase) < 0;
43
+ export function pairs(origins) {
44
+ let forks = 0;
45
+ let closes = 0;
46
+ for (let i = 0; i < origins.length; i += 1)
47
+ for (let j = i + 1; j < origins.length; j += 1)
48
+ if (cancels(origins[i], origins[j]))
49
+ forks += 1;
50
+ else
51
+ closes += 1;
52
+ return { forks, closes };
53
+ }
54
+ export function laminar(origins) {
55
+ const x = origins.reduce((sum, one) => sum + Math.cos(one.phase), 0);
56
+ const y = origins.reduce((sum, one) => sum + Math.sin(one.phase), 0);
57
+ return x * x + y * y > origins.length;
58
+ }
@@ -0,0 +1,3 @@
1
+ import type { Lattice } from '../lattice/lattice.ts';
2
+ import type { Obligatory } from '../lattice/obligatory.ts';
3
+ export declare function join<T>(L: Lattice<T>, c: Obligatory<T>, span: T, witness: string, at?: number): Obligatory<T>;
@@ -0,0 +1,7 @@
1
+ import { UnitError } from "../lattice/errors.js";
2
+ import { mark } from "../lattice/obligatory.js";
3
+ export function join(L, c, span, witness, at) {
4
+ if (witness === '')
5
+ throw new UnitError('join-unwitnessed', 'obligations: REFUSE·join a widening lands only with a witness or the signatures of whoever rests on the old bound');
6
+ return { ...c, marks: [...(c.marks ?? []), mark({ pole: 'ceiling', reach: 'local', span: L.meet(L.top, span), widens: witness, ...(at === undefined ? {} : { at }) })] };
7
+ }
@@ -0,0 +1,3 @@
1
+ import type { Lattice } from '../lattice/lattice.ts';
2
+ import type { Obligatory, World } from '../lattice/obligatory.ts';
3
+ export declare function meet<T>(L: Lattice<T>, c: Obligatory<T>, world?: World<T>): T;
@@ -0,0 +1,5 @@
1
+ import { parts } from "../lattice/obligatory.js";
2
+ export function meet(L, c, world = new Map()) {
3
+ const { floor, ceiling } = parts(L, c, world);
4
+ return L.meet(floor, ceiling);
5
+ }
@@ -0,0 +1,2 @@
1
+ import type { Act, Claim, Obligatory } from '../lattice/obligatory.ts';
2
+ export declare function observe<T>(c: Obligatory<T>, claim: Claim<T>, s?: Act): Obligatory<T>;
@@ -0,0 +1,10 @@
1
+ import { UnitError } from "../lattice/errors.js";
2
+ export function observe(c, claim, s = claim.takes === undefined ? 1 : -1) {
3
+ const takes = s === 1 ? undefined : claim.takes ?? claim.id;
4
+ if (s === 1 && claim.takes !== undefined)
5
+ throw new UnitError('sign-mismatch', 'obligations: REFUSE·observe a claim that takes another back is observed at −1, never at +1');
6
+ if (s === -1 && takes === undefined)
7
+ throw new UnitError('withdrawal-unnamed', 'obligations: REFUSE·observe a withdrawal names the claim it takes back, never a value that looks like it');
8
+ const line = takes === undefined ? claim : { origin: claim.origin, span: claim.span, sign: -1, takes, ...(claim.at === undefined ? {} : { at: claim.at }) };
9
+ return { ...c, epoch: Math.max(c.epoch, claim.at ?? c.epoch), seen: [...c.seen, line] };
10
+ }
@@ -0,0 +1,2 @@
1
+ import type { Obligatory } from '../lattice/obligatory.ts';
2
+ export declare function refine<T>(c: Obligatory<T>, steps: number): Obligatory<T>;
@@ -0,0 +1,3 @@
1
+ export function refine(c, steps) {
2
+ return { ...c, at: steps >= c.at.length ? c.at : c.at.slice(0, Math.max(1, steps)) };
3
+ }
@@ -0,0 +1,4 @@
1
+ import type { Lattice } from '../lattice/lattice.ts';
2
+ import type { World } from '../lattice/obligatory.ts';
3
+ import type { Line } from './sign.ts';
4
+ export declare function require<T>(L: Lattice<T>, world: World<T>, name: string, span: T, line?: Line): World<T>;
@@ -0,0 +1,5 @@
1
+ import { cell, mark } from "../lattice/obligatory.js";
2
+ export function require(L, world, name, span, line = {}) {
3
+ const held = world.get(name) ?? cell(name);
4
+ return new Map([...world, [name, { ...held, marks: [...(held.marks ?? []), mark({ pole: 'floor', reach: 'travels', span: L.meet(L.top, span), ...line })] }]]);
5
+ }
@@ -0,0 +1,13 @@
1
+ import type { Lattice } from '../lattice/lattice.ts';
2
+ import type { World } from '../lattice/obligatory.ts';
3
+ export interface Line {
4
+ readonly id?: string;
5
+ readonly at?: number;
6
+ readonly takes?: string;
7
+ }
8
+ export declare function sign<T>(L: Lattice<T>, world: World<T>, name: string, span: T, line?: Line): World<T>;
9
+ export declare function restingOn<T>(world: World<T>): ReadonlyMap<string, readonly string[]>;
10
+ export declare function bites<T>(L: Lattice<T>, world: World<T>, resting: ReadonlyMap<string, readonly string[]>, name: string, span: T): {
11
+ readonly cells: readonly string[];
12
+ readonly visits: number;
13
+ };
@@ -0,0 +1,34 @@
1
+ import { cell, live, mark, restOf } from "../lattice/obligatory.js";
2
+ export function sign(L, world, name, span, line = {}) {
3
+ const held = world.get(name) ?? cell(name);
4
+ return new Map([...world, [name, { ...held, marks: [...(held.marks ?? []), mark({ pole: 'ceiling', reach: 'travels', span: L.meet(L.top, span), ...line })] }]]);
5
+ }
6
+ export function restingOn(world) {
7
+ const out = new Map();
8
+ for (const [name, one] of world)
9
+ for (const bound of one.restsOn)
10
+ out.set(bound, [...(out.get(bound) ?? []), name]);
11
+ return out;
12
+ }
13
+ export function bites(L, world, resting, name, span) {
14
+ const own = (at) => live(world.get(at)?.marks ?? []).filter((one) => one.pole === 'ceiling' && one.reach === 'travels' && one.widens === undefined)
15
+ .reduce((held, one) => L.meet(held, one.span), L.top);
16
+ const above = (at) => restOf(world.get(at) ?? cell(at), world).reduce((held, up) => L.meet(held, own(up)), own(at));
17
+ const bitten = [];
18
+ const edge = [[name, above(name)]];
19
+ const held = new Set([name]);
20
+ for (let i = 0; i < edge.length; i += 1) {
21
+ const [here, was] = edge[i];
22
+ if (L.leq(was, span))
23
+ continue;
24
+ bitten.push(here);
25
+ for (const next of resting.get(here) ?? []) {
26
+ if (held.has(next))
27
+ continue;
28
+ held.add(next);
29
+ const one = world.get(next);
30
+ edge.push([next, one !== undefined && one.restsOn.length === 1 ? L.meet(was, own(next)) : above(next)]);
31
+ }
32
+ }
33
+ return { cells: bitten, visits: edge.length };
34
+ }
@@ -1,4 +1,4 @@
1
- export type UnitErrorCode = 'UNKNOWN_LEVEL' | 'MALFORMED' | 'EMPTY_CHAIN' | 'DUPLICATE_LEVEL' | 'NOT_FINITE' | 'UNKNOWN_ROW';
1
+ export type UnitErrorCode = 'UNKNOWN_LEVEL' | 'MALFORMED' | 'EMPTY_CHAIN' | 'DUPLICATE_LEVEL' | 'NOT_FINITE' | 'UNKNOWN_ROW' | 'rest-cycle' | 'widening-travels' | 'withdrawal-unnamed' | 'sign-mismatch' | 'join-unwitnessed' | 'attention-spent';
2
2
  export declare class UnitError extends Error {
3
3
  readonly code: UnitErrorCode;
4
4
  readonly detail: Readonly<Record<string, unknown>>;
@@ -1,9 +1,27 @@
1
1
  import type { Lattice } from './lattice.ts';
2
+ import type { State } from './types.ts';
3
+ export type Act = 1 | -1;
4
+ export interface Origin {
5
+ readonly name: string;
6
+ readonly phase: number;
7
+ }
2
8
  export interface Claim<T> {
3
9
  readonly origin: string;
4
10
  readonly span: T;
5
11
  readonly id?: string;
6
12
  readonly at?: number;
13
+ readonly sign?: Act;
14
+ readonly takes?: string;
15
+ readonly phase?: number;
16
+ }
17
+ export interface Mark<T> {
18
+ readonly pole: 'floor' | 'ceiling';
19
+ readonly reach: 'local' | 'travels';
20
+ readonly span: T;
21
+ readonly widens?: string;
22
+ readonly id?: string;
23
+ readonly at?: number;
24
+ readonly sign?: Act;
7
25
  readonly takes?: string;
8
26
  }
9
27
  export interface Obligatory<T> {
@@ -11,17 +29,23 @@ export interface Obligatory<T> {
11
29
  readonly epoch: number;
12
30
  readonly seen: readonly Claim<T>[];
13
31
  readonly restsOn: readonly string[];
14
- readonly ceiling?: T;
15
- readonly witnesses?: readonly string[];
32
+ readonly marks?: readonly Mark<T>[];
33
+ }
34
+ export type World<T> = ReadonlyMap<string, Obligatory<T>>;
35
+ export interface Cell<T> {
36
+ readonly floor: T;
37
+ readonly ceiling: T;
38
+ readonly origins: readonly Claim<T>[];
39
+ readonly rest: readonly string[];
40
+ readonly required: T;
41
+ readonly signed: T;
16
42
  }
17
43
  export declare function cell<T>(at: string, epoch?: number, seen?: readonly Claim<T>[], restsOn?: readonly string[]): Obligatory<T>;
18
- export declare function meet<T>(lattice: Lattice<T>, one: Obligatory<T>, bounds?: ReadonlyMap<string, T>): T;
19
- export declare function encounter<T>(lattice: Lattice<T>, one: Obligatory<T>, bounds?: ReadonlyMap<string, T>): {
20
- readonly origins: number;
21
- readonly held: T;
22
- };
23
- export declare function observe<T>(one: Obligatory<T>, claim: Claim<T>): Obligatory<T>;
24
- export declare function sign<T>(lattice: Lattice<T>, bounds: ReadonlyMap<string, T>, name: string, span: T): ReadonlyMap<string, T>;
25
- export declare function sign<T>(lattice: Lattice<T>, world: readonly Obligatory<T>[], name: string, span: T): readonly Obligatory<T>[];
26
- export declare function join<T>(lattice: Lattice<T>, one: Obligatory<T>, span: T, witness: string): Obligatory<T>;
27
- export declare function refine<T>(one: Obligatory<T>, steps: number): Obligatory<T>;
44
+ export declare function mark<T>(one: Mark<T>): Mark<T>;
45
+ export declare function live<L extends {
46
+ readonly id?: string;
47
+ readonly takes?: string;
48
+ }>(lines: readonly L[]): readonly L[];
49
+ export declare function restOf<T>(c: Obligatory<T>, world?: World<T>): readonly string[];
50
+ export declare function parts<T>(L: Lattice<T>, c: Obligatory<T>, world?: World<T>): Cell<T>;
51
+ export declare function state<T>(L: Lattice<T>, c: Obligatory<T>, world?: World<T>): State;
@@ -1,33 +1,58 @@
1
1
  import { coordinate } from "../field/field.js";
2
+ import { UnitError } from "./errors.js";
2
3
  export function cell(at, epoch = 0, seen = [], restsOn = []) {
3
4
  return { at: coordinate(at), epoch, seen, restsOn };
4
5
  }
5
- const standing = (one) => {
6
- const taken = new Set(one.seen.flatMap((claim) => (claim.takes === undefined ? [] : [claim.takes])));
7
- return one.seen.filter((claim) => claim.takes === undefined && (claim.id === undefined || !taken.has(claim.id)));
8
- };
9
- export function meet(lattice, one, bounds = new Map()) {
10
- const rested = one.restsOn.flatMap((name) => (bounds.has(name) ? [bounds.get(name)] : []));
11
- const own = one.ceiling === undefined ? [] : [one.ceiling];
12
- return [...standing(one).map((claim) => claim.span), ...rested, ...own].reduce((held, span) => lattice.meet(held, span), lattice.top);
13
- }
14
- export function encounter(lattice, one, bounds) {
15
- return { origins: new Set(standing(one).map((claim) => claim.origin)).size, held: meet(lattice, one, bounds) };
6
+ export function mark(one) {
7
+ if (one.widens !== undefined && one.reach === 'travels') {
8
+ throw new UnitError('widening-travels', 'obligations: REFUSE·widening-travels a widening stands where it was witnessed and never travels to what rests there', { pole: one.pole });
9
+ }
10
+ return one.takes === undefined ? one : { ...one, sign: -1 };
16
11
  }
17
- export function observe(one, claim) {
18
- return { ...one, epoch: Math.max(one.epoch, claim.at ?? one.epoch), seen: [...one.seen, claim] };
12
+ export function live(lines) {
13
+ const taken = new Set(lines.flatMap((line) => (line.takes === undefined ? [] : [line.takes])));
14
+ return lines.filter((line) => line.takes === undefined && (line.id === undefined || !taken.has(line.id)));
19
15
  }
20
- export function sign(lattice, held, name, span) {
21
- if (!(held instanceof Map)) {
22
- return held.map((one) => (one.restsOn.includes(name) ? { ...one, ceiling: lattice.meet(one.ceiling ?? lattice.top, span) } : one));
16
+ export function restOf(c, world = new Map()) {
17
+ const own = c.at.join('/');
18
+ const out = [];
19
+ const held = new Set();
20
+ const edge = [...c.restsOn];
21
+ for (let i = 0; i < edge.length; i += 1) {
22
+ const name = edge[i];
23
+ if (name === own)
24
+ throw new UnitError('rest-cycle', `obligations: REFUSE·rest ${own} rests on itself: an order of rest with a cycle has no fold to reach`, { at: own });
25
+ if (held.has(name))
26
+ continue;
27
+ held.add(name);
28
+ out.push(name);
29
+ edge.push(...(world.get(name)?.restsOn ?? []));
23
30
  }
24
- return new Map([...held, [name, lattice.meet(held.get(name) ?? lattice.top, span)]]);
31
+ return out;
25
32
  }
26
- export function join(lattice, one, span, witness) {
27
- if (witness === '')
28
- throw new Error('REFUSE·join a widening lands only with a witness or the signatures of whoever rests on the old bound');
29
- return { ...one, ceiling: lattice.join(one.ceiling ?? lattice.top, span), witnesses: [...(one.witnesses ?? []), witness] };
33
+ export function parts(L, c, world = new Map()) {
34
+ const rest = restOf(c, world);
35
+ const above = rest.flatMap((name) => live(world.get(name)?.marks ?? []).filter((one) => one.reach === 'travels' && one.widens === undefined));
36
+ const marks = [...live(c.marks ?? []), ...above].sort((a, b) => (a.at ?? 0) - (b.at ?? 0));
37
+ let required = L.top;
38
+ let signed = L.top;
39
+ for (const one of marks) {
40
+ if (one.pole === 'floor')
41
+ required = L.meet(required, one.span);
42
+ else
43
+ signed = one.widens === undefined ? L.meet(signed, one.span) : L.join(signed, one.span);
44
+ }
45
+ const origins = live(c.seen);
46
+ const held = origins.reduce((acc, claim) => L.meet(acc, claim.span), L.top);
47
+ return { floor: L.meet(required, held), ceiling: L.meet(signed, held), origins, rest, required, signed };
30
48
  }
31
- export function refine(one, steps) {
32
- return { ...one, at: steps >= one.at.length ? one.at : one.at.slice(0, Math.max(1, steps)) };
49
+ export function state(L, c, world = new Map()) {
50
+ const { floor, ceiling, origins, required, signed } = parts(L, c, world);
51
+ if (!L.inhabited(L.meet(required, signed)))
52
+ return 'CONFLICT';
53
+ if (new Set(origins.map((claim) => claim.origin)).size < 2)
54
+ return 'REQUIRED';
55
+ if (!L.inhabited(origins.reduce((acc, claim) => L.meet(acc, claim.span), L.top)))
56
+ return 'CONFLICT';
57
+ return L.inhabited(L.meet(floor, ceiling)) ? 'FREE' : 'FORBIDDEN';
33
58
  }
@@ -1,4 +1,4 @@
1
- import { meet } from "../../lattice/obligatory.js";
1
+ import { meet } from "../../field/meet.js";
2
2
  import { coherence } from "./wave.js";
3
3
  export function disturbance(lattice, one, claim) {
4
4
  const was = meet(lattice, one);
@@ -1,4 +1,5 @@
1
- import { encounter, meet } from "../../lattice/obligatory.js";
1
+ import { encounter } from "../../field/encounter.js";
2
+ import { meet } from "../../field/meet.js";
2
3
  import { coherence } from "./wave.js";
3
4
  import { neighbours, reach } from "../product/reach.js";
4
5
  const at = (cell) => cell.at.join('/');
@@ -1,4 +1,5 @@
1
- import { meet, observe } from "../../lattice/obligatory.js";
1
+ import { meet } from "../../field/meet.js";
2
+ import { observe } from "../../field/observe.js";
2
3
  export function selfFold(lattice, one, epochs, width, spread, seed) {
3
4
  let held = seed;
4
5
  const next = () => { held = (held * 1103515245 + 12345) % 2147483648; return held / 2147483648; };
@@ -1,11 +1,18 @@
1
1
  export { foldIn, witnessesIn } from '../debit/debit.ts';
2
- export { disagree, latest, meetAt, origins, potential, turned } from '../field/encounter.ts';
2
+ export { cancels, disagree, encounter, laminar, latest, meetAt, origins, pairs, potential, turned } from '../field/encounter.ts';
3
3
  export { contracts, coordinate, covers, exclusive, key, passes, point, region, resolution, within } from '../field/field.ts';
4
+ export { join } from '../field/join.ts';
5
+ export { meet } from '../field/meet.ts';
6
+ export { observe } from '../field/observe.ts';
7
+ export { refine } from '../field/refine.ts';
8
+ export { require } from '../field/require.ts';
9
+ export { bites, restingOn, sign } from '../field/sign.ts';
4
10
  export { converge, endsBeforeNow, present } from '../field/present.ts';
5
11
  export { amplitude, coherence, fringes, interfere, phase, seenAs } from './field/wave.ts';
6
12
  export type { Claim } from './field/wave.ts';
7
- export { cell, encounter, join, meet, observe, refine, sign } from '../lattice/obligatory.ts';
8
- export type { Obligatory } from '../lattice/obligatory.ts';
13
+ export { cell, mark, parts, restOf, state } from '../lattice/obligatory.ts';
14
+ export type { Act, Cell, Mark, Obligatory, Origin, World } from '../lattice/obligatory.ts';
15
+ export { looksLeft, pay, price } from '../debit/observer.ts';
9
16
  export { budget, decohere, disturbance, distinct, evolve, sameObject } from './field/physics.ts';
10
17
  export { choose, play } from './field/policy.ts';
11
18
  export { selfFold } from './field/self.ts';
@@ -1,9 +1,16 @@
1
1
  export { foldIn, witnessesIn } from "../debit/debit.js";
2
- export { disagree, latest, meetAt, origins, potential, turned } from "../field/encounter.js";
2
+ export { cancels, disagree, encounter, laminar, latest, meetAt, origins, pairs, potential, turned } from "../field/encounter.js";
3
3
  export { contracts, coordinate, covers, exclusive, key, passes, point, region, resolution, within } from "../field/field.js";
4
+ export { join } from "../field/join.js";
5
+ export { meet } from "../field/meet.js";
6
+ export { observe } from "../field/observe.js";
7
+ export { refine } from "../field/refine.js";
8
+ export { require } from "../field/require.js";
9
+ export { bites, restingOn, sign } from "../field/sign.js";
4
10
  export { converge, endsBeforeNow, present } from "../field/present.js";
5
11
  export { amplitude, coherence, fringes, interfere, phase, seenAs } from "./field/wave.js";
6
- export { cell, encounter, join, meet, observe, refine, sign } from "../lattice/obligatory.js";
12
+ export { cell, mark, parts, restOf, state } from "../lattice/obligatory.js";
13
+ export { looksLeft, pay, price } from "../debit/observer.js";
7
14
  export { budget, decohere, disturbance, distinct, evolve, sameObject } from "./field/physics.js";
8
15
  export { choose, play } from "./field/policy.js";
9
16
  export { selfFold } from "./field/self.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lapxo/obligations",
3
- "version": "0.2.0",
4
- "description": "The algebra of a cell: two poles, origins with phase, six operations.",
3
+ "version": "0.3.0",
4
+ "description": "The algebra of a cell: two poles, origins with phase, eight acts.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "Lapxo",