Конечная переменная в списке прологов - PullRequest
3 голосов
/ 12 ноября 2008

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

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.

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

Ответы [ 2 ]

1 голос
/ 12 ноября 2008

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

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 голосов
/ 13 ноября 2008

Конечная переменная существует потому, что 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).

Это гораздо более "процедурный" подход, чем ваш, хотя :-(. Возможно, есть более элегантный способ ...

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