betterwithage commited on
Commit
3e6e8a7
·
verified ·
1 Parent(s): 2949739

code(atelier): lambda_gate.py from szl-khipu — not a 1.5B retrain

Browse files
Files changed (1) hide show
  1. lambda_gate.py +159 -0
lambda_gate.py ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright 2026 SZL Holdings
3
+ """YUYAY Λ-gate: weighted geometric mean, fail-closed, advisory only.
4
+
5
+ Uniqueness of Λ is Conjecture 1 OPEN. proven_trust is False.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Any, Sequence
11
+
12
+ import numpy as np
13
+
14
+ from .doctrine import CONJECTURE_1, YUYAY_AXES, advisory
15
+
16
+ ArrayLike = Sequence[float] | np.ndarray
17
+
18
+
19
+ class LambdaEval(dict[str, Any]):
20
+ """Dict with attribute access so ev.value and ev['value'] both work."""
21
+
22
+ def __getattr__(self, name: str) -> Any:
23
+ try:
24
+ return self[name]
25
+ except KeyError as exc:
26
+ raise AttributeError(name) from exc
27
+
28
+
29
+ def _as_vec(x: ArrayLike) -> np.ndarray:
30
+ return np.asarray(x, dtype=np.float64).ravel()
31
+
32
+
33
+ def wgm(x: ArrayLike, w: ArrayLike) -> float:
34
+ """Weighted geometric mean. Any 0 or non-finite axis → 0. Weights must sum to 1."""
35
+ xv = _as_vec(x)
36
+ wv = _as_vec(w)
37
+ if xv.size != wv.size or xv.size == 0:
38
+ return 0.0
39
+ if not np.isfinite(xv).all() or not np.isfinite(wv).all():
40
+ return 0.0
41
+ if np.any(xv <= 0.0) or np.any(wv < 0.0):
42
+ return 0.0
43
+ if abs(float(wv.sum()) - 1.0) >= 1e-9:
44
+ return 0.0
45
+ log = float(np.dot(wv, np.log(xv)))
46
+ v = float(np.exp(log))
47
+ return v if np.isfinite(v) else 0.0
48
+
49
+
50
+ def yuyay_weights() -> np.ndarray:
51
+ n = len(YUYAY_AXES)
52
+ return np.full(n, 1.0 / n, dtype=np.float64)
53
+
54
+
55
+ def uniform_weights(n: int) -> np.ndarray:
56
+ if n <= 0:
57
+ return np.zeros(0, dtype=np.float64)
58
+ return np.full(n, 1.0 / n, dtype=np.float64)
59
+
60
+
61
+ def check_a1(x: ArrayLike, w: ArrayLike) -> bool:
62
+ """A1 monotone: raising one axis cannot decrease Λ."""
63
+ xv = _as_vec(x)
64
+ wv = _as_vec(w)
65
+ base = wgm(xv, wv)
66
+ for i in range(xv.size):
67
+ if xv[i] >= 1.0:
68
+ continue
69
+ y = xv.copy()
70
+ y[i] = min(1.0, float(xv[i]) + 0.05)
71
+ if wgm(y, wv) + 1e-12 < base:
72
+ return False
73
+ return True
74
+
75
+
76
+ def check_a2(x: ArrayLike, w: ArrayLike, c: float = 0.5) -> bool:
77
+ """A2 homogeneous: Λ(c x) = c Λ(x) for c in (0, 1]."""
78
+ xv = _as_vec(x)
79
+ wv = _as_vec(w)
80
+ lhs = wgm(xv * c, wv)
81
+ rhs = c * wgm(xv, wv)
82
+ return abs(lhs - rhs) <= 1e-9 * max(1.0, abs(rhs))
83
+
84
+
85
+ def check_a3(w: ArrayLike, c: float = 0.7) -> bool:
86
+ """A3 Egyptian-exact: Λ(c, …, c) = c."""
87
+ wv = _as_vec(w)
88
+ xv = np.full(wv.size, c, dtype=np.float64)
89
+ return abs(wgm(xv, wv) - c) <= 1e-9
90
+
91
+
92
+ def check_a4(x: ArrayLike, w: ArrayLike) -> bool:
93
+ """A4 bounded by max."""
94
+ xv = _as_vec(x)
95
+ if xv.size == 0:
96
+ return True
97
+ v = wgm(xv, w)
98
+ return v <= float(np.max(xv)) + 1e-12
99
+
100
+
101
+ def check_a5(x: ArrayLike, w: ArrayLike) -> bool:
102
+ """A5 permutation invariance."""
103
+ xv = _as_vec(x)
104
+ wv = _as_vec(w)
105
+ if xv.size < 2:
106
+ return True
107
+ perm = np.arange(xv.size)[::-1]
108
+ return abs(wgm(xv[perm], wv[perm]) - wgm(xv, wv)) <= 1e-9
109
+
110
+
111
+ def evaluate_lambda(x: ArrayLike, w: ArrayLike | None = None) -> LambdaEval:
112
+ xv = _as_vec(x)
113
+ if w is None:
114
+ wv = yuyay_weights() if xv.size == len(YUYAY_AXES) else uniform_weights(int(xv.size))
115
+ else:
116
+ wv = _as_vec(w)
117
+ value = wgm(xv, wv)
118
+ axioms = [
119
+ {"id": "A1", "ok": check_a1(xv, wv), "detail": "monotone"},
120
+ {"id": "A2", "ok": check_a2(xv, wv), "detail": "homogeneous"},
121
+ {"id": "A3", "ok": check_a3(wv), "detail": "Egyptian-exact"},
122
+ {"id": "A4", "ok": check_a4(xv, wv), "detail": "bounded-by-max"},
123
+ {"id": "A5", "ok": check_a5(xv, wv), "detail": "permutation-invariant"},
124
+ ]
125
+ failed = next((a for a in axioms if not a["ok"]), None)
126
+ blocked = value == 0.0 or failed is not None
127
+ if blocked:
128
+ reason = (
129
+ "zero-routed or non-finite axis"
130
+ if value == 0.0
131
+ else f"axiom {failed['id']} failed" # type: ignore[index]
132
+ )
133
+ else:
134
+ reason = "advisory pass — uniqueness remains Conjecture 1 OPEN"
135
+ return LambdaEval(value=value, blocked=blocked, reason=reason, axioms=axioms)
136
+
137
+
138
+ def lambda_gate(
139
+ axes: ArrayLike,
140
+ threshold: float = 0.5,
141
+ ) -> LambdaEval:
142
+ """Advisory conjunctive gate. Never claims proven uniqueness."""
143
+ ev = evaluate_lambda(axes)
144
+ score = float(ev["value"])
145
+ passed = (not bool(ev["blocked"])) and score >= threshold
146
+ return LambdaEval(
147
+ score=score,
148
+ passed=passed,
149
+ threshold=float(threshold),
150
+ advisory=True,
151
+ reason=ev["reason"],
152
+ conjecture=CONJECTURE_1,
153
+ proven_trust=False,
154
+ value=score,
155
+ blocked=not passed,
156
+ )
157
+
158
+
159
+ assert advisory is True