Drools I
UWAGA Ukończenie wszystkich ćwiczeń z tego laboratorium jest konieczne do rozpoczęcia pracy na następnych zajęciach!!!
Aby móc korzystać z Drools w Eclipse należy odpowiednio go skonfigurować. W systemie jest zainstalowana awersja Eclipse z wgraną wtyczką do obsługi Drools, ale konieczne jest ustawienie ścieżki do runtime'u Drools w Eclipse. W tym celu, po uruchomieniu eclipse:
Wejdź w Window→Preferences.
Z drzewka po prawej wybierz Drools/Installed Drools Runtime.
Następnie zaznacz runtime znajdujacy sie na liście i wybierz kliknij na przycisk Edit.
Wskaż katalog drools-runtime znajdujacy siew katalogu /usr/local/eclipse/drools-runtime.
Upewnij się, że runtime jest zaznaczony na liście i uruchom ponownie środowisko.
Wstęp
Utworzenie projektu Drools
Kliknij File→New→Project→Drools→Drools Project
Podaj nazwę projektu i kliknij Next
Zaznacz opcje jak na obrazki i kliknij
Next
Upewnij się, że projekt jest związany z jakimś Drools runtime i kliknij Finish.
Struktura projektu Drools
Podział kodu źródłowego
Kod źródłowy projektu Drools dzieli się na dwie części:
Katalog src/main/java gdzie znajduje się kod w języku Java odpowiedzialny za uruchamianie wnioskowania oraz definicje klas wykorzystywanych w bazie wiedzy
Katalog src/main/rules w którym znajdują się definicje reguł i diagramy DroolsFlow.
Podstawowa składnia reguł
Reguły w Drools budowane są według następującego schematu:
rule "NazwaReguły"
// Opcje charakteryzujace regułę
when
// Część warunkowa
then
// Operacje wykonywane w przypadku gdy część warunkowa jest prawdziwa
end
W przykładzie „Hello World” w Eclipse w części warunkowej pojawia się następująca linijka:
m : Message( status == Message.HELLO, myMessage : message )
Należy ją czytać tak: Jeśli w bazie faktów istnieje obiekt klasy Message, taki że jego pole status jest równe polu Message.HELLO, to niech m będize uchwytem do tego obiektu a myMessage uchwytem do pola tego obiektu o nazwie message.
Inaczej mówiąc operator : (dwukropek) działa tutaj podobnie jak operator przypisania a polecenie podobne wywołaniu konstruktora klasy Message jest tak naprawdę instrukcja warunkową.
Uruchomienie wnioskowania w "Hello World"
W pliku DroolsTest.java zamieszczony jest kod odpowiedzialny za stworzenie bazy wiedzy, dodanie faktów i uruchomienie wnioskowania.
metoda
private static KnowledgeBase readKnowledgeBase() throws Exception
odpowiedzialna jest za stworzenie bazy wiedzy na podstawie plików z regułami.
Pliki z regułami muszą być przekazane do obiektu KnowledgeBuilderFactory. Odpowiedzialna jest za to następująca linijka:
...
kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"), ResourceType.DRL);
...
Fakty muszą również zostać dodane do bazy faktów (reprezentowanej przez obiekt klasy StatefulKnowledgeSession:
...
// stworzenie obiektu-faktu
Message message = new Message();
message.setMessage("Hello World");
message.setStatus(Message.HELLO);
// dodanie obiektu-faktu do bazy wiedzy
ksession.insert(message);
...
Ćwiczenie
Uruchom projekt „Hello World”. Zmodyfikuj klasę Message dodaj±c jeszcze jedno pole enumerate o wartości CONVERSATION. Zmodyfikuj regułę Hello tak aby zmieniała status na CONVERSATION. Dopisz regułę odpowiadajacą temu polu. Uruchom projekt.
Cashpoint
Utwórz kolejny projekt analogicznie jak poprzednio, zaznaczając również aby zostały wygenerowane przykłady HelloWorld i DroolsFlow. Następnie postępuj według wskazówek, modyfikując przykładowe pliki.
Opis
System powinien modelować zachowanie typowego bankowemu. Użytkownik podaje bankomatowi swój PIN a następnie może wykonać jedną z następujących operacji:
wypłata gotówki
sprawdzenie salda na koncie
Bankomat ma pewien limit gotówki jaka może wypłacić. Konto użytkownika też ma ograniczone saldo.
Bankomat może odmówić transakcji i zatrzymać kartę po trzech niepoprawnych wpisaniach numeru PIN.
Klasy
Dodaj następujące klasy do swojego projektu do katalogu src/main/java:
Reguły
Zapisz następujące reguły. Umieść je w dwóch plikach: Autoryzacja oraz Akcja.
Aby dodać nowy plik reguł kliknij prawym przyciskiem myszy na nazwę projektu, a następnie New→Other…→Drools/Rule.
Wybierz projekt i katalog w którym ma być umieszczony plik z regułami (<NAZWAPROJEKTU>/src/main/rules),
wpisz nazwę pliku z regułami i nazwę pakietu (com.sample) i kliknij Finish.
Plik: Autoryzacja
Napisz reguły sprawdzające poprawność PINu i w razie gdy PIN został wpisany poprawnie ustawiające wartość pola autoryzacja na true.
Zakładamy, że pole poprawnyPin,saldo,wpisanaKwota,limitGotowki są polami których wartości są ustalane na razie odgórnie.
Nazwa reguły | Warunek | Akcja |
InvalidPIN | poprawnyPIN != wpisanyPIN && iloscProb < 3 | iloscProb++ |
BlockAccount | poprawnyPIN != wpisanyPIN && iloscProb == 3 | blokada=true |
AuthGranted | poprawnyPIN == wpisanyPIN && iloscProb < 3 | autoryzacja=true |
Plik: Akcja
Napisz reguły odpowiedzialne za akcje bankomatu:
Nazwa reguły | Warunek | Akcja |
PayOut | autoryzacja == true && wybranaAkcja == wyplata && wpisanaKwota ⇐ saldo && wpisanaKwota⇐limitGotowki | „Wyplacam pieniadze” |
CahspointLimit | autoryzacja == true && wybranaAkcja == wyplata && wpisanaKwota ⇐ saldo && wpisanaKwota>limitGotowki | „Za malo pieniedzy w bankomacie!” |
AccountLimit | autoryzacja == true && wybranaAkcja == wyplata && wpisanaKwota > saldo | „Za malo srodkow na koncie” |
Balance | autoryzacja == true && wybranaAkcja == saldo | „Twoje saldo to: ” |
Unauthorized | autoryzacja == false && blokada == true | „Brak autoryzacji, blokuje karte” |
Sterowanie wnioskowaniem
Zmodyfikuj plik z katalogu src/main/java/ odpowiedzialny za uruchamianie wnioskowania, tak aby oba pliki z regułami zostały dodane do abzy wiedzy. Stwórz obiekty klas Konto i Bankomat i dodaj je do bazy faktów.
Uruchom wnioskowanie. System prawdopodobnie nie będzie działać poprawnie, albo wpadnie w pętle nieskończoną. Podczas wywoływania update silnik wnioskujący przetworzy jeszcze raz wszystkie reguły, łącznie z tą która wywołała update. Taka sytuacja może powodować zapętlenie się wnioskowania jeśli warunki uruchomienia reguł nie zabezpieczają takiej sytuacji w 100%. Aby oznaczyć regułę jako taka, która powinna być przetworzona tylko raz w cyklu wnioskowania, należy dopisać no-loop przed częścią warunkową:
rule "NazwaReguły"
no-loop
when
// Część warunkowa
then
// Operacje wykonywane w przypadku gdy część warunkowa jest prawdziwa
end
Aby wskazać silnikowi wnioskującemu kolejność uruchamiania reguł, można użyć pola salience, określającego priorytet reguły. Im wyższa wartość salience, tym wyższy priorytet. Reguły o wyższym priorytecie uruchamiane są w pierwszej kolejności.
rule "NazwaReguły"
no-loop
salience 10
when
// Część warunkowa
then
// Operacje wykonywane w przypadku gdy część warunkowa jest prawdziwa
end
Można również korzystać z mechanizmu grupowania reguł w moduły (tutaj agendy). Więcej na ten temat można znaleźć w dokumentacji.
Ćwiczenie
Wykorzystując atrybut salience oraz no-loop popraw działanie systemu ekspertowego.
Konfiguracja Eclipse
Dla chętnych, którzy będą chcieli przyjrzeć się DroolsExpert i DroolsFlow bliżej, poniżej zostały przedstawione zostały kroki konfiguracji Eclipse do współdziałania z pakietem JBoss Rules:
Pobierz Eclipse wersji 3.5 (najnowsza wersja nie działa z Drools 5).
-
-
Zbuduj runtime. Wejdź w Window→Preferences→Drools/Installed Drools Runtime. Kliknij Add a następnie Browse i wskaż katalog w którym chcesz przechowywać runtime (najlepiej niech to będzie katalog wewnątrz katalogu clipse o nazwie drools-runtime. Na sam koniec kliknij na Generate New Runtime i po wygenerowaniu i zaakceptowaniu, upewnij sie że runtime jest zaznaczony na liście.
Komentarze
Z braku lepszego miejsca tutaj studenci wpisują komentarze natury ogólnej do tego lab.