2016-05-26 13 views
0

У меня возникли проблемы с созданием всех списков, соответствующих определенным критериям.Prolog - Как ограничить длину списка переменных

city(new_york, 47). 
city(chicago, 100). 

all_unique([]). 
all_unique([H|T]) :- H = [] ; (not(member(H, T)), all_unique(T)). 

cities([Head|Tail]) :- 
    length(Tail, L), 
    L < 2, 
    city(Head, _A), 
    (Tail = [] ; cities(Tail)). 

Когда я выполняю запрос cities(L), я хочу, чтобы создать все списки городов с максимальной длиной 2 и без повторения. Теперь он возвращает все возможные списки, а затем сохраняет списки попыток, которые явно не соответствуют критериям.

?- cities(L). 
L = [new_york] ; 
L = [chicago] ; 
L = [new_york, new_york] ; 
L = [new_york, chicago] ; 
L = [chicago, new_york] ; 
L = [chicago, chicago] ; 
ERROR: Out of global stack 
?- 

Как сообщить Прологу, чтобы он не пробовал слишком длинные списки или повторял элементы?

+0

'города (L): - findall (Город, город) (Город, _, _), L) '. – lurker

+0

Спасибо, но я не могу использовать findall. Есть ли способ сделать это без findall? –

ответ

3

Ваше определение all_unique/1 лучше основано на :

all_unique([]). 
all_unique([E|Es]) :- 
    maplist(dif(E), Es), 
    all_unique(Es). 

основе maplist/2 вы можете определить cities/1 так:

city_(new_york, 47). 
city_(chicago, 100). 

city(C) :- 
    city_(C, _). 

cities(List) :- 
    length(Ref, 2), 
    append(List, _, Ref), 
    all_unique(List), 
    maplist(city, List). 

Пример запроса:

?- cities(Xs). 
Xs = [] ; 
Xs = [new_york] ; 
Xs = [chicago] ; 
Xs = [new_york, chicago] ; 
Xs = [chicago, new_york] ; 
false.         % terminates universally 
+0

Да, жаль, что твои дела прекрасны. Это просто не работает с моей all_unique. Я не уверен, почему мой не работает. Я не могу использовать maplist или dif –

+0

@JoshR. Какой процессор Prolog вы используете? – repeat

+0

Я использую swi-prolog –

 Смежные вопросы

  • Нет связанных вопросов^_^