Universit degli Studi di Perugia Facolt di Scienze

  • Slides: 88
Download presentation
Università degli Studi di Perugia Facoltà di Scienze MM. FF. NN. Corso di Laurea

Università degli Studi di Perugia Facoltà di Scienze MM. FF. NN. Corso di Laurea in Informatica Guida alla configurazione e all'utilizzo di DROOLS Esame di A cura di Sistemi con vincoli Andrea Valentini Albanelli 1

Sommario Introduzione a Drools Configurazione di Drools • Installazione di Eclipse • Installazione di

Sommario Introduzione a Drools Configurazione di Drools • Installazione di Eclipse • Installazione di GEF • Installazione di MAVEN • Installazione del plugin Drools Struttura delle regole Il nostro primo progetto Drools Inferenza logica 2

Sommario Tipi di valutazione regole Stateless Knowledge Session (Esempio di Driving License) Stateful Knowledge

Sommario Tipi di valutazione regole Stateless Knowledge Session (Esempio di Driving License) Stateful Knowledge Session (Esempio dei pompieri) Altri esempi Drools SUDOKU PONG INVADERS Drools Web Service Installazione di Tomcat Configurazione del web server Drools Riferimenti 3

Introduzione a Drools Cos'è Drools? Drools è un sistema di gestione e produzione di

Introduzione a Drools Cos'è Drools? Drools è un sistema di gestione e produzione di REGOLE Viene detto RULE ENGINE 4

Introduzione a Drools Cos'è un Rule Engine? Strumento per produrre e gestire delle regole

Introduzione a Drools Cos'è un Rule Engine? Strumento per produrre e gestire delle regole Le regole equivalgono a delle implicazioni con premessa e conclusioni. A → B, la premessa è A e la conclusione è B Dato un'insieme di regole, il rule engine verifica se le loro premesse sono verificate, inferendo quindi delle nuove regole. 5

Introduzione a Drools In termini informatici. . . Un rule engine agisce su un

Introduzione a Drools In termini informatici. . . Un rule engine agisce su un insieme di regole riguardanti un programma. Le premesse sono vincoli su stati del programma (es. condizioni su valori di variabili), le conclusioni sono azioni da eseguire nel programma Esempio: Premessa: x=2 , Conclusione: write(“ciao”) Drools controlla il valore di x, se è uguale a 2 scrive ciao 6

Configurazione di Drools è, di fatto, una libreria Java che permette di gestire regole.

Configurazione di Drools è, di fatto, una libreria Java che permette di gestire regole. Va quindi importata in un Programma Java, e questo può essere fatto mediante un IDE Java (Eclipse, Netbeans, etc. . . ) Le prossime slide illustrano gli step da effettuare per configurare l'utilizzo di Drools dentro un IDE Java, con particolare riferimento all'IDE Eclipse versione 4. 3 e Drools 6. 0. 0 7

Installazione di Eclipse Per Windows: Scaricare l'eseguibile di Eclipse Standard 4. 3. 1 dal

Installazione di Eclipse Per Windows: Scaricare l'eseguibile di Eclipse Standard 4. 3. 1 dal sito http: //www. eclipse. org/downloads/? os. Type=windows. Aprirlo e seguire le istruzioni a video per installare Eclipse 8

Installazione di Eclipse Per Ubuntu: E' possibile effettuare l'installazione di Eclipse in 2 modi:

Installazione di Eclipse Per Ubuntu: E' possibile effettuare l'installazione di Eclipse in 2 modi: Mediante gestore di pacchetti: Digitare da terminale apt-get install eclipse Avviare Eclipse digitando da terminale eclipse NOTA: Nel gestore pacchetti potrebbe non essere presente l'ultima versione di Eclipse 9

Installazione di Eclipse Per Ubuntu: E' possibile effettuare l'installazione di Eclipse in 2 modi:

Installazione di Eclipse Per Ubuntu: E' possibile effettuare l'installazione di Eclipse in 2 modi: Mediante binario precompilato: Scaricare l'archivio. tar. gz di Eclipse Standard 4. 3. 1 da http: //www. eclipse. org/downloads/? os. Type=linux Scompattare l'archivio in una qualsiasi cartella (es. /home/user 1/) Aprire il file eclipse dentro la cartella scompattata per avviare eclipse 10

Installazione di Eclipse 11

Installazione di Eclipse 11

Installazione di GEF sta per Graphical Editing Framework, ed è un componente di Eclipse

Installazione di GEF sta per Graphical Editing Framework, ed è un componente di Eclipse necessario per la visualizzazione dei componenti grafici Drools in Eclipse Per installarlo, aprire Eclipse e fare clic sul menu Help → Install new software. Nella finestra che comparirà, fare clic su “Add”. Immettere come Name il nome GEF repository e come Location l'url http: //download. eclipse. org/tools/gef/updates/releases/ e cliccare OK 12

Installazione di GEF Scegliere dall'elenco il plug-in GEF: 13

Installazione di GEF Scegliere dall'elenco il plug-in GEF: 13

Installazione di Maven MAVEN è un plugin per Eclipse che permette di installare più

Installazione di Maven MAVEN è un plugin per Eclipse che permette di installare più facilmente i componenti. Per installarlo, aprire Eclipse e fare clic sul menu Help → Install new software. Nella finestra che comparirà, fare clic su “Add”. Immettere come Name il nome MAVEN repository e come Location l'url http: //download. eclipse. org/technology/m 2 e/releases e cliccare OK 14

Installazione di MAVEN Scegliere dall'elenco il plug-in Maven integration for Eclipse: 15

Installazione di MAVEN Scegliere dall'elenco il plug-in Maven integration for Eclipse: 15

Installazione del plugin Drools 1)Scaricare il plugin Drools dal link: http: //www. jboss. org/drools/downloads.

Installazione del plugin Drools 1)Scaricare il plugin Drools dal link: http: //www. jboss. org/drools/downloads. html 3)Scompattare il. zip in una cartella 2)Aprire Eclipse, e selezionare il menu Help → Install new software 3)Nella finestra che comparirà, fare clic su Add. Immettere come Name il nome drools local update site. 4) Cliccare sul bottone Local e selezionare /binaries/org. drools. updatesite, all'interno della cartella scompattata 5) Selezionare tutti i plugin. Cliccare il bottone Next e poi Finish 16

Installazione del plugin Drools 17

Installazione del plugin Drools 17

Struttura delle regole Le regole Drools hanno la seguente struttura: rule “ID Regola” //

Struttura delle regole Le regole Drools hanno la seguente struttura: rule “ID Regola” // Attributi when // Premessa then // Conclusione end 18

Struttura delle regole Esempio: rule “Insegnante” when $p : Persona( $n : nome, anni

Struttura delle regole Esempio: rule “Insegnante” when $p : Persona( $n : nome, anni > 30) Corso( $s : oggetto == “SCV”, teacher == $p ) then System. out. println(“L'insegnante di SCV ha più di 30 anni”); end 19

Il nostro primo progetto Drools 1)Avviamo Eclipse 2)Clicchiamo su File → New → Drools

Il nostro primo progetto Drools 1)Avviamo Eclipse 2)Clicchiamo su File → New → Drools Project 3)Specificare il nome del progetto 4)Possiamo lasciare selezionate le opzioni per aggiungere un semplice esempio “Hello world” come spunto 5)Scegliamo di generare codice compatibile con “Drools 5. 1 or above” 6)Clicchiamo su finish ORA IMPORTIAMO LE LIBRERIE NEL NOSTRO PROGETTO 20

Il nostro primo progetto Drools PER IMPORTARE LE LIBRERIE DROOLS NEL PROGETTO ECLIPSE: 1)Nel

Il nostro primo progetto Drools PER IMPORTARE LE LIBRERIE DROOLS NEL PROGETTO ECLIPSE: 1)Nel file. tar. gz di drools troveremo 2 cartelle: binaries e sources 2)Nella cartella “sources” c'è il file org. drools. eclipse 6. 0. 0. Final-sources. jar 3)Scompattiamo il file. jar 21

Il nostro primo progetto Drools 1)Da Eclipse, clicchiamo con il destro sul nostro progetto

Il nostro primo progetto Drools 1)Da Eclipse, clicchiamo con il destro sul nostro progetto e selezioniamo Properties 2)Nella sezione Java Build Path selezioniamo ADD External JARs 22

Il nostro primo progetto Drools 1)Selezioniamo tutti i file. jar contenuti nella cartella lib

Il nostro primo progetto Drools 1)Selezioniamo tutti i file. jar contenuti nella cartella lib presente all'interno del file jar scompattato precedentemente ( org. drools. eclipse-6. 0. 0. Final-sources. jar ) 2)Clicchiamo su OK e torniamo al progetto 1)Ora nel nostro progetto abbiamo 2 files: /src/main/java/com/sample/Drools. Test. java File java contenente il main /src/main/rules/Sample. drl File DRL di regole DROOLS 23

Il nostro primo progetto Drools. Test. java /** * This is a sample class

Il nostro primo progetto Drools. Test. java /** * This is a sample class to launch a rule. */ public class Drools. Test { public static final void main(String[] args) { try { // load up the knowledge base Knowledge. Base kbase = read. Knowledge. Base(); Stateful. Knowledge. Session ksession = kbase. new. Stateful. Knowledge. Session(); Knowledge. Runtime. Logger logger = Knowledge. Runtime. Logger. Factory. new. File. Logger(ksession, "test"); // go ! Message message = new Message(); message. set. Message("Hello World"); message. set. Status(Message. HELLO); ksession. insert(message); ksession. fire. All. Rules(); logger. close(); } catch (Throwable t) { t. print. Stack. Trace(); } } private static Knowledge. Base read. Knowledge. Base() throws Exception {. . . } 24

} Il nostro primo progetto Drools. Test. java public static class Message { public

} Il nostro primo progetto Drools. Test. java public static class Message { public static final int HELLO = 0; public static final int GOODBYE = 1; private String message; private int status; public String get. Message() { return this. message; } public void set. Message(String message) { this. message = message; } public int get. Status() { return this. status; } public void set. Status(int status) { this. status = status; } 25

Il nostro primo progetto Drools Sample. drl package com. sample import com. sample. Drools.

Il nostro primo progetto Drools Sample. drl package com. sample import com. sample. Drools. Test. Message; rule "Hello World" when m : Message( status == Message. HELLO, my. Message : message) then System. out. println( my. Message ); m. set. Message( "Goodbye cruel world" ); m. set. Status( Message. GOODBYE ); update( m ); end rule "Good. Bye" when Message( status == Message. GOODBYE, my. Message : message ) then System. out. println( my. Message ); end 26

Il nostro primo progetto Drools Questo semplice programma controlla se esiste un elemento di

Il nostro primo progetto Drools Questo semplice programma controlla se esiste un elemento di classe Message con stato = HELLO. In caso affermativo, lo riscrive a video, poi setta il messaggio a Goodbye cruel world e lo stato a GOODBYE. Questo fa innescare la seconda regola che scrive a video Goodbye cruel world. Quindi mandando in esecuzione il nostro programma, otteniamo su schermo: Hello World Goodbye cruel world 27

Errori noti Ecco alcuni errori che potreste ottenere per questo esempio: In fase di

Errori noti Ecco alcuni errori che potreste ottenere per questo esempio: In fase di compilazione, potreste ottenere: Unable to load dialect 'org. drools. compiler. rule. builder. dialect. java. Java. Dialect. Configuration : java: org. drools. compiler. rule. builder. dialect. java. Java. Dialect. Configur ation' Se ottenete questo errore, dovete importare nel progetto il file core 3. 4. 2. v_883_R 34 x. jar scaricabile da https: // repository. jboss. org/nexus/content/repositories/thirdpartyreleases/org/eclipse/jdt/core/3. 4. 2. v_883_R 34 x/core 3. 4. 2. v_883_R 34 x. jar 28

Errori noti Ecco alcuni errori che potreste ottenere per questo esempio: Eclipse potrebbe non

Errori noti Ecco alcuni errori che potreste ottenere per questo esempio: Eclipse potrebbe non accettare gli import di tipo org. drools. In questo caso sosituiteli con questi import: import org. kie. api. logger. Kie. Runtime. Logger; import org. kie. internal. *; import org. kie. internal. runtime. *; import org. kie. internal. logger. *; import org. kie. internal. builder. *; import org. kie. internal. io. *; import org. kie. api. io. *; 29

Il nostro primo progetto Drools Se siete riusciti ad eseguire senza errori questo primo

Il nostro primo progetto Drools Se siete riusciti ad eseguire senza errori questo primo progetto, significa che Drools è correttamente configurato in Eclipse. Nelle slide successive partiremo sempre da questo progetto come base, e lo modificheremo per i nostri scopi. 30

Inferenza logica Una regola Drools può modificare variabili e richiamare metodi di qualunque oggetto

Inferenza logica Una regola Drools può modificare variabili e richiamare metodi di qualunque oggetto Java Può farlo in 2 modi: Con delle istruzioni Java: rule "Hello World" when m : Message( status == Message. HELLO) then m. set. Message( "Goodbye cruel world" ); m. status = Message. HELLO; end In questo caso i cambiamenti dell'oggetto rimangono nascosti a Drools. DROOLS NON RIVALUTA LE REGOLE PER 31 L'OGGETTO MODIFICATO!

Inferenza logica Modifichiamo il file. drl del primo esempio, utilizzando solo istruzioni Java rule

Inferenza logica Modifichiamo il file. drl del primo esempio, utilizzando solo istruzioni Java rule "Hello World" when m : Message( status == Message. HELLO, my. Message : message) then System. out. println( my. Message ); m. set. Message( "Goodbye cruel world" ); m. set. Status( Message. GOODBYE ); //update( m ); questa non è un'istruzione java, quindi la commentiamo end rule "Good. Bye" when Message( status == Message. GOODBYE, my. Message : message ) then System. out. println( my. Message ); end 32

Inferenza logica Se mandiamo in esecuzione l'output è ora: Hello World Questa volta la

Inferenza logica Se mandiamo in esecuzione l'output è ora: Hello World Questa volta la seconda regola Good. Bye non si è innescata, nonostante la prima regola ha modificato il messaggio in modo che esso verifichi i vincoli dettati dalla seconda regola. Ho utilizzato solo metodi Java, quindi DROOLS non sa che l'oggetto di classe Message è cambiato. Pertanto non rivaluta nuovamente tutte le regole che lo riguardano. NON SI E' GENERATA INFERENZA LOGICA!!! DROOLS VALUTA REGOLE A PARTIRE DALLA SOLA CONOSCENZA INIZIALE (DETTA DI BASE) 33

Inferenza logica Una regola Drools può modificare variabili e richiamare metodi di qualunque oggetto

Inferenza logica Una regola Drools può modificare variabili e richiamare metodi di qualunque oggetto Java Può farlo in 2 modi: Con delle istruzioni DROOLS: -insert(oggetto): inserisce un nuovo oggetto nella conoscenza di Drools, che rivaluta quindi le regole ad esso relative -modify(oggetto) (istruzioni Java di modifica): modifica un oggetto Java e rivaluta le regole ad esso relative -update(oggetto): vengono rivalutate le regole Drools che riguardano un certo oggetto - retract(oggetto): elimina un oggetto precedentemente inserito nella conoscenza di Drools DEVO USARE QUESTE ISTRUZIONI PER GENERARE INFERENZA!!! 34

Inferenza logica Una regola Drools può modificare variabili e richiamare metodi di qualunque oggetto

Inferenza logica Una regola Drools può modificare variabili e richiamare metodi di qualunque oggetto Java Può farlo in 2 modi: Con delle istruzioni DROOLS: -insert(oggetto): inserisce un nuovo oggetto nella conoscenza di Drools, che rivaluta quindi le regole ad esso relative -modify(oggetto) (istruzioni Java di modifica): modifica un oggetto Java e rivaluta le regole ad esso relative -update(oggetto): vengono rivalutate le regole Drools che riguardano un certo oggetto - retract(oggetto): elimina un oggetto precedentemente inserito nella conoscenza di Drools ECCO SPIEGATO L'UTILIZZO DI UPDATE NELL'ESEMPIO 35

Inferenza logica Modifichiamo la prima regola del file. drl del primo esempio, utilizzando il

Inferenza logica Modifichiamo la prima regola del file. drl del primo esempio, utilizzando il modify rule "Hello World" when m : Message( status == Message. HELLO, my. Message : message) then modify (m) {set. Message( "Goodbye cruel world" ), set. Status( Message. GOODBYE )} end IL RISULTATO E' LO STESSO OTTENUTO CON L'UPDATE 36

Tipi di valutazione regole Il Rule Engine valuta le sue regole in una sessione

Tipi di valutazione regole Il Rule Engine valuta le sue regole in una sessione (normalmente soltanto una). Nella sessione, il rule engine esegue più valutazioni di regole L'esecuzione può essere di tipo : STATELESS KNOWLEDGE SESSION Ogni esecuzione valuta a partire soltanto dai fatti presenti nella conoscenza base. Se un oggetto viene creato da DROOLS (ad es. con insert) esso vive solo all'interno della singola esecuzione. STATEFUL KNOWLEDGE SESSION Posso aggiungere della nuova conoscenza di volta in volta ed avviare una nuova esecuzione. Ogni oggetto creato dal RULE ENGINE (ad es. con insert) rimane persistente per sempre. 37

Esempio: Driving License Come esempio STATELESS KNOWLEDGE SESSION vediamo il problema di stabilire se

Esempio: Driving License Come esempio STATELESS KNOWLEDGE SESSION vediamo il problema di stabilire se una persona è in grado di guidare una macchina Applicant. java: La classe che descrive una persona. I suoi attributi più importanti sono age e expiredrivingdate Main. drl: File di regole DROOLS che stabiliscono, in base a dei vincoli, se una persona può guidare una macchina oppure no Main. java: La classe principale che avvia il programma 38

Applicant. java package com. sample; import java. util. *; public class Applicant { private

Applicant. java package com. sample; import java. util. *; public class Applicant { private String name; private int age; private boolean validage = false; private Date expiredrivingdate; public Date current_date = new Date(); //metodi get e set } 39

Main. drl rule "Is not of valid age" when $a : Applicant( age <

Main. drl rule "Is not of valid age" when $a : Applicant( age < 18 ) then $a. set. Validage( false ); System. out. println("The applicant "+$a. get. Name()+" has not a good age for driving a car"); end rule "Is of valid age" when $a : Applicant( age >= 18, validage==false ) then modify ($a) { set. Validage(true) }; System. out. println("The applicant "+$a. get. Name()+" has a good age for driving a car"); end 40

Main. drl rule "Is valid the license" when $a : Applicant( validage, expiredrivingdate >=

Main. drl rule "Is valid the license" when $a : Applicant( validage, expiredrivingdate >= current_date) then System. out. println("The applicant "+$a. get. Name()+" is valid for driving a car"); end rule "Is not valid the license" when $a : Applicant( validage, expiredrivingdate < current_date) then System. out. println("The applicant "+$a. get. Name()+" is not valid for driving a car"); end 41

Main. java import java. text. Simple. Date. Format; import java. util. Arrays; import org.

Main. java import java. text. Simple. Date. Format; import java. util. Arrays; import org. kie. internal. *; import org. kie. internal. runtime. *; import org. kie. internal. logger. *; import org. kie. internal. builder. *; import org. kie. internal. io. *; import org. kie. api. io. *; public class Main { @Suppress. Warnings("deprecation") public static final void main(String[] args) { try { // dichiaro una sessione di tipo Stateless Knowledge. Base kbase = read. Knowledge. Base(); Stateless. Knowledge. Session ksession = kbase. new. Stateless. Knowledge. Session(); Knowledge. Runtime. Logger logger = Knowledge. Runtime. Logger. Factory. new. File. Logger(ksession, "Check driving validity") 42

Main. java // dichiaro 2 persone di tipo applicant Simple. Date. Format date. Format

Main. java // dichiaro 2 persone di tipo applicant Simple. Date. Format date. Format = new Simple. Date. Format("dd/mm/yyyy"); Applicant applicant = new Applicant(); applicant. set. Name("Mr John Smith"); applicant. set. Expiredrivingdate(date. Format. parse("01/01/2014")); applicant. set. Age(19); Applicant applicant 2 = new Applicant(); applicant 2. set. Name("Mr Andrea Valentini"); applicant 2. set. Expiredrivingdate(date. Format. parse("01/01/2012")); applicant 2. set. Age(20); //eseguo la sessione caricando come conoscenza base applicant 2 ksession. execute(Arrays. as. List( new Object[] { applicant, applicant 2 } )); logger. close(); } catch (Throwable t) { t. print. Stack. Trace(); } } @Suppress. Warnings("deprecation") private static Knowledge. Base read. Knowledge. Base() throws Exception { Knowledge. Builder kbuilder = Knowledge. Builder. Factory. new. Knowledge. Builder(); kbuilder. add(Resource. Factory. new. Class. Path. Resource("Main. drl"), Resource. Type. DRL). . . } 43

Esecuzione Se mandiamo in esecuzione l'output è ora: The applicant Mr Andrea Valentini has

Esecuzione Se mandiamo in esecuzione l'output è ora: The applicant Mr Andrea Valentini has a good age for driving a car The applicant Mr John Smith is valid for driving a car The applicant Mr Andrea Valentini is not valid for driving a ca r In questo caso una Stateless Knowledge Session è sufficiente perchè le regole Drools non creano nuovi oggetti, ma lavorano soltanto sulla conoscenza base. 44

Esempio: Pompieri Come esempio STATEFUL KNOWLEDGE SESSION vediamo il problema di identificare un incendio

Esempio: Pompieri Come esempio STATEFUL KNOWLEDGE SESSION vediamo il problema di identificare un incendio in una stanza, attivare un estintore e far scattare un allarme Room. java: La classe che descrive una stanza in un edificio. Ha l'attributo name che indica il nome della stanza. Sprinkler. java: La classe che descrive un estintore. Ha l'attributo room che associa l'estintore ad una stanza, e l'attributo on che indica se l'estintore è attivo Fire. java: La classe che descrive un incendio. Ha l'attributo room che identifica la stanza dell'edificio in cui è presente l'incendio Alarm. java: La classe che descrive un allarme in un edificio. Non ha attributi, la sola esistenza di un oggetto di questa classe indica un allarme attivo Main. java: La classe principale che avvia il programma 45

Classi Java public class Room { private String name // getter and setter methods

Classi Java public class Room { private String name // getter and setter methods here } public classs Sprinkler { private Room room; private boolean on; // getter and setter methods here } public class Fire { private Room room; // getter and setter methods here } public class Alarm { } 46

fire. Alarm. drl Creiamo il nostro file di regole Drools. Le prime 2 regole

fire. Alarm. drl Creiamo il nostro file di regole Drools. Le prime 2 regole servono ad attivare/disattivare l'estintore specifico in caso di incendio in una stanza rule "When there is a fire turn on the sprinkler" when $fire: Fire($room : room) $sprinkler : Sprinkler( room == $room, on == false ) then modify( $sprinkler ) { set. On( true ) }; System. out. println( "Turn on the sprinkler for room " + $room. get. Name() ); retract($fire); end rule "When the fire is gone turn off the sprinkler" when $room : Room( ) $sprinkler : Sprinkler( room == $room, on == true ) not Fire( room == $room ) then modify( $sprinkler ) { set. On( false ) }; System. out. println( "Turn off the sprinkler for room " + $room. get. Name() ); end 47

fire. Alarm. drl Inseriamo altre 2 regole per attivare/disattivare l'allarme in caso di incendio

fire. Alarm. drl Inseriamo altre 2 regole per attivare/disattivare l'allarme in caso di incendio rule "Raise the alarm when we have one or more fires" when exists Fire() then insert( new Alarm() ); System. out. println( "Raise the alarm" ); end rule "Cancel the alarm when all the fires have gone" when not Fire() $alarm : Alarm() then retract( $alarm ); System. out. println( "Cancel the alarm" ); end 48

fire. Alarm. drl Altra regola che scrive che tutto va bene quando non ci

fire. Alarm. drl Altra regola che scrive che tutto va bene quando non ci sono allarmi ed estintori attivi rule "Status output when things are ok" when not Alarm() not Sprinkler( on == true ) then System. out. println( "Everything is ok" ); end In questo file. drl notiamo l'utilizzo dei costrutti Drools insert() e retract() per generare inferenza logica anche su oggetti inseriti da Drools 49

Main. java import java. util. Hash. Map; import java. util. Map; import org. kie.

Main. java import java. util. Hash. Map; import java. util. Map; import org. kie. internal. *; import org. kie. internal. runtime. *; import org. kie. internal. logger. *; import org. kie. internal. builder. *; import org. kie. internal. io. *; import org. kie. api. io. *; public class Main { @Suppress. Warnings("deprecation") public static final void main(String[] args) { try { // dichiaro una sessione di tipo Stateful Knowledge. Base kbase = read. Knowledge. Base(); Stateful. Knowledge. Session ksession = kbase. new. Stateful. Knowledge. Session(); Knowledge. Runtime. Logger logger = Knowledge. Runtime. Logger. Factory. new. File. Logger(ksession, "Check fire in a building"); 50

Main. java //dichiaro le stanze dandogli un nome String[] names = new String[]{"kitchen", "bedroom",

Main. java //dichiaro le stanze dandogli un nome String[] names = new String[]{"kitchen", "bedroom", "office", "livingroom"}; Map<String, Room> name 2 room = new Hash. Map<String, Room>(); //inserisco nella conoscenza base le stanze e gli estintori disponibili for( String name: names ){ Room room = new Room( name ); name 2 room. put( name, room ); ksession. insert( room ); Sprinkler sprinkler = new Sprinkler( room ); ksession. insert( sprinkler ); } //avvio il rule engine ksession. fire. All. Rules(); logger. close(); } catch (Throwable t) { t. print. Stack. Trace(); } } @Suppress. Warnings("deprecation") private static Knowledge. Base read. Knowledge. Base() throws Exception { Knowledge. Builder kbuilder = Knowledge. Builder. Factory. new. Knowledge. Builder(); kbuilder. add(Resource. Factory. new. Class. Path. Resource("fire. Alarm. drl"), Resource. Type. DRL). . . } 51

Esecuzione Se mandiamo in esecuzione l'output è ora: Everything is ok Aggiungiamo nel main

Esecuzione Se mandiamo in esecuzione l'output è ora: Everything is ok Aggiungiamo nel main qualche incendio: Fire kitchen. Fire = new Fire(name 2 room. get("kitchen")); Fire office. Fire = new Fire(name 2 room. get("office")); Fact. Handle kitchen. Fire. Handle =ksession. insert( kitchen. Fire ); Fact. Handle office. Fire. Handle = ksession. insert( office. Fire ); ksession. fire. All. Rules(); Otteniamo l'output: Turn on the sprinkler for room kitchen Turn on the sprinkler for room office Turn off the sprinkler for room kitchen Everything is ok 52

Esecuzione Notiamo che nell'ultimo output, il rule engine ha effettuato inferenza logica sugli oggetti

Esecuzione Notiamo che nell'ultimo output, il rule engine ha effettuato inferenza logica sugli oggetti che ha creato e/o modificato. L'incendio fa attivare a Drools un'estintore per stanza. L'estintore poi si spegne, e questo implica che è tutto OK. 53

Importiamo alcuni esempi drools Sono disponibili in rete alcuni esempi drools da importare in

Importiamo alcuni esempi drools Sono disponibili in rete alcuni esempi drools da importare in un workspace Eclipse Per farlo: Scaricare gli esempi in una cartella con git clone https: //github. com/droolsjbpm/drools. git Da Eclipse, fare clic sul menu File → Import Selezionare Maven → Existing Maven Projects e fare clic su Next Selezionare il path drools-examples/src dalla cartella git clonata 54

SUDOKU Nella cartella del progetto /src/main/java troviamo la classe org. drools. examples. sudoku contenente

SUDOKU Nella cartella del progetto /src/main/java troviamo la classe org. drools. examples. sudoku contenente un risolutore di Sudoku. L'esempio dimostra come usare Drools per trovare una soluzione in un ampio spazio delle soluzioni usando i vincoli 55

SUDOKU Vengono utilizzati 2 file. drl: validate. drl: contiene regole per controllare la presenza

SUDOKU Vengono utilizzati 2 file. drl: validate. drl: contiene regole per controllare la presenza di numeri duplicati in riga, colonna e nel quadrato, ovvero per verificare la validità di una soluzione provata sudoku. drl: contiene principalmente regole per allocare i numeri nelle celle e per eliminare numeri dall'elenco dei numeri candidati 56

SUDOKU validate. drl: rule "duplicate in cell row" when $c: Cell( $v: value !=

SUDOKU validate. drl: rule "duplicate in cell row" when $c: Cell( $v: value != null ) $cr: Cell. Row( cells contains $c ) exists Cell( this != $c, value == $v, cell. Row == $cr ) then System. out. println( "cell " + $c. to. String() + " has a duplicate in row " + $cr. get. Number() ); end La regola “duplicate in cell row” trova una cella con un valore allocato e controlla se nella stessa riga c'è un valore identico oppure no. Analogamente per “duplicate in cell col” e “duplicate in cell sqr” 57

SUDOKU sudoku. drl: rule "duplicate in cell row" when $c: Cell( $v: value !=

SUDOKU sudoku. drl: rule "duplicate in cell row" when $c: Cell( $v: value != null ) $cr: Cell. Row( cells contains $c ) exists Cell( this != $c, value == $v, cell. Row == $cr ) then System. out. println( "cell " + $c. to. String() + " has a duplicate in row " + $cr. get. Number() ); end La regola “duplicate in cell row” trova una cella con un valore allocato e controlla se nella stessa riga c'è un valore identico oppure no. Analogamente per “duplicate in cell col” e “duplicate in cell sqr” 58

SUDOKU Eseguiamo l'esempio impostando la giusta classe come classe da eseguire: Dal menu di

SUDOKU Eseguiamo l'esempio impostando la giusta classe come classe da eseguire: Dal menu di Eclipse, facciamo clic su Run → Run configurations ed impostiamo drools-examples come Project e org. drools. examples. sudoku. Sudoku. Example come Main class. Infine facciamo clic su Run 59

SUDOKU 60

SUDOKU 60

PONG Nella cartella del progetto /src/main/java troviamo la classe org. drools. games. pong contenente

PONG Nella cartella del progetto /src/main/java troviamo la classe org. drools. games. pong contenente una piccola realizzazione del famoso gioco Pong. 61

PONG Vengono utilizzati 2 principali file. drl: move. drl: contiene regole per gestire il

PONG Vengono utilizzati 2 principali file. drl: move. drl: contiene regole per gestire il movimento della pallina e dei giocatori sul campo di gioco. game. drl: contiene regole per stabilire quando un giocatore ha fatto un punto 62

PONG move. drl: rule Move. Ball agenda-group "Move" when ui : Pong. UI( )

PONG move. drl: rule Move. Ball agenda-group "Move" when ui : Pong. UI( ) ball : Ball() $r : Run() then modify( ball ) { x = ball. x + ( ball. dx * ball. speed), y = ball. y + ( ball. dy * ball. speed )}; end La regola “Move. Ball” muove la pallina calcolando continuamente la nuova posizione di coordinate x ed y. La nuova posizione viene calcolata basandosi sulla posizione corrente, velocità e direzione 63

PONG move. drl: rule "Detect Move Bat Up" agenda-group "Move" when ui : Pong.

PONG move. drl: rule "Detect Move Bat Up" agenda-group "Move" when ui : Pong. UI( ) ( ( Key. Pressed( key. Text == "A" ) and bat : Bat( player. Id == Player. Id. Player. One ) ) or (Key. Pressed( key. Text == "K" ) and bat : Bat( player. Id == Player. Id. Player. Two ) ) ) then modify( bat ) { dy = 0 - bat. speed }; end La regola “Detect Move Bat Up” controlla è stato premuto il bottone per spostarsi in su per entrambi i giocatori ( pulsanti A e K ). In caso affermativo sposta la posizione del giocatore. E' presente un'altra regola analoga per il movimento in giù dei giocatori 64

PONG game. drl: rule "Player. One Win" agenda-group "Game" when ui : Pong. UI(

PONG game. drl: rule "Player. One Win" agenda-group "Game" when ui : Pong. UI( ) ball : Ball( x >= pconf. table. Width + width ) player : Player( id == Player. Id. Player. One ) then ui. clear. Ball(ball); // deltas won't match new position, so clear now modify ( ball ) { x = (pconf. table. Width/2)-(pconf. ball. Width/2), y = (pconf. table. Height/2)-(pconf. ball. Width/2), dx = 1, dy = 0, speed = pconf. ball. Starting. Speed } modify( player ) { score = player. score + 1 }; end Questa regola stabilisce la vittoria del giocatore 1 in base alla posizione della pallina, ed incrementa di 1 il punteggio del giocatore. E' presente una regola analoga per il giocatore 2 65

PONG Eseguiamo l'esempio impostando la giusta classe come classe da eseguire: Dal menu di

PONG Eseguiamo l'esempio impostando la giusta classe come classe da eseguire: Dal menu di Eclipse, facciamo clic su Run → Run configurations ed impostiamo drools-examples come Project e org. drools. games. pong. Pong. Main come Main class. Infine facciamo clic su Run 66

INVADERS Nella cartella del progetto /src/main/java troviamo la classe org. drools. games. invaders contenente

INVADERS Nella cartella del progetto /src/main/java troviamo la classe org. drools. games. invaders contenente il famoso gioco Invaders 67

INVADERS Vengono utilizzati 2 principali file. drl: Move. drl: contiene regole per gestire il

INVADERS Vengono utilizzati 2 principali file. drl: Move. drl: contiene regole per gestire il movimento del giocatore. Bullet. drl: contiene regole per gestire il movimento del proiettile sparato dal giocatore 68

INVADERS Move. drl: rule Ship. Delta. Move. Left agenda-group "Move" when s : Ship()

INVADERS Move. drl: rule Ship. Delta. Move. Left agenda-group "Move" when s : Ship() Key. Pressed( key. Text == "Z" ) then modify( s ) { dx = 0 - s. speed } end rule Ship. Delta. Stop. Left agenda-group "Move" when s : Ship() not Key. Pressed( key. Text == "Z" ) then modify( s ) { dx = 0 } end Le regole “shipdeltamoveleft” e “shipdeltamoveright” modificano la variabile dx, che vale 0 se il giocatore è fermo, un valore negativo se si sta spostando a sinistra e positivo se si sta spostando a destra. 69

INVADERS Bullet. drl: rule Insert. Bullet agenda-group "Bullet" when Key. Pressed( key. Text ==

INVADERS Bullet. drl: rule Insert. Bullet agenda-group "Bullet" when Key. Pressed( key. Text == "M" ) s : Ship() not Bullet() then b = new Bullet(); b. x = s. x + (s. width/2) - (b. width/2); b. y = s. y - s. height - b. height; b. width = conf. bullet. Width; b. height = conf. bullet. Height; b. dy = 0 - conf. bullet. Speed; insert( b ); end La regola “Insert. Bullet”, alla pressione del tasto M, crea un nuovo oggetto di classe Bullet, impostandone larghezza, altezza e posizione 70

INVADERS Eseguiamo l'esempio impostando la giusta classe come classe da eseguire: Dal menu di

INVADERS Eseguiamo l'esempio impostando la giusta classe come classe da eseguire: Dal menu di Eclipse, facciamo clic su Run → Run configurations ed impostiamo drools-examples come Project e org. drools. games. invaders. Invaders 6 Main come Main class. Infine facciamo clic su Run 71

INVADERS 72

INVADERS 72

DROOLS Web Service In questa sezione vedremo come è possibile incapsulare un programma Java

DROOLS Web Service In questa sezione vedremo come è possibile incapsulare un programma Java che fa uso di DROOLS all'interno di un servizio WEB Faremo uso di Tomcat, un container WEB che permette la pubblicazione di applicativi Java come servizi WEB 73

Installazione di Tomcat Dal sito ufficiale (http: //tomcat. apache. org/) scaricare l'eseguibile per windows,

Installazione di Tomcat Dal sito ufficiale (http: //tomcat. apache. org/) scaricare l'eseguibile per windows, nella sezione Download (http: //tomcat. apache. org/download-80. cgi) Installare tramite gestore dei pacchetti, digitando da terminale sudo apt-get install tomcat 7 74

Installazione di Tomcat Se l'installazione è avvenuta correttamente, digitando da browser http: //localhost: 8080

Installazione di Tomcat Se l'installazione è avvenuta correttamente, digitando da browser http: //localhost: 8080 verrà visualizzata la pagina di benvenuto di Tomcat 75

Configurazione del web server DROOLS Il sito ufficiale di Drools mette a disposizione un

Configurazione del web server DROOLS Il sito ufficiale di Drools mette a disposizione un esempio di WEB service collegato ad un'applicativo Drools Da http: //www. jboss. org/drools/downloads scarichiamo il file ZIP Drools and j. BPM integration 76

Configurazione del web server DROOLS Dentro la cartella binaries dell'archivio zip è presente il

Configurazione del web server DROOLS Dentro la cartella binaries dell'archivio zip è presente il file drools-camel-server-example-6. 0. 1. Final. war Creiamo la cartella drools-server in CATALINA_HOME/webapps ed estraiamo al suo interno tutti i file dell'archivio. war CATALINA_HOME è la directory di installazione di TOMCAT, quella di default per Ubuntu è /var/lib/tomcat 7/ 77

Configurazione del web server DROOLS Tra i file estratti troviamo 2 file JSP: index.

Configurazione del web server DROOLS Tra i file estratti troviamo 2 file JSP: index. jsp e test. jsp index. jsp è una semplice pagina che scrive Execution server is running (già operativa se si accede all'url http: //localhost: 8080/drools-server ) test. jsp è un esempio di pagina web Java che comunica con un applicativo Java Dobbiamo modificare test. jsp per farlo comunicare con la nostra Applicazione DROOLS 78

Configurazione del web server DROOLS Riprendiamo l'esempio degli estintori, ed avviamo un'esecuzione del programma

Configurazione del web server DROOLS Riprendiamo l'esempio degli estintori, ed avviamo un'esecuzione del programma tramite WEB 79

Configurazione del web server DROOLS Modifichiamo test. jsp prevendendo il parametro msg per impostare

Configurazione del web server DROOLS Modifichiamo test. jsp prevendendo il parametro msg per impostare il numero delle stanze: <%@ page import="com. sample. Main" %> <%@ page content. Type="text/html; charset=UTF-8" %> <html> <head> <title>Test Server</title> </head> <body> <h 1>Sending Test Message</h 1> <% Main test = new Main(); String msg = request. get. Parameter("msg"); if ( msg == null ) { msg = "5"; } %> …. 80

Configurazione del web server DROOLS …. . Sending Message: "<%=msg%>"<br/> <% String res =

Configurazione del web server DROOLS …. . Sending Message: "<%=msg%>"<br/> <% String res = test. avvia( msg ); %> Response: "<%=res%>" </body> </html> In risposta vogliamo ottenere tutti i messaggi che prima venivano stampati in console dal programma Java. Dobbiamo quindi adattare leggermente il nostro programma Java, inizialmente pensato per stampare in console con System. out. println 81

Configurazione del web server DROOLS Aggiungiamo due nuovi metodi in Main. java: public class

Configurazione del web server DROOLS Aggiungiamo due nuovi metodi in Main. java: public class Main { @Suppress. Warnings("deprecation"). . . static String response = ""; public static void stampa(String res){ response += "n" + res; System. out. println(res); } public String avvia(String n){ response = ""; try { // dichiaro una sessione di tipo Stateful Knowledge. Base kbase = read. Knowledge. Base(); Stateful. Knowledge. Session ksession = kbase. new. Stateful. Knowledge. Session(); Knowledge. Runtime. Logger logger = Knowledge. Runtime. Logger. Factory. new. File. Logger(ksession, "Check fire in a building"); // dichiaro le stanze dandogli un nome int Intn = Integer. parse. Int(n); String[] names = new String[Intn]; for(int i=0; i<names. length; i++){ names[i] = "room number "+i; } 82

Configurazione del web server DROOLS Aggiungiamo due nuovi metodi in Main. java: Map<String, Room>

Configurazione del web server DROOLS Aggiungiamo due nuovi metodi in Main. java: Map<String, Room> name 2 room = new Hash. Map<String, Room>(); //inserisco nella conoscenza base le stanze e gli estintori disponibili for( String name: names ){ Room room = new Room( name ); name 2 room. put( name, room ); ksession. insert( room ); Sprinkler sprinkler = new Sprinkler( room ); ksession. insert( sprinkler ); } Fire room 0 fire = new Fire(name 2 room. get("room number 0")); Fire room 1 fire = new Fire(name 2 room. get("room number 1")); ksession. insert( room 0 fire ); ksession. insert( room 1 fire ); ksession. fire. All. Rules(); logger. close(); } catch (Throwable t) { t. print. Stack. Trace(); } return response; } 83

Configurazione del web server DROOLS Sostituiamo in fire. Alarm. drl tutte le chiamate a

Configurazione del web server DROOLS Sostituiamo in fire. Alarm. drl tutte le chiamate a System. out. println, con chiamate al nuovo metodo stampa Ad Esempio, la prima regola diventa: rule "Raise the alarm when we have one or more fires" when exists Fire() then insert( new Alarm() ); Main. stampa("Raise the alarm"); end 84

Configurazione del web server DROOLS INFINE. . . Il file DRL e i precompilati.

Configurazione del web server DROOLS INFINE. . . Il file DRL e i precompilati. class del progetto Eclipse (ovvero tutto ciò che troviamo nella directory target nella cartella del progetto Eclipse) devono essere copiati in CATALINA_HOME/drools-server/WEB-INF/classes Le librerie. jar del progetto (ovvero tutto ciò che troviamo nella directory lib nella cartella del progetto Eclipse) devono essere copiati in CATALINA_HOME/drools-server/WEB-INF/lib CATALINA_HOME/drools-server/WEB-INF/classes e CATALINA_HOME/drools-server/WEB-INF/lib devono essere inserite rispettivamente nelle variabili d'ambiente shared. loader e common. loader presenti all'interno del file di configurazione di Tomcat catalina. properties. Riavviare Tomcat, dopo averle modificate. 85

Configurazione del web server DROOLS FATTO!!! Ora possiamo richiamare il servizio web, sia da

Configurazione del web server DROOLS FATTO!!! Ora possiamo richiamare il servizio web, sia da browser digitando l'url http: //localhost: 8080/drools-server/test. jsp? msg=5 (in questo caso stiamo passando il parametro msg con valore 5, ovvero vogliamo avviare un esecuzione con 5 stanze) sia da terminale mediante messaggi JSON digitando, ad esempio: curl -H "Content-Type: application/json" -d "msg=5" http: //localhost: 8080/drools 2/test. jsp 86

Configurazione del web server DROOLS FATTO!!! 87

Configurazione del web server DROOLS FATTO!!! 87

Riferimenti Drools Documentation version 6. 0. 0 Final http: //www. jboss. org/drools Developer's Cookbook

Riferimenti Drools Documentation version 6. 0. 0 Final http: //www. jboss. org/drools Developer's Cookbook (Amador, 2012) Drools Jboss Rules 5. X Developer's Guide (Bali, 2013) Jboss Drools Business Rules (Browne, 2009) 88