Está en la página 1de 13

Breve tutorial sobre Jess

Beln Daz Agudo

JESS
1. Introduccin
Jess es un shell para construir sistemas expertos escrito en Java. Jess da soporte para desarrollar sistemas
expertos basados en reglas que estn totalmente integrados con aplicaciones escritas en el lenguaje Java.
Jess es una biblioteca escrita en Java que sirve como un intrprete para el lenguaje Jess que es muy
similar al lenguaje CLIPS que ya conocemos.
La pgina oficial del sistema Jess es: http://herzberg.ca.sandia.gov/jess/
Desde all se puede descargar la biblioteca y documentacin que se puede usar para completar esta breve
descripcin de las caractersticas principales de Jess y cmo intercambiar informacin con programas Java.
Para usar jess necesitamos al menos la versin compilada de la biblioteca que se encuentra en el archivo
jess.jar. Adems se incluye y se recomienda consultar la documentacin (/docs/index.html) o manual.pdf y
los ejemplos (/examples).
En el laboratorio usaremos la versin 6.2 que es para la que tenemos licencia. Actualmente est disponible
la versin 7 por lo que la actualizaremos cuando tengamos la nueva licencia. No hay cambios que nos
afecten entre las dos versiones.

2. Interfaz de lnea de rdenes

Para tener una interfaz de lnea de rdenes parecida (pero mucho ms simple) a la que manejbamos en
CLIPS hay que ejecutar la clase jess.Main o jess.Console (lo ejecuta en una ventana aparte).
La clase jess.Main proporciona una interfaz de lnea de comandos a Jess, pero adems es el ncleo de
las interfaces grficas (jess.Console y jess.ConsoleApplet).
Ejemplos:
java jess.Main
examples/fullmab.clp
java jess.Console
con la distribucin binaria:
java cp jess.jar jess.Main examples/fullmab.clp
en una ventana aparte:
java cp jess.jar jess.Console examples/fullmab.clp
Tambin se puede invocar el intrprete y despus cargar los ficheros con batch:
java cp jess.jar jess.Console
(batch Jess60/examples/fullmab.clp)
El archivo de ejemplo fullmab.clp incluye cdigo CLIPS que termina con las instrucciones:
(reset)
(run)
La clase jess.Main lleva a cabo varias acciones:

Lee un archivo de cdigo Jess (opcional, slo si se pasa como argumento en la llamada. Para ello
usa la clase parser jess.Jesp.

Lee y ejecuta la entrada del usuario de forma cclica.

3. Formas de uso de Jess


Jess puede ser utilizado de varias formas incluyendo aplicaciones de lnea de comandos, aplicaciones con
interfaz grfica, servlets y applets.
Se pueden desarrollar distintos tipos de aplicaciones que dependen de dnde quiera escribir el cdigo. Es
decir, decidir una arquitectura en la que se escribe principalmente cdigo Java o cdigo Jess.

Jess -1

Breve tutorial sobre Jess

Beln Daz Agudo

Una forma de utilizar Jess en la que el control estar principalmente en el cdigo Java consiste en manejar
objetos de la clase RETE de la biblioteca.
Cada objeto rete representa un motor de razonamiento independiente, de forma que un mismo programa
puede incluir varios motores independientes (cada uno con su memoria de trabajo, base de reglas, ..).
Para utilizar Jess de forma incrustada en una aplicacin Java simplemente ser necesario crear uno (o
ms) objetos rete y manipularlo a travs de los mtodos adecuados.
El siguiente ejemplo muestra una forma sencilla de utilizar Jess mediante un objeto RETE
Ejemplo 1 (este cdigo est en el CV)
import jess.*;
import java.io.*;
public class Jesster
{
// The inference engine
private static Rete m_rete;
// Fichero que almacena el fuente del programa clips que vamos a cargar
private static String programaFuente;
// Constructor
public Jesster()
{
m_rete = new Rete();
programaFuente = "wordgame.clp";
cargaPrograma(programaFuente);
System.out.println("Cargando programa " + programaFuente + " ");
}
public static void main(String[] args)
{
int choice;
int i;
Jesster jesso;
jesso = new Jesster();
jesso.reset();
jesso.run();
jesso.listaHechos();
jesso.halt();
}
// obtiene e imprime la lista de hechos
public static void listaHechos()
{
java.util.Iterator iterador; // java.util.Iterator
iterador= m_rete.listFacts();
while (iterador.hasNext()) {
System.out.println(iterador.next());
}}
public static void halt()
{
try
{ m_rete.halt(); }
catch (JessException je3)
{ System.out.println("Error: no puedo detener programa "); }
}
public static void cargaPrograma(String nombre)
{
try
{ m_rete.executeCommand("(batch \"" + nombre + "\")"); }
catch(JessException je0)
{
System.out.println("Error: no puedo leer programa " + nombre);
if (je0.getNextException() != null)
{
System.out.println(je0);
System.out.println("Nested exception is:\n");
System.out.println(je0.getNextException().getMessage());
je0.getNextException().printStackTrace();
}
else
je0.printStackTrace();
Jess -2

Breve tutorial sobre Jess

Beln Daz Agudo

}
}

Jess -3

Breve tutorial sobre Jess

Beln Daz Agudo

public static void reset()


{
try
{ m_rete.reset();
}
catch(JessException je2)
{ System.out.println("Error: no puedo resetear ");
if (je2.getNextException() != null)
{
System.out.println(je2);
System.out.println("Nested exception is:\n");
System.out.println(je2.getNextException().getMessage());
je2.getNextException().printStackTrace();
}
else
je2.printStackTrace();
}
}
public static void run()
{
try
{ m_rete.run();
}
catch(JessException je4)
{ System.out.println("Error: no puedo ejecutar ");
if (je4.getNextException() != null)
{
System.out.println(je4);
System.out.println("Nested exception is:\n");
System.out.println(je4.getNextException().getMessage());
je4.getNextException().printStackTrace();
}
else
je4.printStackTrace();
}
}
}

4. Mtodos de la clase Rete que aparecen en el ejemplo


(extraidos de la documentacin):
Class Rete
public Value executeCommand(java.lang.String cmd)
throws JessException
Call a Jess function in this engine's global context.
Parameters:
cmd - A string containing a value Jess function
Returns:
The function's result.
Throws:
JessException - If anything goes wrong
En el cdigo se hace una llamada a la funcin batch, pero se pueden consultar otras funciones que se
pueden llamar en el Apndice A de la documentacin (archivo function_index.html)
Ejemplos:
m_rete.executeCommand("(batch \"" + nombre + "\")");
m_rete.executeCommand("(batch jess/examples/pumps/pumps-fromjava.clp)");
Jess -4

Breve tutorial sobre Jess

Beln Daz Agudo

m_rete.executeCommand("(reset)");
m_rete.executeCommand("(run)");

public void halt()


throws JessException

Stop the engine from firing rules.

public void reset()throws JessException

Reset the Rete engine. Remove all facts, activations, etc. Clear all non-globals from the global scope.
Assert (initial-fact). Broadcasts a JessEvent of type RESET.
Throws:
JessException - If anything goes wrong.

Es equivalente a:

m_rete.executeCommand("(reset)");

public int run()throws JessException

Run the actual engine.


Returns:
The number of rules fired
Throws:
JessException - If anything goes wrong.

Es equivalente a:

m_rete.executeCommand("(run)");

public java.util.Iterator listFacts()

Return an Iterator over all the facts currently on the fact-list

Otras funciones que pueden ser tiles:

public Fact assertFact(Fact f)throws JessException


Assert a fact
Parameters:
f - A Fact object. This fact becomes the property of Jess after calling assertFact() -- don't change
any of its fields until the fact is retracted!
Returns:
The fact ID on success, or -1.
Throws:
JessException - If anything goes wrong

public Fact retract(Fact f)


throws JessException

Retract a fact.
Parameters:
f - A Fact object. Doesn't need to be the actual object that appears on the fact-list; can just be a
Fact that could compare equal to one.
Throws:
JessException - If anything goes wrong.

Ejemplo 2:
El siguiente ejemplo muestra cmo se puede utilizar el mtodo executeCommand para ejecutar desde Java
cualquier llamada a una funcin Jess. Realmente en el ejemplo todo se hace en Jess pero controlado desde
un programa Java.
import jess.*;
public class ExSquare
{ public static void main(String[] unused)
{ try
{ Rete r = new Rete();
r.executeCommand("(deffunction square (?n) (return (* ?n ?n)))");
Value v = r.executeCommand("(square 3)");
System.out.println(v.intValue(r.getGlobalContext()));
// Prints '9'
// La funcin intValue devuelve el contenido de v como un entero. Recibe
Jess -5

Breve tutorial sobre Jess


// como parmetro el contexto actual del objeto rete.
}
catch (JessException ex)
{ System.err.println(ex); }
} }
C:\> java ExSquare
9

Beln Daz Agudo

Comentarios:

La clase RU (Rete Utilities) contiene utilidades generales para Jess. Es una clase sin constructor
y todos sus atributos y mtodos son estticos.

Funcall es una clase (subclase de ValueVector) para parsear e interpretar las llamadas a
funcin. Sus instancias representan llamadas a una funcin.
o Constructor de la clase
Funcall(java.lang.String name, Rete engine), siendo name el nombre de
la llamada a funcin que vamos a llamar en el objeto Rete indicado por engine.
o El mtodo add lo hereda de la clase ValueVector y aade un nuevo elemento al final.
o El mtodo execute se encarga de ejecutar la funcin en un cierto contexto.
o El mtodo arg se usa para darle los argumentos a la funcin. Hace lo mismo que
add pero permite encadenar las llamadas porque devuelve objetos Funcall en vez de
ValueVector (como add).
Se puede llamar a funciones Jess utilizando jess.Funcall en vez de utilizar

jess.Rete.executeFunction().
Ejemplo:

Rete r = new Rete();


Context c = r.getGlobalContext();
Value dimension = new Value("dimension", RU.ATOM);
Funcall f = new Funcall("defclass", r);
f.arg(dimension).arg(new Value("java.awt.Dimension", RU.ATOM));
f.execute(c);
new Funcall("facts", r).execute(c);

La clase Value representa los valores tipados de Jess. El mtodo type() devuelve la constante de
tipo que representa el valor.
Constructores:
Value(boolean b) Construct a boolean value object (one of the RU.ATOMs TRUE
or FALSE.
Value(double d, int type) Construct a value of floating-point type.
Value(int value, int type)Construct a value of integral type.
Value(java.lang.Object o) Construct a value of external address type.
Value(java.lang.String s, int type) Construct a value of String type.
Value(Value v) Construct a value that is a copy of another Value.
Value(ValueVector f, int type) Construct a value of list type.

5. Mtodos para definir y listar distintos elementos de Jess


Quiz la manera ms fcil para definir templates, hechos y otros elementos es usar el lenguaje Jess y hacer
que desde java (a travs de las funciones de la biblioteca) se parseen y carguen los archivos
correspondientes.
An as muchos de los elementos de Jess estn presentes como clases en la biblioteca Jess y se pueden
utilizar para construir instancias en Java y despus aadirlas al motor de reglas explcitamente.
Los siguientes mtodos de la clase Rete permiten aadir elementos a un motor de reglas (un objeto Rete):

public void addDeffacts(Deffacts)

public void addDefglobal(Defglobal)

public void addDefrule(Defrule)

public void addDeftemplate(Deftemplate)

public void addUserfunction(Userfunction)


Jess -6

Breve tutorial sobre Jess

Beln Daz Agudo

public void addUserpackage(Userpackage)

Los siguientes mtodos de la clase Rete devuelven (dado un nombre) los elementos existentes en un motor
de reglas.

public Defglobal findDefglobal(String)

public Defrule findDefrule(String)

public Deftemplate findDeftemplate(String)

public Userfunction findUserfunction(String)

Los siguientes mtodos de la clase Rete devuelven elementos java.util.Iterators para las distintas
estructuras de datos de un motor de reglas:
public Iterator listActivations()

public Iterator listDeffacts()

public Iterator listDefglobals()

public Iterator listDefrules()

public Iterator listDeftemplates()

public Iterator listFacts()

public Iterator listFunctions()

6. Llamadas a funciones Java desde Jess


Desde el cdigo JESS (archivos clp) se puede hacer llamadas a funciones Java usando call. Por ejemplo,
observar cmo se usa para detener la ejecucin del programa:
(deffacts idle-fact
(idle))
(defrule sleep-if-bored
(declare (salience -100))
?idle <- (idle)
=>
(retract ?idle)
(call java.lang.Thread sleep 100)
(assert (idle)))

7. Transferencia de valores entre cdigo Jess y Java


Se pueden utilizar los siguientes mtodos de la clase jess.Rete.
public Value store(String name, Value val);
public Value store(String name, Object val);
public Value fetch(String name);
public void clearStorage();
Que se corresponden con las siguientes funciones que estn disponibles en Jess:
(store <name> <value>)
(fetch <name>)
(clear-storage)
Para almacenar un valor con store se utiliza un nombre y un valor (que en Jess puede ser cualquier valor y
en Java puede ser cualquier objeto jess.Value o cualquier objeto Java)

Jess -7

Breve tutorial sobre Jess

Beln Daz Agudo

Para recuperar un valor con fetch se utiliza un nombre y se devuelve cualquier valor almacenado con ese
nombre (o null en Java y nil en Jess si dicho objeto no existe).
Como se puede observar el mecanismo de comunicacin es realmente sencillo mediante el uso de estas dos
funciones pues son complementarias. Se establece un pipeline de forma que si desde Java enviamos un
objeto mediante un store, lo recogemos des de JESS con la funcin fetch, y de la misma forma si la
comunicacin se realiza en el sentido inverso. Conociendo estas dos funciones vemos como seria la
interaccin habitual entre Java y JESS. Slo se permite el intercambio de informacin de tipos simples
pero es suficiente para las prcticas que haremos. Existen mecanismos de intercambio de informacin
estructurada en forma de objetos java que se asertan como objetos o hechos CLIPS. Estas caractersticas se
pueden consultar en la documentacin pero el siguiente ejemplo muestra cmo se crea un objeto en Java y
se pasa a Jess que lo utiliza como argumento para definir una instancia (definstance en Jess).
import jess.*;
public class ExFetch
{
public static void main(String[] unused) throws JessException
{ Rete r = new Rete();
r.store("DIMENSION", new java.awt.Dimension(10, 10));
r.executeCommand("(defclass dimension java.awt.Dimension)");
r.executeCommand("(definstance dimension (fetch DIMENSION) static)");
r.executeCommand("(facts)");
} }
C:\> java ExFetch
f-0
(MAIN::dimension (class <External-Address:java.lang.Class>) (height 10.0) (size
<External-Address:java.awt.Dimension>) (width 10.0) (OBJECT <ExternalAddress:java.awt.Dimension>))
For a total of 1 facts.
Las funciones clearStorage() y clear-storage eliminan todos los valores de la tabla (se almacenan
como una tabla hash)..
Las funciones clear y Java clear() llamarn a clearStorage(), pero reset y reset() no lo harn.
Es decir, que los datos almacenados estn disponibles tras las llamadas a reset().

Jess -8

Breve tutorial sobre Jess

Beln Daz Agudo

Ejemplo 3 (este cdigo est en el CV)


import jess.*;
import java.io.*;
import javax.swing.*;
public class Jesster
{
// The inference engine
public static Rete m_rete;
// Fichero que almacena el fuente del programa clips que vamos a cargar
private static String programaFuente;
// Constructor
public Jesster()
{
m_rete = new Rete();
programaFuente = "cadenas.clp";
cargaPrograma(programaFuente);
System.out.println("Cargando programa " + programaFuente + " ");
}
public static void main(String[] args)
{
int choice;
int i;
Jesster jesso;
jesso = new Jesster();
jesso.reset();
for(int i=1;i<tecleado[0];i++)
cadena = cadena + Integer.toString(tecleado[i]);
String cadena = "7372";
Value v1 = null;
try {
v1 = new Value("7372",RU.STRING);
}
catch (JessException ex) {
}
m_rete.store("teclas_pulsadas",v1);
jesso.run();
jesso.listaHechos();
Value v=m_rete.fetch("palabra_sugerida");
System.out.println("La palabra sugerida es: ");
System.out.println(v.toString());
jesso.halt();

//
//

}
// imprime la lista de hechos
public static void listaHechos()
{
java.util.Iterator iterador; // java.util.Iterator
iterador= m_rete.listFacts();
while (iterador.hasNext()) {
System.out.println(iterador.next());
}
}
public static void halt()
{
try
{ m_rete.halt(); }
catch (JessException je3)
{ System.out.println("Error: no puedo detener programa "); }
}
public static void cargaPrograma(String nombre)
{
try
{ m_rete.executeCommand("(batch \"" + nombre + "\")");
}
catch(JessException je0)
{
System.out.println("Error: no puedo leer programa " + nombre);
Jess -9

Breve tutorial sobre Jess

Beln Daz Agudo

if (je0.getNextException() != null)
{
System.out.println(je0);
System.out.println("Nested exception is:\n");
System.out.println(je0.getNextException().getMessage());
je0.getNextException().printStackTrace();
}
else
je0.printStackTrace();
}
}
public static void reset()
{
try
{ m_rete.reset();
}
catch(JessException je2)
{ System.out.println("Error: no puedo resetear ");
if (je2.getNextException() != null)
{
System.out.println(je2);
System.out.println("Nested exception is:\n");
System.out.println(je2.getNextException().getMessage());
je2.getNextException().printStackTrace();
}
else
je2.printStackTrace();
}
}
public static void run()
{
try
{ m_rete.run();
}
catch(JessException je4)
{ System.out.println("Error: no puedo ejecutar ");
if (je4.getNextException() != null)
{
System.out.println(je4);
System.out.println("Nested exception is:\n");
System.out.println(je4.getNextException().getMessage());
je4.getNextException().printStackTrace();
}
else
je4.printStackTrace();
}
}
}

8. La clase jess.Fact
La clase jess.Fact (subclase de ValueVector) se usa para representar los hechos. Cada hecho se guarda
como una lista en la que las entradas se corresponden con los slots. El nombre del hecho se guarda en una
variable separada (que se puede obtener a travs del mtodo getName()).
Una vez que un objeto jess.Fact se aserta pasa a formar parte de las estructuras de datos internas del
objeto Rete (por lo que se deja de tener el control sobre l y no se deben hacer cambios sobre sus slots ya
que no se reflejan en el hecho de la parte jess).
Al hacer retract del hecho, se devuelve el control sobre el objeto Fact.
Jess -10

Breve tutorial sobre Jess

Beln Daz Agudo

Ejemplo 4: construccin de hechos sin orden desde Java


Creacin de un template y aserto de un hecho sin orden de esa plantilla.
import jess.*;
public class ExPoint
{
public static void main(String[] unused) throws JessException
{ Rete r = new Rete();
r.executeCommand("(deftemplate point \"A 2D point\" (slot x) (slot y))");
Fact f = new Fact("point", r);
f.setSlotValue("x", new Value(37, RU.INTEGER));
f.setSlotValue("y", new Value(49, RU.INTEGER));
r.assertFact(f);
r.executeCommand("(facts)");
} }
C:\> java ExPoint
f-0
(MAIN::point (x 37) (y 49))
For a total of 1 facts.
Ejemplo 5: en el que el template tiene un multislot
En Java, un multislot se representa mediante un objeto Value de tipo RU.LIST; el objeto Value contiene
un ValueVector con los campos del multislot.
import jess.*;
public class ExMulti
{
public static void main(String[] unused) throws JessException
{
Rete r = new Rete();
r.executeCommand("(deftemplate vector \"A named vector\"" +
" (slot name) (multislot list))");
Fact f = new Fact("vector", r);
f.setSlotValue("name", new Value("Groceries", RU.ATOM));
ValueVector vv = new ValueVector();
vv.add(new Value("String Beans", RU.STRING));
vv.add(new Value("Milk", RU.STRING));
vv.add(new Value("Bread", RU.STRING));
f.setSlotValue("list", new Value(vv, RU.LIST));
r.assertFact(f);
r.executeCommand("(facts)");
} }
C:\> java ExMulti
f-0
(MAIN::vector (name Groceries) (list "String Beans" "Milk" "Bread"))
For a total of 1 facts.
Ejemplo 6: creacin de un hecho ordenado desde Java
Un hecho ordenado se representa como un hecho no ordenado con un nico multislot llamado __data. NO
es necesario crear un template para un hecho ordenado: se crear automaticamente si no existe.
import jess.*;
public class ExOrdered
{
public static void main(String[] unused) throws JessException
{
Rete r = new Rete();
Fact f = new Fact("letters", r);
ValueVector vv = new ValueVector();
vv.add(new Value("a", RU.ATOM));
vv.add(new Value("b", RU.ATOM));
vv.add(new Value("c", RU.ATOM));
f.setSlotValue("__data", new Value(vv, RU.LIST));
r.assertFact(f);
r.executeCommand("(facts)");
}
}
C:\> java ExOrdered
f-0
(MAIN::letters a b c)
For a total of 1 facts.
Jess -11

Breve tutorial sobre Jess

Beln Daz Agudo

9. La clase jess.Deftemplate
Ejemplo alternativo al uso de deftemplate dentro de executeCommand que hemos usado en el ejemplo
anterior.
import jess.*;
public class ExBuildDeftemplate
{
public static void main(String[] unused) throws JessException
{
Rete r = new Rete();
Deftemplate dt = new Deftemplate("point", "A 2D point", r);
Value zero = new Value(0, RU.INTEGER);
dt.addSlot("x", zero, "NUMBER");
dt.addSlot("y", zero, "NUMBER");
r.addDeftemplate(dt);
// Now create and assert Fact
} }
C:\> java ExBuildDeftemplate

10.

Formatear la salida. Clase

PrettyPrinter

La clase jess.PrettyPrinter puede producir una salida formateada de muchos objetos Jess, por
ejemplo de las clases jess.Defrule, jess.Deffunction, jess.Defquery, etc. En general de
cualquier cosa que implemente la interfaz jess.Visitable.
jess.PrettyPrinter se usa de forma muy simple: definir una instancia, pasar el objeto que se quiere
mostrar como argumento del constructor, y llamar al mtodo toString para obtener el resultado
formateado.
import jess.*;
public class ExPretty
{
public static void main(String[] unused) throws JessException
{
Rete r = new Rete();
r.executeCommand("(defrule myrule (A) => (printout t \"A\" crlf))");
Defrule dr = (Defrule) r.findDefrule("myrule");
System.out.println(new PrettyPrinter(dr));
} }
C:\> java ExPretty
(defrule MAIN::myrule
(MAIN::A)
=>
(printout t "A" crlf))

11.
Aadir funciones java para que puedan ser llamadas
desde jess. addUserpackage
La funcin addUserpackage de la clase Rete hace accesible cierta parte del cdigo Java para que pueda ser
llamado desde el archivo jess.
Por ejemplo:

rete.addUserpackage(new minesweeper.jesspackage.BoardFunctions(tablero));
hace accesible que podamos hacer desde jess las llamadas a ciertas funciones del objeto
tablero. La clase aadida (en este ejemplo BoardFunctions) debe implementar
jess.Userpackage
public class BoardFunctions implements jess.Userpackage {
public void add(Rete engine) {
engine.addUserfunction(new LevantaFunction(tablero));
/* permite la llamada tablero.levanta */
engine.addUserfunction(new MarcaFunction(tablero));
engine.addUserfunction(new DesmarcaFunction(tablero));
Jess -12

Breve tutorial sobre Jess

Beln Daz Agudo

engine.addUserfunction(new ContenidoFunction(tablero));
engine.addUserfunction(new RandomFunction(tablero));
engine.addUserfunction(new TotalMinesFunction(tablero));

Para cada una de las funciones se define una clase que implementa jess.Userfunction

public class LevantaFunction implements Userfunction.


Se recomienda consultar la documentacin.

Jess -13

También podría gustarte