我需要做一个谓词,select(ListOfLists, X)
作为解决方案返回列表列表中每个不同数字的解决方案,从列表中单独的数字开始,例如:
select([[1,2,3],[1,2],[4],[3]],X).
会回来:
X = 4 ;
X = 3 ;
X = 2 ;
X = 1
只要首先显示列表中单独的数字,订单就无关紧要。
为此,首先我编写了2个其他谓词,即:
%OrderedList is Lists ordered by size.
orderListsBySize(Lists, OrderedLists).
示例:orderListsBySize([[1,2],[6],[3,4,5]], L).
- > L = [[6], [1,2], [3,4,5]]
和
%ListsWithoutX is Lists without the X elements
removeFromLists(X, Lists, ListsWithoutX).
示例:removeFromLists(1,[[1,2],[3],[4,1,5]],L).
- > L = [[2],[3],[4,5]]
这两个谓词都有效。
然后,为了执行select(ListOfLists, X)
谓词,我尝试了以下内容:
select([[X|[]]|_], X). select(L1,S) :-
orderListsBySize(L1, [[X|XS]|LS]),
length(XS, A),
A == 0,
select([[X|[]]|M], S),
removeFromLists(X, [XS|LS], M).
select([[X|_]|_], X).
但它不起作用。
用其他语言做这不是一项艰苦的练习,问题是我仍然很难理解prolog是如何工作的。我得到了任何帮助,谢谢!
答案 0 :(得分:1)
你可以从:
开始select2(ListOfLists,Element):-
length(List,_Len),
member(List,ListOfLists),
member(Element,List).
这将返回所有答案,但随后陷入寻找更大列表的循环中。
这可以使用:-use_module(library(clpfd)).
来避免,并且定义fd_length/2
不会继续寻找更大的列表然后存在于列表列表中。
fd_length(L, N) :-
N #>= 0,
fd_length(L, N, 0).
fd_length([], N, N0) :-
N #= N0.
fd_length([_|L], N, N0) :-
N1 is N0+1,
N #>= N1,
fd_length(L, N, N1).
select(ListOfLists,Element):-
maplist(length,ListOfLists,Lengths),
sort(Lengths,SortedLength),
last(SortedLength,Biggest),
Biggest #>= Len,
fd_length(List,Len),
member(List,ListOfLists),
member(Element,List).
示例查询:
?-select([[1,2,3],[1,2],[4],[3]],X).
X = 4
X = 3
X = 1
X = 2
X = 1
X = 2
X = 3
false
如果您需要独特的解决方案,可以将其放在setof/3
中,然后再次致电member/2
。