我有三种类型的事实:
album(code, artist, title, date).
songs(code, songlist).
musicians(code, list).
示例:
album(123, 'Rolling Stones', 'Beggars Banquet', 1968).
songs(123, ['Sympathy for the Devil', 'Street Fighting Man']).
musicians(123, [[vocals, 'Mick Jagger'], [guitar, 'Keith Richards', 'Brian Jones']].
我需要创建这4条规则:
在一起(X,Y)如果X和Y在同一张专辑中播放,则成功。
artistchain(X,Y)如果从X到Y存在一系列专辑,则会成功; 两个音乐家通过'在一起'链接在链中。
角色(X,Y)如果X有角色Y(例如吉他),这就成功了。
歌曲(X,Y)如果艺术家X录制了歌曲Y,则成功。
任何帮助?
我无法提出太多但是我想出了角色(X,Y):
role(X,Y) :- prole(X,Y,musicians(_,W)).
prole(X,Y,[[Y|[X|T]]|Z]).
prole(X,Y,[[Y|[H|T]]|Z]) :- prole(X,Y,[[Y|T]|Z]).
prole(X,Y,[A|Z]) :- prole(X,Y,Z).
但这不起作用。如果我手动输入列表而不是音乐家(_,W),如[[1,2,3],[4,5,6]],它确实有效。
我是否有另一种方法可以将列表作为变量插入?
至于其他规则,我完全失败了。任何帮助都会非常感激。
答案 0 :(得分:1)
你对Prolog有一种误解:在Prolog中回答一个目标与调用一个函数不同! 例如:你期望“角色(X,Y): - prole(X,Y,音乐家(_,W))。”执行时,“musicians(_,W)”将被评估,因为它是“prole”的参数。这不是Prolog的工作方式。在每一步中,它都尝试用存储的谓词统一目标,并且所有参数都被作为变量或基础术语处理。 正确的方法是:
role(X,Y) :- musicians(_, L), prole(X,Y,L).
第一个目标将L与音乐家列表统一起来,第二个目标找到角色(假设您的其余代码是正确的)。
答案 1 :(得分:0)
Little Bobby Tables是对的,你需要了解Prolog的声明风格。您的目标是提供一组与数据库中的事实相匹配的规则。
很简单,想象一下我有以下数据库
guitarist(keith).
guitarist(jim).
in_band('Rolling Stones', keith).
in_band('Rolling Stones', mick).
假设我想知道滚石乐队中谁是吉他手和。我可以使用像这样的规则
stones_guitarist(X):-
guitarist(X),
in_band('Rolling Stones', X).
当一个规则中给出一个变量名(在这种情况下为X)时,它在规则期间保持其值,所以我们所说的是作为吉他手的X也必须是同一个X中的X.乐队名为“滚石乐队”。
您可以通过多种方式安排数据库。例如,如果音乐家的名字本身就是一个列表可能会更容易(例如[guitar,[keith,brian]])。
我希望歌曲(X,Y)的以下示例有所帮助。我正在使用Sicstus Prolog,所以导入列表库以获得'成员',但是如果你没有,那么你自己很容易做到。
:- use_module(library(lists)).
song(ARTIST,SONG):-
album(CODE,ARTIST,_,_),
songs(CODE,TRACKS),
member(SONG,TRACKS).