To jest stara wersja strony!
Opis
Grzegorz Caban, grzegorz.caban@gmail.com
Investigate runtime integration aspects, mainly the integration of the Object-Oriented Model in Prolog with a Java VC possibilities executable design, LogTalk, etc.
Feasibility study, a prototype.
Spotkania
08.03.04
080318
integr LogTalk+Java
porówn Sicstus LT
-
080401
selekcja przykładów MVC, patrz
materialy, logtalk!
080408
080415
080429
080527
przetwarzanie danych w modelu: search, search&replace, właściwości (liczenie znaków,słów, linii), ?, kolorowanie składni (csv, prolog, java?)
thermostat: 3 klasy: model (
reguły), view (1 okienko, wejście: dzień tyg (1-7), miesiąc (1-12), godzina(1-24), readio boxes? sliders?), wyjście: 1 liczba → temperatura), controller
Projekt
Edytor Dokumentów
Edytor dokumentów – Pomysły na system regułowy:
kolorowanie składni
wyszukiwanie słów kluczowych, analiza zdan, jezyka,
xml, html (np formatowanie tekstu na podstawie tagów i atrybutów html)
kontrola czy tekst zawiera wszystkie wymagane elementy (np sprawdzanie poprawnosci podania, faktury itp)
inteligentne wyszukiwanie strukturalne
Przykłady MVC
Edytor dokumentów – bardzo prosty przykład z stron Sun'a, aplikacja do „edycji” tekstu, ale zbudowana zgodnie z MVC i przede wszystkim pełne źródła w Javie.
-
Sklep internetowy - dość dokładnie opisany ale bez źródeł. Wydaje się trochę za duży.
Mailing List - krótki tutorial do J2EE i Struts'ów ze stron IBM'a. Przykład dość prosty ale niezle udokumentowany i są też wystawione źródła.
Integracja LogTalk'a z Java
Używanie modułów Prologa z obiektów LogTalk
Rozwiązaniem problemu z poprzedniego tygodnia jest stosunkowo proste, mianowicie do wywoływania metod z pakietu należy użyć operatora {}/1. Inaczej LogTalk próbuje jakoś zrobić z modułu obiekt i nie zawsze to działa.
Także poprawne wywołanie wygląda tak :
jpl_test:-
{ jpl_new('javax.swing.JFrame', ['Frame with dialog'], F) },
A poniżej działający już poniższy przykład :
:-use_module(library(jpl),[jpl_new/3, jpl_call/4]).
:-object(logTalkControler).
:-public(toString/0).
:-public(testValue/1).
:-public(jpl_test/0).
:-initialization(
write('Constructor speaking')).
test(a).
test(b).
test(c).
value(a).
testValue(X) :-
test(X),
value(X).
jpl_test:-
{jpl_new('javax.swing.JFrame', ['Frame with dialog'], F)},
{jpl_call(F, setLocation, [400, 300], _)},
{jpl_call(F, setSize, [400, 300], _)},
{jpl_call(F, setVisible, [@(true)], _)},
{jpl_call(F, toFront, [], _)}.
:-end_object.
Konfiguracja SWI-Prolog do LogTalk'a
Na podstawie własnych doświadczeń. Aby utworzyć, skompilować i załądować do pamieci obiekty LogTalk'a konieczne jest wcześniejsze skonfigurowanie używanego kompilatora Prolog'a. Na potrzeby tego projektu zakładam, że jest nim SWI-Prolog, jakkolwiek jeśli wierzyć dokumentacji LogTalk'a to jest on w pełni kompatybilny z większościa innych kompilatorów Prolog'a.
Aby zintegrować LogTalk'a z SWI:
należy wykonać predykat consult na trzech plikach, które można znaleźć w katalogu instalacyjnym LogTalk'a :
configs/swi.config - ustawia zmienne i konfiguruj srodowisko Prologa
complier/logtalk.pl - laduje kompilator LogTalka
libpaths/libpaths.pl - ustawia sciezki do bibliotek standardowych LogTalka
chyba najwygodniej jest sporządzić sobie plik startowy:
:-consult('lib/Resources/logtalk/swi.config').
:-consult('lib/Resources/logtalk/logtalk.pl').
:-consult('lib/Resources/logtalk/libpaths.pl').
który pożniej uruchamiamy z Javy przed tworzeniem obiektów LogTalk, w następujący sposób:
JPL.setDefaultInitArgs(
new String[] {
"pl",
"-f", "none",
"-g", "set_prolog_flag(debug_on_error,false)",
"-q",
"-nosignals"
}
);
Query q = new Query("['lib/logtalkLoad.pl'].");
if (!q.hasSolution())
{
RuntimeException e = new RuntimeException("error loading logtalk");
}
else
{
System.out.println("Hurray!");
}
Po udanym wykonaniu powyższego kodu jesteśmy już w stanie tworzyć obiekty LogTalk z kodu Javy i wywoływać ich metody :
//utworznie instancji obiektu logTalkControler
Query loadControler = new Query("logtalk_load",
new Term[]{
new Atom("logTalkControler")
}
);
//wywolanie metody testValue obiektu logTalkControler
Query askLgt = new Query("logTalkControler::testValue(valueToTest).");
System.out.println("Is 'a' a proper TestValue?:"
+ (askLgt("testValue", "a")?"YES":"NO!"));
Pełną treść tego przykładu zamieszczam tutaj logtalkjava.
Niestety dalej natrafiam na problemy z próba uruchomienia komunikacji w drugą strone, tzn wywołania kodu Javy z LogTalka. Mimo iż modul jpl bardzo dobrze się sprawdza przy tworzeniu obiektów Javy, jak widać np w tym przykładzie :
:-use_module(library(jpl)).
jpl_test:-
jpl_new('javax.swing.JFrame', ['Frame with dialog'], F),
jpl_call(F, setLocation, [400, 300], _),
jpl_call(F, setSize, [400, 300], _),
jpl_call(F, setVisible, [@(true)], _),
jpl_call(F, toFront, [], _),
jpl_call('javax.swing.JOptionPane', showInputDialog, [F, 'Write sth'], N),
jpl_call(F, dispose, [], _),
( N == @(null) ->
write('You cancelled');
write('You typed'), write(N)
),
nl.
:-jpl_test.
Działa bez zarzutu, wyświetlając okienko dialogowe. Ale już próba uruchomienia podobnego kodu w metodzie obiektu LogTalk:
:-use_module(library(jpl),[jpl_new/3, jpl_call/4]).
:-object(logTalkControler).
:-public(toString/0).
:-public(testValue/1).
:-public(jpl_test/0).
:-initialization(
write('Constructor speaking')).
test(a).
test(b).
test(c).
value(a).
testValue(X) :-
test(X),
value(X).
jpl_test:-
jpl_new('javax.swing.JFrame', ['Frame with dialog'], F),
jpl_call(F, setLocation, [400, 300], _),
jpl_call(F, setSize, [400, 300], _),
jpl_call(F, setVisible, [@(true)], _),
jpl_call(F, toFront, [], _).
:-end_object.
Powoduje dość ciekawy komunikat przy próbie kompilacji w swi :
63 ?- logtalk_load(logTalkControler).
<<< reloading source file logTalkControler...
>>> compiling source file logTalkControler...
compiling object logTalkControler...
WARNING! These predicates are called but never defined: jpl_call/4, jpl_new/3
compiled object logTalkControler...
>>> logTalkControler source file compiled
WARNING! Redefining object logTalkControler
Constructor speaking
% logTalkControler.pl compiled 0.00 sec, 92 bytes
<<< logTalkControler source file reloaded
(1 compilation warning and 1 loading warning)
true.
64 ?- logTalkControler::jpl_test.
ERROR: Undefined procedure: jpl_new/3
ERROR: However, there are definitions for:
ERROR: jpl_new/3
I oczywiście nie działa. Podejrzewam, że problem tkwi w niewłaściwie dodanym pakiecie. Ale nie udało mi się jeszcze znaleźć rozwiązania..
Opis ogolny LogTalk
Opierając się na przykładzie znalezionym na stronie jednym z sposobów integracji obiektów LogTalk z Java jest użycie jednego z pakietów SWI_Prolog, JPL : Java to Prolog Interface.
JPL który oferuje dwustronny interface pomiędzy Prologiem a Java.
Probując wywołać predykat Prologa z kodu Javy posługujemy się następującą składnią :
Query q2 =
new Query(
"child_of",
new Term[] {new Atom("joe"),new Atom("ralf")}
);
System.out.println(
"child_of(joe,ralf) is " +
( q2.query() ? "provable" : "not provable" )
);
Przykład pokazuje przesłanie zapytania do bazy wiedzy prologa. Można ten mechanizm wykorzystać do wywoływania predykatów wewnątrz obiektów LogTalk, czyli de facto do wywoływania metod na obiektach LogTalk z obiektów Java'y.
Gdy konieczne jest wysłanie komunikatu do obiektu Java'y z poziomu Prologa, JPL oferuje następujące rozwiązanie :
Predykat jpl_new/3 pozwala na utworzenie instancji obiektu klasy z Javy :
jpl_new( 'javax.swing.JFrame', ['frame with dialog'], F)
Natomiast predykat jpl_call/4 pozwala wywołać metodę na utworzonym powyżej obiekcie:
jpl_call( F, setVisible, [@(true)], _)
Jak widać JPL umożliwia obustronne wywoływanie metod pomiędzy obiektami klas zdefiniowanych w Javie i w Prologu. Jeżeli dodać do tego obiektowość oferowaną przez LogTalk to wydaje się, że jest to zestaw spełniający dane wymagania. Przykład całej klasy napisanej w Javie, służącej do komunikacji z obiektami LogTalk znajduje się tutaj LogTalkEngine
Analiza istniejących rozwiązań
yap - yap jako wysoko wydajny kompilator Prologa, wzbogacony o takie funkcjonalności jak : strumienie We/Wy, socket'y, moduły wyjątki, debugger itp. nie wydaje się być narzędziem przydatnym w tym projekcie, zwłaszcza że gdy w jego dokumentacji pojawia się temat obiektowości polecane jest użycie LogTalk'a, który swoją drogą podobno dość dobrze się integruje z yap'em.
amzi - narzędzie płatne, choć można wykorzystywać do celów akademickich za darmo, niestety bez źródeł. Bardzo dobrze udokumentowane. Posiada interface do używania prologa z Javy, poprzez obiekt klasy LogicServer możemy się łatwo odwoływać do bazy wiedzy Prologa, w sposób przypominający przesyłanie zapytań do bazy danych.Natomiast dokładna dokumentacja :
LogicServer API. Rozwiązanie wydaje się być zbliżone do SICStus'a. Wygląda na brak wsparcia dla obiektowości.
SICStus Prolog - umożliwia integracje aplikacji napisanej w Prologu z inna napisana w Java/.NET poprzez
PrologBeans. Klient, aplikacja JAVA'owowa przesyła komunikaty, które są odpowiednio oceniane przez server-Prolog'a, obie aplikacje są osobnymi procesami, komunikują się przez sockety TCP, czyli w architekturze klient-serwer. SICStus Prolog wspiera także obiektowość poprzez moduł „The Objects Package—library(objects)”, czyli zapewnia enkapsulacje, dziedziczenie itp.
LogTalk - własne wsparcie dla obiektowości, poprzez LogTalk objects, zapewnia wszystkie podstawowe wymagania. Nie znalazłem bezpośredniego wsparcia dla integracji z innymi platformami, natomiast dokumentacja wspomina o takich możliwościach, dzięki
"wysoko poziomowemu mapowaniu obiektów LogTalk".. Szczegóły na razie nie znane, ale przykład integracji Javy z LogTalk
tutaj
Prolog OOP - umożliwia stosowanie prolog'owych modułów do za modelowania obiektowości, umożliwia wykorzystywanie wiekszości podstawowych predykatów obiektowości takich jak:
Natomiast nie ma w nim mowy o możliwościach integracji Prologa z innym obiektowym językiem, to jest tylko próba wprowadzenia obiektowości do samego Prologa.
TrincProlog - oferuje właściwie analogiczny pomysł, czyli rozszerzenie prologa o obiektowość. Tyle, że tym razem dodatkowe słowa kluczowe pozwalają na deklarowanie klas niezależnie od modułów (czyli np kilka klas w jednym module, itp ). Tyle, że niestety znowu brak możliwości integracji z innymi językami. Obiecująco wyglądała część do
tworzenia aplikacji Windows, ale okazało się że jest już gotowe
API pozwalające odwoływać się do obiektów
GUI (Window, Button, itp.) poprzez predykaty prologa. Być może można by wykorzystać to
API od odwoływania się do dowolnych obiektów, zbudować analogiczne?
Sprawozdanie
Materiały