我学习 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