Celem laboratorium jest przedstawienie podstaw integracji języka Prolog, na przykładzie środowiska SWI z językiem Java.
Integracja jest realizowana za pośrednictwem interfejsu JPL.
Od uczestników wymaga się znajomości podstaw Prologu i podstawowej znajomości języka Java.
Uwaga: w tym laboratorium może się przydać znajomość lab. z metaprogramowania.
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.
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/
JPL zapewnia Prologową reprezentację typów obecnych w Javie. Pełny opis jest tu.
Patrz również:
Do tworzenia obiektów Javy służy predykat
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
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
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
jpl_set/3
.
jpl_set( +Object, +Field, +Value)
Na przykład:
jpl_set( +Class_or_Object, +Field, +Datum)
Przydatne informacje:
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ń 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<ss4.length ; i++ ) System.out.println( "X = " + ss4[i].get("X")); System.out.println( "each solution of " + t4); while ( q4.hasMoreSolutions() ){ java.util.Hashtable s4 = q4.nextSolution(); System.out.println( "X = " + s4.get("X")); } String t5 = "ojciec(X,Y)"; Query q5 = new Query(t5); System.out.println( "each solution of " + t5 ); while ( q5.hasMoreSolutions() ){ java.util.Hashtable s5 = q5.nextSolution(); System.out.println( "X = " + s5.get("X") + ", Y = " + s5.get("Y")); } } }
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
Należy przyjrzeć się (przypomnieć sobie!) proste systemu ekspertowe z laboratorium z metaprogramowania.
W szczególności, jeżeli zadaniem jest stworzenie GUI w Javie do
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 przykład tutaj.
Proszę przejrzeć wszystkie przykłady z projeku MIW08_ruleruntimeg i każdy z nich uruchomić.
Mając „nieśmiertelny” program rodzina z pierwszych zajęć (uwaga: pełna wersja fam2.pl jest na drugim lab!) należy napisać GUI w Javie, pozwalające na zadawaniu pytań, w dwóch wariantach:
Uwaga: Prolog wywołuje Javę!
Dodać prosty interfejs w Javie do programu learner. (analogicznie jak w systemie car).
Uwaga: Prolog wywołuje Javę!
Mając programy rodzina i planer lotów z Lab o reprezentacji wiedzy należy stworzyć interfejsy pozwalające na odpowiednio:
Uwaga: Java wywołuje Prolog!
Tu studenci mogą wpisywać swoje uwagi.
— Grzegorz J. Nalepa 2009/05/06 09:13