Jess, The Rule Engine for the Java Platform Seminario per il Corso di laboratorio di Sistemi Intelligenti a cura di A. Gilitus Sito ufficiale:

Post on 02-May-2015

223 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

Transcript

Jess, The Rule Engine for the Java Platform

Seminario per il Corso di laboratorio di Sistemi Intelligenti a cura di A. Gilitus

Sito ufficiale: http://herzberg.ca.sandia.gov/jess/

Jess, The Rule Engine for the Java Platform

Come usare il Jess:

• Interfaccia a riga di comando

• Comando batch

Interfaccia a riga di comando

Per lanciare l’interfaccia a riga di comando è sufficiente digitare:

java jess.MainA questo punto compare il prompt: Jess> in cui digitare i comandi come in CLIPS. Es.Jess> (assert (pippo))

Comando batch

Per caricare un programma scritto in Jess si utilizza il comando batch:

Jess> (batch nomefile.clp)

Oppure specificare il file CLIPS sulla riga di comando quando si carica l’ambiente di Jess.

java jess.Main nomefile.clp

Jess, The Rule Engine for the Java Platform

• Parallelo Jess/CLIPS

• Implementazione di Jess con Java

Parallelo Jess/CLIPS

• Differenze nell’utilizzo dei moduli

• Allowed-value

• Interfaccia Grafica

1. Non si dichiara il modulo MAIN. Regole, fatti, template, ecc. che compaiono nel modulo MAIN devono avere la dicitura MAIN:: davanti.

2. Non si usano import e export, a differenza del CLIPS ogni modulo importa da tutti e esporta a tutti.

3. Ogni fatto dichiarato in un determinato modulo (per es. nel modulo PIPPO) sarà distinto dal nome del modulo stesso in working memory, per es. nel caso di una assert(ciao) nel modulo PIPPO, si avrà il fatto: f-1 PIPPO::ciao

4. Per riferirsi a fatti asseriti da altri moduli, è necessario esplicitare il nome del modulo che li ha asseriti.

Differenze nell’utilizzo dei moduli

Non si dichiara il modulo MAIN.

JESS(deftemplate MAIN::solution (slot value

(default no))) (deffacts MAIN::param (solution (value no)) (maxdepth 0))

(deffacts MAIN::S0 (status 0 clear a NA) (status 0 on a b )

(status 0 on b c ) (status 0 ontable c NA)

(status 0 ontable d NA) (status 0 clear d NA)

(status 0 handempty NA NA))

(deffacts MAIN::final (goal on a b) (goal on c d) (goal

ontable d NA) (goal on b c))

CLIPS(defmodule MAIN (export ?ALL))

(deftemplate solution (slot value (default no)))

(deffacts param (solution (value no)) (maxdepth 0))

(deffacts S0 (status 0 clear a NA) (status 0 on a b )

(status 0 on b c ) (status 0 ontable c NA)

(status 0 ontable d NA) (status 0 clear d NA)

(status 0 handempty NA NA))

(deffacts final (goal on a b) (goal on c d) (goal

ontable d NA) (goal on b c))

Non si usano import e exportJESS

(defmodule MAIN2) (defrule got-solution(declare (salience 100))(solution (value yes)) =>

(assert (risolto))(pop-focus)

)

(defrule pick (status ?s on ?x ?y) (status ?s clear ?x ?) (status ?s handempty ? ?) (maxdepth ?d) (test (< ?s ?d)) (not (exec ?s pick ?x ?y)) => (assert (apply ?s pick ?x ?y)))

CLIPS(defmodule MAIN2 (import MAIN ?ALL)

(export ?ALL))(defrule got-solution(declare (salience 100))(solution (value yes)) =>

(assert (risolto))(pop-focus)

)

(defrule pick (status ?s on ?x ?y) (status ?s clear ?x ?) (status ?s handempty ? ?) (maxdepth ?d) (test (< ?s ?d)) (not (exec ?s pick ?x ?y)) => (assert (apply ?s pick ?x ?y)))

Ogni fatto dichiarato in determinato modulo sarà distinto dal nome del modulo stesso in working memory

Es. le asserzioni nel modulo PIPPO, compariranno in working memory nel seguente modo:

f-1 PIPPO::ciao …

f-2 PIPPO::sono …

f-3 PIPPO::Pippo …

Per riferirsi a fatti asseriti da altri moduli, è necessario esplicitare il nome del modulo che li ha asseriti

es:(defmodule NEW )(defrule check-ancestor (declare (salience 50))?f1 <- (MAIN2::ancestor ?a) (or (test (> ?a 0)) (test (= ?a 0))) (MAIN2::news ?s) (status ?s ?op ?x ?y) (not (status ?a ?op ?x ?y)) => (assert (MAIN2::ancestor (- ?a 1))) (retract ?f1) (assert (diff ?a)))

Allowed-value

All’interno di un deftemplate si possono

dichiarare diversi slot, in CLIPS si possono

assegnare diversi valori a questi slot sotto

forma di valori permessi: allowed-value. In

Jess non sono ammessi.

Load-facts

In Jess è possibile caricare un intero blocco di fatti memorizzati su file.

(load-facts nomefile)

Es. caricare la dichiarazione della mappa del supermercato.

Interfaccia Grafica

Il Jess non ha un’interfaccia grafica come il CLIPS. E’ stato pensato per essere utilizzato tramite Java.

L’interfaccia grafica di CLIPS rende le operazioni di debug molto semplici, in Jess il debug è complicato, a meno che…

JessGUI

Implementazione di Jess con Java

Prima distinzione: scegliere chi sarà l'applicazione pilota, cioè, colei che deterrà il controllo sull'altra.

Il Jess consente di effettuare questa scelta:- Java applicherà il controllo sul Jess (consigliato, facile utilizzo)- Jess applicherà il controllo su Java (Writing GUI in Jess, Cap 7., Help di Jess, sconsigliato, difficile utilizzo)

Java controlla il Jess

• Istanziazione di uno o più motori Jess.• Il motore inferenziale Jess è basato sulla classe

Rete.– knowledge base, – agenda, – lista dei fatti, – stack dei moduli,– ecc.

• La classe Rete controlla tutto, o quasi, il motore inferenziale

Utilizzo della classe Rete

Es. 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)"); // Prints '9' System.out.println(v.intValue(r.getGlobalContext()));

} catch (JessException ex)

{ System.err.println(ex); }

} }

Livello di interazione

1. Si inizializza Jess e si costruisce il programma Jess sfruttando i metodi della classe Rete (tutto eseguito da Java), il codice Jess risulta spezzato e annegato in quello Java.

Pro e contro:Difficile correzione del programma Jess, caldamente sconsigliato.

Livello di interazione

2. Si inizializza Jess gli si fa caricare il programma Jess e lo si esegue (possibilmente utilizzando thread separati). Questo metodo consente di mantenere una separazione netta, o quasi, tra Java e Jess.

Pro e contro:Mantenendo slegate le due esecuzioni è possibile ottenere più che buoni risultati, cambiare il codice Jess non comporta la modifica del codice Java.

Livello di interazione

3. Evoluzione del punto 2., si possono applicare “correzioni” al programma Jess prima o durante l’esecuzione (inserendo, per esempio, un fatto in knowledge base).

Pro e contro:

Si può utilizzare per un eventuale debug, bisogna ricordarsi tutti i punti in cui si è interagito con il Jess per eventuali modifiche.

Metodi di utilizzo più frequente

1. caricamento di un programma Jess,

2. reset del motore inferenziale,

3. comando di run,

4. comando di step,

5. metodo per controllare i fatti in knoledge base,

6. metodo per controllare lo stack dei focus,

7. metodo per controllare l’agenda,

8. utilizzo dei watch.

Caricamento di un programma Jess

Utilizzo della classe JESP:

• carica il programma

• esegue il parse controlla se ci sono errori nel codice

Jesp, un esempiopublic void caricaImpostazioni(){

try{FileInputStream fis = new

FileInputStream("superLarge.jess");Jesp j = new Jesp(new InputStreamReader(fis), rete);do{

try{j.parse(false);

}catch(JessException re){ re.printStackTrace(); }}while (fis.available() > 0);

}catch(IOException e){ e.printStackTrace(); }}

Reset, Run e Step

• reset() esegue il reset del motore inferenziale (come in CLIPS)

• run() …

• run(1) questo metodo run consente di eseguire un certo numero step prima di fermarsi.

Fatti, Focus e Agenda

• listFacts() restituisce un iteratore, i cui elementi sono di tipo Fact.

• listFocusStack() non funziona bene, si consiglia di usare il metodo getFocus() che ritorna il nome del modulo in cima allo stack.

• listActivations(String nomeModulo) restituisce un iteratore contenente le regole di possibile attivazione.nomeModulo riduce l’elenco delle regole attivabili al solo modulo interessato

Watch

• watchAll()

• unWatchAll()

• watch(int i)

• unWatch(int i)

Jess controlla Java

• Previsione futuristica: creare le classi Java che il Jess dovrà controllare.

• Istanziare le classi create tramite il Jess.

Un esempio

Jess> ;; Create the widgets

(defglobal ?*f* = (new java.awt.Frame "Button Demo"))

Jess> (defglobal ?*b* = (new java.awt.Button "Hello"))

Jess> ;; Define the deffunction

(deffunction say-hello "Unconditionally print a message" (?evt) (printout t "Hello, World!" crlf))

Jess> ;; Connect the deffunction to the button

(?*b* addActionListener (new jess.awt.ActionListener say-hello (engine)))

Jess> ;; Assemble and display the GUI

(?*f* add ?*b*)

Jess> (?*f* pack)

Jess> (set ?*f* visible TRUE)

WINDOW_CLOSING Event

Jess> ;; If the event is a WINDOW_CLOSING event, exit the program (deffunction frame-handler (?evt)

(if (= (?evt getID) (get-member ?evt WINDOW_CLOSING))then

(call (get ?evt source) dispose) (exit)))

Jess> ;; Connect this deffunction to the frame (?*f* addWindowListener

(new jess.awt.WindowListener frame-handler (engine)))

Documentazione

• Consultabile online sul sito ufficiale: http://herzberg.ca.sandia.gov/jess/

• Tutti i riferimenti alle classi del package Jess sono consultabili attraverso le API della documentazione.

top related