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