feat: 梅花易数证据链架构 + 64卦爻辞
This commit is contained in:
1 parent
0a7858bc98
commit
cea8e012b5
4 files changed
+1364
-1
No files matched your search
@@ -0,0 +1,625 @@
|
||||
/**
|
||||
* 梅花易数证据链架构
|
||||
* 参考 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;
|
||||
}
|
||||
Reference in new issue
Block a user