如何消除SWI-Prolog中“谓词语句未集中”的编译警告?
解决SWI-Prolog中“Clauses of X/Y are not together in the source-file”警告
问题描述
在SWI-Prolog中编写家族关系代码时,编译出现多条“Clauses of X/Y are not together in the source-file”(X/Y的子句在源码中未连续放置)警告。曾怀疑是谓词名称中的下划线导致问题,修改名称后无效,求解决办法。
原始代码
schwester_von(a,b):-weiblich(c),mutter_von(c,a),mutter_von(c,b),a\==b. bruder_von(a,b):-weiblich(c),mutter_von(c,a),mutter_von(c,b),a\==b. grossvater_von(a,b):-maennlich(a),(vorfahr_von(a,c), (vater_von(c,b);mutter_von(c,b))). vorfahr_von(a,b):-vater_von(a,b);mutter_von(a,b);((vater_von(a,c);mutter_von(a,c)), vorfahr_von(c,b)). einzelkind(a):-(vater_von(b,a);mutter_von(c,a)),not(bruder_von(a,d); schwester_von(a,e)). mutter_von(a,b):-weiblich(a). vater_von(a,b):-maennlich(a). schwester_von(a,b):-weiblich(a). bruder_von(a,b):-maennlich(a). grossvater_von(a,b):-maennlich(a). grossmutter_von(a,b):-weiblich(a). vater_von(stefan,barbara). vater_von(stefan,annalena). mutter_von(marianne,barbara). mutter_von(marianne,annalena). mutter_von(barbara,timo). vater_von(christopher,timo). mutter_von(annalena,ursula). mutter_von(annalena,thomas). vater_von(christian,ursula). vater_von(christian,thomas). mutter_von(ursula,uta). vater_von(ralf,uta). vater_von(thomas,sven). mutter_von(sabrina,sven). maennlich(stefan). weiblich(barbara). weiblich(annalena). weiblich(marianne). maennlich(timo). maennlich(christopher). weiblich(ursula). maennlich(thomas). maennlich(christian). weiblich(uta). maennlich(ralf). maennlich(sven). weiblich(sabrina).
编译警告信息
警告: /Users/user1/Desktop/fakten.pl:16: 警告: schwester_von/2的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:1 警告: 当前谓词: vater_von/2 警告: 使用 :- discontiguous schwester_von/2. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:17: 警告: bruder_von/2的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:3 警告: 当前谓词: schwester_von/2 警告: 使用 :- discontiguous bruder_von/2. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:18: 警告: grossvater_von/2的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:5 警告: 当前谓词: bruder_von/2 警告: 使用 :- discontiguous grossvater_von/2. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:21: 警告: vater_von/2的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:15 警告: 当前谓词: grossmutter_von/2 警告: 使用 :- discontiguous vater_von/2. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:23: 警告: mutter_von/2的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:14 警告: 当前谓词: vater_von/2 警告: 使用 :- discontiguous mutter_von/2. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:26: 警告: vater_von/2的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:15 警告: 当前谓词: mutter_von/2 警告: 使用 :- discontiguous vater_von/2. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:27: 警告: mutter_von/2的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:14 警告: 当前谓词: vater_von/2 警告: 使用 :- discontiguous mutter_von/2. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:29: 警告: vater_von/2的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:15 警告: 当前谓词: mutter_von/2 警告: 使用 :- discontiguous vater_von/2. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:31: 警告: mutter_von/2的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:14 警告: 当前谓词: vater_von/2 警告: 使用 :- discontiguous mutter_von/2. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:32: 警告: vater_von/2的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:15 警告: 当前谓词: mutter_von/2 警告: 使用 :- discontiguous vater_von/2. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:34: 警告: mutter_von/2的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:14 警告: 当前谓词: vater_von/2 警告: 使用 :- discontiguous mutter_von/2. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:40: 警告: maennlich/1的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:36 警告: 当前谓词: weiblich/1 警告: 使用 :- discontiguous maennlich/1. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:42: 警告: weiblich/1的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:37 警告: 当前谓词: maennlich/1 警告: 使用 :- discontiguous weiblich/1. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:43: 警告: maennlich/1的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:36 警告: 当前谓词: weiblich/1 警告: 使用 :- discontiguous maennlich/1. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:45: 警告: weiblich/1的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:37 警告: 当前谓词: maennlich/1 警告: 使用 :- discontiguous weiblich/1. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:46: 警告: maennlich/1的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:36 警告: 当前谓词: weiblich/1 警告: 使用 :- discontiguous maennlich/1. 来抑制此消息 警告: /Users/user1/Desktop/fakten.pl:48: 警告: weiblich/1的子句在源码中未连续放置 警告: 早期定义在/Users/user1/Desktop/fakten.pl:37 警告: 当前谓词: maennlich/1 警告: 使用 :- discontiguous weiblich/1. 来抑制此消息 % /Users/user1/Desktop/fakten.pl 编译完成 0.00 秒, 38 条子句 警告: 无法从 "'Earlier definition at /Users/user1/Desktop/fakten.pl':1" 找到可编辑内容 XPCE Xt 警告: Xlib不支持当前区域设置,区域设置已设为C ?-
解决方法
原因分析
SWI-Prolog默认要求:同一个谓词的所有子句必须在源码中连续放置。你的代码里,比如schwester_von/2先在第1行定义了一条子句,之后在第16行又定义了另一条,中间被bruder_von/2、grossvater_von/2等其他谓词的子句隔开,因此触发警告。该问题与谓词名称中的下划线无关。
方法一:重新组织代码(推荐)
把同一个谓词的所有子句集中放在一起,这是Prolog代码的规范写法,可读性和维护性更强。修改后的代码示例:
% 性别谓词:所有男性事实集中放置 maennlich(stefan). maennlich(timo). maennlich(christopher). maennlich(thomas). maennlich(christian). maennlich(ralf). maennlich(sven). % 性别谓词:所有女性事实集中放置 weiblich(barbara). weiblich(annalena). weiblich(marianne). weiblich(ursula). weiblich(uta). weiblich(sabrina). % 母亲关系:规则+事实集中放置 mutter_von(a,b):-weiblich(a). mutter_von(marianne,barbara). mutter_von(marianne,annalena). mutter_von(barbara,timo). mutter_von(annalena,ursula). mutter_von(annalena,thomas). mutter_von(ursula,uta). mutter_von(sabrina,sven). % 父亲关系:规则+事实集中放置 vater_von(a,b):-maennlich(a). vater_von(stefan,barbara). vater_von(stefan,annalena). vater_von(christopher,timo). vater_von(christian,ursula). vater_von(christian,thomas). vater_von(ralf,uta). vater_von(thomas,sven). % 祖先关系 vorfahr_von(a,b):-vater_von(a,b);mutter_von(a,b);((vater_von(a,c);mutter_von(a,c)), vorfahr_von(c,b)). % 祖父关系:所有子句集中放置 grossvater_von(a,b):-maennlich(a),(vorfahr_von(a,c), (vater_von(c,b);mutter_von(c,b))). grossvater_von(a,b):-maennlich(a). % 祖母关系 grossmutter_von(a,b):-weiblich(a). % 姐妹关系:所有子句集中放置 schwester_von(a,b):-weiblich(c),mutter_von(c,a),mutter_von(c,b),a\==b. schwester_von(a,b):-weiblich(a). % 兄弟关系:所有子句集中放置 bruder_von(a,b):-weiblich(c),mutter_von(c,a),mutter_von(c,b),a\==b. bruder_von(a,b):-maennlich(a). % 独生子女定义 einzelkind(a):-(vater_von(b,a);mutter_von(c,a)),not(bruder_von(a,d); schwester_von(a,e)).
方法二:使用discontiguous声明(临时抑制警告)
如果不想调整代码结构,可以在代码开头添加discontiguous声明,告诉Prolog该谓词的子句允许不连续放置。示例:
:- discontiguous schwester_von/2. :- discontiguous bruder_von/2. :- discontiguous grossvater_von/2. :- discontiguous vater_von/2. :- discontiguous mutter_von/2. :- discontiguous maennlich/1. :- discontiguous weiblich/1. % 后续为原始代码 schwester_von(a,b):-weiblich(c),mutter_von(c,a),mutter_von(c,b),a\==b. ...
此方法仅适合临时场景,会降低代码可读性,不推荐长期使用。
内容的提问来源于stack exchange,提问作者daniel235
相关产品推荐
相关产品推荐

