To jest stara wersja strony!
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:
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)).
Ćwiczenie
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.
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:
xattr [name: day,
abbrev: day,
class: simple,
type: day,
comm: in,
callback: [ask_console,[day]]
].
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:
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.
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)).
Języki programowania
Callbacki dla interpretera HeaRT mogą być zaimplementowane w jednym z następujących języków:
Prolog
Są to zwykłe predykaty w języku Prolog:
xcall ask_console : [AttName] >>> (write('Type value for attribute: '),
write(AttName),nl,
read(Answer),
alsv_new_val(AttName,Answer)).
Ćwiczenie
Aby uruchomić wnioskowanie bezpośrednio z interpretera HeaRT, należy pobrać kod interpretera: 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
gox(current, ListaTabelDoPrzetworzenia, ddi)
.
Uruchom wnioskowanie dla poniższego modelu: 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:
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)).
Przykład callbacku wczytującego liczbę z określonego zakresu pokazany jest poniżej:
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)).
Ćwiczenie
Uruchom wnioskowanie dla przykładu z bankomatem i prześledź działanie callbacków:
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 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
javac callbacks/input/*.java skeleton/*.java
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.
callback: [ask_symbolic_GUI,[day]]
Dopisać predykaty
xcall do pliku HMR, definiujące wywołanie callbacka, np.:
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)).
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 (
gox/3). Dopisz callback wyświetlający wynik wnioskowania w XPCE.
Pobierz ten
plik HMR i dopisz (zmodyfikuj istniejące wersje prologowe) do niego callbacki w Javie bazując na przykładzie z poprzedniej sekcji.