Prolog如何获取规则中的相邻数字

Prolog how to get adjacent numbers in rule

序言很新,无论如何

我有一个包含姓名、路号、地址的数据库。

habite('Name', Num, 'Address').

我想创建一个规则voisins(X,Y),其中 returns 与 Y 具有相同地址但 Num 为 Num 或其相邻项 (Num+1) 和 (Num- 1).

我尝试执行以下操作

voisins(X,Y) :-
    habite(X,Num,Address),
    ANum is Num+1,
    habite(Y,ANum,Address);
    BNum is Num-1,
    habite(Y,BNum,Address).

也尝试过

voisins(X,Y) :-
    habite(X,Num,Address),
    ANum is Num+1,
    BNum is Num-1,
    habite(Y,ANum,Address),
    habite(Y,ANum,Address).

它们都不起作用。我觉得这有一个非常简单的答案,但我对 Prolog 很陌生,所以我真的不知道。感谢任何帮助。

您可以尝试以下方法:

voisins(X,Y) :-
  habite(Y,YNum,Address),
  habite(X,XNum,Address),
  (XNum =:= YNum ; XNum =:= YNum - 1 ; XNum =:= YNum + 1).

第一个目标找到姓名为Y的人的路号和地址,然后统一到变量YNum和Address , 分别。第二个目标然后将变量 X 与一个与 Y 具有相同地址的人的姓名统一起来,同时将 XNum 与此人的道路号码统一起来。最后,将 XNum 与 YNum 进行比较,以查看它是否满足您在开头提到的约束条件。这通过析取表示:(;)/2.

基本上,Prolog 将尝试查看 XNum 是否具有与 YNum 相同的(算术)值。如果此检查成功,则谓词 voisins(X,Y) 对于统一为 X 的名称为真,因此它会回复您并通过回溯继续搜索其他答案。另一方面,如果它失败了,它会移动到下一个并检查那个是否成立等。

等价地,你也可以将上面的谓词写成:

voisins(X,Y) :-
  habite(Y,YNum,Address),
  habite(X,YNum,Address).
voisins(X,Y) :-
  habite(Y,YNum,Address),
  habite(X,XNum,Address),
  XNum =:= YNum - 1.
voisins(X,Y) :-
  habite(Y,YNum,Address),
  habite(X,XNum,Address),
  XNum =:= YNum + 1.

此处,析取已“展开”为 voisins 的三个独立定义,其中每个定义都进行三个比较之一。它的工作方式与之前的解决方案类似,只是现在 Prolog 将选择下一个可用的谓词作为替代,以防比较失败。另外,请注意 XNum =:= YNum 检查如何更简洁地表达,因为值 YNum 在 habite(X,YNum,Address) 中使用以进一步限制 X 的可能值。