Files
meihua-yishu/calculator/src/evidence.ts
T

626 lines
26 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 梅花易数证据链架构
* 参考 mingyu 项目的 evidence 模式,为排盘结果增加结构化证据链
*
* 核心原则:
* - 每个 fact 必须有具体的 limitation(不能是泛泛免责)
* - 证据链是增强层,不破坏现有排盘流程
* - 支持/约束/反证三位一体
*/
import { WUXING_SHENG, WUXING_KE, getTrigramByNumber } from './trigrams.js';
import type { HuaResult } from './analysis.js';
import { getTraditionalText } from './tradition.js';
// ═══════════════════════════════════════════
// 类型定义
// ═══════════════════════════════════════════
/** 证据阶段键 */
export type MeihuaStageKey = 'origin' | 'process' | 'result';
/** MeihuaFact 基础接口 — 所有 fact 的公共字段 */
export interface MeihuaFact {
key: string;
status: string;
promptText: string;
sources: string[];
limitation: string;
}
/** 卦象结构事实 */
export interface HexagramStructureFact extends MeihuaFact {
stage: MeihuaStageKey;
label: '主卦' | '互卦' | '变卦';
hexagramName: string;
symbol: string;
upperTrigram: string;
lowerTrigram: string;
nature: string;
judgment: string;
}
/** 阶段体用事实 */
export interface StageEvidence extends MeihuaFact {
stage: MeihuaStageKey;
label: string;
hexagramName: string;
ti: { name: string; element: string; seasonState: string };
yong: { name: string; element: string; seasonState: string };
relation: string;
support: string[];
constraints: string[];
basis: string;
}
/** 阶段推进事实(主→互→变的体用关系变化) */
export interface TransitionFact extends MeihuaFact {
fromStageKey: string;
toStageKey: string;
fromStage: MeihuaStageKey;
toStage: MeihuaStageKey;
fromRelation: string;
toRelation: string;
}
/** 反证事实 */
export interface CounterEvidenceFact extends MeihuaFact {
ownerStageKey: string;
stage: MeihuaStageKey;
type: '体用关系限制' | '体卦月令限制' | '用卦月令限制' | '现实复核限制';
detail: string;
}
/** 应期事实 */
export interface TimingFact extends MeihuaFact {
order: number;
type: '动爻层位' | '月建旺衰' | '体卦状态' | '原应期条件';
rawText?: string;
}
/** 传统文本事实(卦辞/爻辞) */
export interface TraditionalTextFact extends MeihuaFact {
stage: '主卦' | '互卦' | '变卦';
hexagram: string;
kind: '卦辞' | '爻辞' | '用辞';
yaoPosition?: number;
applicability: '当前卦辞辅助' | '当前动爻辅助' | '未发动背景' | '特殊用辞背景';
originalText: string;
traditionalSignals: string[];
topicTags: string[];
}
/** 完整的证据链分析结果 */
export interface MeihuaEvidenceAnalysis {
key: 'meihua:evidence';
status: '已计算';
// 卦象结构
hexagramFacts: HexagramStructureFact[];
// 阶段体用
stages: StageEvidence[];
// 阶段推进
transitionFacts: TransitionFact[];
// 反证
counterEvidenceFacts: CounterEvidenceFact[];
counterSummary: { status: '有明确反证' | '未见明确反证'; detail: string };
// 应期
timingFacts: TimingFact[];
// 传统文本
traditionalFacts: TraditionalTextFact[];
// 汇总
summary: {
factCount: number;
stageCount: number;
transitionCount: number;
counterCount: number;
traditionalCount: number;
timingCount: number;
};
// 全局限制
limitations: string[];
// 原始 prompt 文本
promptText: string;
}
// ═══════════════════════════════════════════
// 限制声明常量(每个类型的具体约束)
// ═══════════════════════════════════════════
const STAGE_FACT_LIMITATION =
'阶段体用事实只描述主卦、互卦或变卦中的体用五行关系与月令旺衰;阶段标签、支持或限制不得直接解释为现实起因、过程、结果、吉凶或成功率' as const;
const HEXAGRAM_FACT_LIMITATION =
'主互变卦象事实只记录当前上下经卦、卦名与卦符;不得由卦名或阶段位置直接推断现实事件、人物、吉凶、成败或应期' as const;
const TRANSITION_FACT_LIMITATION =
'阶段推进事实只比较相邻已记录阶段的体用关系变化;不得把卦内先后直接写成现实事件必然按同样顺序发生,跨阶段缺口时更不得补造中间过程' as const;
const COUNTER_FACT_LIMITATION =
'反证事实只表示某一阶段存在泄耗、受克、休囚死或待现实复核等限制;不得把单项反证直接写成现实失败、灾祸、伤病、损失或必然结果' as const;
const COUNTER_SUMMARY_LIMITATION =
'反证汇总只说明当前阶段核验是否发现明确限制;未见明确反证不代表现实风险为零,也不得按反证数量换算吉凶总分或成功率' as const;
const TIMING_FACT_LIMITATION =
'应期事实只提供动爻层位、体用生克、月令旺衰与现实条件的相对触发;不得把爻位、卦数、阶段数量或旺衰换算唯一日期,也不证明事件必然发生' as const;
const TRADITIONAL_FACT_LIMITATION =
'卦辞与爻辞是《周易》传统取象原文,只用于当前主互变结构和动爻层位的辅助解释,不证明现实吉凶、婚育、疾病、伤亡、诉讼、财物得失、人物意图或固定时间结果' as const;
const SUMMARY_FACT_LIMITATION =
'梅花证据汇总只统计起卦、主互变卦象、体用、推进、传统文本、反证与应期事实的覆盖情况;不得按数量生成吉凶总分、成功率、人物意图或唯一日期' as const;
// ═══════════════════════════════════════════
// 辅助函数
// ═══════════════════════════════════════════
function unique(values: string[]): string[] {
return Array.from(new Set(values.filter(Boolean)));
}
/** 判断旺相休囚死 */
function getSeasonState(element: string, season: string): string {
const s = season;
// 旺
if ((s.includes('春') && element === '木') ||
(s.includes('夏') && element === '火') ||
(s.includes('秋') && element === '金') ||
(s.includes('冬') && element === '水') ||
(s.includes('末') && element === '土')) return '旺';
// 相(被旺者所生)
if ((s.includes('春') && element === '火') ||
(s.includes('夏') && element === '土') ||
(s.includes('秋') && element === '水') ||
(s.includes('冬') && element === '木') ||
(s.includes('末') && element === '金')) return '相';
// 休(生旺者)
if ((s.includes('春') && element === '水') ||
(s.includes('夏') && element === '木') ||
(s.includes('秋') && element === '土') ||
(s.includes('冬') && element === '金') ||
(s.includes('末') && element === '火')) return '休';
// 囚(克旺者)
if ((s.includes('春') && element === '金') ||
(s.includes('夏') && element === '水') ||
(s.includes('秋') && element === '木') ||
(s.includes('冬') && element === '土') ||
(s.includes('末') && element === '火')) return '囚';
// 死(被旺者所克,或被克者)
return '死';
}
/** 体用关系 → 支持/约束 */
function relationEvidence(relation: string): { support: string[]; constraints: string[] } {
switch (relation) {
case '用生体': return { support: ['外来助力生扶体卦'], constraints: [] };
case '比和': return { support: ['体用同五行,关系同气'], constraints: ['仍须结合旺衰与现实条件'] };
case '体克用': return { support: ['体卦对用卦具有制约能力'], constraints: ['主动推进可能伴随消耗'] };
case '体生用': return { support: ['体卦向事项一方投入'], constraints: ['体卦存在泄耗'] };
case '用克体': return { support: [], constraints: ['外部事项对体卦形成压力'] };
default: return { support: [], constraints: ['现有资料不足以确定五行关系'] };
}
}
/** 旺衰 → 支持/约束 */
function stateEvidence(role: '体' | '用', state: string): { support: string[]; constraints: string[] } {
if (state === '旺' || state === '相') return { support: [`${role}卦得月令${state}`], constraints: [] };
if (state === '休' || state === '囚' || state === '死') return { support: [], constraints: [`${role}卦月令${state}`] };
return { support: [], constraints: [] };
}
/** 判断五行关系(返回简化标签) */
function getRelationLabel(tiElement: string, yongElement: string): string {
if (tiElement === yongElement) return '比和';
if (WUXING_SHENG[yongElement] === tiElement) return '用生体';
if (WUXING_SHENG[tiElement] === yongElement) return '体生用';
if (WUXING_KE[yongElement] === tiElement) return '用克体';
if (WUXING_KE[tiElement] === yongElement) return '体克用';
return '关系未定';
}
/** 传统文本信号分类 */
function classifyTraditionalSignals(text: string): string[] {
const riskText = text.replace(/无咎|无悔|悔亡|无不利/g, '');
return unique([
/吉|亨|利|无咎|悔亡|无悔|无不利/.test(text) ? '传统有利或通达标签' : '',
/凶|厉|吝|悔|咎|灾|不利|无攸利/.test(riskText) ? '传统风险或受限标签' : '',
/贞|永贞/.test(text) ? '守正与持续条件标签' : '',
/往|征|涉|行|进|退|出|入/.test(text) ? '行动与进退标签' : '',
]);
}
/** 传统文本主题分类 */
function classifyTraditionalTopics(text: string): string[] {
return unique([
/女|妇|婚|归妹|孕|夫|妻/.test(text) ? '关系与婚育类象' : '',
/死|疾|病|灾|伤|血|丧|亡/.test(text) ? '健康伤亡与损失类象' : '',
/讼|狱|刑|伐|师|寇|攻/.test(text) ? '争议、刑罚与攻守类象' : '',
/财|资|获|得|食|畜|货/.test(text) ? '资源与得失类象' : '',
/年|月|日|岁|旬|三年|八月/.test(text) ? '传统时间措辞' : '',
/王|君子|大人|小人|侯/.test(text) ? '身份与角色类象' : '',
]);
}
// ═══════════════════════════════════════════
// 证据链生成函数
// ═══════════════════════════════════════════
/**
* 为排盘结果生成完整证据链
* @param result calculateHua() 的返回值
* @param input 原始输入(用于获取起卦参数)
*/
export function buildEvidence(result: HuaResult): MeihuaEvidenceAnalysis {
const season = result.wangShuai.season;
const dongYao = result.dongYao;
const tiElement = result.wuxingAnalysis.tiElement;
const yongElement = result.wuxingAnalysis.yongElement;
// ── 1. 卦象结构事实 ──
const hexagramFacts = buildHexagramFacts(result);
// ── 2. 阶段体用事实 ──
const stages = buildStageEvidence(result, season);
// ── 3. 阶段推进事实 ──
const transitionFacts = buildTransitionFacts(stages);
// ── 4. 反证 ──
const counterEvidenceFacts = buildCounterEvidence(stages);
const counterSummary = {
status: counterEvidenceFacts.length > 0 ? '有明确反证' as const : '未见明确反证' as const,
detail: counterEvidenceFacts.length > 0
? `发现${counterEvidenceFacts.length}条反证:${counterEvidenceFacts.map(f => f.detail).join(';')}`
: '当前盘面未见明确反证',
limitation: COUNTER_SUMMARY_LIMITATION,
};
// ── 5. 应期 ──
const timingFacts = buildTimingFacts(result, season);
// ── 6. 传统文本 ──
const traditionalFacts = buildTraditionalFacts(result, dongYao);
// ── 7. 汇总 ──
const factCount = hexagramFacts.length + stages.length + transitionFacts.length
+ counterEvidenceFacts.length + timingFacts.length + traditionalFacts.length;
const summary = {
factCount,
stageCount: stages.length,
transitionCount: transitionFacts.length,
counterCount: counterEvidenceFacts.length,
traditionalCount: traditionalFacts.length,
timingCount: timingFacts.length,
limitation: SUMMARY_FACT_LIMITATION,
};
// ── 全局限制 ──
const limitations = [
'梅花易数证据链仅描述卦象结构、体用五行关系与月令旺衰,不证明现实吉凶、成败、概率或固定应期',
'传统卦辞爻辞是《周易》原文辅助,不直接对应现实事件、人物、婚育、疾病、伤亡或诉讼',
'反证与支持仅反映盘面五行生克状态,不代表现实中的必然结果或风险为零',
'应期分析只提供相对触发条件,不得换算为绝对日期或时间节点',
];
// ── promptText ──
const promptText = [
...hexagramFacts.map(f => f.promptText),
...stages.map(f => f.promptText),
...transitionFacts.map(f => f.promptText),
...counterEvidenceFacts.map(f => f.promptText),
counterSummary.detail,
...timingFacts.map(f => f.promptText),
...traditionalFacts.map(f => f.promptText),
].join('\n');
return {
key: 'meihua:evidence',
status: '已计算',
hexagramFacts,
stages,
transitionFacts,
counterEvidenceFacts,
counterSummary,
timingFacts,
traditionalFacts,
summary,
limitations,
promptText,
};
}
// ── 子生成器 ──
function buildHexagramFacts(result: HuaResult): HexagramStructureFact[] {
const defs = [
{ stage: 'origin' as MeihuaStageKey, label: '主卦' as const, hex: result.mainHexagram.hexagram, upperName: result.mainHexagram.upper.name, lowerName: result.mainHexagram.lower.name },
{ stage: 'process' as MeihuaStageKey, label: '互卦' as const, hex: result.mutualHexagram, upperName: result.mutualHexagram.upper.name, lowerName: result.mutualHexagram.lower.name },
{ stage: 'result' as MeihuaStageKey, label: '变卦' as const, hex: result.changedHexagram, upperName: result.changedHexagram.upper.name, lowerName: result.changedHexagram.lower.name },
];
return defs.map(({ stage, label, hex, upperName, lowerName }) => ({
key: `meihua:hexagram:${stage}`,
status: '已记录',
stage,
label,
hexagramName: hex.name,
symbol: hex.symbol,
upperTrigram: upperName,
lowerTrigram: lowerName,
nature: hex.nature,
judgment: hex.judgment,
promptText: `${label}${hex.name}${hex.symbol},上${upperName}下${lowerName},${hex.judgment}`,
sources: ['先天八卦取数', '六十四卦结构'],
limitation: HEXAGRAM_FACT_LIMITATION,
}));
}
function buildStageEvidence(result: HuaResult, season: string): StageEvidence[] {
const tiPos = result.tiGua.position;
const yongPos = result.yongGua.position;
// 主卦体用
const mainTiName = result.tiGua.trigram.name;
const mainYongName = result.yongGua.trigram.name;
const mainRelation = getRelationLabel(result.tiGua.trigram.element, result.yongGua.trigram.element);
// 互卦体用:体卦位置不变,互卦对应位置
const mutualTiNum = tiPos === 'upper' ? result.mutualHexagram.upper : result.mutualHexagram.lower;
const mutualYongNum = yongPos === 'upper' ? result.mutualHexagram.upper : result.mutualHexagram.lower;
const mutualTi = getTrigramByNumber(mutualTiNum);
const mutualYong = getTrigramByNumber(mutualYongNum);
const mutualRelation = getRelationLabel(mutualTi.element, mutualYong.element);
// 变卦体用
const changedTiNum = tiPos === 'upper' ? result.changedHexagram.upper : result.changedHexagram.lower;
const changedYongNum = yongPos === 'upper' ? result.changedHexagram.upper : result.changedHexagram.lower;
const changedTi = getTrigramByNumber(changedTiNum);
const changedYong = getTrigramByNumber(changedYongNum);
const changedRelation = getRelationLabel(changedTi.element, changedYong.element);
const defs = [
{
stage: 'origin' as MeihuaStageKey, label: '主卦', hexName: result.mainHexagram.hexagram.name,
ti: { name: mainTiName, element: result.tiGua.trigram.element },
yong: { name: mainYongName, element: result.yongGua.trigram.element },
relation: mainRelation,
basis: `动爻第${result.dongYao}爻在${result.dongYao <= 3 ? '下卦' : '上卦'},${result.dongYao <= 3 ? '上卦' : '下卦'}为体`,
},
{
stage: 'process' as MeihuaStageKey, label: '互卦', hexName: result.mutualHexagram.name,
ti: { name: mutualTi.name, element: mutualTi.element },
yong: { name: mutualYong.name, element: mutualYong.element },
relation: mutualRelation,
basis: '体卦位置与主卦一致,互卦取主卦2/3/4爻为下卦、3/4/5爻为上卦',
},
{
stage: 'result' as MeihuaStageKey, label: '变卦', hexName: result.changedHexagram.name,
ti: { name: changedTi.name, element: changedTi.element },
yong: { name: changedYong.name, element: changedYong.element },
relation: changedRelation,
basis: '体卦位置与主卦一致,变卦由动爻阴阳互换所得',
},
];
return defs.map(({ stage, label, hexName, ti, yong, relation, basis }) => {
const relEv = relationEvidence(relation);
const tiState = getSeasonState(ti.element, season);
const yongState = getSeasonState(yong.element, season);
const tiEv = stateEvidence('体', tiState);
const yongEv = stateEvidence('用', yongState);
const support = [...relEv.support, ...tiEv.support, ...yongEv.support];
const constraints = [...relEv.constraints, ...tiEv.constraints, ...yongEv.constraints];
const promptText = `${label}${hexName}:体卦${ti.name}${ti.element}(月令${tiState}),用卦${yong.name}${yong.element}(月令${yongState}),关系${relation};依据:${basis};支持:${support.join('、') || '未见额外增强'};限制:${constraints.join('、') || '未见明确盘内限制'}`;
return {
key: `meihua:stage:${stage}`,
status: '已计算',
stage,
label,
hexagramName: hexName,
ti: { ...ti, seasonState: tiState },
yong: { ...yong, seasonState: yongState },
relation,
support,
constraints,
basis,
promptText,
sources: ['动爻所在经卦定体用规则', '主卦、互卦、变卦上下经卦五行', `月建${season}与五行旺相休囚死关系`],
limitation: STAGE_FACT_LIMITATION,
};
});
}
function buildTransitionFacts(stages: StageEvidence[]): TransitionFact[] {
const transitions: TransitionFact[] = [];
for (let i = 0; i < stages.length - 1; i++) {
const from = stages[i];
const to = stages[i + 1];
const changed = from.relation !== to.relation;
transitions.push({
key: `meihua:transition:${from.stage}-${to.stage}`,
status: '连续',
fromStageKey: from.key,
toStageKey: to.key,
fromStage: from.stage,
toStage: to.stage,
fromRelation: from.relation,
toRelation: to.relation,
promptText: `${from.label}→${to.label}:体用关系由「${from.relation}」${changed ? '变为' : '保持'}「${to.relation}」${changed ? ',存在变化' : ',关系稳定'}`,
sources: ['阶段体用关系比较'],
limitation: TRANSITION_FACT_LIMITATION,
});
}
return transitions;
}
function buildCounterEvidence(stages: StageEvidence[]): CounterEvidenceFact[] {
const counters: CounterEvidenceFact[] = [];
for (const stage of stages) {
// 体卦受克
if (stage.relation === '用克体') {
counters.push({
key: `meihua:counter:${stage.stage}:用克体`,
ownerStageKey: stage.key,
stage: stage.stage,
type: '体用关系限制',
status: '已触发',
detail: `${stage.label}体卦${stage.ti.name}${stage.ti.element}受用卦${stage.yong.name}${stage.yong.element}克制`,
promptText: `反证:${stage.label}体卦${stage.ti.name}受用卦${stage.yong.name}克制,存在外来压力`,
sources: ['五行克关系'],
limitation: COUNTER_FACT_LIMITATION,
});
}
// 体生用(泄耗)
if (stage.relation === '体生用') {
counters.push({
key: `meihua:counter:${stage.stage}:体生用`,
ownerStageKey: stage.key,
stage: stage.stage,
type: '体用关系限制',
status: '已触发',
detail: `${stage.label}体卦${stage.ti.name}${stage.ti.element}生用卦${stage.yong.name}${stage.yong.element},体卦泄耗`,
promptText: `反证:${stage.label}体卦${stage.ti.name}生用卦${stage.yong.name},体卦存在泄耗`,
sources: ['五行生关系'],
limitation: COUNTER_FACT_LIMITATION,
});
}
// 体卦休囚死
if (['休', '囚', '死'].includes(stage.ti.seasonState)) {
counters.push({
key: `meihua:counter:${stage.stage}:体卦${stage.ti.seasonState}`,
ownerStageKey: stage.key,
stage: stage.stage,
type: '体卦月令限制',
status: '已触发',
detail: `${stage.label}体卦${stage.ti.name}${stage.ti.element}月令${stage.ti.seasonState},不得时`,
promptText: `反证:${stage.label}体卦${stage.ti.name}月令${stage.ti.seasonState},体卦不得时`,
sources: ['月令旺衰'],
limitation: COUNTER_FACT_LIMITATION,
});
}
}
return counters;
}
function buildTimingFacts(result: HuaResult, season: string): TimingFact[] {
const facts: TimingFact[] = [];
const tiElement = result.tiGua.trigram.element;
// 动爻层位
facts.push({
key: 'meihua:timing:dongYao',
order: 1,
type: '动爻层位',
status: '已计算',
rawText: `动爻第${result.dongYao}爻`,
promptText: `应期参考:动爻第${result.dongYao}爻(${result.dongYao <= 3 ? '下卦' : '上卦'}),动爻所在经卦为用卦`,
sources: ['动爻位置'],
limitation: TIMING_FACT_LIMITATION,
});
// 月建旺衰
facts.push({
key: 'meihua:timing:season',
order: 2,
type: '月建旺衰',
status: '已计算',
rawText: season,
promptText: `应期参考:当令${season},体卦${tiElement}${result.wangShuai.tiWang ? '旺' : '衰'}`,
sources: ['月令旺衰'],
limitation: TIMING_FACT_LIMITATION,
});
// 体卦状态
const tiState = getSeasonState(tiElement, season);
facts.push({
key: 'meihua:timing:tiState',
order: 3,
type: '体卦状态',
status: '已计算',
rawText: `体卦${result.tiGua.trigram.name}${tiElement}月令${tiState}`,
promptText: `应期参考:体卦${result.tiGua.trigram.name}${tiElement}月令${tiState},${tiState === '旺' || tiState === '相' ? '体旺则应期近' : '体衰则应期远或需待旺时'}`,
sources: ['体卦月令状态'],
limitation: TIMING_FACT_LIMITATION,
});
return facts;
}
function buildTraditionalFacts(result: HuaResult, dongYao: number): TraditionalTextFact[] {
const stages = [
{ stage: '主卦' as const, upperNum: result.mainHexagram.upper.number, lowerNum: result.mainHexagram.lower.number, hexName: result.mainHexagram.hexagram.name, judgment: result.mainHexagram.hexagram.judgment },
{ stage: '互卦' as const, upperNum: result.mutualHexagram.upper as number, lowerNum: result.mutualHexagram.lower as number, hexName: result.mutualHexagram.name, judgment: result.mutualHexagram.judgment },
{ stage: '变卦' as const, upperNum: result.changedHexagram.upper as number, lowerNum: result.changedHexagram.lower as number, hexName: result.changedHexagram.name, judgment: result.changedHexagram.judgment },
];
const facts: TraditionalTextFact[] = [];
for (const { stage, upperNum, lowerNum, hexName, judgment } of stages) {
const text = getTraditionalText(upperNum, lowerNum);
if (!text) continue;
// 卦辞
const judgmentSignals = classifyTraditionalSignals(judgment);
const judgmentTopics = classifyTraditionalTopics(judgment);
facts.push({
key: `${stage}:${hexName}:卦辞`,
status: '已映射',
stage,
hexagram: hexName,
kind: '卦辞',
applicability: '当前卦辞辅助',
originalText: judgment,
promptText: `${stage}${hexName}卦辞「${judgment}」包含${judgmentSignals.join('、') || '未见明确标签'},涉及${judgmentTopics.join('、') || '通用处境类象'};只作为该阶段卦象的传统分类辅助`,
traditionalSignals: judgmentSignals,
topicTags: judgmentTopics,
sources: ['《周易》卦辞', '六十四卦原文资料'],
limitation: TRADITIONAL_FACT_LIMITATION,
});
// 爻辞
for (let i = 0; i < text.yaoCi.length; i++) {
const yaoPosition = i + 1;
const isMoving = stage === '主卦' && yaoPosition === dongYao;
const yaoText = text.yaoCi[i];
const yaoSignals = classifyTraditionalSignals(yaoText);
const yaoTopics = classifyTraditionalTopics(yaoText);
facts.push({
key: `${stage}:${hexName}:爻辞:${yaoPosition}`,
status: '已映射',
stage,
hexagram: hexName,
kind: '爻辞',
yaoPosition,
applicability: isMoving ? '当前动爻辅助' : '未发动背景',
originalText: yaoText,
promptText: `${stage}${hexName}第${yaoPosition}爻「${yaoText}」包含${yaoSignals.join('、') || '未见明确标签'},涉及${yaoTopics.join('、') || '通用处境类象'};${isMoving ? '当前爻位已发动,可作为动爻层位的传统辅助' : '当前爻位未发动,不作为独立判断依据'}`,
traditionalSignals: yaoSignals,
topicTags: yaoTopics,
sources: ['《周易》爻辞', '六十四卦逐爻原文资料'],
limitation: TRADITIONAL_FACT_LIMITATION,
});
}
// 用辞(乾坤)
if (text.yongCi) {
const yongSignals = classifyTraditionalSignals(text.yongCi);
const yongTopics = classifyTraditionalTopics(text.yongCi);
facts.push({
key: `${stage}:${hexName}:用辞`,
status: '已映射',
stage,
hexagram: hexName,
kind: '用辞',
applicability: '特殊用辞背景',
originalText: text.yongCi,
promptText: `${stage}${hexName}用辞「${text.yongCi}」包含${yongSignals.join('、') || '未见明确标签'},涉及${yongTopics.join('、') || '通用处境类象'};本次采用单动爻起卦,不满足六爻皆变的特殊用辞条件`,
traditionalSignals: yongSignals,
topicTags: yongTopics,
sources: ['《周易》乾坤用九用六', '六十四卦特殊用辞资料'],
limitation: TRADITIONAL_FACT_LIMITATION,
});
}
}
return facts;
}