如何解决Prolog SWI中的语法错误?



我得到'语法错误:操作符预期'和警告:'单例变量:…"。

下面是我的代码:

schwester_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)
).
vater_von(Stefan,Barbara).
vater_von(Stefan,Anna-Lena).
mutter_von(Marianne,Barbara).
mutter_von(Marianne,Anna-Lena).
mutter_von(Barbara,Timo).
vater_von(Christopher,Timo).
mutter_von(Anna-Lena,Ursula).
mutter_von(Anna-Lena,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).

我试图避免左括号后面的空格,但错误仍然存在。

我同意评论者的建议,他建议你需要一个更好的编辑器。SWI-Prolog包含一个emacs版本,您现在就可以使用它。如果你使用的是Windows操作系统,可能只需要打开文件即可。语法和错误高亮显示将快速显示错误。作为初学者,使用VSCode可能会更好。

我还建议你开始用英语写代码,这是一个好习惯。例如,一些阅读这个问题的人不理解你的谓语是什么意思,这使得更难回答。

现在让我们看一下代码。

grossvater_von(A,B) :-
maennlich(A),
(
vorfahr_von(A,C),
(
vater_von(C,B)
;
mutter_von(C,B).

这会导致语法错误。你需要右括号:

grossvater_von(A,B) :-
maennlich(A),
(
vorfahr_von(A,C),
(
vater_von(C,B)
;
mutter_von(C,B)
)
).

但是逻辑真的是混在一起了。你可以把祖父定义为男性(好吧!),也可以是孙辈的父亲或母亲的祖先。这是不对的。

  • A不应该是某个祖先,而应该是C的父亲。
  • 如果你使用father_of(vater_von)而不是ancestor,你甚至不需要指定他是男性,但那是。
  • 有一个辅助parent_of(elternteil_von)谓词会更好,所以你不需要那么多连词。试一试!
vorfahr_von(A,B) :-
vater_von(A,B)
;
mutter_von(A,B)
;
(
(
vater_von(A,C)
;
mutter_von(A,C)
),
vorfahr_von(C,B)
).

同样,当您将vater_von;mutter_von的每个实例替换为parent_of(elternteil_von)时,这将更加清晰。兄弟姐妹也是一样。

现在:

vater_von(Stefan,Barbara).

这看起来很无辜,但会让你完全困惑,因为这是绝对错误的。StefanBarbara是自由变量,完全不受限制。当你这样定义它时你也可以问

?- vater_von(pi, 3.14).
true 

因为Prolog绑定了Stefan=piBarbara=3.14。这也是"单例变量"的原因。警告。这意味着这些变量在规则中只出现一次,这通常是一个错误的指示,因为它们并不像那样真正有用。

当然,您一开始并不打算使用变量,而是原子。小写或引号都可以:

vater_von(stefan,barbara).
vater_von('Stefan','Barbara').

更糟:

vater_von(Stefan,Anna-Lena).

Anna-Lena是函子-对两个变量AnnaLena的应用。在这里,你只需要引用它:

vater_von('Stefan','Anna-Lena').

还有一件事:您还会注意到关于不连续谓词的警告。作为一条规则,将谓词的所有规则放在一起——首先陈述所有vater_von事实,然后是所有mutter_von事实,不要混淆它们。

在不可行的情况下,可以使用:- discontiguous指令。

最新更新