2011-07-20 53 views
4

我試圖限定接納與自由變量單項,並返回這些變量的映射列表的謂詞,因此,例如,如果數據庫是找到所有的解決方案,謂語

a(0,1). 
a(1,1). 

的預計產量將

?- eval(a(X,1),Maps). 
Maps = [[[X,0]],[[X,1]]]. 
?- eval(a(X,Y),Maps). 
Maps = [[[X,0],[Y,1]],[[X,1],[Y,1]]]. 

我一直在嘗試使用findall/3做到這一點,但我不能想出一個辦法,要求自由變量及其可能值。如果有幫助,我使用swiprolog。 謝謝。

+0

根據你的數據庫的事實,我認爲第二個例子應該是地圖= [[[X, 0],[Y,1]],[[X,1],[Y,1]]] – gusbro

+0

你說得對,我馬上解決。對不起,我還沒有試圖解決這個問題。 – ailnlv

回答

2

下面是對類似問題的解決方案。對於每個變量而不是列表中包含條目[V,term]的答案列表,查詢goal_answers(Goal, Answerp)找到一對Vars-Terms

goal_answerp(Goal, Answerp) :- 
    term_variables(Goal, Vars), 
    findall(Vars, Goal, Substs), 
    Answerp = Vars-Substs. 

?- goal_answerp(a(X,1), Ms). 
Ms = [X]-[[0],[1]]. 

?- goal_answerp(a(X,Y), Ms). 
Ms = [X,Y]-[[0,1],[1,1]]. 

[編輯]爲了得到答案放回原來的格式使用library(lambda)

?- goal_answerp(a(X,1), Vs-Dss), 
     maplist(Vs+\Ds^VDs^maplist(\V^D^[V,D]^true,Vs,Ds,VDs),Dss,VDss). 
Vs = [X], 
Dss = [[0],[1]], 
VDss = [[[X,0]],[[X,1]]]. 

?- goal_answerp(a(X,Y), Vs-Dss), 
     maplist(Vs+\Ds^VDs^maplist(\V^D^[V,D]^true,Vs,Ds,VDs),Dss,VDss). 
Vs = [X,Y], 
Dss = [[0,1],[1,1]], 
VDss = [[[X,0],[Y,1]],[[X,1],[Y,1]]]. 
+1

謝謝,這是有效的,但你應該用'Pair = Vars-Substs.'代替'Answerp = Vars-Substs.'的行。 – ailnlv

+0

謝謝 - 當一個人想到某種類型時,會發生這種情況。 @gusbro:'Answers'是一個列表,但它是一對。 – false

2

存在一個問題,你想做什麼。頂級解析器已知給變量(例如X,Y)的用戶友好名稱,但在程序中卻是「丟失」的。 這個片段將列出所有綁定,但變量將有通用名:

find_mappings(Template, Mappings):- 
    term_variables(Template, Vars), 
    find_mappings1(Vars, Mapping), 
    findall(Mapping, Template, Mappings). 

find_mappings1([], []). 
find_mappings1([Var|Vars], [[Name,Var]|Mappings]):- 
    term_to_atom(Var, Name), 
    find_mappings1(Vars, Mappings). 

?- find_mappings(a(X,Y), L). 
L = [[['_G385', 0], ['_G386', 1]], [['_G385', 1], ['_G386', 1]]]. 

你可能更喜歡另外一個參數添加到您的程序,以獲得您的變量的正確名稱:

find_mappings(Template, Names, Mappings):- 
    term_variables(Template, Vars), 
    find_mappings1(Vars, Names, Mapping), 
    findall(Mapping, Template, Mappings). 

find_mappings1([], [], []). 
find_mappings1([Var|Vars], [Name|Names], [[Name,Var]|Mappings]):- 
    find_mappings1(Vars, Names, Mappings). 

?- find_mappings(a(X,Y), ['X', 'Y'], L). 
L = [[['X', 0], ['Y', 1]], [['X', 1], ['Y', 1]]]. 
0

我在我面前沒有翻譯,但我想你可以用這個「a」謂詞來做這個特定的設置。

var(X), 
var(Y), 
findall(U, 
    (a(XSol,YSol), U=[[X,XSol], [Y,YSol]]), 
    Maps). 

我不知道爲什麼你會想這樣做使用這種方法雖然任何問題(var這個的可能是不必要的) ...

退房unifiable/3潛在的更好的方法做這樣的事情。

+0

我不知道這是否真的有必要,但我需要做的映射集內部和左連接(我基本上是解析SPARQL模式,但與任意子句,而不是三元組,並使用只有「和」和「選擇「)。這種解決方案几乎可行,但存在gusbro描述的沒有原始變量名稱的問題。它也應該使用任意的子句,而不僅僅是具有已知名稱的二進制子句。謝謝。 – ailnlv

相關問題