|
|
pl:miw:miw08_ruleruntimej [2008/05/20 00:24] miw |
pl:miw:miw08_ruleruntimej [2019/06/27 15:50] |
====== Opis ====== | |
Realizujący: | |
**Marcin Gadamer** <marcin.gadamer@gmail.com> | |
| |
Investigate runtime integration aspects, mainly | |
Prolog+Java integration possibilities | |
* input | |
* Prolog/Java APIs | |
* JSR94 | |
* Jess | |
* JenaRules | |
* integration | |
* output | |
How to integrate Prolog and Java in the best way regarding performance, and coding easiness + examples. | |
[[pl:miw:miw2008_tematy#ruleruntimej|MIW temat]] | |
| |
====== Spotkania ====== | |
===== 08.03.04 ===== | |
| |
| |
| |
===== 080401 ===== | |
* Porównanie API Jeny i RDF SWI Prologu | |
* jak zapisywać //reguły// w Jenie? | |
* jaka jest różnica w sile ekspresji reguł jeny i Prologu? | |
* opis dostarczonych z Jeną mechanizmów wnioskujących (reasoners) | |
| |
| |
===== 080415 ===== | |
* przykład [[hekate:hekate_case_thermostat|termostatu]] w RDF w Jenie | |
| |
| |
===== 080429 ===== | |
* warunki, pobieranie param od użytkow, pobranie z systemu | |
* akcje, odpalanie metod? | |
* [[hekatedev:xtt_minicases|minicases]] | |
| |
| |
===== 080520 ===== | |
* spisywanie sprawozd.: opis jeny, repr reguł w rdf, realizacja therm w jenie, | |
* [[http://oxygen.informatik.tu-cottbus.de/rewerse-i1/?q=node/15|translacja]] [[pl:miw:miw08_xtt_r2ml|therm w r2ml]] do jena (production rules) | |
* próba translacji [[hekate:hekate_markup_language#xttml|XTTML]] do Jena? | |
| |
====== Projekt ====== | |
* "implementacja" jsr94 w prologu | |
* możliwość/sensowność jess/prolog | |
| |
===== Jena wstęp na przykładzie rodziny===== | |
| |
Ponieważ Jess można używać jedynie przez 30 dni, wykorzystuję do integracji framework Jena. | |
| |
* Jednym z zalet Jeny jest czytanie/zapisywanie RDF w RDF/XML, N3 oraz N-Triples. Stąd słuszne wydaje się podejście | |
Prolog <-przedstawienie wiedzy-> RDF <-przedstawienie wiedzy-> Java | |
| |
* Mały program w Java, który pokazuje relacje pomiędzy tatą (Jan), mamą (Krystyna), córką (Kasia), synem (Jasiu) | |
| |
Zostały zapisane następujące dane: | |
corka.addProperty(siostra, syn); | |
tata.addProperty(ojciec, corka); | |
tata.addProperty(ojciec, syn); | |
tata.addProperty(malzonek, mama); | |
mama.addProperty(malzonek, tata); | |
Statement statement1 = model.createStatement(syn, dziecko, mama); | |
Statement statement2 = model.createStatement(syn, dziecko, tata); | |
Statement statement3 = model.createStatement(corka, dziecko, mama); | |
Statement statement4 = model.createStatement(corka, dziecko, tata); | |
| |
W pliku RDF: | |
<code xml> | |
<rdf:RDF | |
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |
xmlns:j.0="http://purl.org/vocab/relacje/" > | |
<rdf:Description rdf:about="http://Family/KowalskiJan"> | |
<j.0:malzonek rdf:resource="http://Family/KowalskiKrystyna"/> | |
<j.0:ojciec rdf:resource="http://Family/KowalskiJasiu"/> | |
<j.0:ojciec rdf:resource="http://Family/KowalskiKasia"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://Family/KowalskiKrystyna"> | |
<j.0:malzonek rdf:resource="http://Family/KowalskiJan"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://Family/KowalskiKasia"> | |
<j.0:dziecko rdf:resource="http://Family/KowalskiJan"/> | |
<j.0:dziecko rdf:resource="http://Family/KowalskiKrystyna"/> | |
<j.0:siostra rdf:resource="http://Family/KowalskiJasiu"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://Family/KowalskiJasiu"> | |
<j.0:dziecko rdf:resource="http://Family/KowalskiJan"/> | |
<j.0:dziecko rdf:resource="http://Family/KowalskiKrystyna"/> | |
</rdf:Description> | |
</rdf:RDF> | |
</code> | |
Przekazany RDF do Javy daje model z zawartością 9 informacji. | |
| |
Po zadaniu prostych zapytań | |
| |
syn.listProperties(dziecko); | |
corka.listProperties(dziecko); | |
corka.listProperties(siostra); | |
otrzymałem: | |
| |
http://Family/KowalskiJasiu jest dzieckiem | |
http://Family/KowalskiJan | |
http://Family/KowalskiKrystyna | |
http://Family/KowalskiKasia jest dzieckiem | |
http://Family/KowalskiJan | |
http://Family/KowalskiKrystyna | |
http://Family/KowalskiKasia ma rodzenstwo | |
http://Family/KowalskiJasiu | |
| |
=====SPARQL===== | |
Zapytania buduje się podobnie jak w języku zapytań SQL z tą różnicą, że podaje się całą trójkę. | |
Zapytanie SPARQL dla podanego powyżej przykładu może wyglądać tak: | |
| |
<code> | |
SELECT ?x ?w ?q | |
WHERE {?x ?w ?q} | |
</code> | |
Oznacza to podgląd całej wiedzy, która jest zawarta w modelu. | |
| |
Na takie zapytanie uzyskałem taką odpowiedź: | |
<code> | |
Jasiu dziecko Jan | |
Jasiu dziecko Krystyna | |
Krystyna malzonek Jan | |
Jan malzonek Krystyna | |
Jan ojciec Jasiu | |
Jan ojciec Kasia | |
Kasia dziecko Jan | |
Kasia dziecko Krystyna | |
Kasia siostra Jasiu | |
</code> | |
| |
Jak widać są to wszytkie informacje, które zawarłem w modelu. (Dla czytelności zostały usunięte URI, aby odpowiedź nie wygdlądała np. tak http://Family/KowalskiJan) | |
| |
Znając zasadę tworzenia zapytania, można otrzymać odpowiedź na "skomplikowane" zapytanie. | |
| |
| |
=====Termostat - RDF===== | |
| |
Aby stworzyć plik RDF reprezentujący model termostatu, najpierw utworzyłem model termostatu wg. reguł. | |
| |
Aby plik taki został wygenerowany ścieżki do resoure'ów oraz propertis'ów muszą być unikalne stąd musiałem stworzyć dwa Stringi, którymi poprzedzałem każdy z nich. | |
<code> | |
static final String resourceUri = "http://Resource/my/"; | |
static final String propertyUri = "http://Property/my/"; | |
</code> | |
| |
| |
Tak zapisałem model w Javie: | |
<code> | |
Model model = ModelFactory.createDefaultModel(); | |
//1 | |
Resource day = model.createResource(resourceUri+ "Day"); | |
Resource workday = model.createResource(resourceUri+"Workday"); | |
Property monday = model.createProperty(propertyUri+"monday"); | |
Property tuesday = model.createProperty(propertyUri+"tuesday"); | |
Property wednesday = model.createProperty(propertyUri+"wednesday"); | |
Property thursday = model.createProperty(propertyUri+"thursday"); | |
Property friday = model.createProperty(propertyUri+"friday"); | |
day.addProperty(monday, workday); | |
day.addProperty(tuesday, workday); | |
day.addProperty(wednesday, workday); | |
day.addProperty(thursday, workday); | |
day.addProperty(friday, workday); | |
| |
//2 | |
Resource weekend = model.createResource(resourceUri + "Weekend"); | |
Property saturday = model.createProperty(propertyUri + "saturday"); | |
Property sunday = model.createProperty(propertyUri+ "sunday"); | |
day.addProperty(saturday, weekend); | |
day.addProperty(sunday, weekend); | |
| |
//3 4 5 | |
Resource time = model.createResource(resourceUri + "time"); | |
Resource hour = model.createResource(resourceUri + "hour"); | |
Property sevenAm = model.createProperty(propertyUri + "seven-before9am"); | |
Property sixPm = model.createProperty(propertyUri + "six-after5pm"); | |
Property noon = model.createProperty(propertyUri + "noon"); | |
time.addProperty(sevenAm, hour); | |
time.addProperty(sixPm, hour); | |
time.addProperty(noon, hour); | |
| |
//6 | |
//-- | |
| |
//7 | |
Resource month = model.createResource(resourceUri+ "month"); | |
Resource summer = model.createResource(resourceUri+"summer"); | |
Property january = model.createProperty(propertyUri+"january"); | |
Property february = model.createProperty(propertyUri+"february"); | |
Property december = model.createProperty(propertyUri+"december"); | |
month.addProperty(january, summer); | |
month.addProperty(february, summer); | |
month.addProperty(december, summer); | |
| |
//8 | |
Resource autumn = model.createResource(resourceUri+"autumn"); | |
Property march = model.createProperty(propertyUri+"march"); | |
Property april = model.createProperty(propertyUri+"april"); | |
Property may = model.createProperty(propertyUri+"may"); | |
month.addProperty(march, autumn); | |
month.addProperty(april, autumn); | |
month.addProperty(may, autumn); | |
| |
//9 | |
Resource winter = model.createResource(resourceUri+"winter"); | |
Property june = model.createProperty(propertyUri+"june"); | |
Property july = model.createProperty(propertyUri+"july"); | |
Property august = model.createProperty(propertyUri+"august"); | |
month.addProperty(june, winter); | |
month.addProperty(july, winter); | |
month.addProperty(august, winter); | |
| |
//10 | |
Resource spring = model.createResource(resourceUri+"spring"); | |
Property september = model.createProperty(propertyUri+"september"); | |
Property october = model.createProperty(propertyUri+"october"); | |
Property november = model.createProperty(propertyUri+"november"); | |
month.addProperty(september, spring); | |
month.addProperty(october, spring); | |
month.addProperty(november, spring); | |
| |
//11 12 13 | |
Resource operation = model.createResource(resourceUri + "operation"); | |
Property businessHours = model.createProperty(propertyUri + "businessHours"); | |
Property notBusinessHours = model.createProperty(propertyUri + "notBusinessHours"); | |
operation.addProperty(businessHours, hour); | |
operation.addProperty(notBusinessHours, hour); | |
| |
//14 15 16 17 18 | |
Resource thermostat = model.createResource(resourceUri + "thermostat"); | |
Resource setting = model.createResource(resourceUri + "setting"); | |
Property degrees20 = model.createProperty(propertyUri + "20degrees"); | |
Property degrees15 = model.createProperty(propertyUri + "15degrees"); | |
Property degrees24 = model.createProperty(propertyUri + "24degrees"); | |
Property degrees27 = model.createProperty(propertyUri + "27degrees"); | |
Property degrees16 = model.createProperty(propertyUri + "16degrees"); | |
Property degrees18 = model.createProperty(propertyUri + "18degrees"); | |
Property degrees14 = model.createProperty(propertyUri + "14degrees"); | |
thermostat.addProperty(degrees20, setting); | |
thermostat.addProperty(degrees15, setting); | |
thermostat.addProperty(degrees24, setting); | |
thermostat.addProperty(degrees27, setting); | |
thermostat.addProperty(degrees16, setting); | |
thermostat.addProperty(degrees18, setting); | |
thermostat.addProperty(degrees14, setting); | |
</code> | |
| |
Na tej podstawie wygenerowałem plik RDF z zapisanym modelem: | |
<code xml> | |
<rdf:RDF | |
xmlns:j.0="http://Property/my/18" | |
xmlns:j.1="http://Property/my/" | |
xmlns:j.2="http://Property/my/15" | |
xmlns:j.3="http://Property/my/24" | |
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |
xmlns:j.4="http://Property/my/27" | |
xmlns:j.5="http://Property/my/16" | |
xmlns:j.7="http://Property/my/14" | |
xmlns:j.6="http://Property/my/20" > | |
<rdf:Description rdf:about="http://Resource/my/time"> | |
<j.1:noon rdf:resource="http://Resource/my/hour"/> | |
<j.1:six-after5pm rdf:resource="http://Resource/my/hour"/> | |
<j.1:seven-before9am rdf:resource="http://Resource/my/hour"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://Resource/my/month"> | |
<j.1:january rdf:resource="http://Resource/my/summer"/> | |
<j.1:february rdf:resource="http://Resource/my/summer"/> | |
<j.1:september rdf:resource="http://Resource/my/spring"/> | |
<j.1:october rdf:resource="http://Resource/my/spring"/> | |
<j.1:july rdf:resource="http://Resource/my/winter"/> | |
<j.1:november rdf:resource="http://Resource/my/spring"/> | |
<j.1:may rdf:resource="http://Resource/my/autumn"/> | |
<j.1:april rdf:resource="http://Resource/my/autumn"/> | |
<j.1:august rdf:resource="http://Resource/my/winter"/> | |
<j.1:june rdf:resource="http://Resource/my/winter"/> | |
<j.1:december rdf:resource="http://Resource/my/summer"/> | |
<j.1:march rdf:resource="http://Resource/my/autumn"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://Resource/my/Day"> | |
<j.1:sunday rdf:resource="http://Resource/my/Weekend"/> | |
<j.1:saturday rdf:resource="http://Resource/my/Weekend"/> | |
<j.1:friday rdf:resource="http://Resource/my/Workday"/> | |
<j.1:thursday rdf:resource="http://Resource/my/Workday"/> | |
<j.1:wednesday rdf:resource="http://Resource/my/Workday"/> | |
<j.1:tuesday rdf:resource="http://Resource/my/Workday"/> | |
<j.1:monday rdf:resource="http://Resource/my/Workday"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://Resource/my/operation"> | |
<j.1:notBusinessHours rdf:resource="http://Resource/my/hour"/> | |
<j.1:businessHours rdf:resource="http://Resource/my/hour"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://Resource/my/thermostat"> | |
<j.7:degrees rdf:resource="http://Resource/my/setting"/> | |
<j.0:degrees rdf:resource="http://Resource/my/setting"/> | |
<j.5:degrees rdf:resource="http://Resource/my/setting"/> | |
<j.4:degrees rdf:resource="http://Resource/my/setting"/> | |
<j.3:degrees rdf:resource="http://Resource/my/setting"/> | |
<j.2:degrees rdf:resource="http://Resource/my/setting"/> | |
<j.6:degrees rdf:resource="http://Resource/my/setting"/> | |
</rdf:Description> | |
</rdf:RDF> | |
| |
</code> | |
| |
| |
| |
| |
| |
| |
===== Przykład programu wnioskującego (Java+Jena) ===== | |
| |
W tej części przedstawię program, który na podstawie danych wejściowych nastawia temperaturę. Program został napisany w oparciu o reguły dla [[hekate:hekate_case_thermostat|termostatu]]. | |
| |
Jako dane wejściowe od użytkownika pobierane są następujące informacje: | |
* miesiąc | |
* dzień | |
* godzina | |
| |
W przyszłości dane te będą mogły być pobierane automatycznie na podstawie aktualnej daty w systemie. Dzięki tak pobieranej informacji będzie możliwe sterowanie temperaturą "prawie" w czasie rzeczywistym. Ze względu na przeprowadzane testy, dane na tym etapie są wpisane w kodzie programu. | |
| |
===Opis programu=== | |
| |
**Założenia:** | |
| |
Program na podstawie pobieranych danych (miesiąc, dzień, godzina) potrafi poprzez zapisane reguły oraz system wnioskowania ustalić temperaturę termostatu. | |
| |
**Implementacja:** | |
* W pierwszej kolejności wpisywane są dane przez użytkownika | |
<code java> | |
//data to run rules | |
String day = "monday"; | |
String hour = "h11"; | |
String month = "july"; | |
</code> | |
| |
* Następnie tworzony jest model (na którym będziemy przeprowadzać wnioskowanie). Ponieważ musimy uwzględnić podane wcześniej informacje, dodajemy je (i tylko je) do modelu. | |
<code java> | |
//creating new model | |
Model model = ModelFactory.createDefaultModel(); | |
// creating day | |
Resource dayResource = model.createResource(baseURI + "day"); | |
Property dayProperty = model.createProperty(baseURI + day); | |
dayResource.addProperty(dayProperty, dayResource); | |
// creating time | |
Resource hourResource = model.createResource(baseURI + "hour"); | |
Property hourProperty = model.createProperty(baseURI + hour); | |
hourResource.addProperty(hourProperty, hourResource); | |
// creating month | |
Resource monthResource = model.createResource(baseURI + "month"); | |
Property monthProperty = model.createProperty(baseURI + month); | |
monthResource.addProperty(monthProperty, monthResource); | |
</code> | |
| |
* Gdy mamy utworzony model musimy zapisać reguły. Użyłem w projekcie ponad 50 reguł, aby móc opisać dokładnie zasadę działania podanego powyżej termostatu. W tym miejscu zapiszę zaledwie ważniejsze reguły. Wszystkie reguły można zobaczyć w kodzie programu. | |
<code java> | |
//day: | |
String ruleSrc = " [ruleD1: (?a http://uri#monday ?b) -> (?a http://uri#monday http://uri#workday)]" | |
+ " [ruleD7: (?a http://uri#sunday ?b) -> (?a http://uri#sunday http://uri#weekend)]" | |
| |
// time: between 9 am and 5 pm | |
+ " [ruleT10: (?x http://uri#h10 ?h) -> (?x http://uri#h10 http://uri#beetwen)]" | |
| |
// time: before 9 am and after 5 pm | |
+ " [ruleT17: (?x http://uri#h17 ?h) -> (?x http://uri#h17 http://uri#out)]" | |
| |
// getting day and hour | |
+ " [ruleGDH1: (?gdh1gd http://uri#" + day + " http://uri#workday),(?gdh1gh http://uri#" + hour + " http://uri#beetwen) -> (http://uri#operation http://uri#mode http://uri#during)]" | |
| |
//months: | |
+ " [ruleS1: (?s1s1 http://uri#january ?s1s2) -> (?s1s1 http://uri#january http://uri#summer)]" | |
+ " [ruleS3: (?s3s1 http://uri#march ?s3s2) -> (?s3s1 http://uri#march http://uri#autumn)]" | |
| |
//getting month and operation | |
+ " [ruleGMO1: (?gmo1gm http://uri#" + month + " http://uri#spring),(?gmo1go http://uri#mode http://uri#during) -> (http://uri#temperature http://uri#set http://uri#20)]" | |
+ " [ruleGMO2: (?gmo2gm http://uri#" + month + " http://uri#spring),(?gmo2go http://uri#mode http://uri#notDuring) -> (http://uri#temperature http://uri#set http://uri#15)]" | |
</code> | |
| |
* Po utworzeniu modelu oraz reguł musimy uruchomić mechanizm wnioskujący. W tym celu należy wpisać | |
<code java> | |
List rules = Rule.parseRules(ruleSrc); | |
Reasoner reasoner = new GenericRuleReasoner(rules); | |
InfModel inf = ModelFactory.createInfModel(reasoner, model); | |
inf.getDeductionsModel().write(System.out); | |
</code> | |
| |
* W celu pokazania powstałego modelu poprzez etap wnioskowania i zapisania go w postaci "trójek" należy wpisać | |
<code java> | |
Iterator list = inf.listStatements(null, null, (RDFNode) null); | |
while (list.hasNext()) { | |
System.out.println(" - " + list.next()); | |
} | |
</code> | |
| |
**Źródła:** | |
| |
Z braku możliwości zamieszczenia pliku z rozszerzeniem .java zamieszczam plik .txt (proszę o ściągnięcie pliku na dysk i zminie rozszerzenia) | |
{{:pl:miw:miw08_ruleruntimej:jenarulesengine.txt|JenaRulesEngine.txt}} | |
| |
W celu uruchomienia aplikacji należy dodać biblioteki frameworka Jena. Źródła można pobrać ze strony [[http://sourceforge.net/project/downloading.php?groupname=jena&filename=Jena-2.5.5.zip&use_mirror=switch | link]] | |
Osobiście korzystałem z wersji frameworka //Jena-2.5.5// | |
| |
| |
**Przykład działania:** | |
* Uruchomienie nr 1 | |
<code> | |
>>> Start Jena Rules <<< | |
Data: | |
day: monday hour: h11 month: july | |
| |
| |
| |
Created model (RDF): | |
<rdf:RDF | |
xmlns:j.0="http://uri#" | |
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" > | |
<rdf:Description rdf:about="http://uri#day"> | |
<j.0:monday rdf:resource="http://uri#day"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#month"> | |
<j.0:july rdf:resource="http://uri#month"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#hour"> | |
<j.0:h11 rdf:resource="http://uri#hour"/> | |
</rdf:Description> | |
</rdf:RDF> | |
| |
| |
| |
Deduction model (RDF): | |
<rdf:RDF | |
xmlns:j.0="http://uri#" | |
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" > | |
<rdf:Description rdf:about="http://uri#day"> | |
<j.0:monday rdf:resource="http://uri#workday"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#month"> | |
<j.0:july rdf:resource="http://uri#winter"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#hour"> | |
<j.0:h11 rdf:resource="http://uri#beetwen"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#temperature"> | |
<j.0:set rdf:resource="http://uri#18"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#operation"> | |
<j.0:mode rdf:resource="http://uri#during"/> | |
</rdf:Description> | |
</rdf:RDF> | |
| |
| |
| |
Deduction model presented in N3: | |
- [http://uri#temperature, http://uri#set, http://uri#18] | |
- [http://uri#hour, http://uri#h11, http://uri#beetwen] | |
- [http://uri#operation, http://uri#mode, http://uri#during] | |
- [http://uri#day, http://uri#monday, http://uri#workday] | |
- [http://uri#month, http://uri#july, http://uri#winter] | |
- [http://uri#month, http://uri#july, http://uri#month] | |
- [http://uri#day, http://uri#monday, http://uri#day] | |
- [http://uri#hour, http://uri#h11, http://uri#hour] | |
</code> | |
| |
| |
* Uruchomienie nr 2 | |
<code> | |
| |
>>> Start Jena Rules <<< | |
Data: | |
day: sunday hour: h15 month: october | |
| |
| |
| |
Created model (RDF): | |
<rdf:RDF | |
xmlns:j.0="http://uri#" | |
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" > | |
<rdf:Description rdf:about="http://uri#day"> | |
<j.0:sunday rdf:resource="http://uri#day"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#month"> | |
<j.0:october rdf:resource="http://uri#month"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#hour"> | |
<j.0:h15 rdf:resource="http://uri#hour"/> | |
</rdf:Description> | |
</rdf:RDF> | |
| |
| |
| |
Deduction model (RDF): | |
<rdf:RDF | |
xmlns:j.0="http://uri#" | |
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" > | |
<rdf:Description rdf:about="http://uri#day"> | |
<j.0:sunday rdf:resource="http://uri#weekend"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#month"> | |
<j.0:october rdf:resource="http://uri#spring"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#hour"> | |
<j.0:h15 rdf:resource="http://uri#beetwen"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#temperature"> | |
<j.0:set rdf:resource="http://uri#15"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#operation"> | |
<j.0:mode rdf:resource="http://uri#notDuring"/> | |
</rdf:Description> | |
</rdf:RDF> | |
| |
| |
| |
Deduction model presented in N3: | |
- [http://uri#temperature, http://uri#set, http://uri#15] | |
- [http://uri#hour, http://uri#h15, http://uri#beetwen] | |
- [http://uri#operation, http://uri#mode, http://uri#notDuring] | |
- [http://uri#day, http://uri#sunday, http://uri#weekend] | |
- [http://uri#month, http://uri#october, http://uri#spring] | |
- [http://uri#month, http://uri#october, http://uri#month] | |
- [http://uri#day, http://uri#sunday, http://uri#day] | |
- [http://uri#hour, http://uri#h15, http://uri#hour] | |
</code> | |
| |
| |
* Uruchomienie nr 3 | |
<code> | |
>>> Start Jena Rules <<< | |
Data: | |
day: wednesday hour: h23 month: february | |
| |
| |
| |
Created model (RDF): | |
<rdf:RDF | |
xmlns:j.0="http://uri#" | |
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" > | |
<rdf:Description rdf:about="http://uri#day"> | |
<j.0:wednesday rdf:resource="http://uri#day"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#month"> | |
<j.0:february rdf:resource="http://uri#month"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#hour"> | |
<j.0:h23 rdf:resource="http://uri#hour"/> | |
</rdf:Description> | |
</rdf:RDF> | |
| |
| |
| |
Deduction model (RDF): | |
<rdf:RDF | |
xmlns:j.0="http://uri#" | |
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" > | |
<rdf:Description rdf:about="http://uri#day"> | |
<j.0:wednesday rdf:resource="http://uri#workday"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#month"> | |
<j.0:february rdf:resource="http://uri#summer"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#hour"> | |
<j.0:h23 rdf:resource="http://uri#out"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#temperature"> | |
<j.0:set rdf:resource="http://uri#27"/> | |
</rdf:Description> | |
<rdf:Description rdf:about="http://uri#operation"> | |
<j.0:mode rdf:resource="http://uri#notDuring"/> | |
</rdf:Description> | |
</rdf:RDF> | |
| |
| |
| |
Deduction model presented in N3: | |
- [http://uri#temperature, http://uri#set, http://uri#27] | |
- [http://uri#hour, http://uri#h23, http://uri#out] | |
- [http://uri#operation, http://uri#mode, http://uri#notDuring] | |
- [http://uri#day, http://uri#wednesday, http://uri#workday] | |
- [http://uri#month, http://uri#february, http://uri#summer] | |
- [http://uri#month, http://uri#february, http://uri#month] | |
- [http://uri#day, http://uri#wednesday, http://uri#day] | |
- [http://uri#hour, http://uri#h23, http://uri#hour] | |
| |
</code> | |
| |
| |
| |
===== Translacja r2ml do reguł Jeny ===== | |
| |
Miałem przeprowadzić translację therm w r2ml do reguł Jeny. | |
| |
W tym celu skorzystałem ze strony [[http://oxygen.informatik.tu-cottbus.de/rewerse-i1/?q=node/15|strona]] a wykorzystałem do tego thermy ze strony [[pl:miw:miw08_xtt_r2ml:thermostat|r2ml]]. | |
| |
Niestety po przekopiowaniu całego tekstu do wspomnianego translatora otrzymałem bład postaci: | |
<code> | |
[ERR0011] org.xml.sax.SAXParseException: The markup in the document following the root element must be well-formed. | |
</code> | |
| |
Postanowiłem więc spróbować dla każdej z reguł w r2ml zastosować translator. Dla pierwszej reguły | |
<code xml> | |
<r2ml:RuleBase xmlns:r2ml="http://www.rewerse.net/I1/2006/R2ML" | |
xmlns:r2mlv="http://www.rewerse.net/I1/2006/R2ML/R2MLV" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:xs="http://www.w3.org/2001/XMLSchema" | |
xmlns:userv="http://www.businessrulesforum.com/2005/userv#" | |
xmlns:swrlb="http://www.w3.org/2003/11/swrlb" | |
xsi:schemaLocation="http://oxygen.informatik.tu-cottbus.de/R2ML/0.5/R2ML.xsd"> | |
| |
<r2ml:ProductionRuleSet> | |
<r2ml:ProductionRule r2ml:ruleID="Thermostat01" | |
| |
xmlns:ext="http://borg.ia.agh.edu.pl/~tpalosz/jboss/org.drools.examples.Date"> | |
<r2ml:Documentation> | |
<r2ml:RuleText r2ml:textFormat="plain"> | |
if the day is Monday | |
or the day is Tuesday or the day is Wednesday | |
or the day is Thursday or the day is Friday | |
then today is a workday | |
</r2ml:RuleText> | |
</r2ml:Documentation> | |
<r2ml:conditions> | |
| |
<r2ml:qf.Disjunction> | |
<r2ml:DatatypePredicateAtom r2ml:datatypePredicateID="swrlb:equal"> | |
<r2ml:dataArguments> | |
<r2ml:AttributeFunctionTerm r2ml:attributeID="day"> | |
<r2ml:contextArgument> | |
<r2ml:ObjectVariable r2ml:name="date" r2ml:classID="Date"/> | |
</r2ml:contextArgument> | |
</r2ml:AttributeFunctionTerm> | |
<r2ml:TypedLiteral r2ml:lexicalValue="Monday" r2ml:datatypeID="xs:string"/> | |
</r2ml:dataArguments> | |
</r2ml:DatatypePredicateAtom> | |
| |
<r2ml:DatatypePredicateAtom r2ml:datatypePredicateID="swrlb:equal"> | |
<r2ml:dataArguments> | |
<r2ml:AttributeFunctionTerm r2ml:attributeID="day"> | |
<r2ml:contextArgument> | |
<r2ml:ObjectVariable r2ml:name="date" r2ml:classID="Date"/> | |
</r2ml:contextArgument> | |
</r2ml:AttributeFunctionTerm> | |
<r2ml:TypedLiteral r2ml:lexicalValue="Tuesday" r2ml:datatypeID="xs:string"/> | |
</r2ml:dataArguments> | |
</r2ml:DatatypePredicateAtom> | |
| |
<r2ml:DatatypePredicateAtom r2ml:datatypePredicateID="swrlb:equal"> | |
<r2ml:dataArguments> | |
<r2ml:AttributeFunctionTerm r2ml:attributeID="day"> | |
<r2ml:contextArgument> | |
<r2ml:ObjectVariable r2ml:name="date" r2ml:classID="Date"/> | |
</r2ml:contextArgument> | |
</r2ml:AttributeFunctionTerm> | |
<r2ml:TypedLiteral r2ml:lexicalValue="Wednesday" r2ml:datatypeID="xs:string"/> | |
</r2ml:dataArguments> | |
</r2ml:DatatypePredicateAtom> | |
| |
<r2ml:DatatypePredicateAtom r2ml:datatypePredicateID="swrlb:equal"> | |
<r2ml:dataArguments> | |
<r2ml:AttributeFunctionTerm r2ml:attributeID="day"> | |
<r2ml:contextArgument> | |
<r2ml:ObjectVariable r2ml:name="date" r2ml:classID="Date"/> | |
</r2ml:contextArgument> | |
</r2ml:AttributeFunctionTerm> | |
<r2ml:TypedLiteral r2ml:lexicalValue="Thursday" r2ml:datatypeID="xs:string"/> | |
</r2ml:dataArguments> | |
</r2ml:DatatypePredicateAtom> | |
| |
<r2ml:DatatypePredicateAtom r2ml:datatypePredicateID="swrlb:equal"> | |
<r2ml:dataArguments> | |
<r2ml:AttributeFunctionTerm r2ml:attributeID="day"> | |
<r2ml:contextArgument> | |
<r2ml:ObjectVariable r2ml:name="date" r2ml:classID="Date"/> | |
</r2ml:contextArgument> | |
</r2ml:AttributeFunctionTerm> | |
<r2ml:TypedLiteral r2ml:lexicalValue="Friday" r2ml:datatypeID="xs:string"/> | |
</r2ml:dataArguments> | |
</r2ml:DatatypePredicateAtom> | |
| |
</r2ml:qf.Disjunction> | |
</r2ml:conditions> | |
| |
<r2ml:producedAction> | |
<r2ml:AssignActionExpression r2ml:propertyID="today"> | |
<r2ml:contextArgument> | |
<r2ml:ObjectVariable r2ml:classID="Date" r2ml:name="date" /> | |
</r2ml:contextArgument> | |
<r2ml:value> | |
<r2ml:TypedLiteral r2ml:lexicalValue="workday" r2ml:datatypeID="xs:string"/> | |
</r2ml:value> | |
</r2ml:AssignActionExpression> | |
</r2ml:producedAction> | |
</r2ml:ProductionRule> | |
</r2ml:ProductionRuleSet> | |
| |
</r2ml:RuleBase> | |
</code> | |
| |
Otrzymałem coś takiego | |
<code> | |
r2ml:qf.DisjunctionDisjunction is not supported by Jena Rules ! | |
</code> | |
| |
Taki sam komunikat otrzymałem dla drugiej reguły. | |
| |
| |
Dla trzeciej reguły tłumaczenie się powiodło, jednak wynik tego tłumaczenia jest daleki od spodziewanego. | |
| |
Wygląda on tak | |
<code> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<!--// Jena output of R2ML Derivation Rules and Production Rules--> | |
<jena> | |
| |
| |
<ns xmlns:r2mlv="http://www.rewerse.net/I1/2006/R2ML/R2MLV" | |
xmlns:userv="http://www.businessrulesforum.com/2005/userv#" | |
xmlns:swrlb="http://www.w3.org/2003/11/swrlb" | |
xmlns:xs="http://www.w3.org/2001/XMLSchema" | |
xmlns:r2ml="http://www.rewerse.net/I1/2006/R2ML" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:ext="http://borg.ia.agh.edu.pl/~tpalosz/jboss/org.drools.examples.Date"/> | |
| |
| |
| |
| |
| |
[ () ge( | |
time( | |
?date | |
)) () -> ] | |
| |
| |
| |
| |
| |
| |
</jena> | |
</code> | |
| |
Skontaktowałem się więc z Tomkiem w celu uzyskania jakiejś pomocy. Ustaliliśmy, zresztą zgodnie z komunikatem, że prawdopodobnie translator nie obsługuje Disjunction, które Tomek zastosował. | |
| |
Dla trzeciego tłumaczenia, te które się udało próbowaliśmy więc uzyskać "lepszy" rezultat, jednak zarówno przy zastosowaniu słownika oraz bez niego rezultaty pozostają takie same. Podejrzewamy więc, że stworzone thermy w r2ml'u odbiegają od standardu w jakim działa wspomniany translator. Możliwe jest, że reguły zapisane w r2ml są poprawnie, jednak translator nie potrafi ich przekształcić na właściwy kod Jeny. | |
| |
| |
| |
===== Translacja xttml do reguł Jeny ===== | |
| |
Po zapoznaniu się z formą zapisu reguł w formacie [[hekate:hekate_markup_language#xttml|XTTML]] doszedłem do następujących wniosków: | |
| |
* Mam przedstawić podaną regułę z XTTML w Jenie | |
<code> | |
rule_1: if att_0 in <1,5>u{8} then att_1 = att_0 + 1 and att_1 = 5 + sin(att_0) | |
</code> | |
| |
Mogę w tym celu stworzyć nowy model zgodnie z trójką zasób1<-własność->zasób2 (zasób1,własność,zasob2) oraz na tak stworzonym modelu skorzystać z reguł, które są opisane również jako trójka (a,b,c)->(d,e,f) (jeśli zachodzi taka trójka (a,b,c) to wykonaj na modelu (e,f,g)) Dodatkowo jest możliwość w zapisie reguł określenia ilości czynników jakie muszą zajść, żeby wykonać operację na modelu. | |
* Reguły w Jenie powinny być zapisane "nie matematycznie" tzn Jena posiada jedynie kilka "prymitywnych funkcji wbudowanych" natomiast bardziej skomplikowane operacje (takie jak sinus nie są uwzględniane). Na [[http://jena.sourceforge.net/inference/|stronie]] można zobaczyć, jakie funkcje są wbudowane. Do tego konkretnego przykładu pomocne będą | |
<code> | |
lessThan(?x, ?y) | |
greaterThan(?x, ?y) | |
le(?x, ?y), ge(?x, ?y) | |
| |
Test if x is <, >, <= or >= y. Only passes if both x and y are numbers or time instants (can be integer or floating point or XSDDateTime). | |
| |
| |
sum(?a, ?b, ?c) | |
addOne(?a, ?c) | |
difference(?a, ?b, ?c) | |
min(?a, ?b, ?c) | |
max(?a, ?b, ?c) | |
product(?a, ?b, ?c) | |
quotient(?a, ?b, ?c) | |
| |
Sets c to be (a+b), (a+1) (a-b), min(a,b), max(a,b), (a*b), (a/b). Note that these do not run backwards, if in sum a and c are bound and b is unbound then the test will fail rather than bind b to (c-a). This could be fixed. | |
</code> | |
| |
* Można więc zapisać, że na modelu ma się coś wykonać (operacja po słowie then) gdy **lessThan(att_0, 5)** oraz **greaterThan(att_0, 1)** [ lessThan(att_0, 5),greaterThan(att_0, 1)->.....] | |
| |
* Operacje na modelu //att_1 = att_0 + 1// and //att_1 = 5 + sin(att_0)// zapiszemy po -> jako dwa osobne działania. Pierwsze z nich //att_1 = att_0 + 1// możemy zapisać ponownie wykorzystując funkcje Jeny **sum(att_0, 1, att_1)**. Drugie działanie //att_1 = 5 + sin(att_0)// już tak prosto nie da się wykonać ponieważ brak jest odpowiedniej funkcji do obliczania sinusa. Jednak zapytanie powinno wyglądać podobnie do tego **sum(5, sin(att_0), att_1)** | |
| |
* Można więc ostatecznie zapisać podaną regułę jako String w postaci | |
<code> | |
String str = "rule1: lessThan(att_0, 5),greaterThan(att_0, 1)-> sum(att_0, 1, att_1),sum(5, sin(att_0), att_1)"; | |
</code> | |
| |
| |
| |
| |
| |
====== Sprawozdanie ====== | |
| |
| |
| |
| |
| |
====== Materiały ====== | |
| |
===== Basic ===== | |
[[http://jena.sourceforge.net/documentation.html| Dokumentacja]] - Dokumentacja do frameworka Jena | |
| |
[[http://www.ibm.com/developerworks/xml/library/j-jena/index.html| IBM]] - Wprowadzenie do Jena wykonane przez IBMa | |
| |
[[http://www.oreilly.com/catalog/pracrdf/chapter/ch08.pdf|RDF]] - wszytstko o RDF - PDF wykonany przez wydawnictwo O'Reilly | |
| |
[[http://pl.wikipedia.org/wiki/System_ekspertowy| System ekspertowy]] - Wikipedia | |
| |
[[http://java.sun.com/developer/technicalArticles/J2SE/JavaRule.html| Java Rule Engine API]] - Getting Started With the Java Rule Engine API (JSR 94): Toward Rule-Based Applications (Sun) | |
| |
[[http://javaboutique.internet.com/tutorials/rules_engine/| Java Rules Engine API (JSR 94)]] - Java Rules Engine API (JSR 94) in javaboutique | |
| |
===== Jena + SPARQL ===== | |
| |
[[http://www.ibm.com/developerworks/xml/library/j-sparql/| RDF in SPARQL]] - Search RDF data with SPARQL | |
| |
[[http://jena.sourceforge.net/ARQ/| AQR]] - Query engine for Jena | |
| |
[[http://2006.ruleml.org/slides/tutorial-holger.pdf| Rules Example]] - Rules example using Jena + Pellet (pdf file!) | |
| |
===== Jena rules ===== | |
| |
[[http://jena.sourceforge.net/inference/index.html#rules| Jena rules page]] - Jena rules documentation | |
| |
[[http://www.ldodds.com/blog/archives/000219.html| Example]] - Rules in Jena example | |
| |
[[http://jena.hpl.hp.com/juc2006/proceedings/reynolds/rules-slides.ppt| Examlpe2]] - HP Example of using Jena Rules (ppt file!) | |
| |
===== Prolog ===== | |
| |
[[http://www.swi-prolog.org/packages/rdf2pl.html| Prolog parser]] - SWI-Prolog RDF parser | |
| |
[[http://www.swi-prolog.org/packages/semweb.html| Semantic Web Library]] - SWI-Prolog Semantic Web Library | |
| |
[[http://www.xml.com/pub/a/2001/07/25/prologrdf.html| RDF in Prolog]] - RDF Applications with Prolog | |