pi-fovea 0.29.2 → 0.30.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/LAWS.bend ADDED
@@ -0,0 +1,110 @@
1
+ import Base
2
+ import ./proofs/disclosure.bend as D
3
+ import ./proofs/heat.bend as H
4
+ import ./proofs/kernel.bend as K
5
+ import ./proofs/basis.bend as B
6
+
7
+ # Proposed specifications extracted from render.ts and heat.ts. Review these independently
8
+ # of PROOF.bend; do not weaken a law to make an implementation pass.
9
+
10
+ # Disclosure: these six laws cover the entire five-Boolean input domain.
11
+ law scope_wins:
12
+ for excluded: Bool
13
+ for seen: Bool
14
+ for repeat: Bool
15
+ for nucleus: Bool
16
+ {K.disclosure(False{}, excluded, seen, repeat, nucleus) == D.Drop{} : D.Decision}
17
+
18
+ law exclusion_wins:
19
+ for scope: Bool
20
+ for seen: Bool
21
+ for repeat: Bool
22
+ for nucleus: Bool
23
+ {K.disclosure(scope, True{}, seen, repeat, nucleus) == D.Drop{} : D.Decision}
24
+
25
+ law fresh_revealed:
26
+ for repeat: Bool
27
+ for nucleus: Bool
28
+ {K.disclosure(True{}, False{}, False{}, repeat, nucleus) == D.Reveal{} : D.Decision}
29
+
30
+ law seen_suppressed:
31
+ for nucleus: Bool
32
+ {K.disclosure(True{}, False{}, True{}, False{}, nucleus) == D.Suppress{} : D.Decision}
33
+
34
+ law periphery_suppressed:
35
+ for repeat: Bool
36
+ {K.disclosure(True{}, False{}, True{}, repeat, False{}) == D.Suppress{} : D.Decision}
37
+
38
+ law nucleus_repeated:
39
+ for seen: Bool
40
+ {K.disclosure(True{}, False{}, seen, True{}, True{}) == D.Reveal{} : D.Decision}
41
+
42
+ # Executed natural-number accounting. This does NOT prove token estimation,
43
+ # renderer formatting, or binary-search monotonicity. Keep boundary tests.
44
+ law shown_bounded_by_total:
45
+ for +total: Nat
46
+ for requested: Nat
47
+ {Nat.is_le(K.shownCount(total, requested), total) == True{} : Bool}
48
+
49
+ law shown_bounded_by_request:
50
+ for total: Nat
51
+ for +requested: Nat
52
+ {Nat.is_le(K.shownCount(total, requested), requested) == True{} : Bool}
53
+
54
+ law counts_conserved:
55
+ for +total: Nat
56
+ for +requested: Nat
57
+ {Nat.add(K.shownCount(total, requested), K.remainingCount(total, requested)) == total : Nat}
58
+
59
+ law full_prefix_omits_nothing:
60
+ for +total: Nat
61
+ {K.remainingCount(total, total) == 0n : Nat}
62
+
63
+ law cap_idempotent:
64
+ for +total: Nat
65
+ for +cap: Nat
66
+ {K.shownCount(K.shownCount(total, cap), cap) == K.shownCount(total, cap) : Nat}
67
+
68
+ # Exact nonnegative rational transport model, not IEEE-754 or the exponential.
69
+ law heat_vector_add_mass:
70
+ for +xs: +List<Nat>
71
+ for +ys: +List<Nat>
72
+ {H.sum(H.add(xs, ys)) == Nat.add(H.sum(xs), H.sum(ys)) : Nat}
73
+
74
+ law heat_scale_mass:
75
+ for +mass: Nat
76
+ for +weights: +List<Nat>
77
+ {H.sum(H.scale(mass, weights)) == Nat.mul(mass, H.sum(weights)) : Nat}
78
+
79
+ # D = 1 + denominator is strictly positive. For source numerators a over Q,
80
+ # transport returns numerators over D*Q; this equality conserves rational mass.
81
+ law heat_transport_mass:
82
+ for +columns: +List<H.Column>
83
+ for +denominator: Nat
84
+ for normalized: H.Normalized(columns, 1n+denominator)
85
+ {H.sum(H.transport(columns)) == Nat.mul(H.input_mass(columns), 1n+denominator) : Nat}
86
+
87
+ law heat_singleton_mass:
88
+ for +mass: Nat
89
+ {H.sum(H.transport([H.Source{mass, [1n]}])) == mass : Nat}
90
+
91
+ # Executed basis-extension commands. Float64 evaluation remains host code.
92
+ law basis_empty_refused:
93
+ for order: Nat
94
+ {K.basisStep(0n, order) == B.Empty{} : B.Step}
95
+
96
+ law basis_complete_retained:
97
+ for +have: Nat
98
+ for +order: Nat
99
+ for complete: {Nat.is_le(1n+have, order) == False{} : Bool}
100
+ {K.basisStep(1n+have, order) == B.Done{} : B.Step}
101
+
102
+ law basis_first_order:
103
+ for order: Nat
104
+ {K.basisStep(1n, 1n+order) == B.First{} : B.Step}
105
+
106
+ law basis_next_exact:
107
+ for +have: Nat
108
+ for +order: Nat
109
+ for missing: {Nat.is_le(2n+have, order) == True{} : Bool}
110
+ {K.basisStep(2n+have, order) == B.Next{2n+have, 1n+have, have} : B.Step}
package/PROOF.bend ADDED
@@ -0,0 +1,118 @@
1
+ import Base
2
+ import ./LAWS.bend as Laws
3
+ import ./proofs/disclosure.bend as D
4
+ import ./proofs/counts.bend as C
5
+ import ./proofs/counts-proof.bend as CP
6
+ import ./proofs/heat.bend as H
7
+ import ./proofs/nat-proof.bend as N
8
+ import ./proofs/kernel.bend as K
9
+ import ./proofs/basis.bend as B
10
+
11
+ def Laws.scope_wins(excluded, seen, repeat, nucleus):
12
+ {==}
13
+
14
+ def Laws.exclusion_wins(scope, seen, repeat, nucleus):
15
+ match scope:
16
+ case False{}:
17
+ {==}
18
+ case True{}:
19
+ {==}
20
+
21
+ def Laws.fresh_revealed(repeat, nucleus):
22
+ {==}
23
+
24
+ def Laws.seen_suppressed(nucleus):
25
+ {==}
26
+
27
+ def Laws.periphery_suppressed(repeat):
28
+ match repeat:
29
+ case False{}:
30
+ {==}
31
+ case True{}:
32
+ {==}
33
+
34
+ def Laws.nucleus_repeated(seen):
35
+ match seen:
36
+ case False{}:
37
+ {==}
38
+ case True{}:
39
+ {==}
40
+
41
+ def Laws.shown_bounded_by_total(total, requested):
42
+ +requested = requested
43
+ %Equal.sym(Nat, C.fastShown(total, requested), C.shown(total, requested), CP.shown_equiv(total, requested)) : {Nat.is_le(_, total) == True{} : Bool}
44
+ CP.bounded_total(total, requested)
45
+
46
+ def Laws.shown_bounded_by_request(total, requested):
47
+ +total = total
48
+ %Equal.sym(Nat, C.fastShown(total, requested), C.shown(total, requested), CP.shown_equiv(total, requested)) : {Nat.is_le(_, requested) == True{} : Bool}
49
+ CP.bounded_request(total, requested)
50
+
51
+ def Laws.counts_conserved(total, requested):
52
+ %Equal.sym(Nat, C.fastShown(total, requested), C.shown(total, requested), CP.shown_equiv(total, requested)) : {Nat.add(_, C.fastRemaining(total, requested)) == total : Nat}
53
+ %Equal.sym(Nat, C.fastRemaining(total, requested), C.remaining(total, requested), CP.remaining_equiv(total, requested)) : {Nat.add(C.shown(total, requested), _) == total : Nat}
54
+ CP.conserved(total, requested)
55
+
56
+ def Laws.full_prefix_omits_nothing(total):
57
+ %Equal.sym(Nat, C.fastRemaining(total, total), C.remaining(total, total), CP.remaining_equiv(total, total)) : {_ == 0n : Nat}
58
+ CP.full(total)
59
+
60
+ def Laws.cap_idempotent(total, cap):
61
+ %Equal.sym(Nat, C.fastShown(C.fastShown(total, cap), cap), C.shown(C.fastShown(total, cap), cap), CP.shown_equiv(C.fastShown(total, cap), cap)) : {_ == C.fastShown(total, cap) : Nat}
62
+ %Equal.sym(Nat, C.fastShown(total, cap), C.shown(total, cap), CP.shown_equiv(total, cap)) : {C.shown(_, cap) == C.fastShown(total, cap) : Nat}
63
+ %Equal.sym(Nat, C.fastShown(total, cap), C.shown(total, cap), CP.shown_equiv(total, cap)) : {C.shown(C.shown(total, cap), cap) == _ : Nat}
64
+ CP.idempotent(total, cap)
65
+
66
+ def Laws.heat_vector_add_mass(xs, ys):
67
+ match xs ys:
68
+ case Nil{} _:
69
+ {==}
70
+ case x <> tail Nil{}:
71
+ Equal.sym(Nat, Nat.add(H.sum(x <> tail), 0n), H.sum(x <> tail), N.add_zero(H.sum(x <> tail)))
72
+ case x <> xt y <> yt:
73
+ %N.add_shuffle(x, y, H.sum(xt), H.sum(yt)) : {Nat.add(Nat.add(x, y), H.sum(H.add(xt, yt))) == _ : Nat}
74
+ %Laws.heat_vector_add_mass(xt, yt) : {Nat.add(Nat.add(x, y), H.sum(H.add(xt, yt))) == Nat.add(Nat.add(x, y), _) : Nat}
75
+ {==}
76
+
77
+ def Laws.heat_scale_mass(mass, weights):
78
+ match mass:
79
+ case 0n:
80
+ {==}
81
+ case 1n+p:
82
+ %Laws.heat_scale_mass(p, weights) : {H.sum(H.add(weights, H.scale(p, weights))) == Nat.add(H.sum(weights), _) : Nat}
83
+ Laws.heat_vector_add_mass(weights, H.scale(p, weights))
84
+
85
+ def Laws.heat_transport_mass(columns, denominator, normalized):
86
+ match columns:
87
+ case Nil{}:
88
+ {==}
89
+ case H.Source{mass, weights} <> tail:
90
+ (column_norm, tail_norm) = normalized
91
+ %N.mul_add(mass, H.input_mass(tail), 1n+denominator) : {H.sum(H.add(H.scale(mass, weights), H.transport(tail))) == _ : Nat}
92
+ %Equal.cong(Nat, Nat, x => Nat.mul(mass, x), H.sum(weights), 1n+denominator, column_norm) : {H.sum(H.add(H.scale(mass, weights), H.transport(tail))) == Nat.add(_, Nat.mul(H.input_mass(tail), 1n+denominator)) : Nat}
93
+ %Laws.heat_scale_mass(mass, weights) : {H.sum(H.add(H.scale(mass, weights), H.transport(tail))) == Nat.add(_, Nat.mul(H.input_mass(tail), 1n+denominator)) : Nat}
94
+ %Laws.heat_transport_mass(tail, denominator, tail_norm) : {H.sum(H.add(H.scale(mass, weights), H.transport(tail))) == Nat.add(H.sum(H.scale(mass, weights)), _) : Nat}
95
+ Laws.heat_vector_add_mass(H.scale(mass, weights), H.transport(tail))
96
+
97
+ def Laws.heat_singleton_mass(mass):
98
+ %N.mul_one(mass) : {H.sum(H.transport([H.Source{mass, [1n]}])) == _ : Nat}
99
+ %N.add_zero(mass) : {H.sum(H.transport([H.Source{mass, [1n]}])) == Nat.mul(_, 1n) : Nat}
100
+ Laws.heat_transport_mass([H.Source{mass, [1n]}], 0n, ({==}, Unit{}))
101
+
102
+ def Laws.basis_empty_refused(order):
103
+ {==}
104
+
105
+ def Laws.basis_complete_retained(have, order, complete):
106
+ %Equal.sym(Bool, Nat.is_le(1n+have, order), False{}, complete) : {B.choose(_, 1n+have) == B.Done{} : B.Step}
107
+ {==}
108
+
109
+ def Laws.basis_first_order(order):
110
+ match order:
111
+ case 0n:
112
+ {==}
113
+ case 1n+p:
114
+ {==}
115
+
116
+ def Laws.basis_next_exact(have, order, missing):
117
+ %Equal.sym(Bool, Nat.is_le(2n+have, order), True{}, missing) : {B.choose(_, 2n+have) == B.Next{2n+have, 1n+have, have} : B.Step}
118
+ {==}
package/README.md CHANGED
@@ -544,12 +544,22 @@ calls and proof checking are not modeled; Bend 1/HVM syntax is not supported.
544
544
 
545
545
  ```sh
546
546
  bun install
547
- bun run check:fast # typecheck + tests your working tree affects
547
+ bun run check:fast # Bend laws + artifact parity + typecheck + affected tests
548
548
  bun run test:smoke # curated scan-to-render floor, seconds
549
549
  bun run bench # rate–distortion and refresh bench against ../pi-fabric
550
550
  bun run bench tests/fixtures/mini # self-contained smoke run
551
551
  ```
552
552
 
553
+ Development checks require **Bend 2.0.26** (`bend guide`). See [laws, proofs, and
554
+ which tests they can replace](docs/proofs.md). Bend is development-only; the
555
+ extension and published CLI need no Bend installation or generation step.
556
+ Production executes the committed Bend-compiled disclosure, prefix-accounting,
557
+ and heat-basis command kernels. After changing their sources or adapters, run
558
+ `bun run proofs:generate`; `bun run proofs:artifact` checks the receipt without
559
+ Bend. CLI builds check that receipt; publishing also proves and reproduces the
560
+ artifact. The Float64 heat solver still relies on numerical tests, not a proof
561
+ of its approximation or rounding errors.
562
+
553
563
  The [warm-path performance report](docs/performance.md) compares the coverage-complete implementation with the optimized version. `bun run corpus:performance <coverage-work> <before-source> <after-source> [rounds]` runs alternating, isolated comparisons with a shared extraction snapshot, independent Git indexes, and exact graph, focus/dwell/sketch, and overflow-content checks. It does not trade fewer candidates or weaker freshness checks for speed. For Node, run `NODE_OPTIONS='--import tsx' node scripts/performance-corpus.mjs ...`; development dependencies are required.
554
564
 
555
565
  Warm matching derives query terms once and caches normalized symbol names by weak node identity, checking renames before reuse. Focus builds only the heat orders currently needed; dwell appends missing orders without replacing its existing basis. No new kernel or review state is introduced. Independent cold extraction can select different literal-join locations when capture order varies, so this paired benchmark deliberately makes no cold-extraction speedup claim.
@@ -0,0 +1,12 @@
1
+ # Third-party notices
2
+
3
+ ## Bend 2.0.26
4
+
5
+ The generated policy kernel contains Bend's emitted JavaScript trampoline and
6
+ compiled Base primitives from [Bend 2.0.26](https://github.com/bendlang/bend/tree/v2.0.26),
7
+ Copyright 2026 HigherOrderCO, licensed under Apache-2.0. Pi Fovea removes the
8
+ CLI invocations, adds library exports, and tree-shakes/minifies unused runtime
9
+ code using the bridge pattern developed in Pi Fabric.
10
+
11
+ The complete license is distributed at
12
+ [docs/licenses/bend-apache-2.0.txt](docs/licenses/bend-apache-2.0.txt).