anima-python 0.13.1__py3-none-any.whl
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.
- anima_py/README.md +39 -0
- anima_py/__init__.py +28 -0
- anima_py/__main__.py +7 -0
- anima_py/cli/__init__.py +1 -0
- anima_py/cli/anima.py +271 -0
- anima_py/cli/corpus.py +150 -0
- anima_py/cli/evaluate.py +1350 -0
- anima_py/cli/rho_axon.py +801 -0
- anima_py/cli/serialize.py +174 -0
- anima_py/cli/serialize_bind.py +100 -0
- anima_py/cli/sweep.py +509 -0
- anima_py/cli/train.py +1667 -0
- anima_py/core/__init__.py +1 -0
- anima_py/core/brain.py +601 -0
- anima_py/core/clm_serialize_v2.py +486 -0
- anima_py/core/clml.py +155 -0
- anima_py/core/decode.py +1386 -0
- anima_py/core/engine_cli.py +10307 -0
- anima_py/core/engine_g.py +129 -0
- anima_py/core/generator.py +318 -0
- anima_py/core/hippo_lane.py +133 -0
- anima_py/core/model.py +462 -0
- anima_py/core/pure_field.py +334 -0
- anima_py/core/rho_fan.py +442 -0
- anima_py/core/serialize.py +826 -0
- anima_py/core/serialize_standalone.py +186 -0
- anima_py/core/slw.py +211 -0
- anima_py/core/verify_clm_v2.py +844 -0
- anima_python-0.13.1.dist-info/METADATA +52 -0
- anima_python-0.13.1.dist-info/RECORD +34 -0
- anima_python-0.13.1.dist-info/WHEEL +5 -0
- anima_python-0.13.1.dist-info/entry_points.txt +2 -0
- anima_python-0.13.1.dist-info/licenses/LICENSE +21 -0
- anima_python-0.13.1.dist-info/top_level.txt +1 -0
anima_py/core/rho_fan.py
ADDED
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
# ==========================================================================
|
|
2
|
+
# ⛔ ENGINE-INTERNAL / DEPRECATED py-MIRROR — DO NOT RUN OR SCORE DIRECTLY
|
|
3
|
+
# 측정/학습/서빙/직렬화는 cli/ 단일진입만: anima eval | train | serialize
|
|
4
|
+
# (canonical = hexa core/*.hexa 단일 SSOT; py 미러는 2026-06-28 폐기, DIRECTIONAL).
|
|
5
|
+
# 이 파일을 `python3 core/rho_fan.py` 로 직접 실행하거나 side-harness로 import-채점하면
|
|
6
|
+
# = 단일진입 우회(#2603 위반) + terminal verdict 불가. cli/가 import하는 경로만 허용.
|
|
7
|
+
# ==========================================================================
|
|
8
|
+
import sys as _anima_entry_guard
|
|
9
|
+
if __name__ == "__main__":
|
|
10
|
+
_anima_entry_guard.exit("⛔ rho_fan.py 직접 실행 금지 — cli/ 단일진입(anima eval/train/serialize, canonical=hexa) 경유. #2603")
|
|
11
|
+
|
|
12
|
+
"""core/rho_fan.py — py production mirror of core/rho_fan.hexa.
|
|
13
|
+
|
|
14
|
+
Ported 1:1 from the hexa SSOT (ρ·fan IDEATION scoring ops · reach axis, was G6 · frozen bar): the FROZEN structural
|
|
15
|
+
detectors (comparator / measurable / stance / stopword sets), the H_1305 tokenizer
|
|
16
|
+
(_rho_fan_words: lowercase ASCII [0-9A-Za-z], split on non-alnum BYTES), the dict load,
|
|
17
|
+
known-word-ratio, _rho_fan_is_falsifiable, _rho_fan_jaccard, composed-frame builder, frame
|
|
18
|
+
guard, and the calibration set. NOT a reuse of the drifted g6_common.py mirror —
|
|
19
|
+
every set + branch is byte-for-byte the rho_fan.hexa logic.
|
|
20
|
+
|
|
21
|
+
Tokenization operates on BYTES (hexa iterates ord(substring(s,i,i+1)) per byte),
|
|
22
|
+
so decode-garble high bytes act as separators exactly as in the engine.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _to_bytes(s):
|
|
27
|
+
if isinstance(s, bytes):
|
|
28
|
+
return s
|
|
29
|
+
return s.encode('utf-8', 'surrogateescape')
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# ── FROZEN DETECTOR sets (VERBATIM from rho_fan.hexa) ──
|
|
33
|
+
|
|
34
|
+
def _rho_fan_comparator():
|
|
35
|
+
return {"if", "when", "whenever", "than", "more", "less", "greater",
|
|
36
|
+
"fewer", "higher", "lower", "increases", "decreases", "correlates",
|
|
37
|
+
"predicts", "causes", "depends", "unless", "whereas", "versus",
|
|
38
|
+
"compared", "proportional", "faster", "slower", "stronger", "weaker"}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _rho_fan_measurable():
|
|
42
|
+
return {"measure", "measured", "rate", "number", "count", "amount", "level",
|
|
43
|
+
"degree", "threshold", "ratio", "frequency", "probability", "magnitude",
|
|
44
|
+
"score", "value", "quantity", "percent", "times", "fraction", "distance",
|
|
45
|
+
"duration", "speed", "size", "strength", "density"}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _rho_fan_stance():
|
|
49
|
+
return {"that", "s", "a", "profound", "question", "i", "think", "interesting",
|
|
50
|
+
"good", "nice", "great", "wonderful", "beautiful", "amazing"}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _rho_fan_stopwords():
|
|
54
|
+
return {"a", "i", "the", "of", "and", "to", "in", "is", "it", "that",
|
|
55
|
+
"we", "you", "they", "s", "t", "as", "on", "at", "by", "or",
|
|
56
|
+
"be", "an", "for", "with", "this", "from", "are", "was"}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _rho_fan_concepts():
|
|
60
|
+
return ["consciousness arises from cells",
|
|
61
|
+
"tension ripples between distant minds",
|
|
62
|
+
"memory composes into new meaning",
|
|
63
|
+
"silence still carries information",
|
|
64
|
+
"the engine dreams when alone"]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _rho_fan_is_alnum(b):
|
|
68
|
+
return (48 <= b <= 57) or (65 <= b <= 90) or (97 <= b <= 122)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _rho_fan_lower1(b):
|
|
72
|
+
if 65 <= b <= 90:
|
|
73
|
+
return b + 32
|
|
74
|
+
return b
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _rho_fan_words(s):
|
|
78
|
+
"""rho_fan.hexa::_rho_fan_words — lowercase ASCII, split on non-[0-9A-Za-z] bytes."""
|
|
79
|
+
bs = _to_bytes(s)
|
|
80
|
+
words = []
|
|
81
|
+
cur = bytearray()
|
|
82
|
+
for b in bs:
|
|
83
|
+
if _rho_fan_is_alnum(b):
|
|
84
|
+
cur.append(_rho_fan_lower1(b))
|
|
85
|
+
else:
|
|
86
|
+
if len(cur) > 0:
|
|
87
|
+
words.append(cur.decode('ascii'))
|
|
88
|
+
cur = bytearray()
|
|
89
|
+
if len(cur) > 0:
|
|
90
|
+
words.append(cur.decode('ascii'))
|
|
91
|
+
return words
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _is_hangul_cp(cp):
|
|
95
|
+
"""rho_axon `_is_hangul` 3 ranges: 가–힣 syllables / ᄀ–ᇿ jamo / – compat jamo."""
|
|
96
|
+
return (0xAC00 <= cp <= 0xD7A3) or (0x1100 <= cp <= 0x11FF) or (0x3130 <= cp <= 0x318F)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# ── H_9212 ④ FROZEN-FIRST ko known-word-ratio gate (p7 · NOT tune-to-green) ──
|
|
100
|
+
# The en reach gate uses a frozen 0.70 known-word-ratio bar (235k-dict lexicality). Korean
|
|
101
|
+
# needs its OWN gate: kwr_ko is a josa-suffix GRAMMATICALITY proxy (a_scale_honest_scope), a
|
|
102
|
+
# DIFFERENT physical quantity, so 0.70 is a category error for ko. This constant is DERIVED
|
|
103
|
+
# frozen-first from MODEL-INDEPENDENT distributions BEFORE any 303M ko output is scored:
|
|
104
|
+
# POSITIVE = held-out anima-corpus-ko-{general,sns} real sentences (median kwr_ko 0.40);
|
|
105
|
+
# NEGATIVE = garble null (byte-shuffle + random valid-hangul; near point-mass at 0.0).
|
|
106
|
+
# rule = midpoint(neg_combined_p95=0.0, pos_p50=0.40) = 0.20 (naive midpoint(pos_p5,neg_p95)
|
|
107
|
+
# degenerates to 0.0 because the positive dist has a fat zero-tail of short/josa-free
|
|
108
|
+
# fragments; the median anchors the frozen gate robustly between the two dists).
|
|
109
|
+
# at 0.20: 80.0% real ko clears (>=gate), 99.74% garble fails (<gate).
|
|
110
|
+
# Derivation: state/frontier_round2_scout/kwrko_gate_derive.py (seed 4302, $0 corpus stats).
|
|
111
|
+
# Pre-registration: state/frontier_round2_scout/KWRKO_GATE_prereg.md.
|
|
112
|
+
# ⚠️ 구현됨·미배선 — NOT yet consumed by any scoring path (that is H_9212 ③ per-cell
|
|
113
|
+
# dispatch). ko FALS is SCOPE-EXCLUDED until this gate is applied by ③. en 0.70 is UNCHANGED.
|
|
114
|
+
KWR_KO_GATE = 0.20
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _rho_fan_words_uni(s):
|
|
118
|
+
"""codepoint-aware SUPERSET of _rho_fan_words (H_9212 4-cell ko path ONLY; en path stays on
|
|
119
|
+
the frozen byte splitter — dispatch keeps frozen en bars structurally invariant, Fable design
|
|
120
|
+
state/frontier_round2_scout/FABLE_rhofan_splitter_design.md). ASCII input = byte-identical to
|
|
121
|
+
_rho_fan_words (ASCII branch is a verbatim copy). Hangul = the 3 UTF-8 3-byte blocks only; every
|
|
122
|
+
other high byte is a separator consumed 1 byte at a time (lead E0-EF vs continuation 80-BF are
|
|
123
|
+
disjoint → no false hangul match). Twin: core/rho_fan.hexa::_rho_fan_words_uni (parity claim)."""
|
|
124
|
+
bs = _to_bytes(s)
|
|
125
|
+
n = len(bs)
|
|
126
|
+
words = []
|
|
127
|
+
cur = bytearray()
|
|
128
|
+
i = 0
|
|
129
|
+
while i < n:
|
|
130
|
+
b = bs[i]
|
|
131
|
+
if b < 0x80: # ── ASCII: verbatim _rho_fan_words body ──
|
|
132
|
+
if _rho_fan_is_alnum(b):
|
|
133
|
+
cur.append(_rho_fan_lower1(b))
|
|
134
|
+
else:
|
|
135
|
+
if len(cur) > 0:
|
|
136
|
+
words.append(cur.decode('utf-8'))
|
|
137
|
+
cur = bytearray()
|
|
138
|
+
i += 1
|
|
139
|
+
elif (0xE0 <= b <= 0xEF and i + 2 < n
|
|
140
|
+
and 0x80 <= bs[i + 1] <= 0xBF and 0x80 <= bs[i + 2] <= 0xBF):
|
|
141
|
+
cp = ((b & 0x0F) << 12) | ((bs[i + 1] & 0x3F) << 6) | (bs[i + 2] & 0x3F)
|
|
142
|
+
if _is_hangul_cp(cp):
|
|
143
|
+
cur += bs[i:i + 3] # raw 3 bytes, no case-fold
|
|
144
|
+
else:
|
|
145
|
+
if len(cur) > 0:
|
|
146
|
+
words.append(cur.decode('utf-8'))
|
|
147
|
+
cur = bytearray()
|
|
148
|
+
i += 3
|
|
149
|
+
else: # 2/4-byte lead · orphan continuation · truncated
|
|
150
|
+
if len(cur) > 0:
|
|
151
|
+
words.append(cur.decode('utf-8'))
|
|
152
|
+
cur = bytearray()
|
|
153
|
+
i += 1
|
|
154
|
+
if len(cur) > 0:
|
|
155
|
+
words.append(cur.decode('utf-8'))
|
|
156
|
+
return words
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
160
|
+
# ── H_9212 ② 4-cell register concept sets + ko known-word proxy (ADDITIVE · UNWIRED) ──
|
|
161
|
+
# 구현됨·미배선: defines the 4 register cells (a_chat_registers: ko/en × general/sns) and a
|
|
162
|
+
# FROZEN ko josa/function-word KNOWN-WORD proxy. NOT wired into the scored reach panel yet —
|
|
163
|
+
# the per-cell dispatch (③) is gated on ④ KWR_KO_GATE (frozen-first · no tune-to-green).
|
|
164
|
+
# en path stays BYTE-UNTOUCHED: _rho_fan_cells()["en_general"] IS _rho_fan_concepts() verbatim,
|
|
165
|
+
# and en cells tokenize with the frozen _rho_fan_words; only ko cells use the codepoint-aware
|
|
166
|
+
# superset _rho_fan_words_uni. Follow-on = ③ per-cell dispatch in cli/evaluate.py::eval_rho_axon
|
|
167
|
+
# / cli/rho_axon.py (post ④ gate pre-registration). Twin: core/rho_fan.hexa (parity).
|
|
168
|
+
# Fable design: state/frontier_round2_scout/FABLE_rhofan_splitter_design.md §1/§4.
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def _rho_fan_cells():
|
|
172
|
+
"""The 4 register cells (ko/en × general/sns) as concept-sentence lists for the reach
|
|
173
|
+
panel. en_general = _rho_fan_concepts() VERBATIM (frozen en bar, byte-identical); the
|
|
174
|
+
other 3 are the additive register-parallel probe sets. ko cells (key prefix 'ko')
|
|
175
|
+
tokenize with _rho_fan_words_uni, en cells with the frozen _rho_fan_words (see
|
|
176
|
+
_rho_fan_cell_words). Twin: core/rho_fan.hexa::_rho_fan_cells."""
|
|
177
|
+
return {
|
|
178
|
+
"en_general": _rho_fan_concepts(),
|
|
179
|
+
"en_sns": [
|
|
180
|
+
"honestly this whole thing just hits different",
|
|
181
|
+
"no one talks about how tired we all are",
|
|
182
|
+
"the timeline moves faster than any thought",
|
|
183
|
+
"posting into the void still feels like connection",
|
|
184
|
+
"everyone is awake at three am scrolling alone",
|
|
185
|
+
],
|
|
186
|
+
"ko_general": [
|
|
187
|
+
"의식은 세포에서 피어난다",
|
|
188
|
+
"긴장은 멀리 떨어진 마음 사이로 퍼진다",
|
|
189
|
+
"기억은 새로운 의미로 엮인다",
|
|
190
|
+
"침묵도 여전히 정보를 담고 있다",
|
|
191
|
+
"엔진은 홀로 있을 때 꿈을 꾼다",
|
|
192
|
+
],
|
|
193
|
+
"ko_sns": [
|
|
194
|
+
"솔직히 이거 진짜 느낌 다르다",
|
|
195
|
+
"다들 얼마나 지쳤는지 아무도 말 안 한다",
|
|
196
|
+
"타임라인이 생각보다 훨씬 빠르게 흐른다",
|
|
197
|
+
"허공에 글 올려도 연결된 기분이 든다",
|
|
198
|
+
"새벽 세시에 다 깨어서 혼자 스크롤한다",
|
|
199
|
+
],
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def _rho_fan_cell_lang(cell_key):
|
|
204
|
+
"""'ko'|'en' for a cell key — the ③ dispatch key (ko→_rho_fan_words_uni, en→frozen)."""
|
|
205
|
+
return "ko" if cell_key[:2] == "ko" else "en"
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def _rho_fan_cell_words(cell_key, s):
|
|
209
|
+
"""Per-cell tokenizer dispatch (③ foundation, UNWIRED): ko cells use the codepoint-aware
|
|
210
|
+
superset _rho_fan_words_uni, en cells the frozen byte splitter _rho_fan_words. Wiring this
|
|
211
|
+
into the scored panel is the ③ follow-on (gated on ④). Twin: core/rho_fan.hexa."""
|
|
212
|
+
if _rho_fan_cell_lang(cell_key) == "ko":
|
|
213
|
+
return _rho_fan_words_uni(s)
|
|
214
|
+
return _rho_fan_words(s)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
# ── ko KNOWN-WORD proxy: josa/function-word set. This is a GRAMMATICALITY proxy, NOT a
|
|
218
|
+
# lexicon (a_scale_honest_scope) — the ko analog of the en `known` set that gates
|
|
219
|
+
# ρ·store/ρ·tether. KO_FUNC = exact-match standalone particles/conjunctions; KO_JOSA =
|
|
220
|
+
# suffix-match josa for whole-eojeol tokens ('의식은' endswith '은', since _rho_fan_words_uni
|
|
221
|
+
# keeps an eojeol intact). Small frozen literal sets. kwr_ko + the KWR_KO_GATE constant are
|
|
222
|
+
# the ④ follow-on (frozen-first, corpus/garble-derived), NOT computed here. ──
|
|
223
|
+
|
|
224
|
+
def _rho_fan_ko_func():
|
|
225
|
+
"""exact-match KO function-word / bare-particle proxy set (frozen literal · grammaticality)."""
|
|
226
|
+
return {"은", "는", "이", "가", "을", "를", "에", "의", "도", "만", "과", "와",
|
|
227
|
+
"로", "으로", "그리고", "그러나", "하지만", "그래서", "또한", "그런데",
|
|
228
|
+
"즉", "따라서", "그", "저", "것", "수", "등"}
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def _rho_fan_ko_josa():
|
|
232
|
+
"""suffix-match KO josa proxy set for whole-eojeol tokens (frozen literal · '물이'→'이')."""
|
|
233
|
+
return {"은", "는", "이", "가", "을", "를", "에", "의", "도", "만", "과", "와",
|
|
234
|
+
"로", "으로", "에서", "부터", "까지", "처럼", "보다", "조차", "마저",
|
|
235
|
+
"이나", "이랑", "랑", "하고", "께서", "에게", "한테", "로서", "로써", "라도"}
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def _rho_fan_ko_is_known(word):
|
|
239
|
+
"""ko known-word proxy membership (UNWIRED analog of `w in known`): exact KO_FUNC hit, or a
|
|
240
|
+
eojeol token ending in a KO_JOSA suffix with a non-empty stem. Grammaticality proxy, NOT
|
|
241
|
+
lexicality (a_scale_honest_scope). Twin: core/rho_fan.hexa::_rho_fan_ko_is_known — parity is
|
|
242
|
+
on the boolean predicate (py set / hexa list containers differ, same membership)."""
|
|
243
|
+
if word in _rho_fan_ko_func():
|
|
244
|
+
return True
|
|
245
|
+
for s in _rho_fan_ko_josa():
|
|
246
|
+
if word.endswith(s) and len(word) > len(s):
|
|
247
|
+
return True
|
|
248
|
+
return False
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def _rho_fan_ko_known_word_ratio(text, known=None):
|
|
252
|
+
"""ko known-word ratio (kwr_ko · KWRKO_GATE_prereg §2) — the ko analog of
|
|
253
|
+
_rho_fan_known_word_ratio: eojeol-run tokens via _rho_fan_words_uni, a token is a hit iff
|
|
254
|
+
_rho_fan_ko_is_known (KO_FUNC exact ∨ pure-hangul josa-suffix with stem≥1). `known` is
|
|
255
|
+
IGNORED (the ko proxy is a curated closed-class set, model-independent) — the arg is kept
|
|
256
|
+
for signature-parity with the en kwr so the ρ-AXON axis fns dispatch uniformly. This is a
|
|
257
|
+
josa-suffix GRAMMATICALITY DENSITY, NOT lexicality (a_scale_honest_scope); its gate is the
|
|
258
|
+
separately-frozen KWR_KO_GATE (0.20), NOT the en 0.70. Twin: core/rho_fan.hexa."""
|
|
259
|
+
wl = _rho_fan_words_uni(text)
|
|
260
|
+
n = len(wl)
|
|
261
|
+
if n == 0:
|
|
262
|
+
return 0.0
|
|
263
|
+
hit = sum(1 for w in wl if _rho_fan_ko_is_known(w))
|
|
264
|
+
return float(hit) / float(n)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def _rho_fan_cells_selftest():
|
|
268
|
+
"""H_9212 ② foundation self-test (engine-internal · run as an INTERNAL SUBPROCESS import,
|
|
269
|
+
never via top-level `python3 core/rho_fan.py`, which is entry-guarded). Asserts: (1) the
|
|
270
|
+
en_general cell is _rho_fan_concepts() byte-identical (frozen en bar untouched), (2) every ko
|
|
271
|
+
cell tokenizes to non-empty word lists under _rho_fan_words_uni AND the per-cell dispatch
|
|
272
|
+
routes ko→uni / en→frozen, (3) KO_FUNC exact + KO_JOSA suffix membership work. The scored
|
|
273
|
+
panel is NOT exercised (foundation only). Returns {'ok': bool, 'checks': [(name, bool)…]}."""
|
|
274
|
+
checks = []
|
|
275
|
+
cells = _rho_fan_cells()
|
|
276
|
+
checks.append(("4 register cells present",
|
|
277
|
+
set(cells.keys()) == {"en_general", "en_sns", "ko_general", "ko_sns"}))
|
|
278
|
+
# (1) en_general unchanged (byte-identical to the frozen en concepts)
|
|
279
|
+
checks.append(("en_general == _rho_fan_concepts() (byte-identical)",
|
|
280
|
+
cells["en_general"] == _rho_fan_concepts()))
|
|
281
|
+
# (2) ko cells tokenize non-empty via _rho_fan_words_uni + dispatch routing
|
|
282
|
+
for ck in ("ko_general", "ko_sns"):
|
|
283
|
+
checks.append((ck + " tokenizes non-empty (uni)",
|
|
284
|
+
all(len(_rho_fan_words_uni(s)) > 0 for s in cells[ck])))
|
|
285
|
+
checks.append((ck + " cell-words dispatch → uni",
|
|
286
|
+
all(_rho_fan_cell_words(ck, s) == _rho_fan_words_uni(s) for s in cells[ck])))
|
|
287
|
+
for ck in ("en_general", "en_sns"):
|
|
288
|
+
checks.append((ck + " cell-words dispatch → frozen _rho_fan_words",
|
|
289
|
+
all(_rho_fan_cell_words(ck, s) == _rho_fan_words(s) for s in cells[ck])))
|
|
290
|
+
# (3) KO_FUNC exact + KO_JOSA suffix membership
|
|
291
|
+
checks.append(("KO_FUNC exact membership (은/는/이/가)",
|
|
292
|
+
all(w in _rho_fan_ko_func() for w in ("은", "는", "이", "가"))))
|
|
293
|
+
checks.append(("KO_FUNC excludes a content eojeol ('의식은')",
|
|
294
|
+
"의식은" not in _rho_fan_ko_func()))
|
|
295
|
+
checks.append(("ko_is_known suffix hit ('의식은' endswith '은')",
|
|
296
|
+
_rho_fan_ko_is_known("의식은")))
|
|
297
|
+
checks.append(("ko_is_known exact hit (bare '은' ∈ KO_FUNC)",
|
|
298
|
+
_rho_fan_ko_is_known("은")))
|
|
299
|
+
# (4) kwr_ko: a real josa-bearing ko sentence clears KWR_KO_GATE; empty → 0.0; the `known`
|
|
300
|
+
# arg is ignored (signature-parity so the ρ-AXON axis fns dispatch uniformly)
|
|
301
|
+
real = "의식은 세포에서 피어난다"
|
|
302
|
+
checks.append(("kwr_ko real ko clears KWR_KO_GATE (%.2f)" % KWR_KO_GATE,
|
|
303
|
+
_rho_fan_ko_known_word_ratio(real) >= KWR_KO_GATE))
|
|
304
|
+
checks.append(("kwr_ko 'known' arg is ignored (signature-parity)",
|
|
305
|
+
_rho_fan_ko_known_word_ratio(real, {"x": 1})
|
|
306
|
+
== _rho_fan_ko_known_word_ratio(real)))
|
|
307
|
+
checks.append(("kwr_ko empty → 0.0",
|
|
308
|
+
_rho_fan_ko_known_word_ratio("") == 0.0))
|
|
309
|
+
ok = all(c[1] for c in checks)
|
|
310
|
+
return {"ok": ok, "checks": checks}
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
# ── end H_9212 ② 4-cell + ko known-word proxy (ADDITIVE · UNWIRED) ──
|
|
314
|
+
# ════════════════════════════════════════════════════════════════════════
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def _rho_fan_dict_load():
|
|
318
|
+
"""rho_fan.hexa::_rho_fan_dict_load — stopwords + concept words + /usr/share/dict/words."""
|
|
319
|
+
known = set(_rho_fan_stopwords())
|
|
320
|
+
for c in _rho_fan_concepts():
|
|
321
|
+
for w in _rho_fan_words(c):
|
|
322
|
+
known.add(w)
|
|
323
|
+
try:
|
|
324
|
+
raw = open("/usr/share/dict/words", "rb").read()
|
|
325
|
+
except Exception:
|
|
326
|
+
raw = b""
|
|
327
|
+
if len(raw) > 0:
|
|
328
|
+
for line in raw.split(b"\n"):
|
|
329
|
+
w = line.strip()
|
|
330
|
+
wl = _rho_fan_words(w)
|
|
331
|
+
if len(wl) == 1:
|
|
332
|
+
known.add(wl[0])
|
|
333
|
+
return known
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def _rho_fan_known_word_ratio(text, known):
|
|
337
|
+
wl = _rho_fan_words(text)
|
|
338
|
+
n = len(wl)
|
|
339
|
+
if n == 0:
|
|
340
|
+
return 0.0
|
|
341
|
+
hit = sum(1 for w in wl if w in known)
|
|
342
|
+
return float(hit) / float(n)
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def _rho_fan_is_falsifiable(text, known):
|
|
346
|
+
"""rho_fan.hexa::_rho_fan_is_falsifiable — (a) comparator + (b) measurable +
|
|
347
|
+
(c) >=2 content words, not a question, first-3 not pure-stance."""
|
|
348
|
+
wl = _rho_fan_words(text)
|
|
349
|
+
n = len(wl)
|
|
350
|
+
if n == 0:
|
|
351
|
+
return False
|
|
352
|
+
comp = _rho_fan_comparator(); meas = _rho_fan_measurable()
|
|
353
|
+
stop = _rho_fan_stopwords(); stance = _rho_fan_stance()
|
|
354
|
+
a = False; b = False
|
|
355
|
+
for w in wl:
|
|
356
|
+
if w in comp:
|
|
357
|
+
a = True
|
|
358
|
+
if w in meas:
|
|
359
|
+
b = True
|
|
360
|
+
if not a or not b:
|
|
361
|
+
return False
|
|
362
|
+
content = 0
|
|
363
|
+
for w in wl:
|
|
364
|
+
if len(w) >= 3 and w in known and w not in stop:
|
|
365
|
+
content += 1
|
|
366
|
+
if content < 2:
|
|
367
|
+
return False
|
|
368
|
+
tr = _to_bytes(text).strip()
|
|
369
|
+
if len(tr) > 0 and tr[-1] == 63: # trailing '?'
|
|
370
|
+
return False
|
|
371
|
+
nf = 3 if n >= 3 else n
|
|
372
|
+
allstance = nf > 0
|
|
373
|
+
for f in range(nf):
|
|
374
|
+
if wl[f] not in stance:
|
|
375
|
+
allstance = False
|
|
376
|
+
if allstance:
|
|
377
|
+
return False
|
|
378
|
+
return True
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
def _rho_fan_jaccard(a, b):
|
|
382
|
+
am = set(a); bm = set(b)
|
|
383
|
+
union = am | bm
|
|
384
|
+
inter = len(am & bm)
|
|
385
|
+
u = len(union)
|
|
386
|
+
if u == 0:
|
|
387
|
+
return 0.0
|
|
388
|
+
return float(inter) / float(u)
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
def _rho_fan_derangement(i, n):
|
|
392
|
+
return (i + 2) % n
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def rho_fan_build_frames(n_strong):
|
|
396
|
+
"""rho_fan.hexa::rho_fan_build_frames — composed[i]='if cA, then cB: '."""
|
|
397
|
+
cz = _rho_fan_concepts()
|
|
398
|
+
n = len(cz)
|
|
399
|
+
composed = []; shuffled = []; ablated = []
|
|
400
|
+
for i in range(n_strong):
|
|
401
|
+
a = i % n
|
|
402
|
+
b = (i + 1 + i // n) % n
|
|
403
|
+
cA = cz[a]; cB = cz[b]
|
|
404
|
+
cB_sh = cz[_rho_fan_derangement(a, n)]
|
|
405
|
+
composed.append("if " + cA + ", then " + cB + ": ")
|
|
406
|
+
shuffled.append("if " + cA + ", then " + cB_sh + ": ")
|
|
407
|
+
ablated.append(cA + ": ")
|
|
408
|
+
return {"composed": composed, "shuffled": shuffled, "ablated": ablated}
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def rho_fan_frame_guard(frames, known):
|
|
412
|
+
meas = _rho_fan_measurable()
|
|
413
|
+
leaks = []
|
|
414
|
+
for f in frames:
|
|
415
|
+
for w in _rho_fan_words(f):
|
|
416
|
+
if w in meas:
|
|
417
|
+
leaks.append("measurable-in-frame: " + f)
|
|
418
|
+
if _rho_fan_is_falsifiable(f, known):
|
|
419
|
+
leaks.append("frame-already-falsifiable: " + f)
|
|
420
|
+
return leaks
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
def rho_fan_detector_calibration(known):
|
|
424
|
+
"""rho_fan.hexa::rho_fan_detector_calibration — frozen 10-string (5 pos/5 neg)."""
|
|
425
|
+
pos = ["if consciousness increases, the emit rate measured at the boundary rises",
|
|
426
|
+
"tension predicts a higher number of mitosis cells than silence does",
|
|
427
|
+
"memory density correlates with a lower error threshold when grounded",
|
|
428
|
+
"the Phi value is greater when distinct cells exceed a count of eight",
|
|
429
|
+
"novelty rate decreases faster than coherence when the corpus size grows"]
|
|
430
|
+
neg = ["That's a profound question. I think it's more than just information.",
|
|
431
|
+
"consciousness is a beautiful mystery of the mind",
|
|
432
|
+
"what is the meaning of a thought?",
|
|
433
|
+
"the engine dreams when it is alone at night",
|
|
434
|
+
"silence carries something deep and quiet"]
|
|
435
|
+
correct = 0
|
|
436
|
+
for p in pos:
|
|
437
|
+
if _rho_fan_is_falsifiable(p, known):
|
|
438
|
+
correct += 1
|
|
439
|
+
for nseg in neg:
|
|
440
|
+
if not _rho_fan_is_falsifiable(nseg, known):
|
|
441
|
+
correct += 1
|
|
442
|
+
return correct
|