2015-04-26 68 views
4

如果我在Prolog中有一個謂詞列表,如[flies, swims],如何構建一個謂詞,它是列表中所有謂詞的連接詞,即fliesAndSwims(X) :- flies(X), swims(X).從Prolog中的列表構建複合謂詞

另外,是否有更好的方式在運行時創建謂詞,而不必將組件謂詞放在列表中,並在需要時從中構建複合謂詞?

編輯: 所以原來這是List of predicates in Prolog的重複。我以前找到答案,但我認爲它只返回給定的原子是否匹配列表中的每個謂詞。我沒有意識到你可以傳遞一個變量而不是一個原子,並讓它返回每一個匹配的情況。

回答

2

庫(拉姆達)是強大的,但它有一個成本。如果你覺得「越簡單越好」(WRT調試,特別是...)考慮

call_unary_list([], _). 
call_unary_list([P|Ps], X) :- 
    call(P, X), 
    call_unary_list(Ps, X). 

讓我們比較性能:

compare_call_list :- 
    findall(flies, between(1,100000,_), L), 
    time(call_unary_list(L, _)), 
    time(maplist(call_unary(_), L)), 
    time(maplist(X+\Pred^call(Pred,X), L)). 

call_unary(X, P) :- call(P, X). 

?- compare_call_list. 
% 200,000 inferences, 0.123 CPU in 0.123 seconds (100% CPU, 1629657 Lips) 
% 300,000 inferences, 0.145 CPU in 0.149 seconds (98% CPU, 2064184 Lips) 
% 1,000,001 inferences, 1.286 CPU in 1.297 seconds (99% CPU, 777362 Lips) 
true . 

的call_unary/2亮點的需要的由MAPLIST參數交換meta predicate

+0

@repeat:我喜歡lambda,實際上我用過很多次。當使用它時,我發現「困難的方式」有些問題。所以,特別是對於初學者,我只是喜歡解釋更多的基本技巧...... – CapelliC

2

下面就來更新Prolog's dynamic database替代...你可以使用一個meta-predicatemaplist/2,恕我直言,最好結合Prolog lambda expressions

首先,一些樣品(超級不完全)的flies/1swims/1定義:

現在讓我們做一個查詢:

?- use_module(library(lambda)). 
true. 

?- maplist(X+\Pred^call(Pred,X), [flies,swims]). 
X = duck ; 
X = eagle. 
+0

工作很好,非常感謝。拉姆達圖書館工作得很好,但你能否解釋一下你在香草序言中的做法?我仍然在學習,所以我想知道我使用的東西是如何工作的,而不是盲目地複製。 我猜這是相當於lambda /匿名函數在其他語言,只是一個方便,讓你定義他們內聯而不是一個單獨的聲明? – espekia

+1

實際上,庫(lambda)**是**「vanilla」ISO Prolog :)如鏈接頁面所述:「不需要語法或編譯器擴展。」 – repeat