Both sides previous revision
Poprzednia wersja
Nowa wersja
|
Poprzednia wersja
|
pl:miw:piw08_prolog_java [2008/06/03 13:40] miw |
pl:miw:piw08_prolog_java [2019/06/27 15:50] (aktualna) |
Istnieją także interpretery Prologu (właściwie języka Prologo-podobnego) w Javie, jest to dość duża grupa projektów, ale rozwiązania te są dość ubogie i mniej efektywne. | Istnieją także interpretery Prologu (właściwie języka Prologo-podobnego) w Javie, jest to dość duża grupa projektów, ale rozwiązania te są dość ubogie i mniej efektywne. |
| |
====== Implementacja JPL ====== | |
| |
1. Należy stwożyć zmienną środowiskową SWI_HOME_DIR ze ścieżką do katalogu w którym jest zainstalowany SWIProlog. | ====== Implementacja ====== |
2. Do zmiennej PATH należy dodać dodać ścieżkę do katalogu SWI_HOME_DIR\bin | |
| |
===== Wywoływanie SWIProlog z Java'y ===== | ===== JPL ===== |
| |
| * Należy stwożyć zmienną środowiskową SWI_HOME_DIR ze ścieżką do katalogu w którym jest zainstalowany SWIProlog. |
| * Do zmiennej PATH należy dodać dodać ścieżkę do katalogu SWI_HOME_DIR\bin |
| |
| |
| |
| |
| ==== Wywoływanie SWIProlog z Javy ==== |
| |
W kodzie Java'y należy: | W kodzie Java'y należy: |
| |
| |
* Aby pojedynczo otrzymywać kolejno wyniki wywołujemy na zmiane dwie funkcje | * Aby pojedynczo otrzymywać kolejne wyniki wywołujemy na zmiane dwie funkcje |
| |
| |
| |
| |
===== Wywoływanie Java'y z SWIProlog ===== | |
| ==== Wywoływanie Javy z SWIProlog ==== |
| |
Wykorzystuje się 4 predykaty | Wykorzystuje się 4 predykaty |
* jpl_new(+Class,+Params,-Ref) | * jpl_new(+Class,+Params,-Ref) |
| |
| |
jpl_new( 'nazwa_klasy', [parametry_funkcji_odzielone_przecinkami], Referencja) | jpl_new( 'nazwa_klasy', [parametry_funkcji_odzielone_przecinkami], Referencja) |
| |
nazwa_klasy Referencja new nazwa_klasy(parametry_funkcji_odzielone_przecinkami); | nazwa_klasy Referencja new nazwa_klasy(parametry_funkcji_odzielone_przecinkami); |
| Jeśli chcemy stworzyć obiekt napisanej przez nas klasy pliki class muszą zostać umieszczone w odpowiednim katalogu względem pliku pl (nazwa package, do którego należy nasza klasa). Niestety nie da się korzystać z klas umieszczonych w plikach jar |
| |
* jpl_call( +Ref, +Method, +Params, -Result) | * jpl_call( +Ref, +Method, +Params, -Result) |
| |
jpl_call( Referencja, 'nazwa_funkcji', [parametry_funkcji_odzielone_przecinkami], Wynik) | jpl_call( Referencja, 'nazwa_funkcji', [parametry_funkcji_odzielone_przecinkami], Wynik) |
Po takim wywołaniu na obiekcie dostępnym poprzez referencję Referencja wywoływana jest funkcja nazwa_funkcji. Jest to odpowiednik Java'owego: | Po takim wywołaniu na obiekcie dostępnym poprzez referencję Referencja wywoływana jest funkcja nazwa_funkcji. Jest to odpowiednik Java'owego: |
| |
jpl_call( 'nazwa_klasy', 'nazwa_funkcji', [parametry_funkcji_odzielone_przecinkami], Wynik) | jpl_call( 'nazwa_klasy', 'nazwa_funkcji', [parametry_funkcji_odzielone_przecinkami], Wynik) |
| Jeśli chcemy wywołać funkcję napisanej przez nas klasy pliki java muszą zostać umieszczone w odpowiednim katalogu względem pliku pl (nazwa package, do którego należy nasza klasa). Niestety nie da się korzystać z klas umieszczonych w plikach jar |
| |
* jpl_get( +Class_or_Object, +Field, -Datum) | * jpl_get( +Class_or_Object, +Field, -Datum) |
Służy do wydobycia wartości atrybutu Field klasy lub obiektu Class_or_Object i przypisania go zmiennej datum | Służy do wydobycia wartości atrybutu Field klasy lub obiektu Class_or_Object i przypisania go zmiennej datum |
| |
* jpl_set( +Class_or_Object, +Field, +Datum) | * jpl_set( +Class_or_Object, +Field, +Datum) |
Służy | Służy do przypisania atrybutowi Field klasy lub obiektu Class_or_Object wartości jaką posiada zmienna datum |
Dw | |
| ===== Interprolog ===== |
| |
| |
| ==== Java API ==== |
| |
| <code java> |
| import java.io.File; |
| import com.declarativa.interprolog.SWISubprocessEngine; |
| |
| public class Car { |
| |
| public static void main(String[] args) { |
| SWISubprocessEngine engine=new SWISubprocessEngine("C:\\SWI\\pl\\bin\\plcon.exe"); |
| File f=new File("car.pl"); |
| engine.consultAbsolute(f); |
| engine.deterministicGoal("start"); |
| engine.shutdown(); |
| } |
| |
| } |
| </code> |
| |
| com.declarativa.interprolog.* - podstawowy pakiet Interprologu |
| |
| W celu rozpoczęcia pracy z Interprologiem, należy storzyć obiekt SubProcessEngine ( dla SWI - SWISubProcessEngine, odpowiednio dla YAP i XSB). W konstruktorze obiektu należy podać ścieżkę do interpretera Prologu. Adres interpretera (ścieżka) powinien być określony bezwzględnie, jednak stosując zmienne środowiskowe (PATH) i wywołanie programu z parametrem można z powodzeniem zmieniać dynamicznie interpreter, przez podanie nazwy pliku. |
| |
| <code java> |
| SWISubprocessEngine engine=new SWISubprocessEngine("C:\\SWI\\pl\\bin\\plcon.exe"); |
| </code> |
| |
| <code java> |
| boolean SWISubprocessEngine.consultAbsolute(File f) |
| </code> |
| |
| Pozwala na załadowanie logiki z dowolnego pliku prologowego do interpretera, można także wywołać: |
| |
| <code java> |
| boolean SWISubprocessEngine.deterministicGoal("[file]"); |
| </code> |
| |
| Podstawową metodą komunikacji z Proogiem w Javie jest zadawanie celów. Pozwala na to funkcja: |
| |
| <code java> |
| Object [] SWISubprocessEngine.deterministicGoal(String goal); |
| </code> |
| |
| gdzie goal jest zadanym celem (bez kropki). Zwracana jest tablica obiektów, którą należy przetworzyć, np. wywołanie goal w programie Sudoku jako "top([list])", gdzie list było listą argumentów, zwracało Stringa: "top([newlist])", gdzie newList było listą (prologową, w Javie jako String) wyznaczonych zmiennych oddzielonych przecinkiem. Wymaga to dodatkowego nakładu pracy i mocy obliczeniowej na konwersję danych i dzielenie Stringa. |
| |
| Interprolog nie posiada mechanizmu definiowania niedeterministycznych celów, można to obejść np. wykorzystując Java Term Model z bilbioteki Interprologu http://www.declarativa.com/interprolog/faq.htm#nonDeterministicGoal |
| jednak nie jest to bardzo wygodne. |
| |
| Tych kilka metod pozwala komunikować się z Prologiem z poziomu Javy w zakresie zadawania celów i korzystania z bazy wiedzy. |
| |
| |
| ==== Prolog API ==== |
| |
| Interprolog posiada także predykaty Prologowe pozwalające na komunikację z Javą z poziomu Prologu. |
| |
| Najbardziej podstawowym z nich jest javaMessage występujący w trzech wersjach: |
| |
| <code> |
| javaMessage( Target,Result,Exception,MessageName,ArgList,NewArgList ) |
| </code> |
| |
| Target określa docelowy obiekt Javy do którego wysyłana jest wiadomość |
| |
| Result wynik wywołania metody obiektu |
| |
| Exception wyjątek jaki może się pojawić |
| |
| MessageName metoda obiektu Target |
| |
| ArgList lista argumentów wywołania metody w postaci obiektów kompatybilnych z Java |
| |
| NewArgList zawiera te same argumenty co ArgList, ale pobrane są one po zakończeniu działania metody, daje możliwość monitorowania zmian stanu obiektu |
| |
| |
| <code> |
| javaMessage( Target,Result,Message ) |
| </code> |
| |
| Target j.w. |
| |
| Result j.w. |
| |
| Message pozwala na wywołanie metody przez nazwaMetody(parametry), pozwala na wykorzystanie podstawowych konwersji np. integer(value), string(value). Pomija zmiany stanu obiektu. |
| |
| |
| <code> |
| javaMessage(Target,Message) |
| </code> |
| |
| Działa jak javaMessage(Target,_,Message) |
| |
| Pozostałe predykaty opisane są tu: http://www.declarativa.com/interprolog/prologAPI.htm |
| |
| System ekspertowy Car demonstruje wykorzystanie wyżej opisanej metody: |
| |
| <code> |
| javaMessage('javax.swing.JOptionPane', |
| showMessageDialog(null,string('This program diagnoses why a car won''t start.'))), |
| </code> |
| |
| Wyświetla okienko z wiadomością informacyjną. |
| |
| <code> |
| javaMessage('javax.swing.JOptionPane',A, |
| showConfirmDialog(null,string(' |
| When you first started trying to start the car, |
| \n did the starter crank the engine normally?'))), |
| </code> |
| |
| Wyświetla okno z zapytaniem Yes/No do użytkownika, zwraca 0 lub 1. |
| |
| <code> |
| ipObjectSpec(C,X,Variables,_) |
| </code> |
| |
| Pozwala wykorzystać obiekt otrzymany z metody Java w Prologu. Przykład użycia: |
| |
| <code> |
| ipObjectSpec('java.lang.Integer',B,[A],_), |
| </code> |
| |
| Pozwala odczytać zwrócony obiekt B jako integer A w Prologu. |
| |
| |
====== Porównanie ====== | ====== Porównanie ====== |
| |
* Łatwość programowania - JPL jest zdecydowanie prostszy w obsłudze, nie wymaga inicjalizacji maszyny wnioskującej, metody Java są intuicyjne | * Łatwość programowania - JPL jest zdecydowanie prostszy w obsłudze, nie wymaga inicjalizacji maszyny wnioskującej, metody Java są intuicyjne |
* Szybkość działania - w fazie testów | * Szybkość działania - testy wykazały, że nie ma różnicy w wykorzystaniu obu systemów. Uśrednione wartości testów pokazały, że czas wykonania operacji (rozwiązanie Sudoku) jest bardzo podobny (różnice rzędu 0,01). Pomijając wartości skrajne (prawdopodobnie spowodowane pracą w tle innych aplikacji) pojedyncze wyniki prawie zawsze różniły się o stałą wartość (|time(Interprolog_execution)-time(JPL_execution)|=const). |
* Wygoda - Interprolog nie posiada non-deterministic goal api, stąd wszelkie multiple-solutions trzeba generować w prologu i zwracać jako listę rozwiązań, która jest obiektem typu String w Javie i trzeba ją parsować, natomiast JPL generuje kolejne rozwiązania z poziomu Java poprzez kolejne wywołania tych samych 2 funkcji | * Wygoda - Interprolog nie posiada non-deterministic goal api, stąd wszelkie multiple-solutions trzeba generować w prologu i zwracać jako listę rozwiązań, która jest obiektem typu String w Javie i trzeba ją parsować, natomiast JPL generuje kolejne rozwiązania z poziomu Java poprzez kolejne wywołania tych samych 2 funkcji |
* Dostęp do konsoli interpretera Prologu - JPL musi mieć zdefiniowaną zmienną środowiskową (SWI_HOME_DIR), w której jest adres katalogu domowego SWI, w Interprologu w kodzie programu Java należy wywołać SWISubProcessEngine z parametrem jakim jest śćieżka dostępu do interpretera | * Dostęp do konsoli interpretera Prologu - JPL musi mieć zdefiniowaną zmienną środowiskową (SWI_HOME_DIR), w której jest adres katalogu domowego SWI, w Interprologu w kodzie programu Java należy wywołać SWISubProcessEngine z parametrem jakim jest śćieżka dostępu do interpretera |
* Łączność Prolog-Java - w JPL realizuje się to za pomocą 4 predykatów (tworzenie obiektów Java, wywoływanie funkcji, powiązanie obiektu Java ze zmienną w Prologu, ustalenie wartości zmiennej), w Interprologu działa to na zasadzie komunikacji synchronicznej przez Java Message | * Łączność Prolog-Java - w JPL realizuje się to za pomocą 4 predykatów (tworzenie obiektów Java, wywoływanie funkcji, powiązanie obiektu Java ze zmienną w Prologu, ustalenie wartości zmiennej), w Interprologu działa to na zasadzie komunikacji synchronicznej przez Java Message |
| |
====== Sudoku - przykład wywołania Prologu z poziomu Java ====== | |
| ====== Przykłady programów ====== |
| |
| Programy testowane tylko w środowisku Windows |
| |
===== Interprolog ===== | ===== Interprolog ===== |
| |
http://student.agh.edu.pl/~keepsake/miw/ | |
| ==== Sudoku ==== |
| |
| {{prolog_java_sudoku_interprolog.zip}} |
| |
Wywołanie: java -jar Sudoku.jar [prolog compiler] | Wywołanie: java -jar Sudoku.jar [prolog compiler] |
| |
jar cfm Sudoku.jar manifest *.class | jar cfm Sudoku.jar manifest *.class |
| |
| |
| |
| |
| |
| |
| |
| ==== Car ==== |
| |
| {{prolog_java_car_interprolog.zip}} |
| |
| Kompilacja j.w. |
| |
| Uruchomienie j.w. |
| |
| |
| |
| |
===== JPL ===== | ===== JPL ===== |
| SUDOKU |
| {{prolog_java_sudoku_jpl.zip}} |
| |
http://student.agh.edu.pl/~colesiu/sudoku.rar | Przykład działania wywołania prologa w javie (GUI w javie i wnioskowanie w prologu). |
| Należy ustawić zmienną środowiskową SWI_HOME_DIR, do zmiennej środowiskowej PATH należy dodać SWI_HOME_DIR/bin |
| |
należy ustawić zmienną środowiskową SWI_HOME_DIR, do zmiennej środowiskowej PATH należy dodać SWI_HOME_DIR/bin | CAR.PL |
| {{prolog_java_car_jpl.zip}} |
| |
| Przykład działania wywołania javy w prologu (Okno startowe w javie wywołuje prologa, a prolog wywołuje kolejne dialogBoxy z pytaniami). |
| Należy ustawić zmienną środowiskową SWI_HOME_DIR, do zmiennej środowiskowej PATH należy dodać SWI_HOME_DIR/bin |
| |
====== Problemy ====== | ====== Problemy ====== |
| |
| Do poprawy, --- //[[wojnicki@agh.edu.pl|Igor Wojnicki]] 2008/06/11 13:10//: |
| |
| - https://ai.ia.agh.edu.pl/wiki/pl:miw:piw08_prolog_java#jpl cos nie tak z wersjami |
| - https://ai.ia.agh.edu.pl/wiki/pl:miw:piw08_prolog_java#inne prosze podac linki |
| - literowki |
| - cos nie tak: "Daje możliwość pozwala na załadowanie logiki..." |
| - co z porownaniem Szybkosci Dzialania, https://ai.ia.agh.edu.pl/wiki/pl:miw:piw08_prolog_java#porownanie |
| |
| |