2016-04-25 25 views
1
log2(I,E):- 
    I is 2.0**E, 
    E is log(I)/log(2). 

我正在嘗試使用Prolog來計算功率2被提升到'I'還是2提升到'E'功率等於'I'。我對這種語言非常陌生,根據我的理解,它根據所提供的信息推斷出答案。在Prolog中構建基本2指數計算器

Queries: 
log2(I,3). 
-->false. 

log2(I,3.0). 
-->I = 8.0. 

log2(8,E). 
-->ERROR: is/2: Arguments are not sufficiently instantiated 

log2(8,E). 
-->ERROR: is/2: Arguments are not sufficiently instantiated 

我很困惑,爲什麼我必須提供在第一種情況的浮動,以得到正確的答案,爲什麼Prolog是無法在所有推斷第二種情況的答案。

+2

比較浮點值在任何計算機語言中的相等性總是有風險的業務,因爲內部表示的精度可能會導致原則上相等的兩個數之間的不等。第二個問題,即實例化錯誤,是因爲「is/2」要求表達式中的所有*變量都有一個值來計算表達式。所以'我是2.0 ** E'需要'E'才能得到一個值或者你得到*參數沒有被充分實例化*。 – lurker

+0

@lurker好吧,我現在明白雙方都需要有價值,但我還是不明白,當我不能做你剛剛描述的內容時,我如何才能讓Prolog從另一方推斷出一個價值。 –

回答

3

你在那裏有一個連接。在Prolog,連詞a, b表示:

評估a,並且如果成功,評估b

你正在嘗試做別的事情,也許:

嘗試a,如果不成功,嘗試b

您應該考慮的第一件事就是使用library(clpr),如果它在Prolog實現中可用的話。

隨着SWI-Prolog的:

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

?- {I = 2^3}. 
I = 8.0 ; 
false. 

?- {8 = 2^E}. 
E = 3.0 ; 
false. 

你從字面上沒有問題了。

如果這是不是一種選擇,你需要沿着這些線路做一些事情:

log2(I, E) :- 
    ( number(I) 
    -> E is /* expression here, now that I is a number */ 
    ; number(E) 
    -> I is /* expression here, now that E is a number */ 
    ; /* what do you do if both are variables? */ 
    ). 

注意,如果Expr是一個表達式,而不是一個數量X is Expr甚至會工作。如果你想允許這個,那麼你需要首先嚐試eval(Expr)並且抓住錯誤或者沿着這些線路。