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

如何消除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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 05:45:38