Functions and Imput-Output
Functions and Imput-Output
1. Control Flow
The foreach function evaluates a block of expressions once for each element in a plain list.
Each time through the block, a variable you supply is set equal to the corresponding
entry from the list you also supply. The syntax diagram looks like this:
(foreach <variable> <list> <expression>+)
The while function lets you repeatedly evaluate a group of one or more expressions
as long as some condition remains true:
(while <Boolean expression> do <expression>+)
The first argument in the while function must be a Boolean expression. The while function
evaluates the expression, and if is not FALSE, all other expressions in the body of
the while (except the optional symbol do) are evaluated. The cycle repeats until the
expression becomes FALSE.
You can use the if function to choose what code to execute next. The syntax of
Jess’s if function is similar to the if statement in Java:
(if <Boolean expression> then <expression>+ [else <expression>+])
The first argument to if is a Boolean expression. If the value of the expression is
not FALSE, the if function evaluates the group of expressions that follows the symbol
then, in order. If the expression is FALSE, then the statements after else are
evaluated (if the optional else clause is present.)
E.g. This example uses the function member$, which accepts a value and a plain list
You can chain if functions together, much as you can in Java. All you need to
do is to use a second if function call as the body of an else block. In this example,
three if function calls are nested together:
Jess> (bind ?x 1)
1
Jess> (if (= ?x 3) then
(printout t "?x is three." crlf)
else
(if (= ?x 2) then
(printout t "?x is two." crlf)
else
(if (= ?x 1) then
(printout t "?x is one." crlf))))
?x is one.
2. Functions
In the previous labs, you have used several inbuilt functions in Jess. You can also define your
own function so that you don't have to dump everything inside rules. You should use
deffunction to define a function. You can call the following function by calling (change-
default)
(deffunction change-default ()
......
(assert (Room (x ?x) (has-milk TRUE)))
)
There are two functions available for taking input from Standard input (your terminal). You can
use read to read a single atom or string or number. You can also use readline to read an
entire line as a string.
Jess> (read t)
or inside the code
(if (eq (read) y) then
(retract ?room)
(change-default)
)
To write to the terminal, you can use printout. As for read, you would specify the router-
identifier which is again t as you are printing to the standard output (your terminal).
File I/O is easy in Jess. Use the open function with a <router-identifier> to open a file with
read/write/append mode. Then, to read the contents of the file, you can use the read/readline
function using the same router-identifier that you used for opening the file. Similarly, to write
to a file, you can use printout function using the same router-identifier that you used for
opening the file.
The following example would clearly illustrate the usages of the above functions.
Jess> (open temp.txt id w) ;; open a file temp.txt in write mode
id ;; returns the router-identifier
Jess> (printout id "Howdy!!" crlf) ;; writes the string "Howdy!" into the file corresponding to
the router-identifier id
Jess> (open temp.txt id r) ;; opens the file temp.txt in read mode
id
Jess> (read id) ;; reads the stuff from the file opened using the router-
identifier
Howdy!!
Jess> (system cat temp.txt) ;; just double-checking - reading the contents using unix
command cat
Howdy!!
<External-Address:java.lang.UNIXProcess>
To take the output of your program, you can use the unix command "script <output-file>".
After executing this command, do all your stuff with Jess (run your program) and then come
back to % prompt and say "exit". This will write all your transactions into the output file.
Please follow the following sequence and avoid using screenshots
Example Program taken from Jess Tutorial From Ganesh Rajagopalan Texas A&M
University.
This example contains some things we have not covered – if you find something you
are not familiar with check out the Jess documentation.
;; File: cat.clp
;; author: Ganesh Rajagopalan <[email protected]>
;; date : Nov 20, 2001
;;
;; objective: to implement different functions in jess
;; in a simple problem domain to aid the tutorial
;;
;; In this problem a cat moves in a linear
;; array of rooms until it senses milk in the room
;;
;; Note: You can implement in a better way and more efficient manner
;; The purpose of this code is to understand the syntax and
;; functions
(deftemplate Cat
(slot x (type integer) (default 1))
(slot status (default hungry) )
(slot smells-milk (default FALSE))
)
(deftemplate Room
(slot x (type integer))
(slot has-milk (default FALSE))
)
(deftemplate Phase
(slot has-started (default FALSE))
(slot user-input (default n))
(slot change-def(default FALSE))
)
(defrule ask-user
(declare (salience 500))
(Phase (has-started FALSE))
?room <- (Room (x 5) (has-milk TRUE))
=>
(printout t "Do you want to place milk in a room (otherwise default) {y/n}")
(if (eq (read) y) then
(retract ?room)
(change-default)
)
(assert (Phase (has-started TRUE)))
)
(deffunction change-default ()
(defrule sense-milk
(declare (salience 100))
?cat <- (Cat(x ?x))
(Room (x ?x) (has-milk TRUE))
=>
(modify ?cat (smells-milk TRUE))
(printout t "Cat smells milk" crlf)
)
(defrule drink-milk
(declare (salience 150))
?cat <- (Cat (x ?x) (smells-milk TRUE))
=>
(modify ?cat (status happy))
(printout t "Cat drinks milk and is happy :) in Room "?x crlf)
(halt)
)
(defrule move
(declare (salience 50))
?cat <- (Cat(x ?x) (smells-milk FALSE))
=>
(modify ?cat (x (+ ?x 1) ))
(printout t "Cat moves to ["?x"]." crlf)
)
(deffacts init-room
(Room (x 1))
(Room (x 2))
(Room (x 3))
(Room (x 4))
(Room (x 5) (has-milk TRUE))
(Room (x 6))
(Room (x 7))
(Room (x 8))
(Room (x 9))
(Room (x 10))
)
(deffacts init-Cat
(Cat (x 1)
(status hungry)
)
)
(deffacts init-Phase
(Phase (has-started FALSE)
(user-input n)
(change-def FALSE)
)
)