Both sides previous revision
Poprzednia wersja
Nowa wersja
|
Poprzednia wersja
|
pl:miw:miw08_ruleruntimej:przebieg_pracy [2008/05/30 08:47] miw |
pl:miw:miw08_ruleruntimej:przebieg_pracy [2019/06/27 15:50] (aktualna) |
===== 080527 ===== | ===== 080527 ===== |
* beta sprawozd | * beta sprawozd |
| |
| |
| ====== 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> |
| |
| |
| * Uważam, że uzyskanie takich informacji z wskazanych wcześniej reguł w formacie [[hekate:hekate_markup_language#xttml|XTTML]] będzie bardzo trudnym zadaniem. |
| Jednak wydaje się, że dla reguł "niematematycznych" w formacie XTTML możliwe jest zbudowanie dość prostego parsera, który wyciągnie odpowiednie dane z XTTML i przekaże do metody napisanej w języku Java, która to utworzy reguły dla Jeny. |
| Ponieważ reguły zapisywane są jako jeden String, można stworzyć metodę, która będzie tworzyć jedynie jedną trójkę (a,b,c), natomiast sam algorytm wskaże w które miejsce umieścić znak -> i wpisać operacje na modelu. Przez wielokrotne wywołanie wcześniejszej metody powinniśmy uzyskać podobny efekt. Jednak tak stworzone reguły powinny mieć jak najprostszą postać czyli (a1,a2,a3),(b1,b2,b3)->(c1,c2,c3) |
| |
| |
| |
| |