====== 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//