2011-01-29 2 views
1

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

База данных:

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]]] 
+0

Кажется, единственное, что неправильно о выходе является дополнительной парой квадратных скобок вокруг каждый списка имен. Изучив свой код, вы можете увидеть, что может объяснить эту дополнительную пару скобок и как устранить проблему? Стоит попробовать. – hardmath

+0

Это не единственное, что не так. Я повторяю «супер» в выходе, и я не должен. Он должен появляться только один раз. Я даже не знаю, как это исправить. – nunos

ответ

1

Я вижу в растворе в 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

Поскольку меня так интересует вопрос, я пробую его много.

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

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 необходим, потому что продублирован ответ (я не знаю, как не дублировать его)

+0

спасибо за ваше решение. он работает. тем не менее, я уверен, что есть более простое решение, но только с использованием поисковых систем. Спасибо, в любом случае. – nunos

+0

меня тоже, но я просто слишком устал, чтобы попробовать больше ... Я обновлю решение, если найду его лучше. – zfm

1

Это не короче, чем ответ 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, []). 
Смежные вопросы