Помогите с простым прологическим упражнением - PullRequest
1 голос
/ 29 января 2011

Мне не удалось выполнить это прологическое упражнение. Я надеялся, что кто-то здесь может дать мне несколько советов или опубликовать решение. Заранее спасибо.

База данных:

lig(super, porto).  
lig(super, benfica).  
lig(super, sporting).  
lig(honra, feirense).  
lig(honra, guimaraes).  

jog(sporting, ricardo, gr).  
jog(guimaraes, cleber, de).  
jog(feirense, edgar, me).  
jog(porto, quaresma, av).  
jog(porto, helton, gr).  
jog(benfica, simao, av).  
jog(sporting, moutinho, me).

Пример вывода:

?- calcula(Lista).
Lista = [super-[porto-[quaresma,helton], benfica-[simao], sporting-
[moutinho,ricardo]], honra-[ feirense-[edgar], guimarães-[cleber]]].

Моя процедура:

calcula(Lista) :-
    findall(Lig-[Eq-[X]],
            (lig(Lig, Eq), findall(Jog, jog(Eq, Jog, _), X)),
            Lista).

Мой вывод (что неверно!).

Lista = [super-[porto-[[quaresma, helton]]], super-[benfica-[[simao]]], super-[sporting-[[ricardo, moutinho]]], honra-[feirense-[[edgar]]]

Ответы [ 3 ]

1 голос
/ 23 мая 2011

Это не короче, чем ответ zfm, но он "проще" в том смысле, что он использует только базовые конструкции пролога для непосредственного построения списка. (Не удаляйте дубликаты впоследствии.) Существует некоторое дублирование кода, от которого, возможно, можно избавиться, чтобы получить более короткий ответ.

g(Second, [Third|Rest], Done) :- jog(Second, Third,_),
    not(member(Third, Done)),!,
    g(Second, Rest, [Third|Done]).
g(_,[],_).

f(First, [Second-New|Rest], Done) :- lig(First, Second),
    not(member(Second, Done)),!,
    g(Second, New, []),
    f(First, Rest, [Second|Done]).
f(_,[],_).  

h([First-X|Lista], Done):-
    lig(First,_),
    not(member(First, Done)),!,
    f(First, X, []),
    h(Lista,[First|Done]).
h([], _).

calcula(X) :- h(X, []).
1 голос
/ 23 мая 2011

Я вижу в решении zfm, предикат lig(Lig, _) становится истинным 5 раз, поэтому в окончательном списке есть некоторое дублирование. Вы можете использовать предикат setof/3 и экзистенциальную количественную переменную Eq0^ для удаления дублирования:

calcula(T) :- setof(Lig-X, Eq0^(lig(Lig, Eq0), 
              findall(Eq-U, (lig(Lig,Eq), findall(Jog, jog(Eq, Jog, _), U)), X)), T).
1 голос
/ 30 января 2011

Так как этот вопрос меня так интересует, я очень стараюсь.

Ну, я думаю, это не лучший ответ.Однако я получаю результат.

calcula(Ans):-findall(Lig-X, (lig(Lig, _), 
    findall(Eq-U, (lig(Lig,Eq), findall(Jog, jog(Eq, Jog, _), U)), X)), T), 
    removeEq(T,Ans).

removeEq([A-B,A-_|Tail], [A-B|TailChanged]) :- !, removeEq([A-B|Tail], 
    [A-B|TailChanged]).
removeEq([A-B,C-D|Tail], [A-B,C-D|TailChanged]) :- removeEq([A-B|Tail], 
    [A-B|TailTemp]), removeEq([C-D|TailTemp], [C-D|TailChanged]).
removeEq([X], [X]).

removeEq необходим, потому что есть дублированный ответ (я не знаю, как не дублировать его)

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