Title: CLIPS
1CLIPS
- Bob McKay
- School of Computer Science and Engineering
- College of Engineering
- Seoul National University
- Partly based on
- CLIPS documentation
- Lecture notes by Dr X Yao
2Outline
- CLIPS as a rule-based system
- CLIPS functions
- CLIPS Pattern Matching
3References
- Giarratano and Riley Expert Systems Principles
and Programming, 4th Edition, Course Technology,
ISBN 0-534-38447-1
4What is CLIPS?
- The CLIPS system is a forward-chaining rule-based
expert system shell - That is, a reasoning system for positive definite
clauses - But with a lot of extensions
- It uses the forward-chaining RETE algorithm
- It is written in C
- Syntax is very similar to LISP
- It runs under UNIX, Windows and Macintosh
5Running CLIPS
- On unix, just type clips
- The CLIPSgt prompt will appear
- This is the top level of CLIPS
- On windows and macintosh, just click the CLIPS
icon - To exit, enter (exit)
- Note that all CLIPS commands and functions are
enclosed in a pair of brackets - Comments start with a
6FACTS
- A fact is one or more fields enclosed within
matching left and right parentheses - (isa John student)
- (isa Tom teacher)
7Asserting Facts
- CLIPS keeps track of the facts it believes to be
true through the facts list - It is part of CLIPS working memory
- You can create facts and add them to the fact
list with assert commands - CLIPSgt (assert (isa John student))
- CLIPSgt (assert (isa Tom teacher))
- CLIPSgt (facts) this is a comment
- f-0 (isa John student)
- f-1 (isa Tom teacher)
- The (facts) command displays all the facts
currently in the fact list.
8Retracting Facts
- You can delete a fact from the fact list with the
retract command - You can delete all the facts with the clear
command - CLIPSgt (clear)
- CLIPSgt (assert (isa Mary student) (isa Joe
student) (isa Kay student)) - CLIPSgt (facts)
- f-0 (isa Mary student)
- f-1 (isa Joe student)
- f-2 (isa Kay student)
- CLIPSgt (retract 0 2)
- CLIPSgt (facts)
- f-1 (isa Joe student)
- CLIPSgt (clear)
- CLIPSgt (facts)
- CLIPSgt
9Initial Facts
- Instead of entering facts from CLIPS directly, we
can also define a set of initial facts to be
loaded into CLIPS - These initial facts can be written and edited in
a file - The deffacts function is used for defining
initial facts - (deffacts facts-name comments fact-1 fact-2 ...
fact-n) - Note that the deffacts function can also be
entered under CLIPS - It will only be added to CLIPS's fact list when
CLIPS is reset - The reset command always adds a special fact
(initial-fact) with identifier f-0. - To remove a deffacts function from memory, use
- (undeffacts facts-name)
- We can even remove the system-defined
initial-fact - (undeffacts initial-fact)
10Rules
- Rules are defined using the defrule command
- (defrule rule-name comment
- pattern-1 ... pattern-n
- gt
- action-1 ... action-m)
- Note that the entire rule must be surrounded by
parentheses - Each pattern and action must be too
- CLIPS matches the patterns of rules against facts
in the fact list - If all the patterns of a rule match, the rule is
put on the agenda - The agenda is a priority list of activated rules
awaiting execution - Once a rule is selected by CLIPS for execution,
it is fired and the actions in the RHS
(right-hand-side) of the rule are carried out - The rule is removed from the agenda
- The program stops when no activations are on the
agenda
11Conflict Resolution
- By default, the rules on the agenda are in stack
order - The rules are read bottom to top, which means
that the earliest rules in the KB will be at the
top of the stack - But you can control the rule priorities another
way - CLIPS uses salience to order rules on the
agenda. - The rule with largest salience value has the
highest priority. - Salience is represented by a value between
- -10,000 (lowest priority)
- 10,000 (highest priority)
- You set the salience in the rule definition
- (defrule rule-name comment (declare (salience
25)) - pattern-1 ... pattern-n
- gt
- action-1 ... action-m)
- The default salience value is 0
12The Watch Command
- With the watch command, you can watch a number of
things - facts, activations, rules
- CLIPSgt (reset)
- CLIPSgt (watch facts)
- CLIPSgt (watch activations)
- CLIPSgt (watch rules)
- CLIPSgt (assert (just testing))
- gt f-1 (just testing)
- CLIPSgt (defrule rule-1 "have a try" (declare
(salience 20)) - (just testing) this is the
pattern - gt the arrow
- (printout t "it works!" crlf))
a print function
13The Watch Command
- Activation 20 rule-1 f-1
- CLIPSgt (agenda)
- 20 rule-1 f-1
- For a total of 1 activation
- CLIPSgt (run)
- FIRE 1 rule-1 f-1
- it works!
- CLIPSgt (save "example1.clp") only saves the
defrule or deffacts - CLIPSgt (unwatch all)
- CLIPSgt (agenda)
- CLIPSgt (run)
- CLIPSgt
14Other facts commands
- (save-facts)
- saves the current fact list to a file
- (load-facts)
- reads a file of facts into the fact list
- Different from the (load) command which reads a
file into CLIPS' memory - (rules)
- tells us how many rules are in CLIPS' memory
- what their names are
- (pprule rule-name)
- displays the definition of the rule called
rule-name
15Variables
- Variables names
- "?" followed by a symbol which is the variable
name - A variable can be bound to any value
- CLIPSgt (reset)
- CLIPSgt (assert (isa Joe student) (isa Bo
student)) - CLIPSgt (defrule rule-2
- ?x lt- (isa ?whoever student)
- gt
- (retract ?x)
- (assert (isa ?whoever teacher)))
16Variables
- CLIPSgt (run)
- CLIPSgt (facts)
- f-0 (initial-fact)
- f-1 (isa Joe teacher)
- f-2 )isa Bo teacher)
- For a total of 3 facts
- The left arrow "lt-" binds a variable to an entire
fact
17Wildcards
- A question mark "?" without anything else is a
single field wildcard - It matches anything in a single field
- It is used to match something which we are not
interested in - The multi-field wildcard is "?
- It matches zero or more fields
- It can also have a name like ?here
18Constraints
- Negation constraint
- represented by the prefix .
- x matches anything other than x
- Or constraint
- represented by the infix "_".
- x_y matches either x or y.
- And constraint.
- represented by the infix "".
- Normally used only with other constraints
- otherwise it's not much practical use.
- ?xy_z matches either y or z and binds x to it
- (careful ?xred_yellow)
- matches
- (careful red)
- and
- (careful yellow)
19Mathematical Functions
- CLIPS uses prefix form for arithmetic
- CLIPSgt (defrule addition
- (number ?x ?y)
- gt
- (assert (sum ( ?x ?y))))
is important here - CLIPSgt (assert (number 2 3))
- CLIPSgt (run)
- CLIPSgt (facts)
- f-0 (initial-fact)
- f-1 (number 2 3)
- f-2 (sum 5)
- For a total of 3 facts
20Bind
- You can also use bind to set a variable to a
value - CLIPSgt (defrule addition-again
- (numbers ?x ?y)
- gt
- (bind ?sum ( ?x ?y))
- (printout t "The sum is " ?sum
crlf)) - CLIPSgt (run)
- The sum is 5
- "" or bind in the above tells CLIPS to
perform an evaluation
21Type Conversion
- CLIPSgt ( 1 2)
- 3
- CLIPSgt ( 1 2.0)
- 3.0
- CLIPSgt (integer ( 1 2.9))
- 3
- CLIPSgt (float ( 1 2))
- 3.0
22The test function
- The test function is used to compare values
- (test (function arg-1 arg-2 ... arg-n) )
- the function can be
- eq (equal)
- neq (not equal)
- (numeric equal)
- ! (numeric not equal)
- gt
- gt
- lt
- lt
- ! (not)
- (and)
- __ (or)
23Test
- (defrule same-height
- (height ?x ?hx)
- (height ?y ?hy)
- (test ( ?hx ?hy))
- gt
- (printout t ?x " and " ?y " are of the same
height." crlf))
24Pattern Connectives
- Not the same as field constraints!
- There are three explicit pattern connectives
and, or, not. - (defrule tall-person
- (or (and (isa ?x female)
- (height ?x ?hx)
- (test (gt ?hx 170)))
- (and (isa ?y male)
- (height ?y ?hy)
- (test (gt ?hy 180))) )
- gt
- (printout t "He/She is tall." crlf))
25User-Defined Functions
- You can define your own functions
- (deffunction function-name comment
- (?arg1 ?arg2 ... ?argn)
- ltaction-1gt
- ltaction-2gt
- ...
- ltaction-mgt )
- (deffunction summation (?x ?y ?z)
- (bind ?t ( ?x ?y ?z))
- (printout t "The summation is " ?t crlf))
- To remove a user-defined function, use
undeffunction
26I/O File Open and Close
- Files must be opend before they can be used
- (open "file-name" logical-name mode)
- where mode is one of
- "w" (write)
- "r" (read)
- "r" (read and write)
- "a" (append)
- Closing a file
- (close logical-name)
27I/O Output
- We have already used printout for output to the
terminal - printout can output to a file if we give the
logical name of the file - (open "myfile.dat" writeit "w")
- (fprintout writeit "Here is the message." crlf)
- writeit is the logical name of the file
myfile.dat - Open function creates a writable ("w") file in
the current directory
28I/O Input
- (read logical-name) only read one field
- (readline logical-name) read one line as a
string - If you leave out logical-name (or put t), it
means the terminal - (defrule echo
- no patterns! It matches initial-fact.
- gt
- (fprintout t "Please enter your name
below " crlf) - (bind ?a (readline))
- (fprintout t "Aha, your name is " ?a))
- (reset)
- (run)
29Pattern Matching by Generate Test
- Pattern matching is used extensively in CLIPS
- Especially on the left hand side (LHS) of rules
- usually makes use of
- Variables
- field constraints
- pattern connectives
- Generate-and-test often used for pattern matching
30Generate Test Example
- Suppose we have a fact list with all the student
records - (student John 80)
- (student Joe Smith 70)
- (student Tom Bruce Smith 48)
- We want to print out names of passing students
- their marks are at least 50
- One possible solution is the following rule
- (defrule pass-student "passes"
- (student ?name ?marks) generate
- (test (gt ?marks 50)) test
- gt
- (printout t ?name " passed." crlf))
31Example Remarks
- generate a structure, then test one or more of
its arguments - Note use of a multi field variable (wild card)
- It can be very inefficient.
- Beware that
- a rule will not fired twice for the same set of
facts - but it will fire again if you retract a fact and
assert it again - CLIPS regards the fact as a new one
- although it's literally the same as the retracted
one - Infinite Loops
- Generate and Test can easily generate infinite
loops
32Generate Test Infinite Loops
- Given an initial fact list as
- (student John 80)
- (student Joe Smith 70)
- (student Tom Bruce Smith 48)
- (counter 0)
- (sum 0)
- We want to calculate the average mark
33Infinite Loops (cont)
- Will the this work?
- (defrule summation "get total first"
- (student ?name ?marks)
- ?sum lt- (sum ?total)
- ?counter lt- (counter ?StuNum)
- gt
- (retract ?sum) why ?sum
- (retract ?counter)
- (assert (sum ( ?total ?marks)))
- (assert(counter ( ?StuNum 1))))
- defrule average "get average mark"
- (sum ?total)
- (counter ?StuNum)
- gt
- (assert (average (/ ?total ?StuNum))))
34Infinite Loops (cont)
- What's the result of running this rule?
- summation will loop infinitely on the first
student - Because the sum and counter facts change on
each iteration - So the rule can fire again with the same student
- Solutions
- Simplest
- delete each student after the rule fires
- crude, since we may need the students for other
parts of the system - More complicated, but cleaner
- Use an auxiliary fact
35Infinite Loops Auxiliary Facts
- Replace the summation rule with the following
two - (defrule auxiliary-sum (student ?name ?marks)
- gt
- (assert (mark ?marks))
- (defrule summation "get the total marks first"
- ?m lt- (mark ?marks)
- ?sum lt- (sum ?total)
- ?counter lt- (counter ?StuNum)
- gt
- (retract ?m ?counter ?sum)
- (assert (sum ( ?total ?marks)))
- (assert (counter ( ?StuNum 1))))
36Global Variables
- (bind ?x ( 3.14 3.14)) 9.8596
- (bind ?x (- ?x 1)) What would be the result?
- Global variables defined by defglobal
- (defglobal
- global-var-name expression
- global-var-name expression
- ... ... )
- global-var-name must be of the form ?symbol.
- (defglobal ?x 3.14 ?y 1) two global
variables - (bind ?x ( ?x ?x)) 9.8596
- (bind ?x (- ?x ?y)) 8.8596
- (bind ?x "abc")
37Use of Global Variables
- Global variables may be used in almost any place
that a local variable may occur - There are two exceptions
- Global variables may not be used on the LHS of a
rule to bind a value - the following rule is illegal
- (defrule example (fact ?x) gt (assert (done)))
- Global variables may not be used as a parameter
for a deffunction - (like most other computing languages)
38Non-Ordered Facts
- In ordered facts, fields are distinguished by
position - (what we have seen so far)
- In non-ordered facts, fields are distinguished by
name - The deftemplate function is used to define them
- (deftemplate deftemplate-name optional-comment
- single-field-definition ...
- multifield-definition
- single-field-definition ...)
39Deftemplate example
- (deftemplate student-record
- (field name (type SYMBOL) (default unknown))
- (field year (type INTEGER) (default 2))
- (field major (type STRING) (default "Comp
Sci")) - (multifield hobby (type SYMBOL) (default
football swim))) - (assert (student-record))
- (assert (student-record (year 3) (hobby
basketball)))
40Manipulating Deftemplates
- ppdeftemplate
- Displays the text of a given deftemplate
- (ppdeftemplate ltdeftemplate-namegt)
- list-deftemplates
- Displays the list of all deftemplates
- (list-deftemplates)
- undeftemplate
- Deletes a deftemplate
- (undeftemplate ltdeftemplate-namegt)
41CLIPS Functions
- Predicate Functions
- Mathematical Functions
- Multifield Functions
- String Functions
- Procedural Functions
- Generating Symbols
42Predicate Functions
- A function which returns a FALSE or non-FALSE
value - The colon followed by a predicate function is
called a predicate constraint - Predefined Predicate Functions
- They all end with letter p
43Built-in Predicate Functions
- (evenp arg) even number
- (floatp arg) floating-point number
- (integerp arg) integer
- (numberp arg) float or integer
- (oddp arg) odd number
- (stringp arg) string
- (symbolp arg) symbol
44Predicate Function Examples
- (student ?name ?mark(numberp ?mark))
- (evenp 3.2) FALSE
- (oddp 3.2) TRUE
- (symbolp x) TRUE
- (symbolp 45) FALSE
- (stringp "hello") TRUE
45Built-In Mathematical Functions
- round
- round to closest
- integer
- truncate to integer
- random
- return random integer
- div
- integer division
- max
- maximum value
- min
- minimum value
- abs
- absolute value
- float
- convert to a float
46Mathematical Functions (cont)
- (pi)
- return 3.1415926...
- Note that the brackets are necessary
- (otherwise interpreted as a variable)
- sqrt
- square root
-
- power, x to power y
- exp
- exponential, e to power x
- log
- log e
- log10
- log10
- mod
- modulus
47Mathematical Function Examples
- (mod 5 2)
- returns 1
- (max 1 3.4 (pi) (log 2.81) ( 2 10))
- (mod (random) 2)
- (float (integer (pi)))
48Multifield Functions
- Multifield function names end with
- create
- append any number of fields to create multifield
value - nth
- return the value of the nth field
- member
- test whether a value is a member of a multifield
value - delete
- delete the nth member of the multifield value
- subsetp
- subset testing
49Multifield Function Examples
- (nth 3 (create a b c d e))
- returns c
- (member d (create a b c d e))
- returns 4
- (subsetp (create a d) (create a b c d e))
- returns TRUE
- (delete 2 (create a b c d e))
- returns (a c d e)
50String Functions
- str-cat
- string concatenation
- sym-cat
- symbol concatenation
- sub-string
- returns a sub-string in the range
- str-index
- returns the position of the first matching
character - eval
- evaluate the string
- build
- similar to eval but used with constructs
- upcase
- change all letters to upper case
- lowcase
- change all letters to lower case
- str-compare
- compare two strings according to dictionary order
- str-length
51String Function Examples
- (str-cat "abc" OK 2 3.3 ( 3 4))
- "abcOK23.37"
- (sym-cat "abc" OK 2 3.3 ( 3 4))
- abcOK23.37
- (sub-string 2 4 "abcdefg")
- "bcd"
- (str-index "bcd" "abcdefg")
- 2
- (str-index "bcd" "abc")
- FALSE
- (eval "(create x y z)")
- (x y z)
- (build "(defrule r1 (x y z) gt (assert (done)))")
- TRUE
52String Function Examples
- (upcase "abcOK23.37")
- "ABCOK23.37"
- (lowcase "abcOK23.37")
- "abcok23.37"
- (str-compare "abc" "abd")
- -1
- (str-length "abcOK23.37")
- 10
53Procedural Functions
- if-then-else
- while
- progn
- return
- break
54The if-then-else Function
- very similar to the if-then-else statement in a
procedural language - Like Java, C, .
- (if expression
- then action1 action2 ...
- else action-1 action-2 ...)
- where an action may be any function
- The else part is optional
- This function returns the value of the last
expression or action evaluated
55if-then-else Example
- (defrule print-marks
- ?record lt- (student ?name ?marks)
- gt
- (if (lt ?marks 50)
- then
- (printout t ?name " fails" crlf)
- else
- (printout t ?name " passes" crlf)))
- Note that the above rule can be replaced by two
rules without using if-then-else.
56The while Function
- provides us with a loop structure
- (while expression do do is optional
- action1 action2 ...)
- For example
- (deffunction print-sqrt (?n)
- (while (gt ?n 0)
- (printout t "Sqrt of " ?n " is " (sqrt ?n) crlf)
- (bind ?n (- ?n 1))))
- (print-sqrt 3)
- we should get 4 results
57The progn Function
- evaluates all of its arguments and returns the
value of the last argument - (progn ( 2 3) ( 1 (pi)))
- returns 4.1415926535...
58The return Function
- immediately terminates the currently executing..
- Deffunction
- Defrule
- RHS
- Etc
- can have an optinal argument, the return value
- (deffunction sign (?x)
- (if (gt ?x 0) then (return 0) else (return 1)))
59The break Function
- can be used to terminate
- while loop
- progn execution
- etc
- (deffunction print-sqrt-2 (?n)
- (while TRUE do
- (printout t "Sqrt of " ?n " is " (sqrt ?n) crlf)
- (if (lt ?n 0) then (break))
- (bind ?n (- ?n 1))))
60Symbol-Generating Functions
- gensym
- used to generate a symbol of the form genn
- where n is a positive integer
- (create (gensym) (gensym) (gensym))
- (gen1 gen2 gen3)
- gensym
- generates a unique symbol not currently in the
CLIPS environment - setgen
- sets the starting integer after gen
61Symbol-Generating Example
- (setgen 3)
- returns 3 as its function value
- (create (gensym) (gensym) (gensym))
- returns (gen3 gen4 gen5)
- (gensym)
- returns gen6