如何使用pyswip动态查询Prolog知识库 避免编写大量if语句
报错原因
核心问题是你拼接查询语句时额外添加了不需要的外层双引号。pyswip的query()方法接收原生Prolog语法的字符串,不需要包裹引号。你生成的查询字符串是"asd(sa, X)"(带前后双引号),Prolog会把整个带引号的字符串当做谓词名称尝试调用,自然找不到对应谓词,触发类型错误。
修复后的基础实现
直接去掉多余的引号即可,推荐用f-string简化拼接逻辑,无需定义多个零散变量:
def prolog_search(predicate, first_arg): # 拼接符合Prolog语法的查询语句,无多余外层引号 query_str = f"{predicate}({first_arg}, X)" print(f"执行查询:{query_str}") result = list(prolog.query(query_str)) print(f"查询结果:{result}") return result # 测试调用,对应Prolog查询 asd(sa, X) prolog_search("asd", "sa")
更合理的通用查询实现方案
针对你需要适配上百类查询的场景,推荐用配置映射表替代if分支,后续新增查询仅需更新配置表,无需修改逻辑代码:
# 语音指令到Prolog查询的映射表,新增查询仅需在此添加条目 COMMAND_CONFIG = { "son": { "predicate": "father", "fixed_arg": "michael", # 变量位置:表示返回值是谓词的第2个参数(索引从0开始) "var_index": 1 }, "daughter": { "predicate": "father", "fixed_arg": "dory", "var_index": 1 } # 剩余上百类查询直接在此添加配置即可 } def generic_prolog_search(command_key): # 未匹配到指令直接返回空结果 if command_key not in COMMAND_CONFIG: return [] conf = COMMAND_CONFIG[command_key] # 构造参数列表,变量位置放X,其余位置放固定参数 args = [] # 此处以二元谓词为例,多参数谓词修改参数个数即可 for i in range(2): args.append("X" if i == conf["var_index"] else conf["fixed_arg"]) query_str = f"{conf['predicate']}({','.join(args)})" return list(prolog.query(query_str)) # 实际使用时直接传入语音识别得到的指令即可 voice_command = "son" print(generic_prolog_search(voice_command))
注意:如果你的Prolog谓词参数包含空格、特殊字符,需要按照Prolog语法给参数包裹单引号,例如带空格的人名要写成
'Michael Jackson',拼接时做对应处理即可。
内容的提问来源于stack exchange,提问作者user13513777
相关产品推荐
相关产品推荐

