66 lines
5.0 KiB
PHP
66 lines
5.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
|
require __DIR__ . '/fixtures/CompleteTcmCase.php';
|
|
|
|
use app\adminapi\service\TcmClinicalFactStateGuard as Guard;
|
|
use app\adminapi\service\TcmClinicalReportStream;
|
|
|
|
$count = 0;
|
|
function knowledgeRoleCheck(array $ledger, string $text, bool $expected): void
|
|
{
|
|
++$GLOBALS['count'];
|
|
$review = Guard::validate($ledger, $text);
|
|
if ($review['valid'] !== $expected) throw new RuntimeException('Knowledge role mismatch: ' . json_encode([$text, $review], JSON_UNESCAPED_UNICODE));
|
|
$visible = '';
|
|
$stream = new TcmClinicalReportStream($ledger, static function (string $delta) use (&$visible): bool { $visible .= $delta; return true; });
|
|
$raw = $text . "\r\n\r\n";
|
|
foreach (str_split($raw, 7) as $chunk) if (!$stream->push($chunk)) break;
|
|
++$GLOBALS['count'];
|
|
if ($stream->finish() !== $expected || $stream->rejected() !== !$expected) throw new RuntimeException('Stream role mismatch');
|
|
if ($expected) {
|
|
++$GLOBALS['count'];
|
|
if ($visible !== $raw) throw new RuntimeException('A valid epistemic role must preserve every original byte');
|
|
}
|
|
}
|
|
$ledger = Guard::build(['id' => 1, 'diagnosis_date' => '2026-10-23',
|
|
'present_illness' => '口干。无胸痛。未记录固定刺痛。',
|
|
'tongue' => '舌质淡红,苔少。', 'pulse' => '脉细弱。']);
|
|
foreach (['未见', '没有', '无'] as $marker) foreach (['足以', '能够'] as $modal)
|
|
foreach (['确认', '支持', '证实'] as $relation) foreach (['依据', '证据'] as $noun) {
|
|
knowledgeRoleCheck($ledger, $marker . $modal . $relation . '固定刺痛的本次' . $noun . '。', true);
|
|
knowledgeRoleCheck($ledger, $marker . $modal . $relation . '口干的本次' . $noun . '。', false);
|
|
knowledgeRoleCheck($ledger, $marker . $modal . $relation . '胸痛的当前' . $noun . '。', false);
|
|
}
|
|
foreach (['空值', '空白', '缺项', '默认值', '缺失资料'] as $metadata)
|
|
foreach (['正常', '无异常', '无症状', '明确阴性'] as $inner) {
|
|
knowledgeRoleCheck($ledger, '固定刺痛未记录,不能据' . $metadata . '判为' . $inner . '。', true);
|
|
knowledgeRoleCheck($ledger, '不能据' . $metadata . '判为' . $inner . ',患者无固定刺痛。', false);
|
|
}
|
|
foreach (['属', '属于', '为'] as $copula) foreach (['而非', '不是'] as $contrast)
|
|
foreach (['否认', '明确否认', '阴性记录'] as $record) {
|
|
knowledgeRoleCheck($ledger, '固定刺痛' . $copula . '未记录' . $contrast . $record . '。', true);
|
|
knowledgeRoleCheck($ledger, '口干' . $copula . '未记录' . $contrast . $record . '。', false);
|
|
knowledgeRoleCheck($ledger, '胸痛' . $copula . '未记录' . $contrast . $record . '。', false);
|
|
}
|
|
foreach ([
|
|
'未见足以确认血瘀的本次依据,患者有固定刺痛。',
|
|
'未见足以确认血瘀的本次依据,但口干未记录。',
|
|
'未见足以确认患者有固定刺痛的本次依据。',
|
|
'不能据空值判为无异常且患者无固定刺痛。',
|
|
'不能据空值判为无异常,舌质红绛。',
|
|
'不能据空值判为无异常,脉滑。',
|
|
'固定刺痛属未记录而非否认,患者无固定刺痛。',
|
|
'固定刺痛属未记录而非否认且患者有固定刺痛。',
|
|
'本次无固定刺痛,现有资料有待核实。',
|
|
] as $invalid) knowledgeRoleCheck($ledger, $invalid, false);
|
|
|
|
$fixture = Guard::build(CompleteTcmCase::current());
|
|
knowledgeRoleCheck($fixture, '虚实:神疲、语声低微、动则气短、自汗,脉细弱且按之无力,支持虚证;未见足以确认邪实壅盛的本次依据。阴阳:整体属虚,可偏归阴证范畴,但“阴证”仅为八纲总属,不等于已证实阳虚;现有证据不足以确认阴虚热证或阳虚寒证。', true);
|
|
knowledgeRoleCheck($fixture, '明确阴性:2026-10-23“无恶寒发热,”(s2);“无高热烦渴、汗出淋漓或意识异常”(s2);“无明显五心烦热、潮热盗汗,”(s2);“无畏寒肢冷”(s2);“无咳嗽咯痰、胸痛心悸、浮肿或腹泻”(s2);“无明显急性感染诱因”(s2);“无喘促及异常气味”(s3);“无已知冠心病、心衰或慢性肾病”(s4);“无已知药物过敏史”(s5);“未使用胰岛素或中药”(s6)。' . "\n" . '未知:“未记录腰酸耳鸣或固定刺痛”(s2);婚姻、地区、饮食总量、每日饮水量及近期体重变化等未记录,不能据空值判为无异常。', true);
|
|
knowledgeRoleCheck($fixture, '固定刺痛属未记录而非否认(s2),舌无紫暗瘀斑(s9),仅提示当前血瘀依据不足。', true);
|
|
knowledgeRoleCheck($fixture, '固定刺痛属未记录而非否认(s2),舌质淡红而非明确淡白。', false);
|
|
knowledgeRoleCheck($fixture, '无明显急性感染诱因。', true);
|
|
knowledgeRoleCheck($fixture, '无急性感染诱因。', false);
|
|
echo "Clinical knowledge/data role: {$count} assertions passed (portable, exact streaming bytes).\n";
|