2013-08-24 43 views
4

我知道Prolog(邏輯程序設計)完全是關於返回true和false,而且函數是返回列表,數字,布爾值的任何東西。最初,它似乎並不認爲Prolog有函數的概念,而是依賴於統一的,但你可以做的東西,如:在Prolog中定義(數學)函數

?- X is log(42). 
X = 3.7376696182833684. 

如此看來,存在的功能呢?或者這真的只是某種隱藏統一部分的語法糖?

如果它真的只是語法糖,那麼如果我想要定義像log2這樣的數學「函數」,我該怎麼辦?

我當然可以使用統一的:

log2(X,Result) :- Result is log(X)/log(2). 

但是說,我想用「語法糖函數風格」這樣我就可以寫:

?- X is log2(8). 
X = 3.0. 

我怎樣才能做到這一點在序言?

+2

組合使用新定義的log 2時,有一個過時指令'arithmetic_function',將你想要做什麼,其解決問題。假設你的'的log 2/2'謂詞存在,指令': - arithmetic_function(LOG 2/1).'會讓你的第二個樣品的工作。我不確定它爲什麼被棄用,但似乎仍然在6.2.6中工作。 –

+0

我也想知道這個貶義,有一點要問Jan W.。 Dennis M.喜歡和Amzi一起參與的方法! Prolog將定義「is」的替代方案(例如,帶中綴語法的'iz/2'),並構造評估任何附加功能所需的規則。 – hardmath

回答

4

所以它只是統一..(由於mbratch和墊用於解釋)

這是我解決我的最初的問題,因此使用自定義的數學函數時使我的代碼更易讀:

:- op(900, xfy, <-). 
R <- log2(Y) :- R is log(Y)/log(2), !. 

% the two predicates below solves the problem with using mathematical operators 
% together with self defined functions note that they should always be last 
% 
R <- X :- 
    compound(X), 
    X =..[OP, X2, X3], 
    R2 <- X2, 
    R3 <- X3, 
    Expr =..[OP, R2, R3], 
    R is Expr, !. 
R <- X :- R is X, !. 

然後我可以寫:

?- X <- log2(8). 
X = 3.0. 

進而最後兩個謂詞使得可能寫這樣的化合物:

?- X <- 17*log2(8) - 2. 
X = 49.0. 

請注意,你不能與爛攤子/ 2,因此我有點用我自己的<推翻它 - 操盤

編輯:增加語法糖通過墊建議和補充兩個謂詞與其他數學運算符

+1

您可以使用新定義的綴運營商也在條款頭:的r < - 的log 2(Y): - R是...'。 – mat

+0

啊,那更棒了,非常感謝。 – Michelrandahl

+0

的'op'指令是好玩,可以給你一些有趣和有用的語法方法可以用來表示謂詞。 'is'是一個內置的謂詞,所以你不能改變'is'的定義是什麼。 :) – lurker

8

序言是關於描述關係之間的實體。由於數學函數是一種特殊的關係(將輸入與唯一定義的輸出相關聯),因此可以使用Prolog來描述這些函數。在你的榜樣,實現這種關係的謂詞稱爲is/2,並(is)/2也被定義爲在序言中綴操作符,所以你可以寫:

?- X is log(42).

而不是前綴形式(這是當然的也仍然可容許):

?- is(X, log(42)).

注意is/2執行表達式的算術評價,並結合其結果第一個參數。這與X與Prolog術語log(42)的統一不同。

不過,請注意is/2不是真正的關係,因爲你不能在其他方向使用它:

?- 0 is log(X). 
ERROR: is/2: Arguments are not sufficiently instantiated 

對此的解決方案是使用約束(例如,在實數,稱爲CLP(R)),它可以在各個方向工作。它們可作爲許多現代Prolog系統中的庫或內置程序提供。