为何Prolog程序使用系统findall/3会触发Cannot redefine ,/2错误?
解决Prolog中"Full stop in clause-body? Cannot redefine ,/2"错误
错误原因分析
这个错误的核心是你的代码触发了两个问题之一:
- 子句内部误加了句号(
.),导致Prolog解析时误以为你要重新定义系统内置的,/2谓词(这个谓词是Prolog用来连接多个子目标的,比如goal1, goal2就是按顺序执行两个目标)。 - 你不小心写出了重定义
,/2的代码,比如类似,(X,Y) :- ...的规则,这直接覆盖了系统自带的谓词,触发报错。
排查与修复步骤
检查子句结尾的语法
逐个核对所有事实和规则:- 每个事实(比如
county_deaths(100).)和规则(比如start :- ... .)必须以.结尾,且这个句号只能放在子句的最后,不能出现在规则的body中间。 - 比如如果写成
start :- findall(D, county_deaths(D), DeathsList). min_max(...),这里第一个.就把start谓词提前结束了,后面的min_max(...)会被解析成错误的子句,进而触发,/2的重定义错误。
- 每个事实(比如
删除误定义的系统谓词
检查代码中是否存在类似,(A,B) :- ...或者findall(X,Y,Z) :- ...的自定义规则——这些都是系统内置谓词,绝对不能自己重新定义,直接删掉这类代码即可。关于多次使用findall/3的正确方式
你完全不需要重命名系统的findall/3!这个谓词可以被无限次调用,直接在你的start谓词里按需求多次使用就行,比如:start :- % 第一次调用findall获取死亡数据 findall(D, county_deaths(D), Deaths), min_max(Deaths, MinDeath, MaxDeath), show_result(deaths, MinDeath, MaxDeath), % 第二次调用findall获取确诊数据 findall(C, county_cases(C), Cases), min_max(Cases, MinCase, MaxCase), show_result(cases, MinCase, MaxCase).这种写法完全合法,不会触发任何错误。
内容的提问来源于stack exchange,提问作者user17244850
相关产品推荐
相关产品推荐

