Rok akademicki 2013/2014 Politechnika Warszawska Wydział Elektroniki i Technik Informacyjnych Instytut Informatyki PRACA DYPLOMOWA MAGISTERSKA Wojciech Marcinkowski Implementacja logiki obiektów z wykorzystaniem Prover9 oraz SWI-Prologu Opiekun pracy Prof. dr hab. inż. Jan Mulawka Ocena: ..................................................... ................................................................. Podpis Przewodniczącego Komisji Egzaminu Dyplomowego Kierunek: Informatyka Specjalność: Informatycznych Inżynieria Systemów Data urodzenia: 1987.05.23 Data rozpoczęcia studiów: 2012.10.01 Życiorys Urodziłem się 23 maja 1987 r. w Ciechanowie. W latach 1994-2000 uczęszczałem do Społecznej Szkoły Podstawowej w Ciechanowie. W okresie 2000-2003 uczęszczałem do Publicznego Gimnazjum nr 1 w Ciechanowie. W latach 2003-2007 kształciłem się w I Liceum Ogólnokształcącym im. Zygmunta Krasińskiego w Ciechanowie w klasie o profilu matematyczno-informatycznym. W roku 2007 rozpocząłem studia na Wydziale Elektroniki i Technik Informacyjnych Politechniki Warszawskiej. Ukończyłem tytułem inżyniera w roku 2012. W ramach je z kontynuacji rozpocząłem studia magisterskie na tym samym wydziale w październiku 2012 roku. ........................................................ Podpis studenta EGZAMIN DYPLOMOWY Złożył egzamin dyplomowy w dniu ..................................................................................2014 r z wynikiem ................................................................................................................................... Ogólny wynik studiów: ................................................................................................................ Dodatkowe wnioski i uwagi Komisji: .......................................................................................... ....................................................................................................................................................... ....................................................................................................................................................... STRESZCZENIE Praca stanowi próbę realizacji logiki obiektów kategorialnych i pojęć w technologii Prover9 i SWI-Prolog. Porusza ona zagadnienia na styku sztucznej inteligencji, ontologii i logiki. Logika obiektów jest wariantem logicznego systemu formalnego. Technologie Prover9 i SWI-Prolog dostarczają z kolei języka reprezentacji wiedzy oraz związane z nimi maszyny wnioskujące. W ramach pracy opracowano system logiki obiektów oraz stworzono eksperymentalne środowisko testowe, dzięki czemu możliwa jest implementacja tej logiki na komputerze. Przeprowadzone eksperymenty oraz porównanie ukazały własności poszczególnych zagadnień logiki obiektów oraz pokazały różnice pomiędzy implementacjami w różnych środowiskach tego systemu. Słowa kluczowe: logika formalna, logika obiektów kategorialnych, logika pojęć, systemy wnioskujące, Prover9, SWI-Prolog Implementation of the logic of objects using Prover9 and SWI-Prolog Summary The thesis attempts to implement logic of categorical objects and concepts in the Prover9 and SWI-Prolog technology. Issues in the field of artificial intelligence, ontology and logic have been addressed. The logic of objects is a type of a formal logic system. The Prover9 and SWI-Prolog technology consists of a knowledge representation language and an adequate inference engines. System of logic of objects has been implemented and an appropriate testing environment has been developed. Carried out experiments and comparisons showed properties of logic of objects and also verified capabilities of different computer environment implementations. Keywords: formal logic, logic of categorical objects, logic of concepts, inference engines, Prover9, SWI-Prolog Spis treści 1 Wstęp ................................................................................................................ 1 1.1 Rozwój systemów sztucznej inteligencji inspirowany nowymi metodami reprezentacji wiedzy ....................................................................................................... 1 2 3 1.2 Zakres i cel pracy ...................................................................................... 3 1.3 Zawartość merytoryczna pracy ................................................................. 4 Podstawowe pojęcia teoretyczne występujące w użytej logice rozszerzonej... 5 2.1 Logika obiektów kategorialnych ............................................................... 6 2.2 Logika pojęć .............................................................................................. 8 2.3 Automatyczne dowodzenie twierdzeń .................................................... 10 Opis narzędzi programistycznych wykorzystanych w pracy.......................... 13 3.1 Krótki opis technologii Prover9 .............................................................. 13 3.2 Najważniejsze właściwości języka Python ............................................. 16 3.3 Podstawowe informacje o języku Prolog ................................................ 18 3.3.1 Reguły i fakty .................................................................................... 19 3.3.2 Wykonanie programu ........................................................................ 20 3.3.3 Porównanie implementacji Prologu .................................................. 22 4 5 Propozycja implementacji programowej logiki obiektów .............................. 24 4.1 Proponowane rozwiązanie przedstawionego problemu .......................... 25 4.2 Architektura proponowanego rozwiązania.............................................. 26 4.3 Interfejs graficzny aplikacji..................................................................... 27 4.4 Oprogramowanie pośredniczące ............................................................. 30 4.5 Opis struktur danych ............................................................................... 34 4.6 Podsumowanie rozdziału......................................................................... 36 Eksperymentowanie w utworzonym systemie................................................ 37 5.1 Sprawdzanie poprawności oprogramowania........................................... 37 5.2 Eksperymenty w utworzonym narzędziu programistycznym ................. 38 5.2.1 Automatyczne dowodzenie twierdzeń logiki obiektów kategorialnych 44 5.2.2 Automatyczne dowodzenie twierdzeń logiki pojęć........................... 48 5.3 6 Podsumowanie rozdziału......................................................................... 52 Wnioski ........................................................................................................... 53 6.1 Zrealizowanie celów pracy...................................................................... 53 6.2 Perspektywy na modyfikacje i dalszy rozwój opracowanego oprogramowania............................................................................................................ 54 Bibliografia............................................................................................................ 55 1 Wstęp 1.1 Rozwój systemów sztucznej inteligencji inspirowany nowymi metodami reprezentacji wiedzy W ostatnich latach obserwuje się szybki rozwój zastosowań sztucznej inteligencji [1,2] w różnych dziedzinach działalności człowieka. spektakularne zastosowania, głównie dzięki Sztuczna inteligencja osiąga dwóm aspektom. Po pierwsze rozwiązywanie problemów opiera na wiedzy, od dokładności której, zależy opisanie otaczającego nas świata i znalezienia właściwych rozwiązań drogą wnioskowania. Wiąże się to głównie z nowymi możliwościami metod reprezentacji wiedzy[3]. Po drugie sztuczna inteligencja pozwala przełamać barierę złożoności obliczeniowej problemu i znaleźć zadowalające rozwiązanie w rozsądnym czasie. Wiąże się to z kolei ze spektakularnym rozwojem w ostatnim czasie komputerów kwantowych [22], które są stosowane np. do szybkiego łamania kodów ect. W tej nowej technologii komputery kwantowe wykorzystują właściwości bitów kwantowych, czyli kubitów. W przeciwieństwie do tradycyjnych komputerów, w których bity muszą mieć wartość zero lub jeden; kubit może przyjmować wiele wartości jednocześnie. Pozwala to na bardzo szybkie przetwarzanie informacji. Dzięki wykorzystaniu takich zjawisk jak splątanie lub tunelowanie kwantowe, można teoretycznie rozwiązać wybrane problemy w kilka dni, zamiast tysięcy lat, niezbędnych do rozwiązania tych problemów za pomocą tradycyjnych maszyn istniejących[22]! Niektóre komputery kwantowe nie wykorzystują efektu kwantowego splątania, lecz kwantowego wyżarzania. Jest to algorytm prowadzący do wyboru najlepszego 1 rozwiązania z wielu alternatywnych. Znacznie szybciej, niż w klasycznych komputerach, gdzie stosuje się podobny algorytm zwany symulowanym wyżarzaniem. Metoda symulowanego wyżarzania jest rozwinięciem wcześniejszych metod iteracyjnych, które opierały się na ciągłym ulepszaniu istniejącego rozwiązania do momentu, gdy nie udawało się go dalej poprawić. Algorytm taki zatrzymuje się jednak na minimum lokalnym i nie potrafi znaleźć globalnego minimum. W algorytmie symulowanego wyżarzania może wiec wyjść ze znalezionego minimum lokalnego i dalej podążać w kierunku rozwiązania optymalnego. Kwantowe wyżarzanie możliwe jest dzięki efektowi tunelowania kwantowego (a cząstka może przekroczyć barierę potencjału o wysokości większej niż energia cząsteczki), dzięki któremu poszczególne kubity są ze sobą powiązane – „orientują się” jakie procesy zachodzą w pozostałych. W wywiadzie dla Telegraph.co.uk, Anton Zeilinger, uważany za jednego z prekursorów komputerów kwantowych przewiduje, że takie maszyny staną się codziennością już w najbliższej przyszłości[22]. Jak widać z powyższego przeglądu, formalny opis otaczającego nas świata jest ważnym narzędziem stosowanym w metodach reprezentacji wiedzy. Dlatego ważne są logiki formalne, które są podstawą komputerów. Znanych jest wiele różnych systemów logicznych. Systemy te z różną dokładnością modelują otaczającą nas rzeczywistość. Im modelowanie to jest dokładniejsze, tym formalizm logiki staje się coraz bardziej skomplikowany i trudny. Obserwując rozwój komputerów i sztucznej inteligencji proponowana tam logika, sprowadza się w zasadzie do rachunku predykatów pierwszego rzędu [3]. Natomiast logiki bardziej ogólne tak zwane logiki rozszerzone tj. np. logiki epistamiczne, logiki temporalne nie zostały jak dotąd efektywnie wykorzystane w sztucznej inteligencji. Tak więc z punktu widzenia dalszego rozwoju efektywnych metod reprezentacji wiedzy interesujące wydaje się wykorzystanie w informatyce różnych logik rozszerzonych, które wywodzą się z rachunku predykatów i są ich rozwinięciem. W szczególności interesujące może być użycie logiki obiektów. Ogólnie założeniem większości teorii logicznych nowożytnych w tym rachunku funkcyjnego jak i teorii starożytnych na przykład Arystotelesa jest to, że każde zdanie może być prawdziwe albo fałszywe i nie może być ono prawdziwe i fałszywe jednocześnie. Teorie które spełniają to założenie zaliczamy do teorii klasycznych. 2 Powstały jednak inne, nieklasyczne teorie logiczne, spośród których stworzono nowe systemy logiki jak gdzie wynikania zdań zawierają terminy logika epistemiczna, dotyczące stanów i czynności poznawczych i logika temporalna, która zajmuje się zdaniami o stosunkach czasowych i czasami w sensie gramatycznym [11]. Pomimo dokładniejszego opisu rzeczywistości, logiki te wykorzystują jednak bardzo skomplikowany aparat matematyczny. Można by było posłużyć się nimi do opracowania nowych metod reprezentacji wiedzy dla sztucznej inteligencji, jednak nie dokonano jak dotąd ich implementacji komputerowej. Ze względu na duże trudności pojęciowe w posługiwaniu się wymienionymi logikami w niniejszej pracy skupimy się na mniej skomplikowanej – logice obiektów. 1.2 Zakres i cel pracy Praca niniejsza implementowanych w dotyczyć klasycznych będzie rozwoju komputerach. metod reprezentacji Wykorzystana zostanie wiedzy logika obiektów w wersji opracowanej przez E. Nieznańskiego[3]. Jako system do celów implementacyjnych zostanie wykorzystany język Prover9 oraz SWI-Prolog. Część graficzna aplikacji zostanie napisana w środowisku .NET i języku C#, a środowisko testowe w języku Python. Głównym celem niniejszej pracy jest opracowanie koncepcji i utworzenie aplikacji, która w sposób przyjazny implementować będzie logikę obiektów opracowaną przez Nieznańskiego i dokonanie porównania metod jej implementacji. Aby ukazać interesujące właściwości takich implementacji, przeprowadzonych będzie szereg eksperymentów, których praktyczne realizacje zweryfikowałby system logiczny. Analiza takich systemów i porównanie ich możliwości pozwoli na ocenę ich przydatności. Ponieważ projekt nie jest implementowany w jednym systemie/języku środowisko testowe zostanie wykonane w języku Python. W ramach eksperymentów zostanie zbadana możliwość dowodzenia twierdzeń przez systemy je implementujące. Zostanie także sprawdzona poprawność wnioskowania oraz wydajność tych systemów. Dodatkowa analiza parametrów środowiska Prover9 pomoże ustalić parametry przy których eksperymenty zostaną wykonane wydajniej. 3 1.3 Zawartość merytoryczna pracy Niniejsza praca została podzielona na sześć rozdziałów. Kolejne rozdziały omawiają następujące zagadnienia: w rozdziale pierwszym zostały zebrane przesłanki przemawiające za podjęciem rozważanej tutaj tematyki, w rozdziale drugim przedstawiono zagadnienia teoretyczne, podstawy automatycznego dowodzenia twierdzeń. Następnie podano zestaw twierdzeń logiki obiektów kategorialnych zaczerpnięty z pracy Nieznańskiego[3], rozdział trzeci stanowi wprowadzenie do systemów wykorzystanych do dowodzenia twierdzeń, czyli Prover9 i SWI-Prolog jak i opis narzędzi potrzebnych do utworzenia oprogramowania, rozdział czwarty ukazuje sposób realizacji środowiska eksperymentalnego jak i eksperymentów, rozdział piąty przedstawia przeprowadzone eksperymenty i porównania, rozdział szósty podsumowuje wyniki eksperymentów z rozdziału piątego i prezentuje wyniki i porównania oraz wyniki końcowe. 4 2 Podstawowe pojęcia teoretyczne występujące w użytej logice rozszerzonej Klasyczna logika formalna - w przeciwieństwie do sylogizmu Arystotelesa zazwyczaj wprowadza do swojego języka, oprócz tak zwanych pozytywnych przesłanek, także te negatywne. O ile arystotelesowskie sylogistyki (jako systemy wnioskowania) mogą być skutecznie odtworzone w całości jako teorie częściowych uporządkowań (co wykazał Mostowski), klasyczna logika formalna wraz z uwzględnieniem negacji wyrażeń, nie może być rozwinięta do algebry Boole'a. Jeśli relacje między obiektami opisane przez operator „każdy ... jest. . ." mają koncepcje obiektu który jest największym elementem - to zgodnie z postulatem " wszystko jest obiektem " oznacza, że dopełnienie ostatniego elementu "nie obiektu" będzie pierwszym elementem. Taki "nie-obiekt", będąc zarazem obiektem daje sprzeczność. Zgodnie z ontologicznym widzeniem świata i odniesieniu do klasycznego transcendentalnymi będziemy rozróżnienia nazywać pomiędzy zgodne byty pojęciami kategorialnymi obiektami kategorialnymi. i W związku z tym istotne jest rozważanie dwóch idei: 1. traktowanie słowa "jest" jako synonimu wyrażenia „każdy. . . jest. . . " co ma długą tradycję i jest mocno zakorzenione w języku potocznym, 2. tradycyjna logika jest teorią nie jednego, ale dwóch porządków: częściowego porządku pomiędzy obiektami opisanymi przez słowo "jest" i innego częściowego 5 uporządkowania, pomiędzy pojęciami, zdefiniowanymi przez wyrażenie "koncepcja . . . jest zawarta w koncepcji ...” Połączenia logiczne pomiędzy obydwoma porządkami logicznymi, ujawniają sens słów "jest" i "jest zawarte", co zostało zbadane w trzech systemach logicznych, wynikających z tradycyjnej logiki[4]. Nazwiemy te systemy (1) logiką obiektów kategorialnych, (2) logiką pojęć (3) i logiką systemów. Te wszystkie systemy są połączone w taki sposób, że każdy kolejny system jest w pewnym sensie kontynuacją poprzedniej teorii. W całości funkcjonują jako „dedukcyjna całość”, nazywana dalej logiką obiektów. 2.1 Logika obiektów kategorialnych Podstawowymi elementami formalnymi, jakimi będziemy się posługiwali w tej logice będą zmienne (z kategorii nazw) i użyjemy tylko jednego predykatu "jest". Zatem niech formuła zdaniowa " x is y" będzie reprezentowana przez notacje "y(x)". Formuły zdaniowe ” ~”(negacja), „⇒” ( implikacja), „∧” (koniunkcja), „∨” (alternatywa) i „⇔” (równoważność) razem z kwantyfikatorami: ∀ (uniwersalny), ∃(egzystencjalny) i ∃1 (indywidualny). Wszystkie te formuły i predykaty razem ze zmiennymi zawierają podstawowe terminy tego języka. Wszystkie obiekty w tym języku będą z dziedziny indywidualnych zmiennych. Definicja obiektu w tej logice jest zapożyczona z Łukasiewicza[16]. Jako obiekt rozumiemy tylko coś co nie może na raz posiadać i nie posiadać jakiejś cechy. Według tej definicji, obiektem będziemy nazywali wszystko to co nie jest sprzeczne. Co oznacza, że obiekty są spójne. Różnica pomiędzy jednostkowym obiektem a ogólnym pojęciem obiektu nie odgrywa istotnej roli w logice obiektów. Nicość która może być tu rozumiana jako sprzeczność, nie jest tutaj brana pod rozwagę w przestrzeni gdzie operujemy jedynie na spójnych obiektach. Semantyczny fakt, że zdania kategorialne typu " dla każdego x jest y " mają ten sam sens co zdania " x jest y ", co było udowodnione w pracy Leibniza. W swojej ropzrawie stwierdza on, że 'Sokrates ist der Sohn des Sophroniscus" wird (...) zum Inhalt haben: "Wer immer Sokrates ist, ist der Sohn des Sophroniscus". Man wird auch zutreffend sagen "Jeder Sokrates ist der Sohn des Sophroniscus" obwohl er ein einziger 6 ist'. To założenie Leibniza głosi że forma zdaniowa " x jest y" znaczy to samo co wyrażenie " wszystko co jest x jest także y". Rozważmy teraz aksjomaty tej logiki. Pierwszy aksjomat ma postać: A1. y(x) ⇔ ∀ z [ x(z) ⇒ y(z)]. (2.1) Zaczynając od tego aksjomatu kolejne dwa lematy dowodzimy w prosty sposób. Pierwszy jest o zwrotności relacji "jest" a drugi o jej przechodniości: L1. x(x) (2.2) L2. y(z) ∧ z(x) ⇒ y(x) (2.3) Na podstawie relacji "jest" Nieznański definiuje kolejne tak zwane operatory Arystoteleskie: 'e' ( żaden ... jest ...), 'i' ( częsć ... jest ...), 'o'( część ... nie jest ...) : df. e: xey ⇔ ∀ z [x(z) ⇒ ~y(z)] (2.4) df. i: xiy ⇔ isnieje z[x(z) ∧ y(z)] (2.5) df. o: xoy ⇔ istnieje z [x(z) ∧ ~y(z)] (2.6) Niech obiekt x i y beda identyczne ( x = y ), kiedy maja te same cechy: df. =∶ L18. x = y ⇔ ∀ z [z(x) ⇔ z(y)] x = y y(x) ∧ x(y) (2.7) (2.8) Stwierdzenia [2.1] i [2.2] razem z tezą [2.8] determinują fakt, że relacja określona pomiędzy obiektami słowem „jest” jest relacją częściowego porządku. L19. y(x) [y(x) ∨ x = y] (2.9) L20. ∀ y ∃ z ∀ x [z(x) xey] (2.10) W logice kategorialnych obiektów postulat określający, że dla każdej formuły A[x] w tej logice : ∃ y ∀ x [y(x) A[x]] (2.11) Powyższy postulat mówi o tym, że dla każdego funktora logicznego istnieje obiekt, który zawiera te i tylko te obiekty które spełniają funkcję A, który jest oczywiście fałszywy. Dla przykładu, nie istnieje taki obiekt y, który dla ∀ x[y(x) ~x = x]. To sugeruje, że spójność każdej tezy, która mogłaby według definicji być wprowadzona do teorii, powinna zostać ona udowodniona za każdym razem. By zapewnić spójność nowe tezy powinny być wprowadzone do systemu, Nieznański aksjomatycznie przyjmuje że: A2. ∀ y ∃ z ∀ x [ z(x) xey] (2.12) 7 Na bazie twierdzenia [2.10] definiujemy obiekt y’( nie y ), czyli dopełnienie obiektu: Df. ‘ ∶ y’(x) xey (2.13) Zakładamy również kolejny aksjomat: A3. x(x’’) (2.14) Produktem obiektów x i y będziemy nazywali symbolicznie zapis „x * y”. Def.∗∶ xiy ⇒ ∀ z [x ∗ y(z) x(z) ∧ y(z)] xiy ⇒ ∀ 𝑧 { 𝑧 = 𝑥 ∗ 𝑦 𝑥 (𝑧) 𝑦(𝑧) ∧ ∀u [x(u) ∧ y(u) ⇒ z(u)]} L57. (2.15) (2.16) Kolejnym terminem wartym uwagi jest unia obiektów. Unię obiektów x i y zapisujemy symbolicznie jako „x+y”. Według stwierdzenia z [2.16] produktem obiektów jest ich ograniczenie dolne (infimum). Df. +∶ x’iy’ ⇒ x + y = (x’ ∗ y’)’ (2.17) Ponieważ zmienne oznaczają kategorialne obiekty, a dopełnieniem tych obiektów są też obiekty, x’ oraz y’ są także obiektami. Produkt x’ * y’ jest więc obiektem a jego dopełnienie (x’ * y’)’ też jest obiektem. Dzięki tej własności unia x + y ma gwarantowaną egzystencję i unikalność w logice obiektów z pojęciem dopełnienia produktu. Logika obiektów kategorialnych zawiera oprócz podanych aksjomatów i definicji, 73 tezy. Podane tutaj najważniejsze definicje są tylko fragmentem wszystkich tez. Pozostała ich część znajduje się w artykule Nieznańskiego[3]. 2.2 Logika pojęć Jak wynika z poprzednich rozważań tylko obiekty należą do dziedziny relacji oznaczonej predykatem „jest”, a pojęcia naturze ≤ – – niezależnie od tego czym są w swojej są wzajemnie związane stosunkiem zawierania. Będziemy używali symbolu jako funktora „pojęcie … jest zawarte w pojęciu …”. Podobnie jak słowo „jest” jest podstawowym terminem logiki kategorialnej obiektów, tak wyrażenie „ jest zawarte w” jest podstawowym terminem logiki pojęć. Ponieważ można sobie wyobrazić różnego rodzaju byty, nie tylko obiektów kategorialnych, ale również byty sprzeczne i 8 transcendentalne, wprowadzimy nowy rodzaj zmiennej indywidualnej: a, b, c, które będą reprezentowały wszystko, czyli obiekty i nie-obiekty. Do pojęcia zawierania dodajemy wszystkie postulaty od teorii algebry Boole’a, razem z definicjami pierwszego i ostatniego elementu, supremum, infimum i dopełnienia. P1. a≤ a (2.18) P2. a ≤ b∧b ≤ c ⇒ a ≤ c (2.19) Df1. a ≡ b a ≤ b∧b ≤ a (2.20) P3. ∃b∀a a ≤ b (2. 21) Df2. b ≡ 1 ∀a a ≤ b (2.22) P4. ∃a ∀b (2.23) a ≤ b Df3. a ≡ 0 ∀ a a ≤ b P5. ∀ a ∀ b ∃ c [a ≤ c ∧ b ≤ c ∧ ∀d ( a ≤ d ∧ b ≤ d ⇒ c ≤ d)] Df4. c ≡ a ⋃ b a ≤ c ∧ b ≤ c ∧ ∀d ( a ≤ d ∧ b ≤ d ⇒ c ≤ d) P6. ∀ a ∀ b ∃ c [c ≤ a ∧ c ≤ b ∧ ∀d( d ≤ a ∧ d ≤ b ⇒ d ≤ c)] Df5. c ≡ a ∩ b c ≤ a ∧ c ≤ b ∧ ∀d( d ≤ a ∧ d ≤ b ⇒ d ≤ c) (2.24) (2.25) (2.26) (2.27) (2.28) P7. (a ⋃ b) ∩ c ≡ (a ∩ c) ⋃ (b ∩ c) (2.29) P8. ∀ a ∃ b (a ⋃ b ≡ 1 ∧ a ∩ b ≡ 0) (2.30) Df6. P9. b ≡ ~a ⇒ a ⋃ b ≡ 1 ∧ a ∩ b ≡ 0 ~(1 ≤ 0) (2.31) (2.32) Terminy (oznaczające wyrażenia nominalne) logiki koncepcji są: terminami logiki kategorialnej obiektów, nowych zmiennych a, b, c, stałymi "0" i "1", i wszelkiego rodzaju połączonych terminów, stałych lub zmiennych wymienionych powyżej przez znaki ‘-‘,’ ⋃’,’ ∩’. Natomiast pojęcie "obiektu" zawiera wszystkie pojęcia, z tego zakresu natomiast pojęcie z nie zgodnego bytu, jako puste pojęcie, jest zawarte w każdej koncepcji. Powyższe idee zostały wyrażone w kolejnych dwóch tezach: T1. ∀a a ≤ 1 (2.33) T2. ∀b 0 ≤ b (2.34) Wszystkie pozostałe prawa z teorii algebry Boole'a, zakładamy jako dobrze wiadome, ale określając przy tym jednak słowo "jest", w nowym znaczeniu: Df7. b(a) ~(a ≤ 0) ∧ a ≤ b (2.35) 9 Według tej definicji, „a jest b”, kiedy pojęcie „a” nie jest zawarte w pojęciu sprzecznego bytu i jednocześnie pojęcie jest zawarte w „b”. Poniżej zostaną pokazane serie stwierdzeń demonstrujących połączenia pomiędzy relacjami „jest” i „jest zawarty”. Porównując semantykę logiki pojęć z semantyką logiki kategorialnych obiektów widzimy, że modele logiki pojęć nie są uproszczoną algebrą Boole'a, natomiast modele dla logiki obiektów kategorialnych są systemami relacyjnie generowanych z algebry Boole'a. Śledząc w odwrotnej kolejności relacje wzajemnej zależności między obiema logikami, możemy zauważyć, że modelami z logiką pojęć są tylko Boole’owskie algebry, które mają przestrzeń modelu logiki obiektów kategorialnych jako ostatni element. Semantyczną zależność między obydwiema logikami wyrażonymi powyżej jest wyrażona poprzez jedyny właściwy aksjomat logiki pojęć: P10. 𝑎 ≤ 0 ∨ 1 ≤ 𝑎 ∨ ∃𝑥 𝑥 = 𝑎 (2.36) Automatyczne dowodzenie twierdzeń 2.3 Automatyczne dowodzenie twierdzeń, jest to dziedzina która łączy ze sobą logikę i informatykę. Polega ona na tworzeniu i sprawdzaniu algorytmów poszukiwania dowodów twierdzeń systemów formalnych. Algorytmy te nie tylko mają znaczenie teoretyczne, ale również praktyczne zastosowania ( weryfikacja programów i w dedukcyjnych bazach danych). Algorytmy poszukiwania dowodów twierdzeń zwane też z angielskiego proverami, zazwyczaj stosują metodę rezolucji jako główną regułę dowodzenia[4]. Reguła rezolucji jest to reguła w rachunku zdań, za pomocą której generujemy nowe klauzule, aż dojdziemy do sprzeczności. Jako przykład mając dwie klauzule A i B z których wynika C i w klauzuli A występuje literał q, a w B ~q, a C składa się z reszty literałów występujących w A lub B. W ten sposób można udowodnić, że dane twierdzenie nie jest spełnialne, lub też, co jest równoważne, że jego zaprzeczenie jest tautologią. Dowodzenie metodą rezolucji można opisać w kilku krokach: przekształcenie przesłanek lub aksjomatów w formę klauzul, dodać do zbioru aksjomatów zaprzeczenia twierdzeń, które mają być udowodnione, 10 wygenerować nowe klauzule wynikające z tego zbioru, znaleźć sprzeczność generującą pustą klauzulę, warunki które zostały wykorzystane do utworzenia pustej klauzuli są tymi, w których zaprzeczenie celu jest prawdziwe, Powstały jednak kroki, które są mocno pomocne przy upraszczaniu rezolucji. Należą do nich: przeszukiwanie wszerz, strategia zbioru podpierającego, strategia preferencji jednostkowej, strategia liniowa wejścia, Podstawowym zagadnieniem w automatycznym dowodzeniu twierdzeń jest opracowanie odpowiednich pojęć teorii oraz reguł dowodowych. Poniżej przytoczono niektóre pojęcia tych teorii. Zbiór formuł T będziemy nazywali teorią wtedy i tylko wtedy, gdy jest on zamknięty ze względu na konsekwencje logiczne. Z kolei zbiór formuł T jest zamknięty ze względu na konsekwencje logiczne wtedy i tylko wtedy, gdy dla wszystkich formuł A zachodzi zależność: jeżeli A jest konsekwencją logiczną T, to A∈T. Z kolei reguły dowodowe to reguły generowania twierdzeń ze zbioru aksjomatów reguły wnioskowania (np. reguła odrywania). Należy zauważyć, że podstawowymi własnościami w teorii systemów automatycznego dowodzenia są: niesprzeczność teorii – dla żadnego zdania i jego negacji nie mogą być jednocześnie, zdanie teorii nazywamy rozstrzygalnym, jeżeli ono samo, albo jego negacja, jest twierdzeniem teorii, teoria jest zupełna, jeżeli wszystkie zdania są w niej rozstrzygalne, teoria jest rozstrzygalna, jeżeli istnieje algorytm, który dla każdego jej zdania pozwala stwierdzić, czy jest ono twierdzeniem tej teorii, większość teorii matematycznych, to teorie nierozstrzygalne (np. teoria liczb naturalnych), 11 Ogólnie można stwierdzić, że do najważniejszych zagadnień, którymi zajmuje się teoria automatycznego dowodzenia twierdzeń należą: niesprzeczność, zupełność i rozstrzygalność. 12 3 Opis narzędzi programistycznych wykorzystanych w pracy 3.1 Krótki opis technologii Prover9 Prover9 [14] jest to system służący do dowodzenia twierdzeń w logice pierwszego rzędu. Został on opracowany przez Williama McCune’a, który pierwszą jego wersję opublikował w roku 2005 jako następcę systemu Otter. Prover9 został stworzony razem z systemem Mace4, który szuka skończonych modeli formuł pierwszego rzędu. Oba programy mogą działać jednocześnie dla tych samych danych wejściowych. Kiedy Mace4 próbuje znaleźć kontrprzykład dla zadanych tez, to Prover9 stara się znaleźć ich dowód. Oba programy i wiele innych narzędzi) są zbudowane w oparciu o bibliotekę LADR, aby uprościć implementację. Dowód będący rezultatem programu Prover9 może zostać dodatkowo sprawdzony za pomocą programu Ivy (program odrębnie zweryfikowany za pomocą acl2). W 2006 zostały wprowadzone znaczne zmiany do języka wprowadzającego dane do LADR/Prover9/Mace4. Różnica pomiędzy klauzulami i wzorami została usunięta. Obecnie we wzorach mogą występować dowolne zmienne, a za pomocą formuł można definiować klauzule. Prover9/Mace4 umożliwia również automatyczne zanegowanie podanego twierdzenia i sprawdzanie jego wartości. Prover9 był aktualizowany do roku 2009. Ogólnie jest to wolne oprogramowanie typu open source, wydane na wersji GPL 2 lub nowszej. 13 Język jakim posługuje się Prover9 jest bardzo intuicyjny i łatwy do przyswojenia nawet dla osób nie związanych z informatyką. Dlatego jest on używany przez matematyków a szczególnie przez logików. Aby przedstawić jego właściwości poniżej zamieszczono przykład, w którym na podstawie dwóch zdań chcemy udowodnić trzecie. Jeżeli założymy, że każdy człowiek jest śmiertelny oraz, że Sokrates był człowiekiem to możemy wywnioskować, że Sokrates był śmiertelnikiem. W systemie Prover9 będzie to zakodowane w sposób pokazany na Rys. 3.1. Rys. 3.1. Formuła założeń i celów w programie Prover9 Kod pokazany na Rys. 3.1 zostanie zamieniony na klauzule, a cel zostanie zanegowany. Jeśli system wykaże sprzeczność, twierdzenie zostanie udowodnione. Fragment kodu po transformacji został pokazany na Rys. 3.2. Rys. 3.2. Fragment kodu po uproszczeniu Prover9 Prover9 oprócz wersji, w której system jest uruchamiany z linii poleceń, istnieje również wersja z interfejsem graficznym, która została pokazana na Rys. 3.3 i Rys 3.4. Aby skorzystać z Prover9 w wersji z linii poleceń, należy stworzyć plik. Założenia należy oznaczyć „formulas(assuptions).”, a cele „formulas(goals).”, obie listy należy zakończyć „end_of_list.” W aplikacji z interfejsem graficznym wipsujemy te informacje w odpowiednie pola ( Assumptions i Goals). 14 Aplikacja graficzna Prover9 pozwala również na równoczesne uruchomienie narzędzia Mace4. W zakładce Prover9 Options (Rys. 3.4) można zaobserwować wiele opcji, które można modyfikować do dowodzenia programu, od zmiany wag dla zmiennych, po ustawianie limitów ich ilości czy zmianie kolejności wybierania termów do dowodzenia. Rys. 3.3. Główne okno aplikacji Prover9 15 Rys. 3.4. Zakładka opcji aplikacji Prover9 3.2 Najważniejsze właściwości języka Python Python jest to język programowania wysokiego poziomu, szeroko stosowany w wielu różnych dziedzinach. Główna idea, która przyświecała temu językowi podczas jego powstawania, polegała na tym aby kod napisany w tym języku był dobrze czytelny jak i to, by jego składnia pozwalała programistom wyrazić pojęcia w mniejszej ilości linii kodu, niż dałoby się to uczynić w innych językach, np. takim jak C. Język został tak skonstruowany, aby dało się przy jego pomocy utworzyć zarówno małe jedno plikowe programy jak i te tworzone na dużą skalę[20]. Projekt został rozpoczęty w roku 1989r., jako hobby jego twórcy - Guido van Rossum. Nazwa pochodzi od Latającego Cyrku Monthy Pythona. Python 2.0 pojawił się w roku 2000, zawierał on automatyczne zarządzanie pamięcią (garbage collector) i wsparcie dla Unicode. Kolejna ważna wersja to Python 3.0 wypuszczona w roku 2008, na początku swojego istnienia nie wspierała kompatybilności wstecz, jednak obecnie, większa część głównej funkcjonalności została zaktualizowana tak, aby wspierać kod napisany w starszych wersjach Pythona. 16 Język ten wspiera wiele paradygmatów programowania, wliczając programowanie obiektowe, imperatywne i funkcyjne lub proceduralne style programowania. Posiada on typy dynamiczne, systemowe i automatyczne zarządzanie pamięcią jak i dużą i obszerną wbudowaną bibliotekę standardową. cl a ss Person(object): def __i nit__(self,count): s elf.count = count; s elf.prev = None s elf.next = None def s hout(self,shout,deadif): i f (s hout < deadif): return (shout + 1) s elf.prev.next = s elf.next s elf.next.prev = s elf.prev return 1 cl a ss Chain(object): def __i nit__(self,size): s elf.first = None l a st = None for i i n ra nge(size): current = Pers on(i) i f s elf.first == None : s elf.first = current i f l ast != None : l a st.next = current current.prev = l ast l a st = current s elf.first.prev = l ast l a st.next = s elf.first def kill(self,nth): current = s elf.first s hout = 1 whi le current.next != current: s hout = current.shout(shout,nth) current = current.next s elf.first = current return current i mport time ITER = 100000 s ta rt = ti me.time() for i i n ra nge(ITER): cha i n = Cha in(40) cha i n.kill(3) end = ti me.time() pri nt 'Time per iteration = %s microseconds ' % ((end - s ta rt) * 1000000 / ITER) Rys.3.5 Przykład prostego programu napisanego w języku Python Język Python w swojej budowie, przypomina języki C i Java, lecz różni się ze względu na wcięcia. W C czy w Javie bloki kodu oznaczane są za pomocą znaków „{„ i „}”, natomiast w Pythonie wykorzystuje wspólne bloki kodu, które mają tę samą liczbę białych znaków przed sobą. Ponieważ w Pythonie zmienne nie mają typów, a duża ilość elementów, takich jak elastyczne kolekcje danych, mocno rozbudowane standardowe moduły powodują, że jak pokazano na Rys 3.5 i Rys.3.6, program napisany w języku Python mieści się w mniejszej ilości kodu w porównaniu do innych popularnych języków. Jest to również język skryptowy, więc nie wymaga on kompilacji, przez co tworzenie i debugoweanie programu jest o wiele szybsze. Jest więc to język dla uzyskania zwiększonej produktywności, jakości oraz obsługiwalności projektowanego oprogramowania. 17 #include <stdio.h> #include <stdlib.h> #include <time.h> #include < sys/time.h> class Person { public: Person(int count) : _next(NULL), _prev(NULL) { _count = count; } int shout(int shout, int nth) { if (shout < nth) return (shout + 1); _prev->_next = _next; _next->_prev = _prev; return 1; } int count() { return _count; } Person* next() { return _next; } void next(Person* person) { this->_next = person ; } Person* prev() { return _prev; } void prev(Person* person) { this->_prev = person; } private: int _count; Person* _next; Person* _prev; }; class Chain { public: Chain(int size) : _first(NULL) { Person* current = NULL; Person* last = NULL; for(int i = 0 ; i < size ; i++) { current = new Person(i); if (_first == NULL) _first = current; if (last != NULL) { last->next(current); current->prev(last); } last = current; } _first->prev(last); last->next(_first); } Person* kill(int nth) { Person* current = _first; int shout = 1; while(current->next() != current) { Person* tmp = current; shout = current->shout(shout,nth); current = current->next(); if (shout == 1) { delete tmp; } } _first = current; return current; } Person* first() { return _first; } private: Person* _first; }; int main(int argc, char** argv) { int ITER = 1000000; Chain* chain; struct timeval start, end; gettimeofday(&start;,NULL); for(int i = 0 ; i < ITER ; i++) { chain = new Chain(40); chain->kill(3); delete chain; } gettimeofday(&end;,NULL); fprintf(stdout,"Time per iteration = %d microsecondsnr", (((end.tv_sec - start.tv_sec) * 1000000) + (end.tv_usec start.tv_usec)) / ITER); //fprintf(stdout,"Last man standing is %dnr", (chain>first()->count() + 1)); return 0; } Rys.3.6 Ten sam program co na rys 3.5 tylko w wersji C++. 3.3 Podstawowe informacje o języku Prolog Prolog jest językiem logicznego programowania ogólnego przeznaczenia, związanego ze sztuczną inteligencją i lingwistyką. Korzenie Prologa biorą się z logiki pierwszego rzędu, logiki formalnej i w przeciwieństwie do wielu innych języków programowania Prolog jest deklaratywny, co oznacza, że logika programu jest wyrażona w relacjach, reprezentowanych faktach i zasadach. Obliczenia rozpoczyna uruchamiana kwerenda związana z tymi relacjami. 18 Prolog był jednym z pierwszych języków programowania w logice, i nadal jest najbardziej popularnym wśród tych języków wraz z wieloma nieodpłatnymi i komercyjnymi dostępnymi wdrożeniami. Język był używany do dowodzenia twierdzeń w systemach eksperckich[1] jak również było w jego oryginalnym zamiarze - do zastosowań przy przetwarzaniu języka naturalnego. Współczesne środowiska Prologa, wspierają tworzenie graficznych interfejsów użytkownika, a także aplikacji administracyjnych i sieciowych. W Prologu, logika programu jest wyrażona w relacjach, a obliczenia są inicjowane przez uruchomienie kwerendy nad tymi relacjami. Relacje i kwerendy są zbudowane przy użyciu jedynego typu danych w Prologu czyli termów. Relacje definiowane są przez klauzule. Biorąc pod uwagę zapytanie, silnik Prologu próbuje znaleźć obalenie rozwiązania zanegowanego zapytania. To sprawia, że Prolog (i inne języki programowania w logice), jest szczególnie przydatny w problemach z bazami danych, matematyki symbolicznej i jako aplikacji do parsowania. Ponieważ Prolog pozwala na nie czystą funkcyjnie implementację predykatów, sprawdzanie wartości logicznej niektórych szczególnych predykatów, może mieć pewne zamierzone działanie uboczne, takie jak drukowanie wartości na ekranie. Dlatego Prolog pozwala programistom na stosowanie pewnej ilości programowania logicznego imperatywnego kiedy paradygmaty stają się niewygodne. Ma czysto funkcyjny logiczny podzbiór, zwany "czystym Prologiem", a także szereg nie logicznych funkcji[18]. 3.3.1 Reguły i fakty Program Prolog opisuje relacje, określone za pomocą klauzul. Czysty Prolog jest ograniczony do klauzul Horn'a. Istnieją dwa rodzaje klauzul: fakty i reguły. Reguła jest postaci: Głowa : - Ciało. Jest odczytywana jako "Głowa jest prawdą, jeśli Ciało jest prawdą". Ciało z reguły składa się z odwołań do predykatów, które są nazywane celem reguły. Wbudowany predykat „ , / 2” oznacza koniunkcję celów a „ ; / 2” oznacza alternatywę. Koniunkcje i alternatywy mogą pojawić się tylko w ciele, nie w głowie reguły. Klauzule bez ciała nazywane są faktami. Przykładowym faktem jest : kot(tom). co jest równoznaczne z: kot(tom): - true. 19 Wbudowany predykat „true / 0” jest zawsze prawdziwy. Biorąc powyższy fakt pod uwagę , można utworzyć zapytanie: Czy tom jest kotem? ? -kot(tom). Yes Co jest kotem ? ? - kot(X). X = tom Klauzule z ciałem nazywane są zasadami. Przykład zasady: zwierze(X): - kot (X). Jeśli dodamy tą zasadę i zapytamy, co jest zwierzęciem : ? - zwierze(X). X = tom Ze względu na relacyjny charakter wielu wbudowanych predykatów, relacje te mogą mieć różne zastosowanie. Na przykład, „length/2” może być stosowany do określania długości listy (length(List, L), podając listę jako parametr List) oraz do generowania szkieletu listy określonej długości (length (X , 5)) a także do generowania szkieletów list jak i ich długości jednocześnie (length (X, L)). Podobnie, „append / 3 „może być używany zarówno do łączenia dwóch list (append (ListA, ListB, X) mając listy ListA i ListB), jak również do dzielenia danej listy na dwie części (append(X,Y,List) ). Dzięki temu, biblioteka która na pierwszy rzut oka zawiera małą liczbę predykatów, jest stosowana w wielu problemach które implementują programy napisane w Prologu. 3.3.2 Wykonanie programu Wykonanie programu w Prologu jest inicjowane przez użytkownika poprzez podanie pojedynczego celu, zwanego kwerendą. Metoda rezolucji wykorzystywana przez Prolog to 20 rezolucja SLD (Selective Linear Definite). Jeśli zanegowana kwerenda może zostać obalona, wynika z tego że ta kwerenda, wraz z odpowiednimi przypisaniami zmiennych, jest logiczną konsekwencją programu. W takim przypadku, wszystkie wygenerowane zmienne są zwracane użytkownikowi, a kwerenda została wykonana pomyślnie. Strategia wykonywania programów w Prologu może być uważana jako generalizacja wywołań funkcji z innych języków, jednak w odróżnieniu od nich, wiele klauzul może pasować do głowy relacji. W takim przypadku, system tworzy punkt wyboru, jednoczy cel z klauzulą głowy pierwszej alternatywy i kontynuuje program z jej celami. Jeśli któryś z celów nie zostanie spełniony podczas wykonywania programu, wszystkie przypisania zmiennych, które zostały poczynione przed ostatnim punktem wyboru zostają wycofane, a wykonanie programu jest kontynuowane z kolejną alternatywą która znajdowała się w punkcie wyboru. Taka strategia jest nazywana chronologicznym nawracaniem (ang. chronological backtracking). Na Rys.3.7 został przedstawiony schemat właśnie tej strategii do problemu czterech hetmanów. W przypadku Prologu, algorytm rozpoczyna się w punkcie 1, mając cztery różne możliwości rozmieszczenia hetmana (1 kolumna), Prolog wybiera pierwszą opcję, czyli 2, aż dojdzie do sytuacji 8, po której stwierdzi, że otrzyma wynik. Jednak w Prologu, możemy kontynuować działanie programu, wtedy dzięki chronologicznemu nawracaniu algorytm wróci się do punktu 1, po czym wybierze ścieżkę A. Dzięki temu w Prologu w łatwy sposób możemy otrzymać wszystkie możliwe wyniki problemu. 21 Rys. 3.7 Ilustracja problemu czterech hetmanów z wykorzystaniem chronologicznego nawracania. 3.3.3 Porównanie implementacji Prologu Obecnie istnieje wile implementacji Prologu, które są diametralnie różne, pod względem składni i semantyki (np. Visual Prolog). Kod, który jest ściśle zgodny ze standardem ISO języka Prolog, jest przenośny na wszystkie implementacje norm ISO. Jednak standard ISO dla modułów nie został zaakceptowany przez większość implementacji Prologu. Czynniki, które mogą mieć negatywny wpływ na przenośność kodu, obejmują: wykorzystanie ograniczonych kontra nieograniczonych liczb całkowitych, dodatkowe rodzaje obiektów typy string, zaawansowane typy liczbowe (wymierne i złożone), rozszerzenia funkcji, wątków, korzystanie z bibliotek niedostępne w innych implementacjach, 22 Lista paru implementacji Prologu wraz z porównaniem ich głównych właściwości zestawiona została na Rys. 3.8. PoplogProlo g SICStus Prolog Strawberry Prolog SWI-Prolog tuProlog Visual Prolog XSB Prolog System Licencja Linux(32 - and 64bit),Unix ,Window s Unix,Lin ux,Wind ows,Mac OS X Window s,Unix Free Open Source Unix,Lin ux,Wind ows,Mac OS X JVM,An droid Window s aplikacja graficzna Only throughP OP-11, on Linux unicode Commerci al Tak Tak Freeware, Commerci al LGPL Tak Tak Tak Tak LGPL Tak Tak Freeware, Commerci al LGPL Tak Tak standalone C interface Java interface Syntax Tak Tak Tak Tak Tak Tak Tak Tak Tak Tak Tak Tak Tak Tak Tak Tak Tak Linux,W Tak Tak Tak Tak indows,S olaris,M ac OS X YAP-Prolog Linux,W GPL or Tak Tak Tak Tak indows,S Artistic olaris,M (user ac OS choice) X, HPUX Rys. 3.8 Zestawienie niektórych przykładowych implementacji systemu Prolog Tak Tak W dalszej części niniejszej pracy został wybrany SWI-Prolog ze względu na jego zgodność ze standardem ISO-PROLOG, dostępnością na wszystkich głównych systemach operacyjnych jak i jego popularnością czy dostępnymi samouczkami. 23 4 Propozycja implementacji programowej logiki obiektów Realizacja dogłębnego programowa przemyślenia omówionej koncepcji w systemu, rozdziale który 2 logiki obiektów mógłby jednoznacznie wymaga zbadać właściwości wnioskowania rozwiązania opartego na tej logice. Tak więc naszym celem jest utworzenie systemu do dowodzenia twierdzeń takiej logiki i porównania ich implementacji. Ponieważ logika prezentowana w drugim rozdziale jest oryginalną koncepcją Nieznańskiego, nie była ona dotąd implementowana maszynowo. Interesujące a jednocześnie twórcze poznawczo wydaje się więc utworzenie opgrogramwoania które by automatycznie dowodziło twierdzenia w tej logice. Istnieją dwa podejścia do powstania takiego oprogramowania. Pierwsze polegałoby na napisaniu takiego progrmau od podstaw w niskopoziomowym języku takim jak C++ czy Java. Drugie podejście które zostało wybrane w tej pracy, wymaga stworzenia systemu w oparciu o znany system do maszynowego dowodzenia twierdzeń lub język sztucznej inteligencji. Podejście to, wydaje się być ciekawsze i prostsze, dzięki niemu można przetestować dwa systemy do implementacji ponieważ wymaga tylko modyfikacji i rozszerzeń istniejącego już oprogramowania. Przy wyborze pierwszego systemu do implementacji logiki obiektów, brane były pod uwagę systemy, co do których istniało spore przekonanie, że implementacja systemu się powiedzie. Dlatego jako pierwszy system został wybrany Prover9. Jak zostało to opisane w rozdziale 3, system został stworzony do dowodzenia twierdzeń w logice pierwszego rzędu, jednak równie dobrze nadaje się do implementacji niektórych logik rozszerzonych. Jako drugi system został wybrany język Prolog ze względu na swoją długą historię jako język sztucznej inteligencji. W prologu dowodzi za pomocą reguły rezolucji ale tylko klauzule Horna. Została więc wykorzystana do tego biblioteka leanCop, która pozwala dowodzić twierdzenia nie tylko 24 w postaci klauzul Horna. Dzięki jej modyfikacji można przeprowadzić dowody w logice obiektów. 4.1 Proponowane rozwiązanie przedstawionego problemu Celem tworzonego środowiska programistycznego, było połączenie systemów tak, by powstał jeden interfejs graficzny do wymienionych systemów. Potrzebne jest zautomatyzowanie konkretnych serii eksperymentów, które można by było powtórzyć w ściśle określonych warunkach. W związku z powyższym, środowisko ma umożliwiać dowodzenie logiki obiektów w dwóch systemach, dokonywać skomplikowanych zapytań w tej logice, zapewnić łatwą prezentację dowodów, wspierać proces przetwarzania danych eksperymentalnych, zamieniać język eksperymentów na drugi tak, by dało się spróbować udowodnić twierdzenie w obu systemach, pisząc jedno zapytanie. Do realizacji wykorzystano systemy Prover9 i SWI-Prolog, aby przeprowadzić dowodzenie zapytań w logice obiektów. Język Python wykorzystano do stworzenia parserów, obsługi plików, wykonywania testów. Interfejs graficzny został napisany w języku C# i środowisku .NET. Za pomocą interfejsu graficznego użytkownik może dokonać zapytania, uruchomić testy. Wejście danych w tym przypadku będzie tym samym, jakie jest dla systemu Prover9. Podczas projektowania zauważono, że problem powinien zostać rozwiązany za pomocą standardowych metod inżynierii oprogramowania. Podczas rozważań jakie wymagania powinien spełniać nasz system, zostały zaprojektowane rozwiązania, które realizują wymagania funkcjonalne. Poniżej została przedstawiona uproszczona lista wymagań funkcjonalnych tworzonego środowiska: przetwarzanie oraz wykonywanie zapytań do systemu Prover9 i SWI-Prolog, wyświetlanie i zwracanie analizy wyżej wymienionych zapytań, automatyczne ładowanie baz wiedzy, automatyczne czyszczenie środowiska, możliwość wprowadzania zestawu danych testowych i przygotowanymi do nich pytań, demonstracja wyników aplikacji, prezentacja statystyk związanych z zapytaniami, 25 Stworzone środowisko jest w stanie przeprowadzić wiele skomplikowanych operacji, dodatkowo będzie w stanie w sposób systematyczny przeprowadzić szereg eksperymentów. Dodatkowo interfejs aplikacji będzie graficzny i czytelny dla użytkownika, a wyniki tych eksperymentów zostaną poddane analizie i przedstawione w postaci tabeli. 4.2 Architektura proponowanego rozwiązania Zostanie teraz omówione rozwiązanie do dowodzenia twierdzeń w logice obiektów. Żeby spełnić założenia z punktu 4.1, zostało zaproponowane rozwiązanie w postaci schematu blokowego prezentowanego na Rys. 4.1. Rys. 4.1 Schemat proponowanego rozwiązania Po uruchomieniu aplikacji, użytkownikowi zostanie przedstawiony interfejs graficzny aplikacji. Pozwoli mu on na łatwe wprowadzenie danych. Dlatego do wyboru, zostanie mu przedstawione bezpośrednie wpisanie do ekranu aplikacji założeń teorii jak i celu do udowodnienia. Dodatkowo zostanie dodana możliwość przeprowadzenia zapytania zarówno w środowisku Prover9, uruchomienie modułów jak i w środowisku Prolog. dowodzących. Będzie również Program umożliwi niezależne istniała opcja czyszczenia 26 środowiska, głównie baz danych. Musi się znaleźć funkcja za pomocą której użytkownik będzie mógł zmienić udowodnione, maksymalny czas, w którym to twierdzenie powinno ponieważ ze względu na różne środowiska testowe, zostać dostępne moce obliczeniowe komputerów na których zostanie uruchomiona aplikacja, jak i samej złożoności dowodów, może to trwać zbyt długo niż czas użytkownika przeznaczony na wszystkie testy, które zaplanował. W zależności od wybranych opcji, interfejs graficzny będzie uruchamiał skrypty w języku Python. Ponieważ, język podawany na wejściu powinien być zgodny z językiem Prover9, moduł Pythonowy powinien umożliwić parsowanie takiego języka na drugi, który prover Prologa i leanCop będzie mógł swobodnie zinterpretować. Mając dane, które są zrozumiałe przez oba provery, będziemy mogli przystąpić do dowodzenia twierdzeń. Jednak przed przystąpieniem do tej czynności, należy również zapewnić możliwość przechowywania twierdzeń, aksjomatów lub udowodnionych twierdzeń, które przydadzą się przy kolejnych dowodach. Rozwiązanie tego problemu również zostanie rozwiązane w tym języku, poprzez kumulatywne zapisywanie tez do pliku. 4.3 Interfejs graficzny aplikacji Na początku uruchomienia aplikacji użytkownik widzi ekran jak na Rys. 4.2. Z zakładek na górze ma do wyboru: Theory Test, która służy do testowania wbudowanego zestawu testów, jak i serii testów utworzonych przez użytkownika, User Input, której celem jest umożliwienie użytkownikowi wprowadzenia własnego pojedynczego zapytania, W polu Assumption, użytkownik wprowadza tezy, w formacie zgodnym z Prover9. Taka konwencja została przyjęta, ponieważ jak zostało to wspomniane w rozdziale 3, składnia tego języka jest bardzo prosta i intuicyjna, w porównaniu na przykład do składni TPTP (Thousands of Problems for Theorem Provers), która jest wykorzystywana w leanCop. Oczywistą zaletą jest również fakt, iż taki kod wymaga minimalnych przekształceń, aby Prover9 mógł go udowodnić. Pole Goals służy do wprowadzania celu, który zamierzamy udowodnić, tak jak w przypadku pola Assumptions, tutaj również należy wprowadzić dane w stylu Prover9. Po prawej stronie ekranu, zaczynając od góry, zostały umieszczone pola wyboru, mówiące o tym który prover zostanie wykorzystany do przeprowadzenia dowodów. Pola 27 można oznaczać i odznaczać prawie dowolnie. Ze względu by nie pozwolić na dowodzenie twierdzenia bez wybrania żadnego z proverów, został wprowadzony mechanizm, który blokuje możliwość odznaczenia provera, jeśli został oznaczony tylko jeden. Jest to spowodowane tym aby zmniejszyć liczbę wyskakujących okienek, gdyż żaden z proverów nie został wybrany. Przycisk Prove uruchamia proces dowdzenia. W prawym dolnym rogu znajdują się opcję do wyboru pliku z bazą danych, jak i ustawieniem maksymalnego czasu, jaki damy aplikacji na udowodnienie twierdzenia. Rys. 4.2 Interfejs graficzny stworzonej aplikacji. Jak już zostało wspomniane to wyżej, zakładka Theory test służy do dowodzenia twierdzeń z plików wybranych przez użytkownika jak i przeprowadzenia testu dowodzącego twierdzeń logiki obiektów. Można ją zobaczyć na Rys. 4.3. Pierwszym polem wyboru jest pole Test Type, w którym to użytkownik wybiera czy ma być dowodzony podstawowy zestaw teorii opisany w drugim rozdziale, czy też chce podać własne pliki z testami. Jeśli 28 wybierze Standard Test, i naciśnie przycisk Prove zostanie uruchomiony skrypt do przeprowadzenia dowodów logiki obiektów. Rys.4.3 Interfejs graficzny aplikacji z widoczną zakładką Theory Test. Natomiast po wyborze User Test, użytkownik powinien kliknąć przycisk Load Files, do wczytania plików z testami, a przycisk Load Database jeśli chce dodać bazę danych do przeprowadzanych testów. Wyniki są prezentowane w oknie, wraz z czasem dowodu co można zauważyć na Rys.4.4. 29 Rys. 4.4 Prezentacja dowodu podana przez aplikację 4.4 Oprogramowanie pośredniczące Moduł pośredniczący aplikacji został napisany w języku Python. Odpowiada on głównie za następujące etapy aplikacji: przekazanie informacji między aplikacją graficzną a systemem Prover9 i SWIProlog, konwersję twierdzeń z języka sytemu Prover9 do języka TPTP, tak aby SWIProlog i leanCop mogły udowodnić twierdzenie, obliczanie danych statystycznych dla celów testowych aplikacji, odczytanie dowodu provera, 30 zwracanie informacji od proverów do aplikacji, modyfikacje przyśpieszające dowody, Jak już zostało to zaznaczone w poprzednim rozdziale, dzięki elastyczności jaką daje Python, z łatwością można było te wszystkie wyżej wymienione postulaty zaimplementować w stosunkowo niewielkiej liczbie linii kodu. Brano również pod uwagę moduł IronPython, który implementuje bezpośrednią obsługę skryptów napisanych w języku Python w środowisku .Net i C#, narzędzie to nie zostało dołączone do oprogramowania aplikacji, gdyż byłby to kolejny zewnętrzny system, przez który kod byłby mniej czytelny. Dodatkową niedogodnością takiego rozwiązania byłaby zbyt mocno rozbudowana instalacja środowiska, która i tak już wymaga instalacji 4 różnych systemów. Z kolei do celów komunikacji między programami zastosowano najprostszą metodę komunikacji - plikową. W tym przypadku interfejs graficzny dostarczy dane lub poda nazwy plików, które je zawierają. Oprogramowanie pośredniczące związane z Prover9 znajduje się w pliku prover9.py. Jeśli dane pochodzą bezpośrednio z interfejsu, moduł pośredni, zapewni dodanie odpowiednich nagłówków dla pól Assumptions jak również dla pól Goals. Ponieważ w niektórych sytuacjach program Prover9 ma trudności z udowodnieniem dwóch celów na raz, w przypadku dodania więcej niż jednego celu do pola Goals, omawiany moduł podzieli wejście na tyle plików ile jest celów i do każdego pliku przydzieli oddzielnie cel, który będzie udowadniał jeden po drugim. System może również pracować w systemie z zachowaniem twierdzeń – jeśli twierdzenie zostanie udowodnione, trafia ono do bazy danych, która jest wykorzystywana do dalszych twierdzeń. Po wykonanym dowodzie, moduł przetwarza wynik dowodu podany przez provera, po czym zapisuje odpowiednie informacje dla interfejsu graficznego. Moduł posiada również opcje do rejestrowania przebiegu wielu dowodów. Jest też samodzielny - można go uruchomić z wiersza poleceń, wpisując razem z komendą odpowiednie do funkcji argumenty. Najważniejsze funkcje modułu wraz z ich opsiami zostały opisane w Tab 4.1. 31 Nazwa funkcji proverTest Parametry Opis funkcji inFileList – lista plików; Funkcja przygotowująca środowisko databaseFile- nazwa bazy dowodzenia, uruchamia dowodzenie na każdym z plików, ustala logikę danych; bConcept – czy jest to obiektów logika pojęć; ,bCleanDb –usuwanie bazy; File proveProver – nazwa twierdzeniem pliku z Funkcja przez linie poleń i sczytania wyniku pojedynczego dowodu Argv – parametry podane Funkcja main za uruchomienie Provera9 jak i obsługę Databasefile – nazwa pliku wywołania z baza danych odpowiedzialna opdowiada za poprawne przekazanie parametrów z którymi została wywołana Tab. 4.1 Przegląd głównych funkcji pośredniczących dla celów dowodzenia w Prover9 Kolejnym z modułów napisanym w języku Python jest moduł odpowiedzialny za parsowanie tez i dowodów z języka Prover9 na składnię TPTP, z którego korzysta SWIProlog wraz z leanCop. Zauważmy, że TPTP jest biblioteką problemów testowych, a jego składnia jest wykorzystywana przez dużą liczbę proverów i bibliotek. Jedną z takich bilbiotek jest leanCop, która zawiera potrzebne funkcje do dowodzenia w logice pierwszego rzędu. Składnia stanowczo różni się od tej z Prover9. Moduł parsujący musi przede wszystkim zamienić sposób zapisu nagłówków, kwantyfikatorów, zmiennych i podstawowych operacji logicznych, uważając jednocześnie by rozróżnić operatory które mogłyby zostać błędnie odczytane np. „=” i „==”. Moduł ten dodatkowo zapewnia tworzenie listy plików o nazwie zbliżonej do oryginalnej ze zmienionym sufiksem. Ważniejsze funkcje tego modułu zostały opisane w Tab 4.2. 32 Nazwa funkcji Parametry File proveProlog – Opis funkcji plik z tezami do Funkcja udowodnienia soFar – dotychczasowymi odpowiedzialna uruchomienie plik z obsługę SWI-Prolog wywołania i za jak i sczytania tezami wyniku pojedynczego dowodu prologFile – ścieżka programu SWI-Prolog outputFile – plik wynikowy w Funkcja startCallProlog którym należy uruchamiana w umieścić oddzielnym wątku, aby w razie wyniki czego można zamknąć dowodzenie, jeśli czas został przekroczony Tab. 4.2 Przegląd głównych funkcji pośredniczących dla dowodzenia w SWI-Prolog Ostatnim modułem pośrednim, jest moduł odpowiadający za komunikację pomiędzy interfejsem graficznym a systemem SWI-Prolog z biblioteką leanCop. Tutaj również zastosowano wymiane plikową do zwracania wyników. Wywołanie provera jest wykonywane poprzez odpowiedni skrypt. Należy zauważyć, że oprócz ustawiania opcji i potrzeby parsowania danych wejściowych przez inny moduł, tworzenie i wywoływanie poleceń z bazą danych różni się od rozwiązania z modułu z Prover9. Z kolei prover Prologowy jako parametr może przyjmować wyłącznie jeden plik jako parametr wejściowy, dlatego też moduł tworzy przed każdym dowodzeniem, oddzielną wersję pliku wsadowego, która składa się z połączenia dotychczasowych udowodnionych tez, tez teorii, jak i tez które mają zostać udowodnione wraz z ewentualnymi nowymi założeniami. Funkcje na które należy zwrócić uwagę w tym procesie zostały przedstawione w Tab 4.3. 33 Nazwa funkcji Parametry Opis funkcji toParseTab- lista słów które Główna funkcja parsująca, która parseProv jeszcze należy przeparsować rozpoczyna parsowanie Text – text do sprzawdzenia Funkcja getKwant kwantyfikatorów odpowiedzialna poprawne za umieszczenie kwantyfikatorów z ich zmiennymi Tab. 4.3 Przegląd głównych funkcji pośredniczących dla parsowania z Prover9 do SWI-Prolog 4.5 Opis struktur danych Rozważmy teraz struktury danych użytych w rozwiązaniu. Ponieważ aplikacja nie korzysta z jednego narzędzia, ale z dwóch proverów napisanych w różnych językach i różną składnią twierdzeń, powstał problem reprezentacji danych w aplikacji. Z uwagi na to, składnia Prover9 jest czytelna i prosta do nauczenia, co można zauważyć na Rys. 3.1. Więc aby w pełni skorzystać z systemu do interfejsu graficznego, czy też w plikach z twierdzeniami, wszystkie dane zapisane będą właśnie w tym języku. Przykładowe dane wejściowe jak i przykładowy plik został pokazany na Rys.4.5 i 4.6. i(prym(x),prym(y)) -> all z ( plus(x,y) =z <-> subset(z,x) & subset(z,y) & ( all u (subset(u,x) & subset(u,y) -> subset(u,z)))). Rys. 4.5 Postać przykładowego pliku wejściowego Kolejnym etapem w procesie obliczeniowym jest dostarczenie danych do SWIProloga. Dane z Prover9 są przetwarzane do składni TPTP. Zamiana podstawowych operatorów logicznych jest dokonywana za pomocą prostych podmian. Konwersja zmiennych wraz z kwantyfikatorami została przeprowadzona w inny sposób, ze względu na dwa czynniki. Po pierwsze zmienne w Prover9 nie muszą posiadać kwantyfikatorów w przeciwieństwie do tych w TPTP. Po drugie w Prover9 poprawna deklaracja, jeśli już wymienia kwantyfikatory przed zmiennymi, wówczas przed każdą zmienną musi zostać podany oddzielnie dla niej kwantyfikator. 34 formulas(sos). e(x,y) <-> (all z (subset(x,z) ->( - subset(y,z)))). %defE i(x,y) <-> (∃s z (subset(x,z) &( subset(y,z)))). %defI o(x,y) <-> (∃s z (subset(x,z) &( - subset(y,z)))). %defO end_of_list. formulas(goals). i(x,x). %L3 end_of_list. Rys. 4.6 Przykładowy plik w systemie Prover9 Ostatnią omawianą tu strukturą danych jest forma zwrotu wyników wywołanego polecenia dowodu. Musiał on spełniać następujące warunki: umożliwić automatyczną archiwizację wyników, wynik ma być czytelny i zrozumiały bez dodatkowych narzędzi, wynik powinien zawierać statystki na temat dowodu, być łatwy do odczytania dla interfejsu graficznego, Aby spełnić wszystkie powyższe wymagania, wyniki testów są przetwarzane przez moduł pośredni i zapisywane w jednym pliku, którego nazwa jest kombinacja daty, typu użytego provera i ilości dowodzonych twierdzeń. Treść w nim zawarta zawiera następujące po sobie sekcje informacji: czasowej, użytych opcji, sukcesu dowodów, statystyk związanych z dowodzeniem, Sekcja czasowa zawiera czasy uruchomienia i zakończenia wywołania dowodu poprzez aplikację. Czasy startu dowodzeń proverów jak i ich zakończenia jak i całkowity czas dowodu. Kolejna sekcja opisuje użyte opcje, czyli rodzaj proverów jakie zostały wykorzystane, czy dowodzenie było wywołane z listą plików czy też jako pola w aplikacji, maksymalny czas jaki został przewidziany na każdy dowód. Fragment pliku o sukcesie dowodów, dla każdego pliku wykorzystanego do dowodzenia wymienia jego nazwę, wynik dowodu dla proverów – czyli czy dowód zakończył się sukcesem jak i jego czas trwania. Statystyki zawierają swoiste podsumowanie dowodu, czyli ilość udowodnionych, 35 nieudowodnionych jak i wszystkich rozważanych twierdzeń. Liczbę dowodów przerwanych przez przekroczenie czasu, liczbę dowodów które nie mają rozwiązania w systemie, średnie czasy dowodów wszystkich twierdzeń w każdym z proverów (ich najkrótsze i najdłuższe czasowo dowody wraz z tymi czasami). 4.6 Podsumowanie rozdziału W wyniku przeprowadzonych prac programistycznych utworzono środowisko, które spełnia wszystkie postawione zadania zgodnie ze schematem pokazanym na Rys. 6.1. Utworzone oprogramowanie napisane zostało w języku Python,C# i Prolog, przy użyciu biblioteki leanCop i liczy 1638 linii kodu. Oprogramowanie składa się z dwóch części dowodzących. Pierwsza z nich – zbudowana z Prover9, odpowiada za dowodzenie twierdzeń logiki obiektów, które są oryginalną koncepcją Nieznańskiego oraz nigdy wcześniej nie były implementowane maszynowo. Druga z nich zawiera SWI-Prolog i leanCop również dowodzi twierdzenia , w tej logice jednak została inaczej zaimplementowana. Możliwości utworzonego oprogramowania zostaną zweryfikowane w następnym punkcie. 36 5 Eksperymentowanie w utworzonym systemie 5.1 Sprawdzanie poprawności oprogramowania Przedstawimy teraz wyniki eksperymentów przeprowadzonych z utworzoną aplikacją. Aby zweryfikować poprawność działania stworzonego oprogramowania, konsekwentnie podczas jego tworzenia wykonano testy jednostkowe. Taki sposób postępowania został dokonany ze względu na fakt, iż testy jednostkowe można wykonywać jako zautomatyzowane testy na bieżąco podczas tworzenia kolejnych funkcji i modułów na modyfikowanych funkcjach czy też klasach. Sprzyja to łatwemu wychwyceniu błędu tuż po jego pojawieniu się w kodzie źródłowym programu, jego szybką lokalizację i poprawienie działania programu. Wykonanie przeprowadzonych testów polegało na weryfikacji poprawności działania pojedynczych jednostek systemu, jego metod, funkcji i obiektów. Każdy fragment kodu objęty testem został poddany weryfikacji w taki sposób, że wykonany kod z ustalonym wejściem jest sprawdzany pod kątem otrzymanego wyniku, stanu lub też wyjątku, który jest porównywany z oczekiwanymi rezultatami. Do tego celu dla ważniejszych ścieżek funkcji zostały napisane metody je testujące. Wykonane testy zostały podzielone na następujące fragmenty: analiza ścieżek, testowanie warunków brzegowych. Testy dla ścieżek stworzonego programu, zostały sprawdzone do określenia punktu startowego jak i punktu końcowego dla testu jak i znalezieniu przebiegu programu pomiędzy tymi punktami. Do testowania wartości brzegowych użyto metod testowych, w których 37 podano jako argumenty wartości środkowe, brzegowe i takie które znajdują się pomiędzy ograniczeniami zbioru argumentów. 5.2 Eksperymenty w utworzonym narzędziu programistycznym Utworzona aplikacja pozwala na dwa sposoby komunikacji z użytkownikiem, co zostało opisane w rozdziale 4, za pomocą linii poleceń jak i z pomocą aplikacji z graficznym interfejsem użytkownika. Początkowo rozważano implementację eksperymentów wyłącznie za pomocą konsolowej linii poleceń, jednak takie podejście wiązałoby się z mnóstwem czynności, które w łatwy sposób można zautomatyzować. W trybie linii poleceń, nie jest możliwa praktyczna realizacja serii eksperymentów, które można by było w prosty sposób wykonać i powtarzać w określonych warunkach. Utworzone środowisko pozwala w prosty sposób przeprowadzić testy, czy też modyfikować opcje jeśli dowód nie zostanie znaleziony w wymaganym czasie. Stworzone oprogramowanie, jak to zostało opisane w rozdziale 4, zwraca dużo cennych informacji na temat poszukiwanego dowodu dla użytkownika. Aby zwiększyć szansę na znalezienie takiego dowodu, istnieje możliwość oznaczenia tez, stwierdzeń, które powinny być wykorzystane w pierwszej kolejności. Jest to bardzo istotna własność, ponieważ przy dużej liczbie twierdzeń w bazie danych, systemy Prover9 i SWI-Prolog mogą zacząć szukać rozwiązania w nieodpowiednich klauzulach, lub korzystać z niewłaściwych zasad wnioskowania. W takim przypadku można też spróbować zmienić współczynnik wagowy, aby system nie drążył wciąż tej samej gałęzi rozwiązania. Poniżej pokazano przykładowy plik wejściowy dla systemu Prover9, a zaraz za nim jego rozwiązanie. W dalszej części zostanie przedstawiony ten sam problem dla systemu SWI-Prolog wraz z biblioteką leancop. formulas(sos). incl(x,x). %p1 incl(x,y) & incl(y,z) -> incl(x,z). %p2 exEq(x,y) <-> incl(x,y) & incl(y,x). % def exEq ∃s y all x incl(x,y). %p3 exEq(y,1) <-> all x incl(x,y). % def 1 ∃s x all y incl(x,y). %p4 exEq(x,0) <-> all y incl(x,y). % def 0 38 all x all y ∃s z ( incl(x,z) & incl(y,z) & ( all v ( incl(x,v) & incl(y,v) -> incl(z,v)))). exEq(z,or(x,y)) <-> incl(x,z) & incl(y,z) & all v ( incl(x,v) & incl(y,v) -> incl(z,v)). all x all y ∃s z ( incl(z,x) & incl(z,y) & all v( incl(v,x) & incl(v,y) -> incl(v,z))).%p6 exEq(z,and(x,y)) <-> incl(z,x) & incl(z,y) & all v ( incl(v,x)&incl(v,y) -> inc(v,z)). exEq(and(or(x,y),z),or(and(x,z),and(y,z))).%p7 all x ∃s y ( exEq(or(x,y),1) & exEq(and(x,y),0)). % p8 exEq(y,-x) -> exEq(or(x,y),1) & (exEq(and(x,y),0)). (incl(1,0)). %defnona % p9 end_of_list. formulas(goals). all x ( incl(x,1)). %t1 end_of_list. Jeśli systemowi Prover9 dostarczymy dane w takim formacie, otrzymamy następujący plik wynikowy, w którym zawarty jest dowód naszego twierdzenia. ============================CLAUSES FOR SEARCH=================== % Clauses after input processing: formulas(usable). end_of_list. formulas(sos). 16 incl(x,x). [assumption]. 17 -incl(x,y) ∨ -incl(y,z) ∨ incl(x,z). [clausify(1)]. 18 -exEq(x,y) ∨ incl(x,y). [clausify(2)]. 19 -exEq(x,y) ∨ incl(y,x). [clausify(2)]. 20 exEq(x,y) ∨ -incl(x,y) ∨ -incl(y,x). [clausify(2)]. 21 incl(x,c1). [clausify(3)]. 22 -exEq(x,1) ∨ incl(y,x). [clausify(4)]. 23 exEq(x,1) ∨ -incl(f1(x),x). [clausify(4)]. 24 incl(c2,x). [clausify(5)]. 25 -exEq(x,0) ∨ incl(x,y). [clausify(6)]. 26 exEq(x,0) ∨ -incl(x,f2(x)). [clausify(6)]. 27 incl(x,f3(x,y)). [clausify(7)]. 28 incl(x,f3(y,x)). [clausify(7)]. 39 29 -incl(x,y) ∨ -incl(z,y) ∨ incl(f3(x,z),y). [clausify(7)]. 30 -exEq(x,or(y,z)) ∨ incl(y,x). [clausify(8)]. 31 -exEq(x,or(y,z)) ∨ incl(z,x). [clausify(8)]. 32 -exEq(x,or(y,z)) ∨ -incl(y,u) ∨ -incl(z,u) ∨ incl(x,u). [clausify(8)]. 33 exEq(x,or(y,z)) ∨ -incl(y,x) ∨ -incl(z,x) ∨ incl(y,f4(y,z,x)). [clausify(8)]. 34 exEq(x,or(y,z)) ∨ -incl(y,x) ∨ -incl(z,x) ∨ incl(z,f4(y,z,x)). [clausify(8)]. 35 exEq(x,or(y,z)) ∨ -incl(y,x) ∨ -incl(z,x) ∨ -incl(x,f4(y,z,x)). [clausify(8)]. 36 incl(f5(x,y),x). [clausify(9)]. 37 incl(f5(x,y),y). [clausify(9)]. 38 -incl(x,y) ∨ -incl(x,z) ∨ incl(x,f5(y,z)). [clausify(9)]. 39 -exEq(x,and(y,z)) ∨ incl(x,y). [clausify(10)]. 40 -exEq(x,and(y,z)) ∨ incl(x,z). [clausify(10)]. 41 exEq(x,and(y,z)) ∨ -incl(x,y) ∨ -incl(x,z) ∨ incl(f6(y,z,x),y). [clausify(10)]. 42 exEq(x,and(y,z)) ∨ -incl(x,y) ∨ -incl(x,z) ∨ incl(f6(y,z,x),z). [clausify(10)]. 43 exEq(and(or(x,y),z),or(and(x,z),and(y,z))). [assumption]. 44 exEq(or(x,f7(x)),1). [clausify(11)]. 45 exEq(and(x,f7(x)),0). [clausify(11)]. 46 -exEq(x,-y) ∨ exEq(or(y,x),1). [clausify(12)]. 47 -exEq(x,-y) ∨ exEq(and(y,x),0). [clausify(12)]. 48 -incl(1,0). [assumption]. 49 -incl(c3,1). [deny(13)]. 50 exEq(x,and(y,z)) ∨ -incl(x,y) ∨ -incl(x,z) ∨ -exEq(x,and(u,w)) ∨ -incl(f6(y,z,x),u) ∨ -incl(f6(y,z,x),w). [resolve(14,d,15,d)]. 51 exEq(x,x). [factor(20,b,c),unit_del(b,16)]. 52 -incl(x,y) ∨ incl(f3(x,x),y). [factor(29,a,b)]. 53 -exEq(x,or(y,y)) ∨ -incl(y,z) ∨ incl(x,z). [factor(32,b,c)]. 54 exEq(x,or(y,y)) ∨ -incl(y,x) ∨ incl(y,f4(y,y,x)). [factor(33,b,c)]. 55 exEq(x,or(y,y)) ∨ -incl(y,x) ∨ -incl(x,f4(y,y,x)). [factor(35,b,c)]. 56 -incl(x,y) ∨ incl(x,f5(y,y)). [factor(38,a,b)]. 57 exEq(x,and(y,y)) ∨ -incl(x,y) ∨ incl(f6(y,y,x),y). [factor(41,b,c)]. 58 exEq(x,and(y,y)) ∨ -incl(x,y) ∨ -exEq(x,and(z,u)) ∨ -incl(f6(y,y,x),z) ∨ -incl(f6(y,y,x),u). [factor(50,b,c)]. 59 exEq(x,and(y,z)) ∨ -incl(x,y) ∨ -incl(x,z) ∨ -exEq(x,and(u,u)) ∨ -incl(f6(y,z,x),u). [factor(50,e,f)]. 60 exEq(x,and(y,y)) ∨ -incl(x,y) ∨ -exEq(x,and(z,z)) ∨ -incl(f6(y,y,x),z). [factor(58,d,e)]. end_of_list. formulas(demodulators). end_of_list. ============================== end of clauses for search ============= =============================PROOF============================== % Proof 1 at 0.00 (+ 0.03) seconds. % Length of proof is 9. % Level of proof is 3. % Maximum clause weight is 9. % Given clauses 34. 2 exEq(x,y) <-> incl(x,y) & incl(y,x) # label(non_clause). [assumption]. 4 exEq(y,1) <-> (all x incl(x,y)) # label(non_clause). [assumption]. 13 (all x incl(x,1)) # label(non_clause) # label(goal). [goal]. 16 incl(x,x). [assumption]. 40 20 exEq(x,y) ∨ -incl(x,y) ∨ -incl(y,x). [clausify(2)]. 22 -exEq(x,1) ∨ incl(y,x). [clausify(4)]. 49 -incl(c3,1). [deny(13)]. 51 exEq(x,x). [factor(20,b,c),unit_del(b,16)]. 231 $F. [ur(22,b,49,a),unit_del(a,51)]. ============================end of proof ========================== =============================STATISTICS=========================== Given=34. Generated=245. Kept=215. proofs=1. Usable=34. Sos=160. Demods=0. Limbo=21, Disabled=37. Hints=0. Weight_deleted=0. Literals_deleted=0. Forward_subsumed=29. Back_subsumed=0. Sos_limit_deleted=0. Sos_displaced=0. Sos_removed=0. New_demodulators=0 (0 lex), Back_demodulated=0. Back_unit_deleted=0. Demod_attempts=0. Demod_rewrites=0. Res_instance_prunes=0. Para_instance_prunes=0. Basic_paramod_prunes=0. Nonunit_fsub_feature_tests=836. Nonunit_bsub_feature_tests=726. Megabytes=0.17. User_CPU=0.00, System_CPU=0.03, Wall_clock=0. ============================== end of statistics ===================== =============================end of search========================= THEOREM PROVED Exiting with 1 proof. Komentarz do tego listingu jest następujący. Jako założenia podano aksjomaty z logiki pojęć. Za zadanie przedstawiono znalezienie dowodu tezy T1 2.3.14. System po procesie skolemizacji, przedstawia kolejne kroki w procesie szukania dowodu tez. Jak widać dowód zawiera tylko niektóre klauzule które stworzył w procesie skolemizacji, ponieważ ich część została usunięta w procesie szukania dowodu. Czytając statystyki można zauważyć, że do utworzenia tego dowodu potrzebne było wygenerowanie 245 klazul, z czego 30 zostało wyeliminowanych, a użytecznych zostało 34. Długość dowodu wyniosła 9, a szukanie całego dowodu zajęło 0,03 sekundy. Jednak czas jaki będzie wykorzystywany, to czas całego procesu dowodu, który będzie musiał zostać zmierzony oddzielnie. Kolejny listing przedstawia plik wejściowy dla systemu SWI-Prolog wraz z biblioteką leanCop w składni TPTP. fof(p1,axiom, ( ! [X] : ( incl(X , X)))). 41 fof(p2,axiom, ( ! [Y,X,Z] : ( incl(X , Y) & incl(Y , Z) ⇒ incl(X , Z)))). fof(defexEq,axiom, ( ! [Y,X] : ( exEq(X , Y) ⇔ incl(X , Y) & incl(Y , X)))). fof(p3,axiom, ( ? [Y] : ( ( ! [X] : ( incl(X , Y)))))). fof(def1,axiom, ( ! [Y] : ( exEq(Y , 1) ⇔ ( ! [X] : ( incl(X , Y))))) ). fof(p4,axiom, ( ? [X] : ( ( ! [Y] : ( incl(X , Y)))))). fof(def0,axiom, ( ! [X] : ( exEq(X , 0) ⇔ ( ! [Y] : ( incl(X , Y)))))). fof(p5,axiom, ( ! [Y] : ( ( ! [X] : ( ( ? [Z] : ( (incl(X , Z) & incl(Y , Z) & (( ! [V] : ( (incl(X , V) & incl(Y , V) ⇒ incl(Z , V))))))))))))). fof(defOR,axiom, ( ! [X,Y,Z] : ( exEq(Z , or(X , Y)) ⇔ incl(X , Z) & incl(Y , Z) & ( ! [V] : ( (incl(X , V) & incl(Y , V) ⇒ incl(Z , V))))))). fof(p6,axiom, ( ! [Y] : ( ( ! [X] : ( ( ? [Z] : ( (incl(Z , X) & incl(Z , Y) & ( ! [V] : ( (incl(V , X) & incl(V , Y) ⇒ incl(V , Z)))))))))))). fof(defAND,axiom, ( ! [X,Y,Z] : ( exEq(Z , and(X , Y)) ⇔ incl(Z , X) & incl(Z , Y) & ( ! [V] : ( (incl(V , X) & incl(V , Y) ⇒ inc(V , Z))))))). fof(p7,axiom, ( ! [X,Y,Z] : ( exEq(and(or(X , Y) , Z) , or(and(X , Z) , and(Y , Z)))))). fof(p8,axiom, ( ! [X] : ( ( ? [Y] : ( (exEq(or(X , Y) , 1) & exEq(and(X , Y) , 0))))))). 42 fof(defnona,axiom, ( ! [X,Y] : ( exEq(Y , ~ X) ⇒ exEq(or(X , Y) , 1) & (exEq(and(X , Y) , 0))))). fof(p9,axiom, ~ (incl(1 , 0))). fof(t1,conjecture, ( ! [X] : ( (incl(X , 1))))). Jest to plik wejściowy jaki otrzymamy po przetłumaczeniu pliku wejściowego napisanego w języku Prover9 do formatu TPTP, poprzez wykorzystanie modułu pośredniego. Po przekazaniu powyższego pliku wejściowego do systemu SWI-Prolog i biblioteki leanCop otrzymamy następujący wynik. Proof:' -----'Translation into (disjunctive) clausal form:' ' ('1') '[incl(10∧[],1)] ' ('2') '[incl(1,0)] ' ('3') '[exEq(_G15,~_G14),-exEq(or(_G14,_G15),1)] ' ('4') '[exEq(_G15,~_G14),-exEq(and(_G14,_G15),0)] ' ('5') '[-exEq(or(_G33,1∧[_G33]),1)] ' ('6') '[-exEq(and(_G33,1∧[_G33]),0)] ' ('7') '[-exEq(and(or(_G34,_G35),_G36),or(and(_G34,_G36),and(_G35,_G36)))] ' ('8') '[exEq(_G57,and(_G55,_G56)),-incl(_G57,_G55)] ' ('9') '[exEq(_G57,and(_G55,_G56)),-incl(_G57,_G56)] ' ('10') '[exEq(_G57,and(_G55,_G56)),-inc(_G70,_G57),incl(_G70,_G55),incl(_G70,_G56)] ' ('11') '[-exEq(_G57,and(_G55,_G56)),incl(_G57,_G55),incl(_G57,_G56),incl(2∧[_G57,_G56,_G55],_G55)] ' ('12') '[-exEq(_G57,and(_G55,_G56)),incl(_G57,_G55),incl(_G57,_G56),incl(2∧[_G57,_G56,_G55],_G56)] ' ('13') '[exEq(_G57,and(_G55,_G56)),incl(_G57,_G55),incl(_G57,_G56),inc(2∧[_G57,_G56,_G55],_G57)] ' ('14') '[-incl(3∧[_G81,_G80],_G81)] ' ('15') '[-incl(3∧[_G81,_G80],_G80)] ' ('16') '[-incl(_G209,3∧[_G81,_G80]),incl(_G209,_G81),incl(_G209,_G80)] ' ('17') '[exEq(_G84,or(_G82,_G83)),-incl(_G82,_G84)] ' ('18') '[exEq(_G84,or(_G82,_G83)),-incl(_G83,_G84)] ' ('19') '[exEq(_G84,or(_G82,_G83)),-incl(_G84,_G97),incl(_G82,_G97),incl(_G83,_G97)] ' ('20') '[-exEq(_G84,or(_G82,_G83)),incl(_G82,_G84),incl(_G83,_G84),incl(_G82,4∧[_G84,_G83,_G82])] ' ('21') '[-exEq(_G84,or(_G82,_G83)),incl(_G82,_G84),incl(_G83,_G84),incl(_G83,4∧[_G84,_G83,_G82])] ' ('22') '[exEq(_G84,or(_G82,_G83)),incl(_G82,_G84),incl(_G83,_G84),incl(_G84,4∧[_G84,_G83,_G82])] ' ('23') '[-incl(_G108,5∧[_G108,_G107])] ' ('24') '[-incl(_G107,5∧[_G108,_G107])] 43 ' ('25') ' ('26') ' ('27') ' ('28') ' ('29') ' ('30') ' ('31') ' ('32') ' ('33') ' ('34') ' ('35') ' ('36') '[-incl(5∧[_G108,_G107],_G257),incl(_G108,_G257),incl(_G107,_G257)] '[exEq(_G109,0),-incl(_G109,_G113)] '[-exEq(_G109,0),incl(_G109,6∧[_G109])] '[-incl(7∧[],_G281)] '[exEq(_G117,1),-incl(_G121,_G117)] '[-exEq(_G117,1),incl(8∧[_G117],_G117)] '[-incl(_G299,9∧[])] '[-incl(_G148,_G148)] '[-incl(_G137,_G138),incl(_G137,_G136),incl(_G136,_G138)] '[exEq(_G126,_G125),-incl(_G126,_G125)] '[exEq(_G126,_G125),-incl(_G125,_G126)] '[-exEq(_G126,_G125),incl(_G126,_G125),incl(_G125,_G126)] Proof ' Then clause ('1')'' is false if at least one of the following is false:' ' '[incl(10∧[],1)] 1' Assume 'incl(10∧[],1)' is ''false.' ' '' Then clause ('29')'' under the substitution '[[_G121,_G117],[10∧[],1]] ' '' is false if at least one of the following is false:' ' '' '[exEq(1,1)] 1'.'1' Assume 'exEq(1,1)' is ''false.' ' '' '' '' Then clause ('36')'' under the substitution '[[_G126,_G125],[1,1]] ' '' '' '' is false if at least one of the following is false:' ' '' '' '' '[incl(1,1),incl(1,1)] 1'.'1'.'1' Assume 'incl(1,1)' is ''false.' ' '' '' '' '' '' Then clause ('32')'' under the substitution '[[_G148],[1]] ' '' '' '' '' '' is true.' 1'.'1'.'2' Assume 'incl(1,1)' is ''false.' ' '' '' '' '' '' Then clause ('32')'' under the substitution '[[_G148],[1]] ' '' '' '' '' '' is true.' Jak widać na powyższym przykładzie systemowi SWI-Prolog i bibliotece leancop dowód zajął 5 kroków. Jak można zauważyć na powyższym listingu, system na początku również przechodzi etap skolemizacji. Jak można zauważyć po tym procesie zostaje nam 36 klauzul (system Prover9 miał ich 34). Faktem wartym tutaj wspomnienia jest krótki opis poszczególnych kroków dowodu, który pomaga zrozumieć, co się dzieje w poszczególnych etapach dowodzenia. W kolejnych podrozdziałach zostanie przedstawione podsumowanie przeprowadzonych dowodów w z logiki obiektów kategorialnych jak i logiki pojęć, które to dowody zostały wykonane w analogiczny sposób do powyżej przedstawionego przykładu. 5.2.1 Automatyczne dowodzenie twierdzeń logiki obiektów kategorialnych W analogiczny sposób co przedstawił powyższy przykład zostały przeprowadzone próby dowodów 73 tez przedstawionych w rozdziale 2.2. Wynika z nich, że oba systemy są efektywne do jego implementacji, i w większości przypadków bez większych 44 problemów dowodzą wymienione twierdzenia. Zbiorcza Tabl. 5.1 przedstawia zastaw uzyskanych parametrów wykonania dla podanych założeń dla tez z podrozdziału 2.2. Długość dowodu Czas Numer tezy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 Prover9 (s) SWI-Prolog (s) 0.07400393486022949 0.07900404930114746 0.0870048999786377 0.09100508689880371 0.11100602149963379 1.6900968551635742 0.07900500297546387 0.10100603103637695 0.09800481796264648 0.08300495147705078 0.08300495147705078 0.10300588607788086 0.10400581359863281 0.08500504493713379 0.1000058650970459 0.08800506591796875 0.09800481796264648 0.26601600646972656 0.07900381088256836 0.0890052318572998 0.1150059700012207 0.10900592803955078 0.11800718307495117 0.11500692367553711 0.12400698661804199 0.25501489639282227 0.11700701713562012 0.21801209449768066 0.28101611137390137 0.09300494194030762 0.2420141696929931 0.2020118236541748 0.1730101108551025 0.1860110759735107 0.1770100593566894 0.1920108795166015 0.2210130691528320 0.2370138168334961 0.2340130805969238 0.367020845413208 0.2640151977539062 0.2550148963928222 0.2120118141174316 0.3410191535949707 0.2320129871368408 5.200298070907593 0 21.867249965667725 0.2040109634399414 0 0.3100180625915527 0.2150118350982666 0.1930119991302490 0.1980111598968505 0.2040119171142578 0 0 0.4010231494903564 0 0 0 0 0 0 2.8321621417999268 2.3151321411132812 0.11000704765319824 22.33827805519104 0.09600615501403809 0.08500504493713379 0.10800600051879883 0.14500784873962402 Prover9 0.3040168285369873 0 0 0 0 0 SWI-Prolog 7 7 8 15 17 31 7 3 2 6 9 9 9 9 11 30 35 19 6 22 15 8 8 7 8 16 10 14 19 31 0 30 33 10 19 24 20 6 9 7 7 7 15 27 33 9 11 19 31 27 21 21 33 21 93 0 71 23 0 13 7 7 5 7 0 0 27 0 0 0 0 0 11 0 0 0 0 0 45 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 0.15500903129577637 0.1650099754333496 1.7701010704040527 0.08300495147705078 0.09800601005554199 0.09500503540039062 7.788444995880127 0.0890049934387207 60.4424569606781 14.51082992553711 14.160809993743896 0.0760040283203125 0.7040400505065918 0.36202096939086914 0.09600615501403809 0.12842750549316406 0.16084885597229004 0.09800601005554199 0.09700608253479004 0.08100485801696777 0.11342620849609375 0.14584755897521973 0.1782689094543457 0.21069025993347168 0.6000349521636963 0.6324563026428223 2.351701259613037 2.384122610092163 2.215693235397339 2.248114585876465 2.280535936355591 2.312957286834717 0 0 0 9 9 18 28 4 4 27 37 27 8 8 27 42 15 20 29 36 34 12 12 13 15 19 27 20 29 0 36 39 0 45 46 48 52 0.0037159919738769 0.2090120315551757 0.2170119285583496 0 0.569033145904541 0.4490261077880859 0.3070178031921386 0.348020076751709 1.0270588397979736 0.9290540218353271 0.6610381603240967 1.0440599918365479 1.9941141605377197 2.2241270542144775 1.3900799751281738 1.0730609893798828 0.3190181255340576 1.1580660343170166 1.2360708713531494 1.5760910511016846 2.280129909515381 1.7861018180847168 2.4361391067504883 0 2.0951199531555176 0.3020169734954834 2.4701409339904785 0 4.531259059906006 4.384249925613403 5.628321886062622 3.7012109756469727 2.6991541385650635 0 0 0 0 7 7 0 19 13 7 7 27 27 27 27 15 15 25 19 7 19 19 21 21 17 17 17 3 17 17 19 27 27 27 Tab 5.1 Zbiorcze zestawienie wyników przeprowadzonych eksperymentów z logiki obiektów Ważnym kryterium oceny każdego systemu podsumować wydajność obu systemów w tej logice, Rys. jest jego wydajność. Aby 5.2-5.3 prezentują wykresy słupkowe zależności czasu od numeru twierdzenia , jak i wykres podsumowujący czas trwania przeprowadzenia dowodów w obu systemach jak i ilości udowodnionych tez. 46 73 71 69 67 65 63 61 59 57 55 53 51 49 47 45 43 41 39 37 SWI-Prolog 35 Prover9 33 31 29 27 25 23 21 19 17 15 13 11 9 7 5 3 1 0 5 10 15 20 25 Rys. 5.2 Przedstawia porównanie proverów pod względem czasu dowodzenia poszczególnych twierdzeń w logice obiektów kategorialnych 47 SWI-Prolog; 54 Prover9; 70 Rys. 5.3 Przedstawia porównanie proverów pod względem liczby udowodnionych tez w logice obiektów kategorialnych Podsumowując średni czas na udowodnienie twierdzenia dla Prover9 wyniósł 1,288 sekund a dla SWI-Prologu 1,119 sekund, jednak SWI-Prolog dowiódł zaledwie 54 twierdzenia przy 70 Prover9. 5.2.2 Automatyczne dowodzenie twierdzeń logiki pojęć Analogicznie do poprzedniego podrozdziału zostanie teraz przedstawiony problem dowodzenia w logice pojęć. Składa się ona z 66 twierdzeń przedstawionych w podrozdziale 2.3. Zbiorcza Tabl. 5.2 przedstawia zastaw uzyskanych parametrów wykonania dla podanych założeń. Długość dowodu Czas Numer tezy Prover9 (s) SWI-Prolog (s) Prover9 SWI-Prolog 1 0,086005 0,264015 9 9 2 0,077004 0,245014 9 9 3 0,081004 0,257014 7 5 4 0,100006 0,248014 7 5 5 0,110007 0,203012 7 5 6 0,096005 0,237014 12 21 7 0,087005 0,255014 7 3 8 0,105006 0,194011 7 3 48 9 5,505315 0,261015 19 35 10 0,103006 0,235014 12 19 11 0,097006 0,229013 10 23 12 0,727042 0,449025 21 35 13 0,122007 0,249014 13 11 14 0,091005 0,266016 13 11 15 0,091006 0,195011 14 5 16 0,136008 1,893109 15 15 17 0,127007 0,268015 10 9 18 0,102006 0,198011 15 23 19 0,117007 0,217013 16 27 20 0,122007 0,256015 16 27 21 0,115006 0,258015 12 19 22 0,112007 0,241014 16 29 23 0,107006 0,222013 16 27 24 0,098005 0,227013 12 19 25 0 0 0 0 26 0,243014 0,250014 10 19 27 0,116006 4,140466 15 15 28 0,115007 0,001716 31 0 29 0,084005 0,223013 12 19 30 0,089005 0 13 0 31 0 0 0 0 32 0 6,928854 0 35 33 0,812046 0,212013 19 27 34 5,912542 2,700154 33 33 35 0,946054 0,252015 20 27 36 0 0 0 0 37 0,074005 0,290016 5 7 38 0,076004 0,198011 5 5 39 0,079005 0,200012 5 5 40 0,101006 0,212012 5 5 41 0,092005 0,225013 5 7 49 42 0,108006 0,205012 5 3 43 0,099006 0,195012 5 3 44 0,089005 0,211012 5 5 45 0,099005 0,199012 5 5 46 0,099006 0,190011 5 5 47 0,115007 0,193011 5 5 48 0,084005 0,200011 5 7 49 0,084005 0,192011 5 7 50 0,114006 0,214012 5 7 51 0,124007 0,202012 5 3 52 0,110006 0,198011 5 3 53 0,099005 0,204011 5 7 54 0,125007 0,207012 5 7 55 0,104006 0,194011 5 7 56 0,109006 0,201012 5 7 57 0,100006 0,202011 5 7 58 0,097006 0,200011 5 7 59 0,094005 0,196012 5 7 60 0,105006 0,203011 5 7 61 0,111006 0,207012 5 7 62 0,086005 0,209012 5 7 63 0,085005 0,218013 5 7 64 0,101005 0,223013 5 7 65 0,120007 0,239014 5 7 66 0,123007 0,222013 5 7 Tab. 5.2. Zbiorcze zestawienie wyników przeprowadzonych eksperymentów z logiki pojęć Analogicznie Rys 5.4–5.5 prezentują wykresy słupkowe zależności czasu uzyskania odpowiedzi systemu jak i liczby udowodnionych tez. 50 65 63 61 59 57 55 53 51 49 47 45 43 41 39 37 35 SWI-Prolog 33 Prover9 31 29 27 25 23 21 19 17 15 13 11 9 7 5 3 1 0 1 2 3 4 5 6 7 8 Rys. 5.4 Przedstawia porównanie proverów pod względem czasu dowodzenia poszczególnych twierdzeń w logice pojęć 51 SWI-Prolog; 61 Prover9; 62 Rys. 5.5 Przedstawia porównanie proverów pod względem liczby udowodnionych tez w logice pojęć Średni czas na udowodnienie twierdzenia dla Prover9 wyniósł 0,3006 sekundy a dla SWI-Prologu 0,4322 sekundy. 5.3 Podsumowanie rozdziału Jak można zauważyć z przedstawionych tutaj tablic i wykresów zamieszczonych w podrozdziałach 5.2.1 i 5.2.2 dla logiki obiektów kategorialnych, jak i dla logiki pojęć wynika ogólny wniosek. System Prover9 jest lepszym systemem do implementacji rozważanych tutaj logik. Nie tylko udowodnił on więcej tez, ale także dowodził w krótszym czasie, choć niektóre jego dowody były dłuższe. Z kolei system SWI-Prolog wraz z biblioteką leanCop również wydaje się dość interesującym rozwiązaniem, ponieważ produkuje dowody, które są czasem krótsze, a ich opis jest dosyć jasny. Należy jednak ogólnie stwierdzić, że przy systemie Prover9 i jego prostym i czytelnym języku SWI-Prolog wypada gorzej. 52 6 Wnioski 6.1 Zrealizowanie celów pracy Niniejsza praca dotyczy zagadnień implementacji logiki obiektów kategorialnych i logiki pojęć w technologii Prvover9 i SWI-Prolog. Jak wynika z przedstawionego wyżej materiału, cele pracy zostały wykonane. Zrealizowano środowisko do automatycznego dowodzenia twierdzeń logiki obiektów kategorialnych i logiki pojęć. Program zawiera w sumie ponad 1600 linii kodu. Nowatorstwo tej pracy polega na tym, że wymienione logiki Nieznańskiego miały dotychczas wartość czysto teoretyczną. Nie zostały one wcześniej zaimplementowane w takich systemach w naukach informatycznych. Zastosowanie takich logik do automatycznego dowodzenia twierdzeń rozszerza więc zakres możliwości sztucznej inteligencji. Pomimo pewnych trudności w badaniu tych nowych, nieznanych dotąd szerzej systemów logicznych, należy stwierdzić, że w pełni nadają się one do implementacji maszynowej. Zostały mianowicie zaimplementowane wszystkie twierdzenia logiki obiektów kategorialnych i logiki pojęć w środowisku Prover9 jak i w środowisku SWI-Prolog. Utworzoną aplikację poddano szczegółowej weryfikacji eksperymentalnej. Analiza eksperymentów i płynące z niej wnioski mogą zostać wykorzystane w przyszłości przez osoby, które będą chciały się posłużyć praktycznym zastosowaniem tych logik w systemie Prover9 lub SWI-Prolog przy budowie bardziej rozbudowanych systemów do dowodzenia twierdzeń. Należy jeszcze raz zauważyć, że realizacja systemów do automatycznego dowodzenia twierdzeń opierająca się na logice obiektów kategorialnych jak i na logice pojęć zakończyła się sukcesem. W środowiskach Prover9 i SWI-Prolog zostały odwzorowane większość twierdzeń rozważanych tu teorii logicznych. Kolejnym osiągnięciem pracy są wnioski płynące z przeprowadzonych eksperymentów w zrealizowanych środowiskach dowodzenia, które zostały stworzone dzięki 53 wykorzystaniu standardowych technik stosowanych w inżynierii oprogramowania. W tym celu przeprowadzono analizy i porównania, a dzięki otrzymanej aplikacji, otrzymano szereg korzyści wynikających z faktu ponownego wykorzystania stworzonego oprogramowania. Reasumując – aplikacja która została stworzona w ramach pracy, z punktu widzenia informatyki jest jedną z pierwszych, która automatycznie dowodzi w systemach Prover9 i SWI-Prolog twierdzenia logiki pojęć i obiektów kategorialnych. 6.2 Perspektywy na modyfikacje i dalszy rozwój opracowanego oprogramowania Praca ta może stanowić punkt startowy do prowadzenia dalszych implementacji ontologicznych systemów wnioskujących w technologii Prover9. Osiągnięcia uzyskane w niniejszej pracy mogą być w przyszłości rozwinięty w formie bardziej złożonego systemu ontologicznego wykorzystującego liczne rozszerzenia. Proponowane podejście może być rozszerzone dla szeregu koncepcji ontologicznych jak i logicznych (logika epistemiczna, kategorialna, mereologia itp.), które można wykorzystać do zwiększenia możliwości całego systemu. Efektywna realizacja takich koncepcji w przyszłości stanowiłaby istotny przyczynek dla dalszego rozwoju dziedziny sztucznej inteligencji i systemów automatycznego dowodzenia twierdzeń w rozbudowanych ontologiach. 54 Bibliografia [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] J. Mulawka, Systemy Ekspertowe, Warszawa: WNT, 1997 W. Traczyk, Inżynieria Wiedzy, Warszawa: EXIT, 2010 E. Nieznański, The Logic of Objects, in Philosophical Logic in Poland, Kluwer Academic Publishers, 1994, pp. 129-152 E. Nieznański, Logika, Warszawa: Wyd. C.H.Beck, 2011 S. Russel, P.Norvig, Artificial Inteligence: A Modren Aproach, Upper Saddle River: Prentice Hall, 2010 E. Morawiec, P. Mazanka, Metafizyka klasyczna wersji egzystencjalnej, Warszawa: Wyd. UKSW, 2006 T. Gruber, A translation approach to portalbe ontologies, Knowledge Acquisition, pp. 199-220, 1993 Brassa, I weź tu dogadaj się- Ontologie, Gazeta nr 1(20), 2004 T. Kwiatkowski, Logika ogólna, Lublin: Wyd. UMCS, 1998 J. Cybula, OWL - język definiowania ontologii w semantycznej sieci www, ProDialog, 2004 T. Kwiatkowski, Logika ogólna, Lublin: Wyd. UMCS, 1998 M. Summerfield, Python. Kompletne wprowadzenie do programowania, Helion,2010 S. Leśniewski, Podstawy ogólnej teorii mnogości, I, Moskwa, 1916. "Strona internetowa Prover9" 1 08 2014 [Online]. Available:http://www.cs.unm.edu/~mccune/mace4/ Z. Pawlak, Automatyczne dowodzenie twierdzeń, Warszawa: PZWS, 1965 J. Łukasiewicz, Elementy logiki matematycznej, Wyd. Uniwersytet Adama Mickiewicza, Poznań, 2008 Michael Spivey, An introduction to logic programming through Prolog, Prentice–Hall International, 1995 “Strona internetowa SWI-Prolog” 1 08 2014 [Online] Available: http://www.swiprolog.org/ “Strona internetowa leanCop” 1 08 2014 [Online] Available: http://www.leancop.de/ Mark Lutz, Python. Wprowadzenie, O'Reilly, 2010 Ian Griffiths, Programming C# 5.0: Building Windows 8, Web, and Desktop Applications for the .NET 4.5 Framework, O'Reilly, 2012 W. Nowakowski, Komputery Kwantowe. Osiągnięcia i problemy, Elektronika, nr 11/2013, pp 56,57 55