|
|
pl:dydaktyka:piw:2010:systemy_ekspertowe:hekate_iii [2010/04/26 10:48] esimon |
pl:dydaktyka:piw:2010:systemy_ekspertowe:hekate_iii [2019/06/27 15:50] |
====== Język HMR ====== | |
Język HMR został stworzony w celu tekstowej reprezentacji diagramów XTT^2. Jego składnia została zaprojektowana z uwzględnieniem języka w którym implementowany był HeaRT; innymi słowy, składnia języka HMR jest podzbiorem podstawowej składni Prologu, wzbogaconym o kilka dodatkowych operatorów, odzwierciedlających relacje zachodzące pomiędzy elementami XTT. | |
| |
Plik HMR składa się z następujących sekcji: | |
* Definicje typów (predykat //xtype//), | |
* Opcjonalne definicje grup typów (predykat //xtpgr//), | |
* Definicje atrybutów (predykat //xattr//), | |
* Opcjonalne definicje grup atrybutów (predykat //xatgr//), | |
* Definicje schematów (tabel) (predykat //xschm//), | |
* Definicje reguł (predykat //xrule//), | |
* Opcjonalne definicje stanów (predykat //xstat//). | |
* Opcjonalne definicje callbacków (predykat //xcall//) | |
| |
Każdy z wymienionych predykatów (za wyjątkiem //xschm// i //xrule//) strukturalnie odpowiada liście w języku Prolog, której elementy opisują własności obiektu XTT reprezentowanego przez dany predykat. | |
| |
Na przykład definicja typu //weekdays// i atrybutu //day// wygląda tak jak poniżej: | |
<code> | |
xtype [name: weekdays, | |
base: symbolic, | |
desc: 'A set of days of the week', | |
domain: ['Monday'/1,'Tuesday'/2,'Wednesday'/3,'Thursday'/4,'Friday'/5,'Saturday'/6,'Sunday'/7], | |
ordered: yes | |
]. | |
| |
xattr [name: day, | |
abbrev: day, | |
class: simple, | |
type: weekdays, | |
comm: in, | |
callback: [ask_symbolic_GUI,[day]], | |
desc: 'The current day' | |
]. | |
| |
xcall ask_symbolic_GUI : [AttName] >>> (jpl_new('skeleton.RequestInterface',[],T), | |
alsv_domain(AttName,Domain,symbolic), | |
Params = [AttName|Domain], | |
term_to_atom(Params, AtomParams), | |
jpl_call(T,request,['callbacks.input.ComboBoxFetcher',AtomParams],Answer), | |
atom_to_term(Answer,Answer2,_), | |
alsv_new_val(AttName,Answer2)). | |
</code> | |
| |
=== Ćwiczenie === | |
Porównaj plik HMR z modelem XTT2: | |
* {{:pl:dydaktyka:piw:2010:systemy_ekspertowe:thermostat-clb-pl.pl|}} | |
* Termostat w XTT: | |
| |
====== Callbacks w HMR ====== | |
Callbacki to funkcje wywoływane podczas przetwarzania tabel XTT w celu pobrania danych spoza systemu lub do zaprezentowania tych danych. Przykładową funkcję callbacków przedstawia rysunek poniżej. W systemie symulującym zachowanie bankomatu callbacki będą wykorzystywane do wyświetlenia okna pobierającego PIN i do wyświetlania komunikatów dla użytkownika. | |
| |
{{:pl:dydaktyka:piw:2010:systemy_ekspertowe:callbacks.png|}} | |
| |
| |
Wyróżnia się dwa typy callbacków: | |
* //in// - wywołują się one przed rozpoczęciem (lub w trakcie działania) wnioskowania w celu pobrania wartości atrybutów wymaganych do przeprowadzenia inferencji. | |
* //out// - wywołują się już po zakończeniu wnioskowania w celu prezentacji wartości atrybutów. | |
| |
Typ callbacku zależy od wartości elementu //comm// w definicji atrybutu w języku HMR. | |
| |
Elementem określającym jaki callback ma być wywołany dla danego atrybutu, jest pole **callback**. Jets ono postaci listy, której pierwszy element jest nazwą callbaku do wywołania a drugi jest listą parametrów jakie chcemy przekazać callbackowi: | |
<code> | |
comm: in, | |
callback: [ask_symbolic_GUI,[day]] | |
</code> | |
Powyższy kod oznacza, że dla atrybutu w którym się on pojawi będzie wywołany callback typu //in// o nazwie //ask_symbolic_GUI//, pobierający jako parametr jedną wartość //day//. | |
| |
==== Atrybuty a callbacki ==== | |
Callbacki związane są z atrybutami w języku HMR - każdy atrybut ma dwa pola niezbędne do ustalenia jeśli chcemy korzystać z callbacków: | |
* //comm// - określające kiedy callback zostanie wywołany (//in// albo //out//) | |
* //callback// - nazwa i lista parametrów do wywołania | |
| |
Za definicję callbacku odpowiedni jest predykat //xcall// umieszczany w pliku HMR. Na poniższym przykładzie pokazano wykorzystanie mechanizmu JPL do utworzenia callbacku napisanego w Javie. | |
| |
<code> | |
xcall ask_symbolic_GUI : [AttName] >>> (jpl_new('skeleton.RequestInterface',[],T), | |
alsv_domain(AttName,Domain,symbolic), | |
Params = [AttName|Domain], | |
term_to_atom(Params, AtomParams), | |
jpl_call(T,request,['callbacks.input.ComboBoxFetcher',AtomParams],Answer), | |
atom_to_term(Answer,Answer2,_), | |
alsv_new_val(AttName,Answer2)). | |
</code> | |
| |
==== Języki programowania ==== | |
Callbacki dla interpretera HeaRT mogą być zaimplementowane w jednym z następujących języków: | |
* Prolog | |
* XPCE | |
* Java | |
=== Prolog === | |
Są to zwykłe predykaty w języku Prolog: | |
<code> | |
xcall ask_console : [AttName] >>> (write('Type value for attribute: '), | |
write(AttName),nl, | |
read(Answer), | |
alsv_new_val(AttName,Answer)). | |
</code> | |
| |
**Ćwiczenie** | |
Aby uruchomić wnioskowanie bezpośrednio z interpretera HeaRT, należy pobrać kod interpretera: {{:hekate:heart-m3.tar.gz}} i uruchomić go poleceniem //heart//. W celu skompilowania modelu XTT zapisanego w pliku HMR należy po uruchomieniu HeaRT wpisać w konsoli Prologa //[nazwa-pliku-hmr]// - zwyczajnie skompilować ten plik tak jak każdy inny kod Prologu. Następnie w celu uruchomienia wnioskowania należy wpisać polecenie <code>gox(current, ListaTabelDoPrzetworzenia, ddi)</code>. | |
Uruchom wnioskowanie dla poniższego modelu: {{:pl:dydaktyka:piw:2010:systemy_ekspertowe:thermostat-clb-pl.pl|}} | |
| |
=== XPCE === | |
Są to predykaty w języku Prolog wzbogacone o funkcje XPCE. Aby zapewnić jednak oprawne działanie interpretera HeaRT nalezy korzystać z tego szkieletu: | |
| |
<code> | |
xcall xpce_ask_numeric: [AttName] >>> ( | |
dynamic(end), | |
% Ciało callbacku przygotowujace okienko do wyświetlenia i wyświetlające je | |
repeat, | |
%Oczekiwanie na wciśnięcie przez użytkownika przycisku OK | |
send(@display,dispatch), | |
end,!, | |
retractall(end)). | |
</code> | |
| |
Przykład callbacku wczytującego liczbę z określonego zakresu pokazany jest poniżej: | |
| |
<code> | |
xcall xpce_ask_numeric: [AttName] >>> (alsv_domain(AttName,[Min to Max],numeric), | |
dynamic(end), | |
new(@dialog,dialog('Select a value')), | |
send_list(@dialog,append, | |
[new(I,int_item(AttName,low := Min, high := Max)), | |
new(_,button('Select',and(message(@prolog,assert,end),and(message(@prolog,alsv_new_val,AttName,I?selection),message(@dialog,destroy)))))]), | |
send(@dialog,open), | |
repeat, | |
send(@display,dispatch), | |
end,!, | |
retractall(end)). | |
</code> | |
| |
**Ćwiczenie** | |
Uruchom wnioskowanie dla przykładu z bankomatem i prześledź działanie callbacków: | |
* {{:pl:dydaktyka:piw:2010:systemy_ekspertowe:cashpoint-clb-xpce.pl|}} | |
| |
=== Java === | |
Są to programy napisane w języku Java uruchamiane przez prolog przy użyciu JPL. Aby wykorzystać ten mechanizm należy korzystać ze specjalnie przygotowanych do tego klasy: | |
* DataFetcher.java - klasa abstrakcyjna którą muszą rozszerzać wszystkie callbacki | |
* RequestInterface.java - Kontroler | |
* Response.java - klasa przechowująca dane odebrane od użytkownika. | |
| |
W celu ulatwienia implementacji niektórych callbacków, przygotowano zbiór podstawowych komponentów do pobierania danych od użytkownika: | |
* ComboBoxFetcher.java - przyjmuje listę wartości z jakich można wybierać. Zwraca jedną wybraną wartość | |
* SliderFetcher.java - przyjmuje przedział wartości numerycznych między którymi można wybierać. Zwraca jedna wybraną wartość. | |
* TwoListsFetcher.java - przyjmuje listę wartości jakich można wybierać i zwraca również listę wybranych wartości. | |
* ComboGUI.java - GUI dla ComboBoxFetcher | |
* SliderGUI.java - GUI dla SliderFetcher | |
* TwoListsGUI.java - GUI dla TwoListsFetcher | |
| |
Kod źródłowy klas do pobrania {{:hekate:callbackslibrary.zip|tutaj}}. | |
| |
==Przykład== | |
Aby wykorzystać któryś z komponentów Java do napisania callbacku, należy wykonać następujące kroki: | |
- Skompilować kod źródłowy <code></code> i umieścić go w katalogu z plikiem HMR | |
- Odpowiednio zmodyfikować plik HMR dopisując atrybutom pole //callback// i uzupełniając go nazwą i listą parametrów jakie callback przyjmuje, np. <code>callback: [ask_symbolic_GUI,[day]]</code> | |
- Dopisać predykaty //xcall// do pliku HMR, definiujące wywołanie callbacka, np.:<code> | |
xcall ask_symbolic_GUI : [AttName] >>> ( | |
%Tworzymy obiekt kontrolera: | |
jpl_new('skeleton.RequestInterface',[],T), | |
%Przygotowujemy listę parametrów | |
alsv_domain(AttName,Domain,symbolic), | |
Params = [AttName|Domain], | |
term_to_atom(Params, AtomParams), | |
%Wywołujemy callback i podajemu my listę parametrów znajdującą sie | |
%w termie AtomPArams. Wartosc zwrócona przez callback znajdzie się | |
%w termie Answer. | |
jpl_call(T,request,['callbacks.input.ComboBoxFetcher',AtomParams],Answer), | |
%Zamieniamy zwróconą wartość na term i dodajemy go do bazy faktów | |
atom_to_term(Answer,Answer2,_), | |
alsv_new_val(AttName,Answer2)). | |
</code> | |
- Uruchomić HeaRT w katalogu z plikiem HMR, skompilować ten plik i uruchomić wnioskowanie. Callbacki powinny zostać uruchomione. | |
| |
**Ćwiczenie** | |
Pobierz poniższy kod [[paczka.zip]]. I dla pliku HMR znajdującego się w archiwum uruchom wnioskowanie. | |
| |
=== Ćwiczenie === | |
- Uruchom interpreter HeaRT, wczytaj [[plik]] HMR i uruchom wnioskowanie predykatem (//goxio/3//). Dopisz callback wyświetlający wynik wnioskowania w XPCE. | |
- Pobierz ten {{:pl:dydaktyka:piw:2010:systemy_ekspertowe:thermostat-clb-pl.pl|plik}} HMR i dopisz (zmodyfikuj istniejące wersje prologowe) do niego callbacki w Javie bazując na przykładzie z poprzedniej sekcji. | |
| |
| |
| |