====== Prolog i Java - integracja środowisk ====== Celem laboratorium jest przedstawienie podstaw integracji języka Prolog, na przykładzie środowiska [[http://www.swi-prolog.org/|SWI]] z [[http://java.sun.com/|językiem Java]]. Integracja jest realizowana za pośrednictwem [[http://www.swi-prolog.org/packages/jpl/|interfejsu JPL]]. Od uczestników wymaga się znajomości [[pl:prolog:prolog_lab#czesc_glowna|podstaw Prologu]] i podstawowej znajomości języka Java. //Uwaga:// w tym laboratorium może się przydać znajomość [[pl:prolog:prolog_lab:prolog_lab_metaprog|lab. z metaprogramowania.]] ===== Wprowadzenie ===== ==== Rola JPL ==== JPL jest zestawem bibliotek pozwalających na integrację SWI Prologu ze środowiskiem Java na etapie kompilacji i uruchamiania (//runtime//). Wymaga SUN JDK lub OpenJDK. Ze względów licencyjnych w niektórych dystrybucjach GNU/Linux może być dostępny tylko wtedy, jeżeli jest dostępne to 2. ==== Instalacja JPL ==== Najlepiej: apt-get install swi-prolog-jpl Ogólnie: export JAVA_HOME=/usr/lib/jvm/java-6-sun export LD_LIBRARY_PATH=$JAVA_HOME/jre/lib/i386:$JAVA_HOME/jre/lib/i386/client/ jpl oczekuje, że exec SWI nazywa się //pl//. ln -s /usr/bin/swipl /usr/bin/pl ew. dla uruchamiania bez podawania ścieżki przy //java// ln -s /usr/lib/swi-prolog/lib/i386/libjpl.so /usr/lib/jvm/java-6-sun/jre/lib/i386/client/ ln -s /usr/lib/swi-prolog/lib/i386/libjpl.so /usr/lib/jvm/java-6-sun/jre/lib/i386/ ==== Reprezentacja typów ==== JPL zapewnia Prologową reprezentację typów obecnych w Javie. [[http://www.swi-prolog.org/packages/jpl/prolog_api/overview.html#JPL_types_Java_types_as_seen_by|Pełny opis jest tu.]] ==== Wywoływanie Javy z Prologu ==== Patrz również: * [[http://www.swi-prolog.org/packages/jpl/prolog_api/overview.html|podręcznik]] * [[http://www.swi-prolog.org/packages/jpl/prolog_api/api.html|opis API]] Do tworzenia obiektów Javy służy predykat ''[[http://www.swi-prolog.org/packages/jpl/prolog_api/api.html#jpl_new/3|jpl_new/3]]''. jpl_new( +ClassOrType, +Params, -Result) W wyniku jego użycia dostajemy referencję do nowoutworzonego obiektu, np.: jpl_new( 'javax.swing.JFrame', ['frame with dialog'], F) Do używania metod we wcześniej utworzonych obiektach służy predykat ''[[http://www.swi-prolog.org/packages/jpl/prolog_api/api.html#jpl_call/4|jpl_call/4]]''. jpl_call( +Object, +Method, +Params, -Result) Na przykład: jpl_call( F, setVisible, [@true], @void) Do pobierania wartości pól obiektów służy predykat ''[[http://www.swi-prolog.org/packages/jpl/prolog_api/api.html#jpl_get/3|jpl_get/3]]''. jpl_get( +Object, +Field, -Value) Na przykład: jpl_get( 'java.awt.Color', pink, Pink) Do ustawiania wartości pól obiektów służy predykat ''[[http://www.swi-prolog.org/packages/jpl/prolog_api/api.html#jpl_set/3|jpl_set/3]]''. jpl_set( +Object, +Field, +Value) Na przykład: jpl_set( +Class_or_Object, +Field, +Datum) ==== Wywoływanie Prologu z Javy ==== Przydatne informacje: * [[http://www.swi-prolog.org/packages/jpl/java_api/getting_started.html|wprowadzające]] * [[http://www.swi-prolog.org/packages/jpl/java_api/high-level_interface.html|opis API]] Inicjalizacja Prologu odbywa się automatycznie przy użyciu JPL. Najczęściej do pracy potrzebujemy być w stanie stworzyć Javowe odpowiedniki termów i zadawać pytania. Hierarcha klas JPL potrzebnych do tych zadań [[http://www.swi-prolog.org/packages/jpl/java_api/high-level_interface.html#The%20Class%20Hierarchy|jest opisana tu]]. Mając prosty program w Prologu: rodzic(kasia,robert). rodzic(tomek,robert). rodzic(robert,anna). rodzic(robert,magda). rodzic(magda,jan). kobieta(kasia). kobieta(magda). kobieta(anna). mezczyzna(tomek). mezczyzna(robert). mezczyzna(jan). matka(X,Y) :- rodzic(X,Y), kobieta(X). ojciec(X,Y) :- rodzic(X,Y), mezczyzna(X). zapisujemy go w pliku //family1.pl// Następnie tworzymy prosty program w Javie: import java.util.Hashtable; import jpl.*; import jpl.Query; public class Family { public static void main(String argv[]) { String t1 = "consult('family1.pl')"; Query q1 = new Query(t1); System.out.println( t1 + " " + (q1.hasSolution() ? "succeeded" : "failed") ); String t2 = "kobieta(kasia)"; Query q2 = new Query(t2); System.out.println( t2 + " is " + (q2.hasSolution() ? "provable" : "not provable") ); String t3 = "rodzic(robert,anna)"; Query q3 = new Query(t3); System.out.println( t3 + " is " +(q3.hasSolution() ? "provable" : "not provable") ); String t4 = "ojciec(robert,X)"; Query q4 = new Query(t4); System.out.println( "first solution of " + t4 + ": X = " + q4.oneSolution().get("X")); java.util.Hashtable[] ss4 = q4.allSolutions(); System.out.println( "all solutions of " + t4); for ( int i=0 ; i Kompilacja: javac -classpath /usr/lib/swi-prolog/lib/jpl.jar Family.java Uruchamianie: java -classpath /usr/lib/swi-prolog/lib/jpl.jar\:. -Djava.library.path="$LD_LIBRARY_PATH:/usr/lib/swi-prolog/lib/i386/" Family ===== Ćwiczenia ===== ==== Interfejsy w Javie do programów Prologu ==== Należy przyjrzeć się (przypomnieć sobie!) [[pl:prolog:prolog_lab:prolog_lab_metaprog#tematsystemy_ekspertowe|proste systemu ekspertowe]] z [[pl:prolog:prolog_lab:prolog_lab_metaprog|laboratorium z metaprogramowania]]. W szczególności, jeżeli zadaniem jest stworzenie GUI w Javie do [[pl:prolog:prolog_lab:prolog_lab_metaprog#systemcar|systemu car]], okazuje się, że jedyne elementy wymagające modyfikacji to predykaty związne z interfejsem użytkownika: ''question/2'' i ''info/1'': question(Result,T):- jpl_call('javax.swing.JOptionPane','showConfirmDialog',[(@null),T,'Question',0],X), change(X,Result). info(X):- jpl_call('javax.swing.JOptionPane','showMessageDialog',[(@null),X],F). get_yes_or_no(Q,Result) :- ask_question(Q,X), question(Result,X). change(0,yes). change(1,no). Patrz pełen [[pl:miw:miw08_ruleruntimeg:car|przykład tutaj]]. Proszę przejrzeć wszystkie przykłady z [[pl:miw:miw08_ruleruntimeg|projeku MIW08_ruleruntimeg]] i każdy z nich uruchomić. ==== Interfejsy ==== === Rodzina - revisited === Mając "nieśmiertelny" program //rodzina// z [[pl:prolog:prolog_lab:wprowadzenie|pierwszych zajęć]] (uwaga: pełna wersja //fam2.pl// jest [[pl:prolog:prolog_lab:programy#wymuszanie_nawrotow|na drugim lab]]!) należy napisać GUI w Javie, pozwalające na zadawaniu pytań, w dwóch wariantach: * zadawanie stringu będącego zapytaniem * wyświetlanie prostego checkboxy, pozwalającego na wybór predykatu do zapytania i ew. argumentów. Uwaga: Prolog wywołuje Javę! === Learner === Dodać prosty interfejs w Javie do [[pl:prolog:prolog_lab:programy#dynamiczna_bazy_wiedzy|programu learner]]. (analogicznie jak w systemie //car//). Uwaga: Prolog wywołuje Javę! === Prologowe bazy === Mając programy //rodzina// i //planer lotów// z [[pl:prolog:prolog_lab:reprezentacja_wiedzy|Lab o reprezentacji wiedzy]] należy stworzyć interfejsy pozwalające na odpowiednio: * modyfikowanie bazy prologowej za pomocą GUI w Javie, oraz * zadawanie zapytań Uwaga: Java wywołuje Prolog! === Własne pomysły === :-) ===== Materiały ===== * Paul Singleton, //[[http://www.swi-prolog.org/packages/jpl/|Interfejs JPL]]// * Paul Singleton, //[[http://www.swi-prolog.org/packages/jpl/prolog_api/overview.html|Using Java from Prolog: User guide]]// * Paul Singleton, //[[http://www.swi-prolog.org/packages/jpl/java_api/getting_started.html|Prolog from Java]]// * Piotr Strzelczyk, //[[https://ai.ia.agh.edu.pl/wiki/pl:miw:miw08_prolog_java|Różne interfejsy do Javy w Prologu (MIW08)]]// * Filip Haftek, //[[https://ai.ia.agh.edu.pl/wiki/pl:miw:miw08_ruleruntimeg|Przykłady systemów ekspertowych z GUI w Java (MIW08)]]// * Łukasz Łysik, //[[https://ai.ia.agh.edu.pl/wiki/pl:miw:miw08_prolog_javasockets|Integracja Javy i Prologu przez sockety (MIW08)]]// * Damian Janicki, //[[https://ai.ia.agh.edu.pl/wiki/pl:miw:miw08_ruleruntimeg_2|GUI w Javie do Varda (MIW08)]]// ====== Uwagi, komentarze, propozycje ====== Tu studenci mogą wpisywać swoje uwagi. --- //[[gjn@agh.edu.pl|Grzegorz J. Nalepa]] 2009/05/06 09:13//