Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Tutorial Breve Jess Con Java
Tutorial Breve Jess Con Java
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.
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.
Jess -1
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
}
}
Jess -3
m_rete.executeCommand("(reset)");
m_rete.executeCommand("(run)");
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)");
Es equivalente a:
m_rete.executeCommand("(run)");
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
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:
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.
Los siguientes mtodos de la clase Rete devuelven (dado un nombre) los elementos existentes en un motor
de reglas.
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()
Jess -7
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
//
//
}
// 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
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
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.
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
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
Jess -13