@furongjun1999/dsh-memory 0.4.8 → 0.4.10
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 +54 -26
- package/codebuddy/CODEBUDDY.md +196 -195
- package/codebuddy/README.md +13 -1
- package/codebuddy/mcp.json +9 -0
- package/docs/GBrain/345/217/257/345/200/237/351/211/264/347/202/271_/347/201/265/346/236/242/350/220/275/347/202/271/344/272/244/346/216/245_20260919.md +169 -0
- package/docs/README.md +1 -1
- package/docs/discipline/harnesses.yaml +18 -7
- package/docs/discipline/templates/full.md.tmpl +4 -3
- package/docs/experiments/linkref_backfill/candidates_20260917.json +726 -0
- package/docs/experiments/linkref_backfill/candidates_internal_20260917.json +602 -0
- package/docs/experiments/linkref_backfill/candidates_internal_v2.json +603 -0
- package/docs/experiments/linkref_backfill/candidates_secret_20260917.json +884 -0
- package/docs/experiments/linkref_backfill/candidates_secret_v2.json +789 -0
- package/docs/hive//345/244/232/347/253/257harness/351/200/232/344/277/241/345/245/221/347/272/246_v0.1.md +42 -0
- package/docs/hive//346/243/200/347/264/242/346/224/266/346/225/233/345/256/236/346/265/213/344/270/216S1b/350/256/276/350/256/241_v0.1.md +43 -0
- package/docs/hive//346/243/200/347/264/242/350/267/257/345/276/204/344/270/216/350/256/244/347/237/245/347/273/223/346/236/204/345/245/221/347/272/246_v0.1.md +102 -0
- package/docs/hive//347/234/237/345/256/236/345/272/223/347/253/257/345/210/260/347/253/257/345/256/236/346/265/213_S1b/344/270/216/345/217/254/345/233/236/346/235/203/350/241/241_v0.1.md +57 -0
- package/docs/hive//347/234/237/345/256/236/345/272/223/347/253/257/345/210/260/347/253/257/345/256/236/346/265/213_S7/345/200/222/346/216/222/345/200/231/351/200/211/345/261/202_v0.1.md +126 -0
- package/docs/hive//350/234/202/345/267/242/345/217/214/345/256/236/344/276/213/344/272/222/351/252/214_/350/256/276/350/256/241/345/256/232/347/250/277.md +503 -0
- package/docs/mdcg/D_meta_/345/267/245/347/250/213/345/214/226/346/226/271/346/241/210_v0.2.md +216 -0
- package/docs/mdcg/README/350/257/246/347/273/206/347/211/210_v0.4.5.md +631 -625
- package/docs/mdcg//344/273/243/347/240/201/350/257/204/345/256/241/344/270/216/346/235/241/344/273/266/345/214/226/346/263/250/351/207/212_/345/245/221/347/272/246_v0.1.md +82 -0
- package/docs/mdcg//345/205/250/345/272/223/344/273/243/347/240/201/350/257/204/345/256/241/344/270/216/346/235/241/344/273/266/345/214/226/346/263/250/351/207/212_/350/256/241/345/210/222_v0.1.md +600 -0
- package/docs/mdcg//345/212/237/350/203/275/350/260/203/347/224/250/346/230/240/345/260/204/350/241/250_v0.1.md +47 -45
- package/docs/mdcg//345/255/220/344/273/243/347/220/206/351/205/215/347/275/256/346/240/207/345/207/{206_v0.4.md → 206_v0.5.md} +92 -4
- package/docs/mdcg//347/201/265/346/236/242/350/256/260/345/277/206/345/212/250/350/257/215/345/215/217/350/256/256_v1.0-draft.md +172 -0
- package/docs/mdcg//347/216/257/344/272/214_/347/231/275/347/256/261/345/241/253/345/205/205/346/265/201/346/260/264/347/272/277_v0.1.md +31 -0
- package/docs/mdcg//350/267/250/347/253/257/351/252/214/350/257/201/344/270/216/345/220/214/346/255/245/345/215/217/350/256/256_v0.1.md +93 -0
- package/docs/theory//345/271/266/345/217/221/345/277/205/347/204/266/346/200/247/347/220/206/350/256/272_v0.2.md +2 -2
- package/docs/theory//347/220/206/350/256/272_/346/234/272/345/210/266_/344/273/243/347/240/201_/345/256/236/351/252/214_/347/274/272/345/217/243/347/237/251/351/230/265_v0.1.md +3 -3
- package/docs/theory//350/256/244/347/237/245/344/273/243/347/220/206/344/270/216/346/224/266/346/225/233/347/273/223/346/236/204_/346/235/241/344/273/266/350/256/272/351/207/215/346/236/204_v0.1.md +2 -2
- package/docs//345/267/245/344/275/234/347/272/252/345/276/213_/350/256/244/347/237/245/345/233/276/346/235/241/347/233/256_v1.1.json +434 -433
- package/docs//347/201/265/346/236/242/350/207/252/346/210/221/346/224/271/350/277/233/345/267/245/344/275/234/350/256/241/345/210/222_/345/244/226/351/203/250/347/240/224/347/251/266/347/263/273/345/210/227/345/220/270/346/224/266_v1_20260919.md +286 -0
- package/dsh/README.md +33 -0
- package/dsh/cordis.yml.example +13 -7
- package/dsh/hive-mcp-probe.mjs +94 -0
- package/dsh/hive-mcp.example.yml +62 -0
- package/dsh/update-lingshu.bat +11 -0
- package/dsh/update-lingshu.ps1 +337 -0
- package/lib/hooks.d.ts +3 -0
- package/lib/hooks.js +17 -23
- package/lib/index.d.ts +4 -2
- package/lib/index.js +29 -6
- package/lib/lib/datapath.d.ts +76 -1
- package/lib/lib/datapath.js +199 -13
- package/lib/lib/mdcg_client.d.ts +40 -3
- package/lib/lib/mdcg_client.js +46 -22
- package/lib/lib/mutual.js +4 -4
- package/lib/lib/token_store.js +4 -5
- package/md_cg/audit.py +17 -2
- package/md_cg/autonomy.py +86 -15
- package/md_cg/backfill.py +36 -1
- package/md_cg/backfill_bigdomain.py +34 -0
- package/md_cg/bench6_arms.py +28 -1
- package/md_cg/bench6_common.py +10 -1
- package/md_cg/bench6_competitors.py +6 -1
- package/md_cg/bench_axis_domain.py +9 -1
- package/md_cg/bench_blind_comp.py +7 -1
- package/md_cg/bench_en_atoms_public.py +9 -0
- package/md_cg/bench_governance.py +348 -0
- package/md_cg/bench_lme_zh.py +16 -1
- package/md_cg/bench_locomo.py +2 -1
- package/md_cg/bench_locomo_zh.py +16 -1
- package/md_cg/bench_locomo_zh_public.py +4 -1
- package/md_cg/bench_longmem.py +2 -1
- package/md_cg/bench_membench.py +27 -1
- package/md_cg/bench_p0.py +4 -1
- package/md_cg/bench_progressive.py +13 -1
- package/md_cg/bench_role_views.py +238 -0
- package/md_cg/bench_task_ab.py +8 -1
- package/md_cg/bench_task_ab_llm.py +13 -1
- package/md_cg/bench_unified_en.py +6 -1
- package/md_cg/bench_zh_mad.py +20 -1
- package/md_cg/blindspot_tickets.py +123 -0
- package/md_cg/branches.py +12 -1
- package/md_cg/build_postings.py +73 -0
- package/md_cg/ccgc.py +67 -2
- package/md_cg/census.py +5 -1
- package/md_cg/chain.py +24 -3
- package/md_cg/codeindex.py +134 -17
- package/md_cg/coldverify.py +265 -0
- package/md_cg/comment_gate.py +338 -0
- package/md_cg/cond_compose.py +190 -0
- package/md_cg/cond_facts.py +155 -0
- package/md_cg/cond_template.json +107 -0
- package/md_cg/condition_anchor.py +143 -0
- package/md_cg/conformance.py +69 -4
- package/md_cg/consistency.py +24 -1
- package/md_cg/consolidate.py +53 -2
- package/md_cg/corpus.py +4 -0
- package/md_cg/crosscheck.py +42 -2
- package/md_cg/crypto.py +35 -1
- package/md_cg/d_meta.py +310 -0
- package/md_cg/datapath.py +201 -26
- package/md_cg/docindex.py +122 -1
- package/md_cg/eval_common.py +29 -1
- package/md_cg/evidence.py +27 -1
- package/md_cg/evolution.py +21 -1
- package/md_cg/export.py +11 -1
- package/md_cg/forgetting.py +23 -1
- package/md_cg/fsutil.py +18 -1
- package/md_cg/hotcache.py +214 -0
- package/md_cg/hyperedge.py +251 -0
- package/md_cg/identity.py +18 -1
- package/md_cg/insight.py +17 -1
- package/md_cg/lexicon/build_cedict_en_zh.py +9 -0
- package/md_cg/lexicon/build_standard_en.py +171 -168
- package/md_cg/lexicon/expand_en_zh.py +6 -0
- package/md_cg/lifecycle.py +12 -1
- package/md_cg/linkref.py +281 -0
- package/md_cg/links.py +29 -1
- package/md_cg/mcp_server.py +362 -43
- package/md_cg/md_whitebox.py +53 -1
- package/md_cg/mdcg.py +1003 -27
- package/md_cg/mdcos.py +558 -36
- package/md_cg/metacognition.py +37 -2
- package/md_cg/migrate.py +4 -0
- package/md_cg/migrate_aeis.py +221 -213
- package/md_cg/migrate_roleplay.py +8 -0
- package/md_cg/migrate_wisdom_graph.py +14 -1
- package/md_cg/mreview/__main__.py +3 -0
- package/md_cg/mreview/bundle.py +8 -0
- package/md_cg/mreview/candidates.py +9 -0
- package/md_cg/mreview/govern.py +21 -1
- package/md_cg/mreview/locate.py +34 -0
- package/md_cg/mreview/pipeline.py +29 -1
- package/md_cg/mreview/ruleset.py +16 -1
- package/md_cg/nodefile.py +233 -3
- package/md_cg/pooling.py +23 -1
- package/md_cg/postings.py +298 -0
- package/md_cg/predict.py +89 -9
- package/md_cg/progressive.py +3 -0
- package/md_cg/protect.py +14 -1
- package/md_cg/protocol.py +372 -0
- package/md_cg/provenance.py +262 -0
- package/md_cg/reach.py +453 -0
- package/md_cg/refindex.py +47 -2
- package/md_cg/refine.py +20 -1
- package/md_cg/roleviews.py +89 -0
- package/md_cg/routing.py +76 -0
- package/md_cg/scrub.py +63 -2
- package/md_cg/security.py +26 -1
- package/md_cg/self_state.py +64 -1
- package/md_cg/selfreport.py +151 -0
- package/md_cg/semantic/canonical.py +5 -0
- package/md_cg/semantic/en_normalizer.py +364 -355
- package/md_cg/semantic/zh_en_atoms.py +139 -136
- package/md_cg/signer.py +41 -1
- package/md_cg/sources.py +583 -547
- package/md_cg/statushdr.py +179 -0
- package/md_cg/stg.py +59 -18
- package/md_cg/subgraph.py +23 -0
- package/md_cg/sustain.py +56 -1
- package/md_cg/tasks.py +26 -2
- package/md_cg/test_autonomy.py +26 -0
- package/md_cg/test_bench_governance.py +102 -0
- package/md_cg/test_blindspot_tickets.py +166 -0
- package/md_cg/test_ccgc.py +10 -0
- package/md_cg/test_codeindex.py +338 -0
- package/md_cg/test_comment_gate.py +187 -0
- package/md_cg/test_cond_compose_anchors.py +76 -0
- package/md_cg/test_condition_anchor.py +82 -0
- package/md_cg/test_d_meta.py +412 -0
- package/md_cg/test_datapath_root.py +188 -0
- package/md_cg/test_gain_gate.py +47 -1
- package/md_cg/test_hot_cold.py +187 -0
- package/md_cg/test_hyperedge.py +245 -0
- package/md_cg/test_linkref.py +306 -0
- package/md_cg/test_md_access_parity.py +15 -3
- package/md_cg/test_mr_m1.py +108 -18
- package/md_cg/test_mr_m3.py +8 -1
- package/md_cg/test_p26_refindex.py +49 -20
- package/md_cg/test_p27_docindex.py +236 -2
- package/md_cg/test_p2_mcp.py +1 -1
- package/md_cg/test_p31_insight.py +24 -0
- package/md_cg/test_p44_md_whitebox.py +14 -1
- package/md_cg/test_protocol.py +243 -0
- package/md_cg/test_reach.py +378 -0
- package/md_cg/test_reach_keys.py +201 -0
- package/md_cg/test_reach_meta_exits.py +145 -0
- package/md_cg/test_read_clip.py +8 -4
- package/md_cg/test_retr_s1.py +340 -0
- package/md_cg/test_retr_s1b.py +209 -0
- package/md_cg/test_retr_s3.py +194 -0
- package/md_cg/test_retr_s4.py +163 -0
- package/md_cg/test_retr_s5.py +200 -0
- package/md_cg/test_retr_s6.py +157 -0
- package/md_cg/test_retr_s7.py +385 -0
- package/md_cg/test_retr_s8_time.py +316 -0
- package/md_cg/test_retr_s9_edges.py +286 -0
- package/md_cg/test_retr_s9_entity_ctx.py +175 -0
- package/md_cg/test_review_conformance.py +59 -2
- package/md_cg/test_role_views.py +354 -0
- package/md_cg/test_subproc_encoding.py +188 -0
- package/md_cg/test_trust.py +361 -0
- package/md_cg/test_units_poll.py +71 -0
- package/md_cg/test_v14_fixes.py +397 -0
- package/md_cg/test_validity_filter.py +280 -0
- package/md_cg/test_wisdom_md_store.py +7 -3
- package/md_cg/test_writepipe.py +5 -1
- package/md_cg/theory.py +16 -1
- package/md_cg/tokens.py +40 -8
- package/md_cg/tool_face.py +13 -2
- package/md_cg/trust.py +943 -0
- package/md_cg/twophase.py +12 -1
- package/md_cg/units.py +132 -10
- package/md_cg/vision_evidence.py +24 -1
- package/md_cg/weights.py +24 -1
- package/md_cg/whitebox.py +32 -1
- package/md_cg/whitebox_kb/data/verify_cache.json +21210 -365
- package/md_cg/whitebox_kb/data/verify_savings.jsonl +5078 -0
- package/md_cg/whitebox_kb/wisdom/audit_log/chain_heat.json +10 -10
- package/md_cg/whitebox_kb/wisdom/code_compose.py +113 -6
- package/md_cg/whitebox_kb/wisdom/code_solidified.json +1 -1
- package/md_cg/whitebox_kb/wisdom/verifier.py +340 -55
- package/md_cg/whitebox_kb/wisdom/wisdom-book-cloud.db +0 -0
- package/md_cg/writelimit.py +18 -4
- package/md_cg/writepipe.py +178 -7
- package/package.json +2 -2
- package/skills/skills/designer-perspective/scripts/__pycache__/designer.cpython-310.pyc +0 -0
- package/skills/skills/designer-perspective/scripts/designer.py +17 -1
- package/skills/skills/designer-perspective/tests/selftest.py +3 -1
- package/src/hooks.ts +17 -21
- package/src/index.ts +33 -6
- package/src/lib/datapath.ts +211 -13
- package/src/lib/mdcg_client.ts +64 -25
- package/src/lib/mutual.ts +411 -411
- package/src/lib/token_store.ts +4 -5
- package/zcode/AGENTS.md +196 -195
- package/zcode/README.md +4 -0
- package/md_cg/whitebox_kb/wisdom/wisdom-book-cloud.db-shm +0 -0
- package/md_cg/whitebox_kb/wisdom/wisdom-book-cloud.db-wal +0 -0
package/md_cg/insight.py
CHANGED
|
@@ -59,10 +59,12 @@ V_LABELS = {"v1": "可检索/被引用", "v2": "实践重复", "v3": "外部确
|
|
|
59
59
|
|
|
60
60
|
# ---------------------------------------------------------------- 基础
|
|
61
61
|
|
|
62
|
+
# 生效条件:cg 可提供 root 时返回 os.path.join(cg.root, INSIGHT_LOG)。
|
|
62
63
|
def log_path(cg):
|
|
63
64
|
return os.path.join(cg.root, INSIGHT_LOG)
|
|
64
65
|
|
|
65
66
|
|
|
67
|
+
# 生效条件:向 log_path(cg) 追加 JSONL 的调用若抛任何异常都会被 except Exception 吞掉,无论成败最终都返回 rec。
|
|
66
68
|
def _append(cg, rec):
|
|
67
69
|
"""留痕(best-effort):审计不该反过来打断主流程。"""
|
|
68
70
|
try:
|
|
@@ -72,6 +74,7 @@ def _append(cg, rec):
|
|
|
72
74
|
return rec
|
|
73
75
|
|
|
74
76
|
|
|
77
|
+
# 生效条件:getattr(cg,"index",None) 或其 "nodes" 为 None/假值时返回空列表,否则返回 nodes 中 (e or {}).get("tags") or [] 含 TAG_EVENT 的节点 id 列表。
|
|
75
78
|
def _events(cg):
|
|
76
79
|
"""全部洞见事件节点 id(按 index 层标签粗筛,避免全量读盘)。"""
|
|
77
80
|
nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
|
|
@@ -79,6 +82,7 @@ def _events(cg):
|
|
|
79
82
|
if TAG_EVENT in ((e or {}).get("tags") or [])]
|
|
80
83
|
|
|
81
84
|
|
|
85
|
+
# 生效条件:cg 具备 get,node_id 经 str(node_id or "").strip() 后非空(0/空串等假值回落空串即返回 None)、cg.get(nid) 返回真值节点、且该节点 frontmatter 的 tags(缺键或假值时按 [] 计)包含 TAG_EVENT 时返回该节点,否则返回 None。
|
|
82
86
|
def _read_event(cg, node_id):
|
|
83
87
|
"""读洞见事件节点;非事件节点(标签不符)返回 None。"""
|
|
84
88
|
nid = str(node_id or "").strip()
|
|
@@ -98,6 +102,7 @@ def _read_event(cg, node_id):
|
|
|
98
102
|
|
|
99
103
|
# ---------------------------------------------------------------- 条件快照
|
|
100
104
|
|
|
105
|
+
# 生效条件:conditions 为 None/假值时按空 dict 处理且 missing 登记 CONDITION_KEYS 中不在其中的键;retrievability 由 raw.get("retrievability",0.0) or 0.0 转 float(失败落 0.0)并截断到 [0,1],pressure/tone 不在 PRESSURES/TONES 白名单(含空串回落 "medium"/"neutral")时落 "medium"/"neutral",cross_domain 为字符串时包成单元素列表再排序去重,continuity_turns 经 int(raw.get(...) or 0)(失败落 0)取 max(0,·)。
|
|
101
106
|
def normalize(conditions=None):
|
|
102
107
|
"""C1–C8 归一化;**缺失项显式登记**而不是静默补默认值。"""
|
|
103
108
|
raw = dict(conditions or {})
|
|
@@ -126,6 +131,7 @@ def normalize(conditions=None):
|
|
|
126
131
|
return {"conditions": out, "missing": missing}
|
|
127
132
|
|
|
128
133
|
|
|
134
|
+
# 生效条件:conditions 经 normalize 后,retrievability ≥ C1_WINDOW_MIN、cross_domain 非空、pressure == "low" 三者同时成立时 open 为 True 且 blocked_by 为空,否则 blocked_by 列出未通过的闸门键名。
|
|
129
135
|
def window(conditions=None):
|
|
130
136
|
"""开窗判定:C1 ≥ 0.6 ∧ 跨域(≥1 个域)∧ 低压力。
|
|
131
137
|
|
|
@@ -145,6 +151,7 @@ def window(conditions=None):
|
|
|
145
151
|
"note": "开窗仅表示「条件具备」;是否有效一律由 verify 的外部证据裁决"}
|
|
146
152
|
|
|
147
153
|
|
|
154
|
+
# 生效条件:任意 statement(假值按 "" 计)与 ts(None/0 等假值时回落 time.time())下恒返回 "ins_%d_%s",其中时间数字为 int(ts or time.time())、哈希为 str(statement or "").encode("utf-8") 的 sha1 前 8 位。
|
|
148
155
|
def event_id(statement, ts=None):
|
|
149
156
|
return "ins_%d_%s" % (int(ts or time.time()),
|
|
150
157
|
hashlib.sha1(str(statement or "").encode("utf-8")).hexdigest()[:8])
|
|
@@ -152,6 +159,7 @@ def event_id(statement, ts=None):
|
|
|
152
159
|
|
|
153
160
|
# ---------------------------------------------------------------- record
|
|
154
161
|
|
|
162
|
+
# 生效条件:cg 具备 add/_append,statement 经 str(statement or "").strip() 为空时抛 ValueError;非空时以 str(node_id or event_id(statement)).strip() 为 nid(node_id 假值时回落到 event_id(statement)),_read_event 命中已有事件则返回 duplicate=True/existed_before=True 且 state 取该节点 frontmatter 的 insight_state,未命中则以 STATE_PENDING 写入新节点并返回 duplicate=False/existed_before=False,返回中的 window 来自 window(conditions)。
|
|
155
163
|
def record(cg, statement=None, conditions=None, category="", source="",
|
|
156
164
|
tags=None, importance=0.5, node_id=None, actor=None, **extra):
|
|
157
165
|
"""记录一条洞见事件(pending)+ C1–C8 条件快照。
|
|
@@ -202,6 +210,7 @@ def record(cg, statement=None, conditions=None, category="", source="",
|
|
|
202
210
|
|
|
203
211
|
# ---------------------------------------------------------------- verify
|
|
204
212
|
|
|
213
|
+
# 生效条件:evidence 为 str/dict 时先包成单元素列表、为 None 或假值时按 [] 遍历;每个 dict 项 type 经 str(...).strip().lower() 属 V_TYPES 才保留否则回落 "v1",ref 取 item.get("ref") 或 item.get("source") 或 ""、note 取 item.get("note") 或 "",非 dict 项一律记为 {"type":"v1","ref":str(item),"note":""};v_types 中仅 strip().lower() 后属 V_TYPES 的项追加空 ref/note 条目,最终返回 out。
|
|
205
214
|
def _normalize_evidence(evidence=None, v_types=None):
|
|
206
215
|
"""证据归一化:接受 ``["ref", ...]`` / ``[{"type","ref","note"}]`` / ``v_types``。"""
|
|
207
216
|
ev = evidence
|
|
@@ -223,6 +232,7 @@ def _normalize_evidence(evidence=None, v_types=None):
|
|
|
223
232
|
return out
|
|
224
233
|
|
|
225
234
|
|
|
235
|
+
# 生效条件:_read_event(cg,node_id) 取不到事件节点、或 verdict 经 str(verdict or "").strip().lower() 后非空且不是 verified/falsified 时抛 ValueError;verdict 为 None 或空白时按 v3 → v2 → v1 条数 ≥ V1_MIN_EVIDENCE 的顺序定 verified,有证据但不达门槛或无证据则保持 STATE_PENDING 并附 reason;显式 verdict 直接采信,verified 分支重要度保底 IMPORTANCE_FLOOR 并置保护位,falsified 分支打 TAG_FALSIFIED。
|
|
226
236
|
def verify(cg, node_id=None, evidence=None, v_types=None, verdict=None,
|
|
227
237
|
actor=None, note=""):
|
|
228
238
|
"""用 V1/V2/V3 外部证据裁决洞见事件。
|
|
@@ -305,6 +315,7 @@ def verify(cg, node_id=None, evidence=None, v_types=None, verdict=None,
|
|
|
305
315
|
|
|
306
316
|
# ---------------------------------------------------------------- list / report
|
|
307
317
|
|
|
318
|
+
# 生效条件:state 为真值时只保留 insight_state 与之相等的项(state 为 None/空串等假值则不过滤),limit 为 0 等假值时返回按 created_at 排序后的全部列表,limit 为真值时返回 out[-int(limit):]——limit 为负时该切片等价于 out[|limit|:],即去掉排序后前 |limit| 条而非取前 |limit| 条。
|
|
308
319
|
def list_events(cg, state=None, limit=0):
|
|
309
320
|
out = []
|
|
310
321
|
for nid in _events(cg):
|
|
@@ -326,6 +337,7 @@ def list_events(cg, state=None, limit=0):
|
|
|
326
337
|
return out[-int(limit):] if limit else out
|
|
327
338
|
|
|
328
339
|
|
|
340
|
+
# 生效条件:now 为 None/0 等假值时取 time.time(),window_days 为真值时按 now - window_days*86400 过滤 created_at;已裁决数 verified+falsified < CER_MIN_SAMPLES 时直接返回 cer/se/two_se/significant 为 None、layer_state="insufficient" 的结果,否则按 p=verified/denom 算出 se 与 significant,significant 为假时 p<0.3 取 degraded、否则 watch,significant 为真时 p≥0.5 取 reliable、否则 watch。
|
|
329
341
|
def report(cg, window_days=None, now=None):
|
|
330
342
|
"""CER 条件有效洞见率报告(样本不足不判定)。
|
|
331
343
|
|
|
@@ -369,20 +381,24 @@ def report(cg, window_days=None, now=None):
|
|
|
369
381
|
|
|
370
382
|
# ---------------------------------------------------------------- outlook
|
|
371
383
|
|
|
384
|
+
# 生效条件:entry 为假值或 (entry or {}).get("layer") 为假值时返回 "unknown",否则返回该 layer 值的 str 形式。
|
|
372
385
|
def _layer_of(entry):
|
|
373
386
|
return str((entry or {}).get("layer") or "unknown")
|
|
374
387
|
|
|
375
388
|
|
|
389
|
+
# 生效条件:values 为空/假值时返回 min/p50/p90/max 全为 None 的字典,否则对 sorted(values) 取 0.0/0.5/0.9/1.0 位置的值并各自 round(·,4)。
|
|
376
390
|
def _quartiles(values):
|
|
377
391
|
if not values:
|
|
378
392
|
return {"min": None, "p50": None, "p90": None, "max": None}
|
|
379
393
|
vs = sorted(values)
|
|
394
|
+
# 生效条件:给定 f 与闭包列表 vs,取下标 i = min(len(vs)-1, max(0, int(round(f*(len(vs)-1)))))(f 越界被夹到两端)并返回 round(vs[i], 4);vs 为空时 min 得到 -1 的取值行为源码未做校验。
|
|
380
395
|
def _q(f):
|
|
381
396
|
i = min(len(vs) - 1, max(0, int(round(f * (len(vs) - 1)))))
|
|
382
397
|
return round(vs[i], 4)
|
|
383
398
|
return {"min": _q(0.0), "p50": _q(0.5), "p90": _q(0.9), "max": _q(1.0)}
|
|
384
399
|
|
|
385
400
|
|
|
401
|
+
# 生效条件:cg.index(取不到或假值时 nodes 为空、total=0 使 protected_rate 与 growth 回落 None)与 now(假值时回落 time.time())决定 d1,float(recent_days) 参与 lo_recent 计算,window_days 透传 report 得 d2;suggestions 依序在 basis["unset"] 非零、hi_imp_unprotected 非空、no_neg 非零、pending>=3、layers["unresolved"] 非零、contextual>max(3, knowledge)、rep["layer_state"]=="insufficient" 时各自追加一条,high_importance_unprotected 取排序后前 sample_limit 项(sample_limit=0 时为空列表)。
|
|
386
402
|
def outlook(cg, window_days=None, sample_limit=8, recent_days=7, now=None):
|
|
387
403
|
"""结构洞察:D1 结构判断 + D2 盲区与趋势建议(只读)。
|
|
388
404
|
|
|
@@ -482,4 +498,4 @@ def outlook(cg, window_days=None, sample_limit=8, recent_days=7, now=None):
|
|
|
482
498
|
"d1": d1, "d2": d2, "suggestions": suggestions,
|
|
483
499
|
"generated_at": now,
|
|
484
500
|
"note": ("结构描述与差距定位,不判有效性;suggestions 按优先级给出,"
|
|
485
|
-
"需调用方自行执行并核对")}
|
|
501
|
+
"需调用方自行执行并核对")}
|
|
@@ -50,6 +50,7 @@ CEDICT_URL = "https://www.mdbg.net/chinese/export/cedict/cedict_1_0_ts_utf-8_mdb
|
|
|
50
50
|
LINE_RE = re.compile(r"^(\S+)\s+(\S+)\s+\[[^\]]+\]\s+/(.+)/\s*$")
|
|
51
51
|
|
|
52
52
|
|
|
53
|
+
# 生效条件:无必需形参,被调用即创建模块常量 RAW_DIR、按 CEDICT_URL 发请求(UA 头 + timeout=120),把响应体写入 RAW_GZ,再以 gzip 解压并按 errors="replace" 解码写入 RAW_TXT,最后打印字节数与行数并返回 0;
|
|
53
54
|
def download():
|
|
54
55
|
os.makedirs(RAW_DIR, exist_ok=True)
|
|
55
56
|
req = urllib.request.Request(
|
|
@@ -67,6 +68,7 @@ def download():
|
|
|
67
68
|
return 0
|
|
68
69
|
|
|
69
70
|
|
|
71
|
+
# 生效条件:无必需形参,迭代时逐行读模块常量 RAW_TXT,仅当 strip 后非空、不以 "#" 开头且 LINE_RE.match 命中时产出 (第 2 组, 第 3 组),其余行跳过(生成器,无产出即为空);
|
|
70
72
|
def iter_entries():
|
|
71
73
|
"""CEDICT 行 → (简体, [英文释义段])。注释/空行跳过。"""
|
|
72
74
|
with io.open(RAW_TXT, encoding="utf-8") as f:
|
|
@@ -80,6 +82,7 @@ def iter_entries():
|
|
|
80
82
|
yield m.group(2), m.group(3)
|
|
81
83
|
|
|
82
84
|
|
|
85
|
+
# 生效条件:min_len 取默认 3(调用方可传入覆盖,传入 0 则 len(sub)<min_len 恒不成立、不再做长度过滤),遍历 iter_entries() 的释义按 / 分段、剥 (…) 注、按 ;, 切子段并 strip+lower+去 to/a/an 前缀,子段须 fullmatch [a-z]+、不在 STOPWORDS、长度 ≥ min_len 才计入 rev[en];末尾按 zh 集大小 1 写入 cand[en]、>1 写入 conflicts[en],返回 (cand, conflicts, stat);
|
|
83
86
|
def reverse_map(min_len=3):
|
|
84
87
|
"""词级反查 → (候选 {en: zh}, 冲突 {en: [zh...]}, 统计 dict)。
|
|
85
88
|
|
|
@@ -122,6 +125,7 @@ def reverse_map(min_len=3):
|
|
|
122
125
|
return cand, conflicts, stat
|
|
123
126
|
|
|
124
127
|
|
|
128
|
+
# 生效条件:无必需形参,逐行读模块引用 b6.CORPUS567 并跳过空白行,每行 json.loads 后取 (c.get("zh") or "") 与 (c.get("zh_fields") or {}) 中所有 str 值拼接成一条,最终以换行连成整串返回(无有效行时返回空串);
|
|
125
129
|
def _corpus_text():
|
|
126
130
|
"""领域语料全文(zh 正文+五槽摘要)——冲突集频次消歧用。
|
|
127
131
|
|
|
@@ -143,6 +147,7 @@ def _corpus_text():
|
|
|
143
147
|
return "\n".join(buf)
|
|
144
148
|
|
|
145
149
|
|
|
150
|
+
# 生效条件:无必需形参,逐行读模块引用 b6.CORPUS567 并跳过空白行;摘要取 (c.get("zh_fields") or {}).get("summary") 且 str(...).strip() 后为空时回落 c.get("zh"),非空则 semantic_atoms 切分后空格连接入 sums;正文取 c.get("zh").strip() 非空则同样切分入 bodys;返回 ("\n".join(sums), "\n".join(bodys))(两级均可能为空串);
|
|
146
151
|
def _atoms_texts():
|
|
147
152
|
"""doc 侧同构消歧空间(2026-09-14 消歧口径升级)。
|
|
148
153
|
|
|
@@ -175,6 +180,7 @@ def _atoms_texts():
|
|
|
175
180
|
return "\n".join(sums), "\n".join(bodys)
|
|
176
181
|
|
|
177
182
|
|
|
183
|
+
# 生效条件:给定冲突英文词 en、候选中文集合 zhs、文本对 texts=(摘要原子串, 正文原子串),仅对 2 ≤ len(z) ≤ 4 且按 sorted(zhs) 顺序的候选,依次用摘要 frag 计数、摘要全零时改用正文 frag 计数、前两级全零时改用单原子碎片计数求和(级别 0/1/2 依次),任一非零即入 scored;scored 为空返回 (None, -1),否则按 (-计数, 级别, 长度, 字典序) 排序返回 scored[0] 的中文词与级别;
|
|
178
184
|
def _disambiguate(en, zhs, texts):
|
|
179
185
|
"""单英文词冲突集三级消歧:摘要碎片串 → 正文碎片串 → 碎片字级和。
|
|
180
186
|
|
|
@@ -216,6 +222,7 @@ def _disambiguate(en, zhs, texts):
|
|
|
216
222
|
return scored[0][3], scored[0][1]
|
|
217
223
|
|
|
218
224
|
|
|
225
|
+
# 生效条件:min_len 取默认 3、domain 取默认 True(两者均可由调用方传入覆盖,domain 传假值则跳过消歧分支);先 reverse_map(min_len) 取 cand/conf/stat,当 domain 为真且 conf 非空时以 _atoms_texts() 对每个冲突词调 _disambiguate 并计 disambiguated/body/char/dropped,命中则写回 cand 并 conf.pop(en)、未命中仅计 dropped;随后无条件把 set(cand) & set(EN_ZH) 的键从 cand 移除(手工表优先),再写出 OUT_JSON 并返回 0;
|
|
219
226
|
def build(min_len=3, domain=True):
|
|
220
227
|
cand, conf, stat = reverse_map(min_len)
|
|
221
228
|
stat["disambiguated"] = 0
|
|
@@ -274,6 +281,7 @@ def build(min_len=3, domain=True):
|
|
|
274
281
|
return 0
|
|
275
282
|
|
|
276
283
|
|
|
284
|
+
# 生效条件:无必需形参,两次逐行读模块常量 QUESTIONS 并跳过空白行:第一次对 str(q.get("question") or "") 调 normalize_en_query,把 detail 中 action=="unknown_keep" 的 str(d.get("orig") or "").lower() 逐个计入 Counter;第二次累加各问句 normalize_en_query 返回的第 0 项长度得 total_tokens;打印去重词数/词次/原子序列长度与 top 30 后返回 0(无有效行时计数为零仍返回 0);
|
|
277
285
|
def analyze():
|
|
278
286
|
"""集成后 normalize 的最终残留取证(en_normalizer 已加载 cedict_en_zh.json,
|
|
279
287
|
此处 unknown_keep 即全链路翻译后的真 OOV)。"""
|
|
@@ -304,6 +312,7 @@ def analyze():
|
|
|
304
312
|
return 0
|
|
305
313
|
|
|
306
314
|
|
|
315
|
+
# 生效条件:无必需形参,mode = sys.argv[1] if len(sys.argv) > 1 else "analyze"(仅按参数个数回落,sys.argv[1] 为空串时 mode 即空串、不回落默认);mode=="download" 返回 download()、"build" 返回 build()、"analyze" 返回 analyze(),其余取值打印模块 doc 并返回 2;
|
|
307
316
|
def main():
|
|
308
317
|
mode = sys.argv[1] if len(sys.argv) > 1 else "analyze"
|
|
309
318
|
if mode == "download":
|
|
@@ -1,168 +1,171 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""build_standard_en.py · 英文标准库构建器(语素表 + 词条 → standard_en.json)
|
|
3
|
-
|
|
4
|
-
词条语素带显式英文注 (zh_morph, en_gloss),规避单字歧义(月=month/moon、生=person/living)。
|
|
5
|
-
构建即验证:标准英文必须等于语素英文的 snake_case 直拼。
|
|
6
|
-
"""
|
|
7
|
-
import collections
|
|
8
|
-
import json, io, os, re
|
|
9
|
-
|
|
10
|
-
MORPHEMES = {}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
A("
|
|
63
|
-
A("
|
|
64
|
-
A("
|
|
65
|
-
A("
|
|
66
|
-
A("
|
|
67
|
-
A("
|
|
68
|
-
|
|
69
|
-
A("
|
|
70
|
-
|
|
71
|
-
A("
|
|
72
|
-
A("
|
|
73
|
-
A("
|
|
74
|
-
A("
|
|
75
|
-
A("
|
|
76
|
-
A("
|
|
77
|
-
A("
|
|
78
|
-
A("
|
|
79
|
-
A("
|
|
80
|
-
A("
|
|
81
|
-
A("
|
|
82
|
-
A("
|
|
83
|
-
#
|
|
84
|
-
A("
|
|
85
|
-
|
|
86
|
-
A("
|
|
87
|
-
A("
|
|
88
|
-
A("
|
|
89
|
-
A("
|
|
90
|
-
|
|
91
|
-
A("
|
|
92
|
-
|
|
93
|
-
#
|
|
94
|
-
A("
|
|
95
|
-
|
|
96
|
-
A("
|
|
97
|
-
A("
|
|
98
|
-
|
|
99
|
-
A("
|
|
100
|
-
|
|
101
|
-
A("
|
|
102
|
-
A("
|
|
103
|
-
A("
|
|
104
|
-
A("
|
|
105
|
-
A("
|
|
106
|
-
A("
|
|
107
|
-
A("
|
|
108
|
-
|
|
109
|
-
A("
|
|
110
|
-
|
|
111
|
-
A("
|
|
112
|
-
A("
|
|
113
|
-
A("
|
|
114
|
-
A("
|
|
115
|
-
|
|
116
|
-
A("
|
|
117
|
-
|
|
118
|
-
A("
|
|
119
|
-
A("
|
|
120
|
-
|
|
121
|
-
A("
|
|
122
|
-
|
|
123
|
-
A("
|
|
124
|
-
A("
|
|
125
|
-
|
|
126
|
-
A("
|
|
127
|
-
|
|
128
|
-
A("
|
|
129
|
-
A("
|
|
130
|
-
A("
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if
|
|
146
|
-
problems.append("%s:
|
|
147
|
-
continue
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
"
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
for
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if
|
|
168
|
-
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""build_standard_en.py · 英文标准库构建器(语素表 + 词条 → standard_en.json)
|
|
3
|
+
|
|
4
|
+
词条语素带显式英文注 (zh_morph, en_gloss),规避单字歧义(月=month/moon、生=person/living)。
|
|
5
|
+
构建即验证:标准英文必须等于语素英文的 snake_case 直拼。
|
|
6
|
+
"""
|
|
7
|
+
import collections
|
|
8
|
+
import json, io, os, re
|
|
9
|
+
|
|
10
|
+
MORPHEMES = {}
|
|
11
|
+
# 生效条件:以形参 zh、en 调用时无条件执行 MORPHEMES[zh] = en(同键覆盖),无返回值、无前置校验。
|
|
12
|
+
def M(zh, en):
|
|
13
|
+
MORPHEMES[zh] = en
|
|
14
|
+
|
|
15
|
+
# 动物
|
|
16
|
+
for zh, en in [("牛","cow"),("猪","pig"),("羊","sheep"),("鸡","chicken"),("鸭","duck"),("马","horse"),("狗","dog"),("猫","cat"),("鱼","fish"),("鸟","bird")]:
|
|
17
|
+
M(zh, en)
|
|
18
|
+
# 食
|
|
19
|
+
for zh, en in [("肉","meat"),("奶","milk"),("蛋","egg"),("米","rice"),("菜","vegetable"),("果","fruit"),("油","oil"),("盐","salt"),("糖","sugar"),("茶","tea"),("酒","wine"),("水","water")]:
|
|
20
|
+
M(zh, en)
|
|
21
|
+
# 时间
|
|
22
|
+
for zh, en in [("年","year"),("月","month"),("日","day"),("天","day"),("周","week"),("期","period"),("时","hour"),("分","minute"),("秒","second"),("春","spring"),("秋","autumn"),("冬","winter"),("夏","summer"),("今","this"),("明","next"),("去","past")]:
|
|
23
|
+
M(zh, en)
|
|
24
|
+
# 数
|
|
25
|
+
for zh, en in [("一","one"),("二","two"),("三","three"),("四","four"),("五","five"),("六","six"),("七","seven"),("八","eight"),("九","nine"),("十","ten"),("百","hundred"),("千","thousand")]:
|
|
26
|
+
M(zh, en)
|
|
27
|
+
# 亲
|
|
28
|
+
for zh, en in [("父","father"),("母","mother"),("兄","elder_brother"),("弟","younger_brother"),("姐","elder_sister"),("妹","younger_sister"),("儿","son"),("女","daughter")]:
|
|
29
|
+
M(zh, en)
|
|
30
|
+
# 身
|
|
31
|
+
for zh, en in [("头","head"),("手","hand"),("脚","foot"),("眼","eye"),("口","mouth"),("耳","ear"),("鼻","nose"),("心","heart"),("血","blood"),("骨","bone"),("皮","skin"),("脏","organ")]:
|
|
32
|
+
M(zh, en)
|
|
33
|
+
# 自然
|
|
34
|
+
for zh, en in [("山","mountain"),("水","water"),("火","fire"),("土","soil"),("木","wood"),("金","metal"),("光","light"),("电","electric"),("风","wind"),("雨","rain"),("雪","snow"),("星","star"),("海","sea"),("河","river"),("石","stone"),("云","cloud"),("月","moon")]:
|
|
35
|
+
M(zh, en)
|
|
36
|
+
# 器
|
|
37
|
+
for zh, en in [("车","vehicle"),("船","boat"),("机","machine"),("器","device"),("刀","knife"),("笔","pen"),("书","book"),("门","door"),("窗","window"),("桥","bridge"),("路","road"),("池","cell")]:
|
|
38
|
+
M(zh, en)
|
|
39
|
+
# 动(基形)
|
|
40
|
+
for zh, en in [("走","walk"),("来","come"),("看","see"),("听","listen"),("吃","eat"),("喝","drink"),("说","speak"),("读","read"),("写","write"),("买","buy"),("卖","sell"),("学","study"),("教","teach"),("做","make"),("跑","run"),("飞","fly"),("睡","sleep"),("想","think"),("爱","love"),("用","use"),("开","open"),("关","close")]:
|
|
41
|
+
M(zh, en)
|
|
42
|
+
# 形
|
|
43
|
+
for zh, en in [("大","big"),("小","small"),("高","high"),("低","low"),("新","new"),("旧","old"),("好","good"),("坏","bad"),("长","long"),("短","short"),("快","fast"),("慢","slow"),("热","hot"),("冷","cold"),("多","many"),("少","few"),("重","heavy"),("轻","light"),("深","deep")]:
|
|
44
|
+
M(zh, en)
|
|
45
|
+
# 抽象
|
|
46
|
+
for zh, en in [("力","force"),("气","gas"),("道","way"),("理","principle"),("文","text"),("化","transform"),("话","speech"),("影","shadow"),("音","sound"),("名","name"),("国","country"),("家","home"),("城","city"),("王","king"),("民","people"),("军","army"),("医","medicine"),("药","drug"),("病","disease"),("课","lesson"),("题","question"),("工","work"),("师","master"),("律","law"),("图","graph"),("谱","map"),("数","number"),("物","thing"),("地","earth"),("人","person"),("脑","brain"),("视","view")]:
|
|
47
|
+
M(zh, en)
|
|
48
|
+
# 多字语素(化石词 / 复合单位)
|
|
49
|
+
for zh, en in [("星期","week"),("经济","economy"),("逻辑","logic"),("沙发","sofa"),("咖啡","coffee"),("巧克力","chocolate"),("知识","knowledge"),("工作","work"),("纪律","discipline"),("记忆","memory"),("认知","cognition"),("月光","moon_light"),("十二","twelve"),("兄弟","brothers"),("姐妹","sisters"),("汽","gas")]:
|
|
50
|
+
M(zh, en)
|
|
51
|
+
|
|
52
|
+
# 词条:(zh, [(语素, 英文注)...], 标准英文, legacy 别名, class)
|
|
53
|
+
E = []
|
|
54
|
+
DEFAULT_CLS = "compositional"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# 生效条件:以形参 zh、glosses、std、legacy 调用(cls 省略时取 DEFAULT_CLS)时无条件向 E 追加五元组 (zh, glosses, std, legacy, cls),无返回、无校验。
|
|
58
|
+
def A(zh, glosses, std, legacy, cls=DEFAULT_CLS):
|
|
59
|
+
E.append((zh, glosses, std, legacy, cls))
|
|
60
|
+
|
|
61
|
+
# 食物(语素直拼)
|
|
62
|
+
A("牛肉", [("牛","cow"),("肉","meat")], "cow_meat", ["beef"])
|
|
63
|
+
A("猪肉", [("猪","pig"),("肉","meat")], "pig_meat", ["pork"])
|
|
64
|
+
A("羊肉", [("羊","sheep"),("肉","meat")], "sheep_meat", ["mutton"])
|
|
65
|
+
A("鸡肉", [("鸡","chicken"),("肉","meat")], "chicken_meat", ["chicken"])
|
|
66
|
+
A("鸭肉", [("鸭","duck"),("肉","meat")], "duck_meat", [])
|
|
67
|
+
A("牛奶", [("牛","cow"),("奶","milk")], "cow_milk", ["milk"])
|
|
68
|
+
A("鸡蛋", [("鸡","chicken"),("蛋","egg")], "chicken_egg", ["egg"])
|
|
69
|
+
A("牛肉面", [("牛","cow"),("肉","meat"),("面","noodle")], "cow_meat_noodle", [])
|
|
70
|
+
# 时间
|
|
71
|
+
A("月份", [("月","month")], "month", [], "compositional") # 份=名物化后缀,剔
|
|
72
|
+
A("一月", [("一","one"),("月","month")], "one_month", ["January"])
|
|
73
|
+
A("二月", [("二","two"),("月","month")], "two_month", ["February"])
|
|
74
|
+
A("三月", [("三","three"),("月","month")], "three_month", ["March"])
|
|
75
|
+
A("十二月", [("十二","twelve"),("月","month")], "twelve_month", ["December"])
|
|
76
|
+
A("星期一", [("星期","week"),("一","one")], "week_one", ["Monday"])
|
|
77
|
+
A("星期日", [("星期","week"),("日","sun")], "week_sun", ["Sunday"])
|
|
78
|
+
A("今天", [("今","this"),("天","day")], "this_day", ["today"])
|
|
79
|
+
A("明天", [("明","next"),("天","day")], "next_day", ["tomorrow"])
|
|
80
|
+
A("今年", [("今","this"),("年","year")], "this_year", [])
|
|
81
|
+
A("明年", [("明","next"),("年","year")], "next_year", [])
|
|
82
|
+
A("去年", [("去","past"),("年","year")], "past_year", ["last year"])
|
|
83
|
+
A("春天", [("春","spring")], "spring", ["spring"]) # 天=季节后缀,剔
|
|
84
|
+
A("冬天", [("冬","winter")], "winter", ["winter"])
|
|
85
|
+
# 家庭
|
|
86
|
+
A("父亲", [("父","father")], "father", ["father"]) # 亲=亲缘标记,剔
|
|
87
|
+
A("母亲", [("母","mother")], "mother", ["mother"])
|
|
88
|
+
A("兄弟", [("兄弟","brothers")], "brothers", ["brothers"], "compositional") # 复数是语义本身
|
|
89
|
+
A("姐妹", [("姐妹","sisters")], "sisters", ["sisters"], "compositional")
|
|
90
|
+
A("儿子", [("儿","son")], "son", ["son"])
|
|
91
|
+
A("女儿", [("女","daughter")], "daughter", ["daughter"])
|
|
92
|
+
# 身体
|
|
93
|
+
A("眼睛", [("眼","eye")], "eye", ["eye"]) # 睛=瞳,并入 eye
|
|
94
|
+
A("心脏", [("心","heart"),("脏","organ")], "heart_organ", ["heart"])
|
|
95
|
+
# 自然
|
|
96
|
+
A("火山", [("火","fire"),("山","mountain")], "fire_mountain", ["volcano"])
|
|
97
|
+
A("海水", [("海","sea"),("水","water")], "sea_water", ["seawater"])
|
|
98
|
+
A("月光", [("月","moon"),("光","light")], "moon_light", ["moonlight"])
|
|
99
|
+
A("雪山", [("雪","snow"),("山","mountain")], "snow_mountain", ["snow mountain"])
|
|
100
|
+
# 科技
|
|
101
|
+
A("电脑", [("电","electric"),("脑","brain")], "electric_brain", ["computer"])
|
|
102
|
+
A("电话", [("电","electric"),("话","speech")], "electric_speech", ["telephone"])
|
|
103
|
+
A("电视", [("电","electric"),("视","view")], "electric_view", ["television"])
|
|
104
|
+
A("电影", [("电","electric"),("影","shadow")], "electric_shadow", ["movie", "film"])
|
|
105
|
+
A("电池", [("电","electric"),("池","cell")], "electric_cell", ["battery"])
|
|
106
|
+
A("火车", [("火","fire"),("车","vehicle")], "fire_vehicle", ["train"])
|
|
107
|
+
A("汽车", [("汽","gas"),("车","vehicle")], "gas_vehicle", ["car"])
|
|
108
|
+
A("飞机", [("飞","fly"),("机","machine")], "fly_machine", ["airplane"])
|
|
109
|
+
A("手机", [("手","hand"),("机","machine")], "hand_machine", ["mobile phone"])
|
|
110
|
+
# 学科
|
|
111
|
+
A("数学", [("数","number"),("学","study")], "number_study", ["mathematics"])
|
|
112
|
+
A("化学", [("化","transform"),("学","study")], "transform_study", ["chemistry"])
|
|
113
|
+
A("物理学", [("物","thing"),("理","principle"),("学","study")], "thing_principle_study", ["physics"])
|
|
114
|
+
A("地理学", [("地","earth"),("理","principle"),("学","study")], "earth_principle_study", ["geography"])
|
|
115
|
+
A("生物学", [("生","living"),("物","thing"),("学","study")], "living_thing_study", ["biology"])
|
|
116
|
+
A("热力学", [("热","heat"),("力","force"),("学","study")], "heat_force_study", ["thermodynamics"])
|
|
117
|
+
# 人物
|
|
118
|
+
A("医生", [("医","medicine"),("生","person")], "medicine_person", ["doctor"])
|
|
119
|
+
A("学生", [("学","study"),("生","person")], "study_person", ["student"])
|
|
120
|
+
A("律师", [("律","law"),("师","master")], "law_master", ["lawyer"])
|
|
121
|
+
A("工人", [("工","work"),("人","person")], "work_person", ["worker"])
|
|
122
|
+
# 领域词(认知图相关)
|
|
123
|
+
A("知识图谱", [("知识","knowledge"),("图","graph"),("谱","map")], "knowledge_graph_map", ["knowledge graph"])
|
|
124
|
+
A("认知图", [("认知","cognition"),("图","graph")], "cognition_graph", [])
|
|
125
|
+
A("工作纪律", [("工作","work"),("纪律","discipline")], "work_discipline", [])
|
|
126
|
+
A("记忆库", [("记忆","memory"),("库","store")], "memory_store", [])
|
|
127
|
+
# 化石词(音译/古典,稳定单语素,保留既有英文)
|
|
128
|
+
A("经济", [("经济","economy")], "economy", ["economy"], "opaque")
|
|
129
|
+
A("逻辑", [("逻辑","logic")], "logic", ["logic"], "opaque")
|
|
130
|
+
A("沙发", [("沙发","sofa")], "sofa", ["sofa"], "opaque")
|
|
131
|
+
A("咖啡", [("咖啡","coffee")], "coffee", ["coffee"], "opaque")
|
|
132
|
+
A("巧克力", [("巧克力","chocolate")], "chocolate", ["chocolate"], "opaque")
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# 生效条件:无参调用时遍历模块级 E 的每条 (zh, glosses, std, legacy, cls),凡 zh 不以 glosses 语素 zh 顺序拼接结果开头、或 "_".join(glosses 英文) != std、或 re.search(r"[A-Z]", std) 命中者追加 problems 并 continue,其余条目进 entries;随后将含 MORPHEMES 与 entries 的 out 写入 __file__ 同目录下 standard_en.json,打印统计并逐条打印 problems,problems 非空返回 1,否则返回 0。
|
|
136
|
+
def main():
|
|
137
|
+
problems = []
|
|
138
|
+
entries = []
|
|
139
|
+
for zh, glosses, std, legacy, cls in E:
|
|
140
|
+
join_zh = "".join(z for z, _ in glosses)
|
|
141
|
+
if not zh.startswith(join_zh):
|
|
142
|
+
problems.append("%s: 语素拼合 %s != 词条 %s" % (zh, join_zh, zh))
|
|
143
|
+
continue
|
|
144
|
+
join_en = "_".join(e for _, e in glosses)
|
|
145
|
+
if join_en != std:
|
|
146
|
+
problems.append("%s: 标准英文 %s != 语素拼接 %s" % (zh, std, join_en))
|
|
147
|
+
continue
|
|
148
|
+
if re.search(r"[A-Z]", std):
|
|
149
|
+
problems.append("%s: 标准英文含大写(违 snake_case)" % zh)
|
|
150
|
+
continue
|
|
151
|
+
entries.append({"zh": zh, "glosses": [{"zh": z, "en": e} for z, e in glosses],
|
|
152
|
+
"standard_en": std, "legacy_en": legacy, "class": cls})
|
|
153
|
+
out = {
|
|
154
|
+
"meta": {"name": "lingshu-standard-en", "version": "0.1.0", "rules": "RULES.md",
|
|
155
|
+
"note": "英文标准 = 中文语素序直拼(snake_case);屈折归零;虚词不入名;音译化石词保留为 opaque;四问皆否不入库"},
|
|
156
|
+
"morphemes": MORPHEMES,
|
|
157
|
+
"entries": entries,
|
|
158
|
+
}
|
|
159
|
+
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "standard_en.json")
|
|
160
|
+
with io.open(path, "w", encoding="utf-8", newline="\n") as f:
|
|
161
|
+
json.dump(out, f, ensure_ascii=False, indent=1)
|
|
162
|
+
cls_cnt = collections.Counter(e["class"] for e in entries)
|
|
163
|
+
print("entries=%d morphemes=%d classes=%s problems=%d" % (
|
|
164
|
+
len(entries), len(MORPHEMES), dict(cls_cnt), len(problems)))
|
|
165
|
+
for p in problems:
|
|
166
|
+
print(" !", p)
|
|
167
|
+
return 1 if problems else 0
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
if __name__ == "__main__":
|
|
171
|
+
raise SystemExit(main())
|