• Nie Znaleziono Wyników

Program w języku Prolog składa się z następujących elementów: faktów (prawdziwe stwierdzenia) reguł (związki między faktami) celu (określa zadanie do wykonania)

N/A
N/A
Protected

Academic year: 2021

Share "Program w języku Prolog składa się z następujących elementów: faktów (prawdziwe stwierdzenia) reguł (związki między faktami) celu (określa zadanie do wykonania)"

Copied!
39
0
0

Pełen tekst

(1)

Dariusz Banasiak

(2)

PROLOG – akronim od PROgramming in LOGic

Prolog został stworzony w 1971 przez Alaina Colmeraurera i Philipa Roussela. Podstawy teoretyczne sformułował

Robert Kowalski.

Prolog jest nazywany językiem programowania logicznego.

Podstawą dla jego utworzenia była logika predykatów pierwszego rzędu oraz zasada rezolucji.

Podstawowe implementacje:

Turbo Prolog (firma Borland) – ale to już historia !!!

SWI-Prolog (Jan Wielemaker)

(3)

Język Prolog zalicza się do języków deklaratywnych – pro- gram opisuje jedynie zadanie, które ma zostać rozwiązane (bez podania algorytmu). Program w języku Prolog składa się z następujących elementów:

faktów (prawdziwe stwierdzenia) reguł (związki między faktami)

celu (określa zadanie do wykonania).

Pisząc program w Prologu określamy CO należy rozwiązać, zamiast JAK należy problem rozwiązać.

Program napisany w języku Prologu różni się zasadniczo od programów w językach proceduralnych (Pascal, C, itd.), gdzie należy podać szczegółowy algorytm rozwiązania problemu.

(4)

Podstawowe zastosowania języka Prolog reprezentacja wiedzy

przeszukiwanie przestrzeni stanów rozwiązywanie problemów logicznych dowodzenie twierdzeń

przetwarzanie języka naturalnego realizacja systemów ekspertowych realizacja relacyjnych baz danych symboliczne rozwiązywanie równań

różniczkowanie i całkowanie symboliczne

(5)

Reprezentacja faktów

W Prologu fakty (bezwarunkowo prawdziwe twierdzenia) przedstawia się za pomocą predykatów pierwszego rzędu, których składnia wygląda następująco:

nazwa_predykatu(ob_1, ob_2, ... , ob_n).

Powyższy predykat oznacza relację określoną przez nazwa_predykatu zachodzącą pomiędzy obiektami:

ob_1, ob_2, ... , ob_n, które są argumentami predykatu.

Predykat: lubi(marta, mandarynki).

przedstawia fakt, że Marta lubi mandarynki (obiektami są

„marta” i „mandarynki”, zaś relacją „lubi”).

(6)

Przy tworzeniu predykatów obowiązują następujące reguły:

nazwa relacji (nazwa_pedykatu) jest pisana małymi literami,

argumenty predykatu znajdują się w nawiasach i są oddzielone przecinkami,

liczba argumentów predykatu, ich rodzaj i kolejność jest ściśle określona,

argumentami predykatu mogą być stałe lub zmienne,

stałe pisane są małymi literami, a zmienne zaczynają się dużą literą (stałe można umieścić również w cudzysłowie i wówczas mogą zawierać dowolne znaki),

predykat jest zakończony kropką.

(7)

Uwaga:

Dwa następujące predykaty:

lubi(piotr, marta).

lubi(marta, piotr).

reprezentują zupełnie różne fakty.

(8)

Reprezentacja reguł

Reguły są warunkowymi stwierdzeniami o istnieniu pew- nych zależności między obiektami (faktami).

Język Prolog akceptuje reguły o następującej składni:

IF A1 and A2 and ... and An THEN B

W notacji języka Prolog powyższą regułę można zapisać w jednej z dwóch postaci:

B if A1 and A2 and ... and An . B :- A1 , A2 , ... , An .

(9)

Tworząc regułę należy pamiętać o następujących zasadach:

nagłówek (konkluzja) reguły składa się tylko z jednego predykatu,

część warunkową reguły stanowi koniunkcja (iloczyn) dowolnej liczby warunków,

warunki oddzielone są słowem „and” (lub przecinkiem), reguła zakończona jest kropką.

Jako argumenty predykatów mogą wystąpić zmienne.

Przedstawiają one nazwy obiektów, które nie są w danej chwili znane. W Prologu nazwy zmiennych zaczynają się od dużej litery lub znaku ”_”.

(10)

Regułę, że Marta lubi mężczyzn, którzy są przystojni i jeżdżą porsche można zapisać następująco:

lubi(marta,X) :- mezczyzna(X), przystojny(X), jezdzi(X, porsche).

W regule tej X oznacza zmienną (nieznanego w danej chwili mężczyznę), który spełnia podane warunki.

Regułę, że osoba S jest siostrą osoby X możemy zapisać następująco:

siostra(S,X) :- kobieta(S), rodzice(Matka, Ojciec, S), rodzice(Matka, Ojciec, X), S /= X.

Reguła ta przedstawia prawidłowość: S jest siostrą X, jeżeli S jest kobietą oraz X i S mają tych samych rodziców.

(11)

Reguły i fakty w Prologu nazywa się klauzulami.

Klauzule zawarte w programie tworzą tzw. bazę danych programu.

W bazie może znajdować się większa liczba predykatów o takiej samej nazwie. Wówczas taki zbiór predykatów

będziemy nazywać procedurą.

(12)

Cel

Po wprowadzeniu do bazy faktów i reguł można zadawać pytania (stawiać cele do realizacji). Celem może być:

pytanie o prawdziwość faktu,

polecenia znalezienia nazw obiektów będących w relacji z innymi obiektami.

Cel można określić przez podanie pojedynczego predykatu lub koniunkcji predykatów (tzw. cel złożony). W drugim

przypadku predykaty składowe oddzielone są przecinkami (nazywamy je wówczas podcelami).

(13)

Jeżeli w predykacie (predykatach) celu występują tylko symbole (stałe), to wówczas jest to pytanie o prawdziwość faktów. Odpowiedzią jest wówczas PRAWDA lub FAŁSZ.

Jeżeli w predykatach występują zmienne, to celem jest znalezienie wszystkich obiektów, które znajdują się w okre- ślonej relacji z innymi obiektami.

Inaczej mówiąc mogą one zastąpić zmienną w predykacie celu nie prowadząc do sprzeczności z faktami zawartymi w bazie danych programu.

(14)

Przykład

Baza wiedzy zawiera następujące fakty:

lubi(jan, wino).

lubi(jan, tenis).

lubi(marta, jabłka).

lubi(marta, wino).

Zadane pytania i uzyskane odpowiedzi:

lubi(marta, wino) odpowiedź: YES lubi(marta, tenis) odpowiedź: NO

lubi(X, wino) odpowiedź: X=jan, X=marta lubi(jan, X), lubi(marta, X) odpowiedź: X=wino

(15)

Mechanizm wnioskujący w Prologu

Podstawą wnioskowania w Prologu jest uzgadnianie (dopa- sowanie) klauzul zawartych w bazie wiedzy z danym celem (lub podcelami).

Klauzule próbuje się uzgadniać wtedy, gdy ich predykaty są takie same. Procesowi porównywania poddawane są argumenty predykatów.

Ponieważ argumentem predykatu może być symbol (stała) lub zmienna mogą zachodzić dwa następujące przypadki:

(16)

na tej samej pozycji występuje w jednym predykacie stała, a w drugim zmienna (wówczas zmienna przyjmuje wartość symbolu) – operacja ukonkretniania,

na tej samej pozycji występują dwie zmienne (wówczas następuje powiązanie zmiennych tzn. jeżeli któraś z nich w pewnym momencie zostanie ukonkretniona, to druga zmienna automatycznie przyjmie tą samą wartość) – operacja powiązania.

Operacje ukonkretniania i powiązania są bardzo istotne w procesie wnioskowania realizowanym przez mechanizm wnioskowania języka Prolog.

(17)

Przykłady uzgadniania klauzul:

Fakt Pytanie Uzgadnianie Rodzaj

lubi(jan, wino) lubi(X, wino) X = jan ukonkretnienie lubi(marta, tenis) lubi(marta, Y) Y = tenis ukonkretnienie

lubi(piotr, maria) lubi(V, Z) V = piotr

Z = maria ukonkretnienie lubi(jan, Cos) lubi(jan, X) Cos = X powiązanie

(18)

Przykład

Baza wiedzy zawiera następujące fakty (tekst zawarty między symbolami /* ... */ oznacza komentarz):

matka(alicja, maria). /* k1 - „alicja” jest matką „maria” */

matka(ewa, piotr). /* k2 */

matka(teresa, maria). /* k3 */

matka(olga, jan). /* k4 */

Mamy podany cel:

matka(X, maria).

Cel ten oznacza zadanie znalezienia tych matek, których córki mają na imię Maria.

(19)

Proces wnioskowania polega na kolejnym uzgadnianiu celu z kolejnymi klauzulami znajdującymi się w bazie wiedzy.

W danym przypadku proces ten przebiega następująco:

w wyniku dopasowywania celu z klauzulą 1 zmienna X zostanie ukonkretniona stałą „alicja” (cel został osiągnięty i następuje wyświetlenie wartości zmiennej X = alicja). Następuje też ustawianie tzw. znacznika powrotu na klauzulę 1,

program próbuje dopasować cel z pierwszą klauzulą znajdującą za znacznikiem - jest to klauzula nr 2 (klau- zuli tej nie da się uzgodnić z celem),

(20)

w wyniku uzgodnienia klauzuli 3 z celem otrzymamy nową wartość zmiennej X (zostanie ona ukonkretniona stałą „teresa”) - program wyświetli, a znacznik pozycji zostanie przesunięty na klauzulę nr 3,

następną klauzulą jest klauzula 4 (ponieważ nie można uzgodnić celu i jest to ostatnia klauzula w bazie wiedzy przeszukiwanie zostaje zakończone).

Zostały więc znalezione dwa rozwiązania:

X = alicja X = teresa

(21)

Kolejny przykład ilustruje rolę znaczników w procesie wnioskowania.

Przykład

Baza wiedzy zawiera następujące fakty i reguły:

/* 1 */ ojciec(karol,edward). /* ojciec(o,d) - o jest ojcem d */

/* 2 */ ojciec(karol,august).

/* 3 */ dziadek(X,Y) :- ojciec(X,Z),dziecko(Y,Z).

/* dziadek(d,w) - d jest dziadkiem w */

/* 4 */ dziadek(karol,maurycy).

/* 5 */ dziecko(henryk,edward). /* dziecko(d,r) - d jest dzieckiem r */

/* 6 */ dziecko(teofil,august).

(22)

Celem niech będzie znalezienie wszystkich wnuków Karola, co zapisujemy w sposób formalny:

goal dziadek(karol,W).

Proces wnioskowania w języku Prolog polega na próbie uzgodnienia celu po kolei z klauzulami występującymi w bazie wiedzy:

uzgodnienie celu głównego z klauzulą 3

dziadek(karol,W). dziadek(X,Y) :- ojciec(X,Z), dziecko(Y,Z).

X = karol (ukonkretnienie), W = Y (powiązanie) podcel 1: ojciec(karol,Z)

u

(23)

uzgodnienie podcelu 1 z klauzulą 1

ojciec(karol,Z) ojciec(karol,edward).

Z = edward (ukonkretnienie)

podcel 2: dziecko(W,edward) - drugi podcel klauzuli 3 zn2 = klauzula 1 (znacznik nawracania)

uzgodnienie podcelu 2 z klauzulą 5

dziecko(W,edward) dziecko(henryk,edward).

W = henryk (ukonkretnienie)

rozwiązanie: W = henryk – udowodniono oba podcele klauzuli 3 zn3 = klauzula 5 (znacznik nawracania)

u

u

(24)

szukanie kolejnych klauzul dla podcelu 2

Podcel 2 próbujemy uzgodnić z kolejnymi klauzulami w bazie (od miejsca wskazywanego przez znacznik zn3). Znajdujemy klauzulę 6:

dziecko(W,edward) dziecko(teofil,august).

Ponieważ próba uzgodnienia kończy się niepowodzeniem i klauzula 6 jest ostatnią klauzulą w bazie należy: usunąć znacznik zn3 i wrócić do

znacznika zn2 (podcel 1: ojciec(karol,Z), zn2 = klauzula 1)

uzgodnienie podcelu 1 z klauzulą 2

ojciec(karol,Z) ojciec(karol,august).

Z = august (ukonkretnienie)

podcel 2: dziecko(W,august) - drugi podcel klauzuli 3

u

u

(25)

uzgodnienie podcelu 2 z klauzulą 6

dziecko(W,august) dziecko(teofil,august).

W = teofil (ukonkretnienie)

rozwiązanie: W = teofil – udowodniono oba podcele klauzuli 3 zn3 = klauzula 6 (znacznik nawracania)

szukanie kolejnych klauzul dla podcelu 2

Podcel 2 próbujemy uzgodnić z kolejnymi klauzulami w bazie. Ponieważ klauzula 6 jest ostatnią klauzulą w bazie należy: usunąć znacznik zn3 i wrócić do znacznika zn2 (podcel 1: ojciec(karol,Z), zn2 = klauzula 2)

u

(26)

szukanie kolejnych klauzul dla podcelu 1

Podcel 1 próbujemy uzgodnić z kolejnymi klauzulami (od znacznika zn2).

Ponieważ próba uzgodnienia kończy się niepowodzeniem należy: usunąć znacznik zn2 i wrócić do znacznika zn1 (cel główny: dziadek(karol,W), zn1 = klauzula 3).

uzgodnienie celu głównego z klauzulą 4

dziadek(karol,W). dziadek(karol,maurycy).

W = maurycy (ukonkretnienie) rozwiązanie: W = maurycy

zn1 = klauzula 4 (znacznik nawracania)

u

(27)

szukanie kolejnych klauzul dla celu głównego

Cel główny próbujemy uzgodnić z kolejnymi klauzulami (od znacznika zn1).

Ponieważ próba uzgodnienia kończy się niepowodzeniem należy usunąć znacznik zn1. Ponieważ nie ma już żadnych znaczników powrotu proces przeszukiwania zostaje zakończony.

W wyniku procesu wnioskowania znaleziono następujące rozwiązania:

W = henryk W = teofil

W = maurycy

(28)

Modyfikatory procesu wnioskowania

Operator odcięcia („cut”) jest to bezargumentowy predykat, który zawsze jest prawdziwy i służy do ograniczania nawrotów. Stosowanie odcięcia może być istotne z dwóch powodów:

program będzie działał szybciej (można pominąć cele, których wynik uzgodnienia jest znany z góry i nie wnoszą one do rozwiązania nowych elementów),

program wymaga mniej pamięci (dla pominiętych celów nie trzeba pamiętać związanych z nimi punktów nawra- cania).

Odcięcie należy stosować bardzo ostrożnie!!!

(29)

Odcięcie występuje przeważnie jako jeden z podcelów w części warunkowej reguły i uniemożliwia nawrót do któregokolwiek z poprzedzających go podcelów przy próbie znajdowania rozwiązań alternatywnych. Oznacza to, że dany podcel zostanie uzgodniony tylko jeden raz i nie może być uzgodniony ponownie. Aby zastosować operator odcię- cia w odpowiednim miejscu programu należy umieścić symbol „!” (znak wykrzyknika).

dziadek(X,Y) :- ojciec(X,Z), dziecko(Y,Z), ! . /* znajduje tylko pierwsze rozwiązanie W = henryk */

dziadek(X,Y) :- !, ojciec(X,Z), dziecko(Y,Z). /* zapobiega nawrotom do kolejnych predykatów tego

samego typu – W = henryk, W = teofil */

(30)

Operator odcięcia wykorzystywany jest również przy defi- nicjach rekurencyjnych. Jest on wówczas konieczny do przerwania kolejnych wywołań rekurencyjnych w momencie osiągnięcia warunku stopu.

Przykład

Procedura obliczająca silnię dowolnej liczby:

silnia(0,1) :- !.

silnia(X,Y) :- N is X-1, /* operator podstawienia N = X-1 */

silnia(N,B), Y is X*B.

Zapis silnia(X, Y) oznacza, że wartość X! jest równa Y.

(31)

Rozpatrzmy działanie programu dla celu postaci silnia(5, Y):

1. Próba uzgodnienia celu głównego z klauzulą 1 (niepowodzenie, niezgodny pierwszy argument – w celu występuje 5, w klauzuli 1 występuje 0),

2. Próba uzgodnienia celu głównego z klauzulą 2 (sukces, ukonkretnienie zmiennej X – przyjmuje ona wartość 5, zmienna N przyjmuje wartość 4, pojawia się podcel1: silnia(4, B), znacznik zn1 dla podcelu1 ustawiony na klauzuli 2),

3. Próba uzgodnienia podcelu1 z klauzulą 1 (niepowodzenie),

4. Próba uzgodnienia podcelu1 z klauzulą 2 (sukces, ukonkretnienie zmiennej X – przyjmuje ona wartość 4, zmienna N przyjmuje wartość 3, pojawia się podcel2: silnia(3, B), znacznik zn2 dla podcelu2 ustawiony na klauzuli 2),

5. …

(32)

Proces wnioskowania będzie przebiegał dalej, aż dojdziemy do podcelu5 postaci silnia(0, B). Nastąpi wówczas jego uzgodnienie z klauzulą 1, w wyniku czego zmienna B przyjmie wartość 1. Jeżeli w klauzuli 1 nie byłoby operatora odcięcia, to w kolejnym kroku nastąpiłaby próba uzgodnienia podcelu5 z klauzulą 2. Ponieważ takie uzgodnienie jest możliwe pojawiłby się nowy podcel postaci:

silnia(-1, B).

Jest on jednak niezgodny z definicją silni!

Drugim operatorem modyfikującym proces wnioskowania jest predykat „fail”. Predykat ten jest zawsze fałszywy.

Najczęściej jest stosowany do wymuszenia nawrotów (jest wówczas używany łącznie z operatorem odcięcia).

(33)

Listy

Lista jest podstawową strukturą danych w Prologu. Jest ona uporządkowanym zbiorem dowolnej liczby elementów, którymi mogą być: stałe, zmienne lub struktury (np. inne listy). Przykłady list:

[ ] - lista pusta

[1,2,5,4,7]

[[1,2],[5,4],7] - lista zawiera inne listy

Listę można podzielić na dwa elementy: głowę (head) oraz ogon (tail). Głową jest pierwszy element listy, a ogonem pozostała część listy.

(34)

Z uwagi na fakt, że typową operacją związaną z listami jest ich podział na głowę i ogon wprowadzono specjalny zapis [X | Y]. W tym przypadku zmienna X reprezentuje głowę listy, natomiast zmienna Y jej ogon.

lista głowa ogon

[ ] [1]

[1, 2, 3]

[[1, 2], 3, 4]

[1, [2, 3], [4, 5], 6]

brak 1 1 [1, 2]

1

brak [ ] [2, 3]

[3, 4]

[[2, 3], [4, 5], 6]

(35)

Wybrane operacje na listach

[X | Y] – podział listy na głowę (X) i ogon (Y)

member(X,L) – sprawdzenie czy element X należy do listy L np. member(2,[1,2,3,4,5,6,])

append(L1,L2,L3) – utworzenie listy L3 przez dołączenie listy L2 na koniec listy L1 np. append([1,2],[5,6],X)

(36)

Operacje arytmetyczne w Prologu

Prolog jest językiem służącym przede wszystkim do wykonywania operacji na symbolach.

Posiada on jednak również możliwości wykonywania

operacji arytmetycznych na liczbach całkowitych. Służą do tego wbudowane operatory arytmetyczne:

* (mnożenie), / (dzielenie) , - (odejmowanie), + (dodawanie) i mod (reszta z dzielenia).

Dostępne są również operatory relacyjne:

= (równy), \= (różny), < (mniejszy), > (większy),

<= (mniejszy lub równy) i >= (większy lub równy).

(37)

Przykład

W bazie danych mamy następujące fakty:

urodzony(jan,1974).

urodzony(ludwik,1979).

urodzony(andrzej,1980).

urodzony(marcin,1970).

Aby porównać wiek osób (kto jest starszy od kogo) można zdefiniować następujący predykat:

starszy(X,Y):- urodzony(X,R1), urodzony(Y,R2), R1<R2.

(X jest starszy od Y, jeżeli X urodził się wcześniej niż Y, R1 i R2 to rok urodzenia !)

(38)

Przykład

W bazie danych mamy następujące fakty:

dlugosc(figura1, 20).

szerokosc(figura1, 15).

Aby obliczyć pole powierzchni danej figury można użyć następującej reguły:

pole(X, Y):- dlugosc(X, W1), szerokosc(X, W2), Y=W1*W2.

Pytanie o pole figury o nazwie ’figura1’ ma wówczas postać:

pole(figura1, Y).

(39)

Operacje wejścia i wyjścia

Operacje wejścia i wyjścia umożliwiają komunikację z użyt- kownikiem podczas wykonywania programu.

Predykaty odpowiedzialne za operacje wejścia/wyjścia mo- gą się różnić w zależności od stosowanej implementacji Prologu oraz systemu operacyjnego. Przykłady wbudowa- nych predykatów wejścia-wyjścia:

read(X) – odczytuje term z bieżącego strumienia wejściowego write(X) – zapisuje term X do bieżącego strumienia wyjściowego nl – przejście do nowego wiersza

Przykład:

pytanie1(Dziecko) :- write(’Podaj imie’), read(X), rodzic(X, Dziecko).

Cytaty

Powiązane dokumenty

Własność ta, powiązana logicznie z kwestią linearności wyrażeń językowych, sprowadza się do tego, że z potoku mowy można wydobywać jednostki dwojakiego rodzaju: po

Jeżeli jakieś dane em ­ piryczne przemawiają przeciw jednej lub drugiej teorii, powstały konflikt traktuje się jako dowód na to, że teoria nie stosuje się do sytuacji,

Odbiorcami danych osobowych będą podmioty uprawnione do uzyskania danych osobowych na podstawie przepisów prawa, z uwzględnieniem zasady jawności – dane

Analiza SWOT uwzględnia elementy na zewnętrz przedsiębiorstwa, takie jak: czynniki ekonomiczne, polityczne, technologiczne, społeczne i etyczne.. Czynniki pozytywne to szanse

Twoim zadaniem jest przygotowanie po trzy kulki z gazety, – dzięki zgniataniu papieru.. doskonalisz

Pręty stosowane przy wykonywaniu zestawów elementów ExBox do uciąglenia zbrojenia w konstrukcjach żelbetowych powinny być wykonane ze stali B500B, B500SP bądz z innej stali o

• typ wyniku zwracanego przez return nie przeciąża nazwy metody.. Jest to możliwe dzięki przesłanianiu metod odleglosc.. Klasa Tablice dziedzicząca po klasie JFrame używa

W przypadku wycieku znacznej ilości produktu na ograniczonej powierzchni należy unikać wdychania oparów, zapewnić dostęp powietrza lub założyć ochronny aparat do