prolog - swi-prolog forall 功能不起作用

标签 prolog prolog-toplevel

我有谓词

superclass('Horde', 'Blood Elf').
superclass('Horde', 'Orc').

element('Blood Elf', ['Paladin', 'Priest','Mage','Warlock','Death Knight','Rogue']).
element('Orc', ['Warrior', 'Shaman','Warlock','Death Knight','Hunter','Rogue']).

find(A):-
  (  element(_,B),member(A,B)
  -> forall(
        ( element(_,B), member(A,B) ),
        ( element(C,B), superclass(D,C), format('~w -> ~w -> ~w\n',[D,C,A])))
  ;  superclass(A, _)
  -> format('~w\n',A), forall(superclass(A,B),format('\t~w\n',B))
  ).  

以及 find('Rogue'). 的两个结果。毕竟,谓词只打印其中 1 个。但是,当我将 forall(..) 复制粘贴到控制台时,它给出了全部 2 个结果。为什么?

最佳答案

本质上,您有一个 (->)/2,即 If -> Then如果符合您的情况

( element(_,B), member(A,B) )

采用第一个答案并 promise 它,因此其他答案将不会被考虑。 Then 是一个 forall/2,要么成功一次,要么失败。因此,永远不应该出现您得到多个答案的情况。


因此,您正在将原始程序与查询进行比较:

?- forall(
      (  element(_,B), member('Rogue',B) ),
      (  element(C,B),
         superclass(D,C),
         format('~w -> ~w -> ~w\n',[D,C,'Rogue'])
      )).

但是原来的程序不一样!它本质上是:

?- element(_,B),member(A,B)
    -> forall(
          (  element(_,B), member(A,B) ),
          (  element(C,B),
             superclass(D,C),
             format('~w -> ~w -> ~w\n',[D,C,A]))).

因此,在原始程序中 A B 已修复,而在您的查询中,只有 A 是固定的已修复。

请注意,以这种写出内容的方式进行编程,通常会导致与 Prolog 本身无关的各种错误。我宁愿建议您首先坚持使用 Prolog 的纯粹、单调子集。

关于prolog - swi-prolog forall 功能不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26614402/

相关文章:

prolog - SWI-Prolog 使用移位 CLPFD 报告错误答案

swi-prolog - 如何在不按空格键的情况下查看 SWI-Prolog 中的所有答案?

Prolog、predicate返回正确结果,但也有错误?

list - 如何以更简单的方式合并列表中的元素?序言

list - 使用列表谓词在 Prolog 中查找交集

prolog - 将 Prolog 仿函数转换为具有差异列表的仿函数

database - 将查询结果写入序言中的文件

prolog - Prolog 中的 CLP(B) 加权 sat_count/3

performance - 建议Prolog处理器利用大页面

SWI-Prolog 如何显示整个答案(列表)?