帮助简单的prolog练习

时间:2011-01-29 19:43:40

标签: prolog

我无法解决这个序言练习。我希望有人可以给我一些提示或发布解决方案。提前谢谢。

数据库:

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 个答案:

答案 0 :(得分: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因为答案重复(我不知道如何复制)

答案 1 :(得分:1)

这不比zfm的答案短,但它更简单"以它只使用基本的prolog结构直接构造列表的方式。 (之后不会删除重复项。)有一些代码重复可能会被删除以获得更短的答案。

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, []).

答案 2 :(得分: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).