Дайте в качестве решения каждый другой номер в списке списков - PullRequest
0 голосов
/ 24 мая 2018

Мне нужно сделать предикат, 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).

Но это не работает.
Это не сложное упражнение, которое можно выполнить на других языках.проблема в том, что мне все еще трудно понять, как работает пролог.Я ценю любую помощь, спасибо!

1 Ответ

0 голосов
/ 25 мая 2018

Вы можете начать с:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...