You need to enable JavaScript to run this app. Prolog执行verificar相关代码时触发si(A)过程不存在错误
优惠活动
大模型
产品
解决方案
定价
更多

Prolog执行verificar相关代码时触发si(A)过程不存在错误

报错成因
  • 触发该报错的核心原因是Prolog引擎的谓词存在性校验机制:默认情况下引擎会对所有被调用的谓词做静态检查,如果某谓词既没有在源码中做显式定义,也没有提前声明为可动态修改的谓词,运行时一旦尝试查询该谓词,就会抛出procedure 'xxx' does not exist的错误提示。
  • 对应代码中,si/1、no/1是用于存储用户问诊回答的动态事实库:只有当用户针对某个症状给出“是/否”的明确答复后,才会通过assert/1在运行时往数据库中插入对应的事实。但全程没有对这两个谓词做动态声明,导致执行流走到verificar(S)分支首次尝试查询si(S)时,引擎根本无法识别这个未注册的谓词,直接中断执行抛出错误。从报错给出的可达调用链evaluar -> hipotesis(A) -> resfriado -> verificar(A)也可佐证,此时si(A)的查询发生在任何动态事实插入之前,完全没有对应的谓词定义存在。
解决方案
  • 在所有谓词定义的最开头,添加全局动态谓词声明,明确告知Prolog引擎这两个谓词支持运行时动态增删事实,无需提前做静态存在性校验,声明语句为:
    :- dynamic si/1, no/1.
    
  • 需确保动态声明是全局位置的语句,不要写在某个业务谓词的内部,避免声明作用域不生效。
  • 修复完成后的核心代码可参考如下写法:
    % 全局声明动态存储的事实谓词
    :- dynamic si/1, no/1.
    
    verificar(S) :-
        (si(S)
        ->  
        true ;
        (no(S)
        ->  
        fail ;
        preguntar(S))).
    
    preguntar(Pregunta) :- 
        write('Tiene los siguientes sintomas: '),
        write(Pregunta),
        write('?'),
        read(Respuesta),
        nl,
        ( (Respuesta == si)
        ->  
        assert(si(Pregunta));
        assert(no(Pregunta)), fail).
    
  • 版本兼容提示:如果使用的是早期版本的Prolog解释器,动态声明的语法可能存在细微差异,可根据对应解释器的文档调整声明格式(如部分老版本需要写为:- dynamic(si/1), dynamic(no/1).)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.07 17:15:06