0% found this document useful (0 votes)
38 views

Functions and Imput-Output

This document describes a Jess program that simulates a cat moving between rooms to find milk. It includes templates for a Cat, Room, and Phase. Rules are defined for asking the user to specify the milk location, changing the default location, sensing milk, drinking milk, and moving between rooms. Initial facts are asserted for the rooms, cat, and phase to start the simulation. The program allows the user to optionally set the milk location or use the default of room 5. The cat will then move between rooms, sense when it smells milk, drink the milk, and become happy.

Uploaded by

olivukovic
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
38 views

Functions and Imput-Output

This document describes a Jess program that simulates a cat moving between rooms to find milk. It includes templates for a Cat, Room, and Phase. Rules are defined for asking the user to specify the milk location, changing the default location, sensing milk, drinking milk, and moving between rooms. Initial facts are asserted for the rooms, cat, and phase to start the simulation. The program allows the user to optionally set the milk location or use the default of room 5. The cat will then move between rooms, sense when it smells milk, drink the milk, and become happy.

Uploaded by

olivukovic
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 5

More JESS

Functions and Input/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>+)

E.g. to print each item on a grocery list on a separate line:


Jess> (bind ?grocery-list (create$ eggs milk bread))
(eggs milk bread)
Jess> (foreach ?e ?grocery-list
(printout t ?e crlf))
eggs
milk
bread
The foreach function is useful when you already have a list of values for the loop
variable. Often, though, you need a more general kind of looping construct,
such as while.

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.

E.g. using while to add the numbers from 1 to 10:


Jess> (bind ?i 1)
1
Jess> (bind ?sum 0)
0
Jess> (while (<= ?i 10) do
(bind ?sum (+ ?sum ?i))
(bind ?i (+ ?i 1)))
FALSE
Jess> ?sum

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

Jess> (bind ?grocery-list (create$ eggs milk bread))


(eggs milk bread)
Jess> (if (member$ eggs ?grocery-list) then
(printout t "I need to buy eggs" crlf)
else
(printout t "No eggs, thanks" crlf))
I need to buy eggs
Either the if block or the else block can be terminated early using the return
function. The return value of the whole if function call is the value of the last
expression evaluated.

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)))
)

3. Input and output

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.

- (read <router-identifier>)  ;; router-identifier has to be t for standard input - specifying t is


optional
- (readline <router-identifier>) ;; --same--

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).

- (printout <router-identifier> <expression>)

Jess> (printout t "Howdy!" crlf)


Howdy!
4. File I/O

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.

- (open <file-name> <router-identifier> [r or w or a])

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

> script output.txt


%java jess.Main
Jess> (run)
..
...
Jess> (exit)
%exit
>more output.txt

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

;; template for Cat

(deftemplate Cat
(slot x (type integer) (default 1))
(slot status (default hungry) )
(slot smells-milk (default FALSE))
)

;; template for Room

(deftemplate Room
(slot x (type integer))
(slot has-milk (default FALSE))
)

;; template for phase

(deftemplate Phase
(slot has-started (default FALSE))
(slot user-input (default n))
(slot change-def(default FALSE))
)

;; to ask user whether he wants to specify the location of milk

(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)))
)

;; change the default value of the location of milk

(deffunction change-default ()

(printout t "In which room do you want to keep the milk?")


(bind ?x (read))
(assert (Room (x ?x) (has-milk TRUE)))
)

;; rule for sensing the milk

(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)
)

;; rule for drinking the milk

(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)
)

;; rule for moving

(defrule move
(declare (salience 50))
?cat <- (Cat(x ?x) (smells-milk FALSE))
=>
(modify ?cat (x (+ ?x 1) ))
(printout t "Cat moves to ["?x"]." crlf)
)

;; initial facts for room

(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))
)

;; initial facts for cat

(deffacts init-Cat
(Cat (x 1)
(status hungry)
)
)

;; initial facts for phase

(deffacts init-Phase
(Phase (has-started FALSE)
(user-input n)
(change-def FALSE)
)
)

You might also like