CLIPS 的簡單認識

我學習 CLIPS 的主要目的是研究 Xcode 中自定義 Instruments 功能的時候須要用到。
CLIPS 是一種計算機語言,又稱專家系統。能夠到 sourceforge.net 下載相關的開發工具,在 Mac 上安裝後是這樣的:
bash

image.png

仔細一看,發現本身又精通了一門語言的 Hello world! 打印。圖中分紅兩個部分,分別以下所示: 前半部分:

(defrule hello
=>
(printout t "Hello World!" crlf)
(readline)
)
複製代碼

這裏是主要的是核心代碼。
後半部分:app

(run)
複製代碼

這裏主要是執行 前半部分 代碼的命令,因此執行 (run) 以後 Hello World! 就被打印了。ide

至此能夠發現一個規律: 括號不少。是的,CLIPS 的語法塊都是使用 () 括起來的,可是 => 看起來很特殊,接下來詳細解說一下上面的每一行。函數

  • 第 1 行: 有一個關鍵字 defrule, 意思是定義規則的意思。我猜多是 define rule的縮寫。hello 就是所定義規則的名稱。這一行的開頭是( 與最後一行的 ) 匹配。
  • 第 2 行: => 這個就有點厲害了,暫且理解成一個語法分隔符,會在下面介紹。
  • 第 3 行: Hello World! 就是在這裏輸出的了。
  • 第 4 行: 等待終端輸入、讀取信息。

如今應該已經對 CLIPS 的語法有簡單的認識了。
上面僅僅是一個簡單例子,一個相對比較完整的語法應該是這樣的:工具

(defrule hello
(say hi)
=>
(printout t "Hello World!" crlf)
(readline)
)
複製代碼

當輸入這段代碼以後,在執行 (run) 的時候,發現 Hello World! 並無輸出,這麼淘氣,究竟是爲啥呢?接下來分析一下具體的區別,就是多了一句 (say hi)。 是的、第一次看到這麼寫,盡然沒有報錯,括號直接寫 say hi,這是什麼東西。在 CLIPS 中,這個叫 facts(事實)。那這個 facts 有什麼做用呢?
在解釋以前,先來回顧一下如今已經提到的兩個關鍵詞:rule(規則) 與 facts(事實)。post

  • rule(規則) : 就是上面 defrule 中的全部代碼。
  • facts(事實): 就是最後提到的 (say hi)

在 CLIPS 中所要解決的問題,都使用一個特定的規則來表示,在此同時,一個規則免不了依託於某些事實,事實能夠是 0 個或者是多個。從上面的試驗咱們能得出一個結論,若是這個規則沒有 facts,那麼執行 (run) 以後 Hello World! 有輸出,一旦添加了 facts,那麼將不會有輸出。這是由於在執行 (run) 的時候,系統會在系統內存中檢測這個 rule 中是否有事實,沒有就直接 fire(觸發)這個規則,一旦有 facts,那麼須要這些 facts 都被執行以後,纔會fire(觸發) 這個規則。
我勒個去,那麼問題又來了:facts(say hi) 怎麼來的啊?這個 facts 又是怎麼被 fire(觸發) 呢? 新的概念又出現了:assert,好比 assert(say hi),就表示在內存中定義了一個 facts,叫 (say hi)。當定義以後,執行 (run) 以後,實時(say hi) 就被觸發了。若是你很懵,看下面的圖:
學習

image.png

插播一個小總結 對應一個規則的定義,其模板應該是這樣的:開發工具

(defrule rule_name "optinal_comment"
(pattern_1)            ; 由一些在「=>」以前的元素組成的規則左部分
(pattern_2)
...
(pattern_N)

=>

(action_1)            ; 由一些在「=>」以後的元素組成的規則右部分
(action_2)
...
(action_M))

複製代碼

看了這個定義,聰明的你應該對 CLIPS 的理解更上一層樓。總之,經過上面對規則 hello 的介紹,加上這個定義,你應該知道在最後一個例子中:pattern 有一個,是(say hi),能夠有多個。action 有兩個,分別是 (printout..)(readline),能夠有多個。固然這些 action 被觸發的條件是 action 按照 與(AND) 的關係成立以後。
用一個僞代碼來解說 CLIPS 的規則就是:ui

IF certain conditions are true THEN execute the following actionsspa

上面僞代碼中有兩個關鍵詞:IF 與 ** THEN**。仔細品味,還真是這個道理。IF表明 => 的前半部分,稱 LHSTHEN 表明的是 => 的後半部分,稱 RHS

到這裏、對 CLIPS 的介紹也該告一個段落了。可是學習不能停,在上面的例子中,但願將 hello 規則實現得更加通用一點,告訴別人是誰說的。由上面的介紹知道,能夠寫固定,可是這樣確定不可取的,畢竟寫固定以後是不易於擴展的。接下來就須要介紹一下在 CLIPS 中的變量使用。我將上面的代碼換成了這樣子的:

(defrule hello
(say ?name)
=>
(printout t ?name" say: Hello World!" crlf)
(readline)
)
複製代碼

是的、僅僅是將 facts 換成了 (say ?name)。沒錯,在 CLIPS 中定義變量就是這麼單純:一個問號以後直接加上一個可用字符串就是定義了,使用也是同樣的。那如何去使用呢?文字很難描述,直接看圖:

image.png

當建立一個 facts (say CoderHG) 以後就自動的匹配到 hello 規則中的 (say ?name) 了, 並直接將 CoderHG 賦值給了 ?name 變量。通用格式以下:

?

厲害了、個人鍋,變量就這麼介紹完了 **?!?!?!?!?!?!**還有呢,彆着急。關於變量、可否指定變量類型呢?能夠的,好比有 INTEGERSTRING, 其次還能自定義數據類型,請看以下定義:

; 使用模板定義一個數據類型(同結構體)
(deftemplate started-download
    (slot time (type INTEGER))
    (slot caller-address (type INTEGER))
    (slot signpost-id (type INTEGER))
    (slot image-name (type STRING))
)
複製代碼

在 CLIPS 中,這叫一個模塊,定義一個模塊的關鍵字是 deftemplate。如同以上的定義同樣,這個模板的名稱叫 started-download,在這個模板中有這些屬性:timecaller-addresssignpost-idimage-name。每一個屬性前面必需要有 slot, 後面括號後面的就是具體的數據類型。 是的,就是在 C、JAVA 中,這叫一個結構體。

再來插播其它的小 case
在上面咱們主要是圍繞一個 hello 規則來進行介紹的,那麼另個問題來了。這麼一個規則在 CLIPS 中放到什麼地方了呢?答案是 內存中。這個答案略顯 屌絲,但也無傷大雅。其實更確切的說這些規則都須要依託於在 CLIPS 的模塊中。若是不明確的指明的話,默認是在 MAIN 模塊中。咱們能夠這樣的驗證:

image.png

是的,咱們可使用函數 ppdefrule 來查看一個 rule 的定義,好比(ppdefrule hello)。能夠看到在 hell 的前面有一個咱們沒有寫的 MAIN::,這是默認的,因此通常能夠不用明顯的寫出來。 那麼在 CLIPS 中海油其它的模塊,好比:MODELERRECORDER

是該作一個總結了 在當前文章中主要介紹了這個內容:rule(規則)、facts(事實)、變量、模板與模塊。 對於 CLIPS ,還有更多須要咱們繼續學習深究的東西,可是對於目前的我來講,知道這些差很少夠用。

我對 CLIPS 的學習是針對在 iOS 開發中 Xcode 中 Instruments 自定義 中遇到的。Instruments 自定義 中的實現,都是居於 CLIPS 語言實現的。因此研究 Instruments 自定義 必需要知道 CLIPS 中的一些基本套路。

參考文章

從入門到精通之專家系統CLIPS(二)
Creating Custom Instruments
Xcode 中自定義 Instruments

相關文章
相關標籤/搜索