我學習 CLIPS 的主要目的是研究 Xcode 中自定義 Instruments 功能的時候須要用到。
CLIPS 是一種計算機語言,又稱專家系統。能夠到 sourceforge.net 下載相關的開發工具,在 Mac 上安裝後是這樣的:
bash
Hello world!
打印。圖中分紅兩個部分,分別以下所示:
前半部分:
(defrule hello
=>
(printout t "Hello World!" crlf)
(readline)
)
複製代碼
這裏是主要的是核心代碼。
後半部分:app
(run)
複製代碼
這裏主要是執行 前半部分 代碼的命令,因此執行 (run)
以後 Hello World! 就被打印了。ide
至此能夠發現一個規律: 括號不少。是的,CLIPS 的語法塊都是使用 ()
括起來的,可是 =>
看起來很特殊,接下來詳細解說一下上面的每一行。函數
defrule
, 意思是定義規則的意思。我猜多是 define rule
的縮寫。hello
就是所定義規則的名稱。這一行的開頭是(
與最後一行的 )
匹配。=>
這個就有點厲害了,暫且理解成一個語法分隔符,會在下面介紹。Hello World!
就是在這裏輸出的了。如今應該已經對 CLIPS 的語法有簡單的認識了。
上面僅僅是一個簡單例子,一個相對比較完整的語法應該是這樣的:工具
(defrule hello
(say hi)
=>
(printout t "Hello World!" crlf)
(readline)
)
複製代碼
當輸入這段代碼以後,在執行 (run)
的時候,發現 Hello World!
並無輸出,這麼淘氣,究竟是爲啥呢?接下來分析一下具體的區別,就是多了一句 (say hi)
。 是的、第一次看到這麼寫,盡然沒有報錯,括號直接寫 say hi
,這是什麼東西。在 CLIPS 中,這個叫 facts(事實)。那這個 facts 有什麼做用呢?
在解釋以前,先來回顧一下如今已經提到的兩個關鍵詞:rule(規則) 與 facts(事實)。post
defrule
中的全部代碼。(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)
就被觸發了。若是你很懵,看下面的圖:
學習
插播一個小總結 對應一個規則的定義,其模板應該是這樣的:開發工具
(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表明 =>
的前半部分,稱 LHS
, THEN 表明的是 =>
的後半部分,稱 RHS
。
到這裏、對 CLIPS 的介紹也該告一個段落了。可是學習不能停,在上面的例子中,但願將 hello 規則實現得更加通用一點,告訴別人是誰說的。由上面的介紹知道,能夠寫固定,可是這樣確定不可取的,畢竟寫固定以後是不易於擴展的。接下來就須要介紹一下在 CLIPS 中的變量使用。我將上面的代碼換成了這樣子的:
(defrule hello
(say ?name)
=>
(printout t ?name" say: Hello World!" crlf)
(readline)
)
複製代碼
是的、僅僅是將 facts 換成了 (say ?name)
。沒錯,在 CLIPS 中定義變量就是這麼單純:一個問號以後直接加上一個可用字符串就是定義了,使用也是同樣的。那如何去使用呢?文字很難描述,直接看圖:
當建立一個 facts (say CoderHG)
以後就自動的匹配到 hello 規則中的 (say ?name)
了, 並直接將 CoderHG
賦值給了 ?name 變量。通用格式以下:
?
厲害了、個人鍋,變量就這麼介紹完了 **?!?!?!?!?!?!**還有呢,彆着急。關於變量、可否指定變量類型呢?能夠的,好比有 INTEGER
與 STRING
, 其次還能自定義數據類型,請看以下定義:
; 使用模板定義一個數據類型(同結構體)
(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,在這個模板中有這些屬性:time
, caller-address
,signpost-id
與 image-name
。每一個屬性前面必需要有 slot, 後面括號後面的就是具體的數據類型。 是的,就是在 C、JAVA 中,這叫一個結構體。
再來插播其它的小 case
在上面咱們主要是圍繞一個 hello 規則來進行介紹的,那麼另個問題來了。這麼一個規則在 CLIPS 中放到什麼地方了呢?答案是 內存中。這個答案略顯 屌絲,但也無傷大雅。其實更確切的說這些規則都須要依託於在 CLIPS 的模塊中。若是不明確的指明的話,默認是在 MAIN 模塊中。咱們能夠這樣的驗證:
是的,咱們可使用函數 ppdefrule 來查看一個 rule 的定義,好比(ppdefrule hello)。能夠看到在 hell 的前面有一個咱們沒有寫的 MAIN::
,這是默認的,因此通常能夠不用明顯的寫出來。 那麼在 CLIPS 中海油其它的模塊,好比:MODELER 與 RECORDER。
是該作一個總結了 在當前文章中主要介紹了這個內容:rule(規則)、facts(事實)、變量、模板與模塊。 對於 CLIPS ,還有更多須要咱們繼續學習深究的東西,可是對於目前的我來講,知道這些差很少夠用。
我對 CLIPS 的學習是針對在 iOS 開發中 Xcode 中 Instruments 自定義 中遇到的。Instruments 自定義 中的實現,都是居於 CLIPS 語言實現的。因此研究 Instruments 自定義 必需要知道 CLIPS 中的一些基本套路。
從入門到精通之專家系統CLIPS(二)
Creating Custom Instruments
Xcode 中自定義 Instruments