You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pytholog定义带症状列表的知识库查询失败,求解决方法

问题

想用pytholog构建一个疾病对应症状列表的知识库,写了如下代码:

import pytholog as pl
diseases_kb = pl.KnowledgeBase()
diseases_kb([
     "disease(diabetes, [frequent_urination, extreme_thirst])",
     "disease(pneumonia, [cough, fever, shortness_of_breath])",
])

但执行查询print(diseases_kb.query(pl.Expr("disease(diabetes, Symptoms)")))时,返回结果是['No']。试过用()、list()替换列表语法都没用,怀疑是pytholog解析时会移除括号并按逗号拆分参数,有没有可行的解决办法?

解决办法

pytholog基于Prolog实现,而Prolog的事实参数并不支持Python风格的列表直接解析,得换用符合Prolog规范的方式来处理,这里有几种可行方案:

方案1:拆分疾病-症状为独立事实(推荐)

这是Prolog中存储一对多关系的标准做法,避免列表参数的解析问题,同时更灵活:

import pytholog as pl
diseases_kb = pl.KnowledgeBase()
# 添加疾病-症状对应事实
diseases_kb([
     "disease_symptom(diabetes, frequent_urination)",
     "disease_symptom(diabetes, extreme_thirst)",
     "disease_symptom(pneumonia, cough)",
     "disease_symptom(pneumonia, fever)",
     "disease_symptom(pneumonia, shortness_of_breath)",
     # 定义规则,用findall收集某疾病的所有症状
     "get_disease_symptoms(Disease, Symptoms) :- findall(S, disease_symptom(Disease, S), Symptoms)"
])
# 查询糖尿病的症状
print(diseases_kb.query(pl.Expr("get_disease_symptoms(diabetes, Symptoms)")))

执行后会返回[{'Symptoms': ['frequent_urination', 'extreme_thirst']}],完全符合需求。

方案2:使用Prolog兼容的列表语法直接定义

如果坚持要保留列表形式,确保定义和查询都使用Prolog的列表语法,同时用pl.Expr构造事实:

import pytholog as pl
diseases_kb = pl.KnowledgeBase()
# 用pl.Expr包装每个事实,确保列表被正确解析
diseases_kb([
    pl.Expr("disease(diabetes, [frequent_urination, extreme_thirst])"),
    pl.Expr("disease(pneumonia, [cough, fever, shortness_of_breath])")
])
# 查询
result = diseases_kb.query(pl.Expr("disease(diabetes, Symptoms)"))
print(result)

这种方式能让pytholog正确识别列表参数,返回预期的症状列表。

方案3:手动构造列表参数(调试用)

如果上述方法仍有问题,可以尝试将列表作为原子字符串传递,再通过Prolog规则转换:

import pytholog as pl
diseases_kb = pl.KnowledgeBase()
diseases_kb([
     "disease(diabetes, 'frequent_urination,extreme_thirst')",
     "disease(pneumonia, 'cough,fever,shortness_of_breath')",
     # 定义规则拆分字符串为列表
     "split_symptoms(Str, List) :- split_string(Str, ',', '', List)",
     "get_disease_symptoms(Disease, Symptoms) :- disease(Disease, SymStr), split_symptoms(SymStr, Symptoms)"
])
# 查询
print(diseases_kb.query(pl.Expr("get_disease_symptoms(diabetes, Symptoms)")))

不过这种方式需要依赖Prolog的字符串处理能力,通用性不如前两种方案。


内容的提问来源于stack exchange,提问作者Elissa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:10:21