如何使Prolog能够生成查询的所有可能解决方案

如何使Prolog能够生成查询的所有可能解决方案,prolog,Prolog,我希望能够生成所有可能的元素列表,在最后两个元素之间使用“and”(和普通语言一样)。任何列表中都不应该有重复的元素。所以“三、二、四”是一个正确的列表,就像“二、一”或“五、三、四、一、二”一样。我不是在寻找单一元素列表 我已经编写了以下程序。当我查询Prolog中关于特定列表的信息时,它会正确地告诉我该列表是否有效。然而,当我查询list(X)时,它只生成包含两个元素的列表 有人能建议一种方法,让它使用给定的元素生成所有可能的列表吗?谢谢大家! 我有如下事实: element([one]).

我希望能够生成所有可能的元素列表,在最后两个元素之间使用“and”(和普通语言一样)。任何列表中都不应该有重复的元素。所以“三、二、四”是一个正确的列表,就像“二、一”或“五、三、四、一、二”一样。我不是在寻找单一元素列表

我已经编写了以下程序。当我查询Prolog中关于特定列表的信息时,它会正确地告诉我该列表是否有效。然而,当我查询list(X)时,它只生成包含两个元素的列表

有人能建议一种方法,让它使用给定的元素生成所有可能的列表吗?谢谢大家!

我有如下事实:

element([one]).
element([two]).
element([three]).
element([four]), etc. etc.
生成列表L的谓词有:

list(L):-
     element(E1),
     element(E2),
     E1 \= E2,
     append(E1, [and], X),
     append(X, E2, L).

%recursive case
list(L):-
     element(E),
     append(E, [','], X),
     append(X, Y, L),
     list(Y),
     not_in(E, Y).

not_in([X], [Y]):- X \= Y.
not_in([X], [H|T]):-
     [X] \= [H],
     not_in([X], T).
循环错误 您的代码循环是因为
list(L)
是根据
list(Y)
(递归定义)定义的<代码>元素(E)选择第一个匹配项,即
[one]
,然后将其预先添加到新列表
Y
,无限期。您正在检查最后一行中的
E
Y
中是否不再出现,但循环出现在该行之前

正确实施 由于多次使用
append/3
可能会造成混乱,因此我在这里使用。诀窍是在已经使用的元素周围保留一个列表,以便我们可以提前检查重复出现的情况。这可以避免在事后尝试检查时发生的循环行为

使用示例:

?- phrase(list, List).
List = [one, and, two] ;
...
List = [one, ',', two, ',', three, and, four] ;
...
List = [four, ',', three, ',', two, and, one] ;
false

我最初使用
dif/2
寻求一种不同的解决方案,但这也是一种循环,导致了错误。
list -->
  list([]).

list(T) -->
  element(T, H),
  [and],
  element([H|T], _).
list(T) -->
  element(T, H),
  [','],
  list([H|T]).

element(L, X) -->
  cardinal(X),
  {\+ memberchk(X, L)}.

cardinal(1) --> [one].
cardinal(2) --> [two].
cardinal(3) --> [three].
cardinal(4) --> [four].
?- phrase(list, List).
List = [one, and, two] ;
...
List = [one, ',', two, ',', three, and, four] ;
...
List = [four, ',', three, ',', two, and, one] ;
false