2016-03-04 38 views
1

的Prolog的語法使用的規則<head> :- <body>格式,例如:序言:規則,無非是匿名變量的頭部,並沒有身體

tree(G) :- acyclic(G) , connected(G). ,表示作爲樹的G狀態的狀態取決於無環和連接。

該語法可以以隱式方式擴展爲事實。按照同樣的例子:

connected(graphA)表明connected(graphA):-true.

在這個意義上,人們可能會鬆散定義Prolog的事實總是爲真Prolog的規則。

我的問題:是否在任何情況下都是一個無形的規則(假設在所有條件下都是正確的)是否合適?語法上這樣的規則看起來如下。

graph(X).(暗示graph(X):-true.

+0

使用你的術語,「無形體規則」和「事實」有什麼區別? – 2016-03-05 09:52:48

+0

脫體規則的示例:blah(X)。事實的例子(無定義):blah(a)。請注意,第一個參數使用了一個變量。 –

+0

聽起來不錯@boris –

回答

3

之前回答,重組你的問題:

在Prolog,你會永遠寫什麼也沒有,但匿名變量在頭的規則,並沒有身體?

術語在這裏很重要。 事實只是規則只有一個和沒有身體(這就是爲什麼你的問題有點混亂)。 匿名變量是您明確告訴編譯器在謂詞子句(謂詞子句是變量的語法範圍)的上下文中忽略的變量。如果您確實嘗試將此謂詞子句提供給Prolog編譯器:

foo(Bar). 

您將收到「單變量變量」警告。相反,你可以寫

foo(_). 

,這告訴,這種說法是故意忽略了編譯器,並沒有變量綁定應該與它嘗試。

操作上,當Prolog試圖證明規則時會發生什麼?

  • 首先,統一規則頭部的所有參數,這可能會導致新的變量綁定;
  • 然後,它試圖使用所有現有的變量綁定來證明規則的主體。

正如你所看到的,第二步使得這是一個遞歸定義的算法:證明規則的主體意味着證明其中的每個規則。

來你的問題:什麼是該操作的含義:

foo(_). 

有一個謂語foo/1,並且它是真實的任何說法,因爲有工作要做沒有變量綁定在頭腦中,總是,因爲沒有子目標需要被證明。

我已經看到至少有一個這樣的規則的用法:看看this section of the SWI-Prolog manual的最底部。小代碼示例如下所示:

term_expansion(my_class(_), Clauses) :- 
     findall(my_class(C), 
       string_code(_, "[email protected]#$", C), 
       Clauses). 

my_class(_). 

您應該閱讀鏈接文檔以查看執行此操作的動機。代碼本身的目的是在編譯時間處添加事實表到Prolog數據庫。這是通過術語擴展完成的,這是一種代碼轉換機制,通常通過term_expansion/2使用。您需要定義my_class/1,以便term_expansion/2可以選取它,對其進行轉換,然後將其替換爲擴展的代碼。我強烈建議你把上面的剪下來,放在一個文件中,諮詢它並使用listing/1看看有什麼效果。我得到:

?- listing(my_class). 
my_class(126). 
my_class(33). 
my_class(64). 
my_class(35). 
my_class(36). 

true. 

NB:在這個例子中,你可以用任何東西取代的my_class(_)出現的兩個。你可以寫得如下:

term_expansion(foobar, Clauses) :- 
     findall(my_class(C), 
       string_code(_, "[email protected]#$", C), 
       Clauses). 

foobar. 

最終結果是相同的,因爲操作意義是相同的。然而,使用my_class(_)是自我記錄,並且使得代碼的意圖更加明顯,至少對於一位經驗豐富的Prolog開發人員來說是SWI-Prolog的作者;)。

+1

太棒了,@Boris。很有幫助。 –

1

這通常是如何遞歸定義的基礎案例中被表達。

3

事實上,這只是一個無法無天的規則,就像你所說的那樣。是的,有很多的用例脫胎事實:

  1. 代表靜態數據
  2. 基地的情況下遞歸
  3. ,而不是一些花括號語言僞代碼

     
    boolean is_three(integer x) { 
        if (x == 3) { return true; } 
        else  { return false; } 
    } 
    

    我們可以簡單地寫

     
    is_three(3). 
    
+2

看起來您可能遇到了提交您的答案的問題 - 一旦您有機會重溫您的想法,我很樂意聽到您的想法。 –

+0

不確定你的意思是什麼'問題'。 – Anniepoo

+0

二次閱讀時內容很好...由於某種原因,格式起初使得帖子看起來不完整。我繼續前進並很快重新格式化。我會繼續爲你提供有用的信息。 –

0

爲了突出我最初尋找的內容,我將在以後爲那些可能會發現自己問我最初問題的人提供以下簡短答案。

正如@Anniepoo所建議的,無可辯駁規則的一個例子是遞歸定義的基本案例。看到謂詞,構件(X,L)是爲了說明的例子:

member(X,[X|T]). /* recursive base case*/ 
member(X,[H|T]):- member(X,T). 

在此,構件規則的第一個條目表示的端接基座case--興趣X匹配的項的頭剩下的名單。

我建議訪問@鮑里斯的答案(接受)爲更完整的治療。

+1

由於迂腐的風險,您的術語仍然有點偏離。在你給出的'member/2'的例子中,只有一個_predicate clause_沒有body,不是_rule_!您可能想查看[SWI-Prologs術語詞彙表](http://eu.swi-prolog.org/pldoc/man?section=glossary)。您可能會注意到「規則」根本就沒有;) – 2016-03-10 07:42:28

+0

謝謝。我會研究術語表來刷新。 –