2008-11-12 3 views
3

Я на курсе начинающего уровня в прологе, делая проблему с раскраской карты. Вот мой код.Перемещение переменной в списке прологов

col(Colors,Map,Coloring) :- 
    checkMap(Colors,Map,Coloring). 
checkMap(Colors,[Country1:Country2],Coloring) :- 
    goodColor(Country1:Country2,Coloring,Colors). 
checkMap(Colors,[Country1:Country2|Rest],Coloring) :- 
    goodColor(Country1:Country2,Coloring,Colors), 
    checkMap(Colors,Rest,Coloring). 
goodColor(Country1:Country2,Coloring,Colors) :- 
    mem(Country1:Color1,Coloring),!, 
    mem(Country2:Color2,Coloring),!, 
    mem(Color1,Colors), mem(Color2,Colors), 
    not(Color1=Color2). 
mem(Var,[Var|_]). 
mem(Var,[_|Rest]) :- 
    mem(Var,Rest). 

Мой результат выглядит следующим образом:

?- col([a,b,c],[1:2,1:3,2:3],X). 
X = [1:a, 2:b, 3:c|_G332] ; 
X = [1:a, 2:c, 3:b|_G332] ; 
X = [1:b, 2:a, 3:c|_G332] ; 
X = [1:b, 2:c, 3:a|_G332] ; 
X = [1:c, 2:a, 3:b|_G332] ; 
X = [1:c, 2:b, 3:a|_G332] ; 
fail. 

Каждый знает, как я могу избавиться от отстающей переменной? Я знаю, что это в основном косметический, но я не понимаю, почему он там.

ответ

1

Использование неполной структуры данных является допустимым методом программирования Пролога. Если намерение состоит в том, чтобы использовать неполную структуру данных, то одно решение:

ground_terms([H|T1],[H|T2]) :- ground(H), !, ground_terms(T1,T2). 
ground_terms(_,[]). 

и изменения Col следующим образом:

col(Colors,Map,Coloring) :- 
    checkMap(Colors,Map,Coloring1), 
    ground_terms(Coloring1,Coloring). 
+0

Что такое предикат земли/1 там? Спасибо за ответ :) – Pjotrovitz 2008-11-14 09:03:30

0

Задних переменным там, потому что mem(Var,[Var|_]) связывает несвязанный Coloring переменной [Var|_].

Один из способов избежать этого является аккумулировать карту окраски, например, (очень быстро и очень грязный):

col(Colors,Map,Coloring) :- 
    check(Colors,Map,[],Coloring). 

check(Colors,[],Coloring,Coloring). 

check(Colors,[Country1:Country2 | T],[],L) :- 
    member(Color1,Colors), 
    member(Color2,Colors), 
    Color1 \== Color2, 
    check(Colors,T,[Country1:Color1,Country2:Color2],L). 

check(Colors,[Country1:Country2 | T],Coloring,L) :- 
    member(Country1:Color1,Coloring), 
    member(Country2:Color2,Coloring),!, 
    check(Colors,T,Coloring,L). 

check(Colors,[Country1:Country2 | T],Coloring,L) :- 
    member(Country1:Color1,Coloring),!, 
    member(Color2,Colors), 
    not(member(_:Color2,Coloring)), 
    check(Colors,T,[Country2:Color2|Coloring],L). 

check(Colors,[Country1:Country2 | T],Coloring,L) :- 
    member(Country2:Color2,Coloring),!, 
    member(Color1,Colors), 
    not(member(_:Color1,Coloring)), 
    check(Colors,T,[Country1:Color1|Coloring],L). 

Его гораздо больше «процедурный» подход, чем у вас, хотя :-(Там, наверное, больше. элегантный способ ...