我无法解决这个序言练习。我希望有人可以给我一些提示或发布解决方案。提前谢谢。
数据库:
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 :(得分: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).