logikai programozás

69
Logikai programozás Prolog

Upload: ronni

Post on 12-Jan-2016

54 views

Category:

Documents


2 download

DESCRIPTION

Logikai programozás. Prolog. Programnyelvek. imperatív deklaratív funkcionális logikai. Logikai reprezentáció  logikai program. Predikátumok konstans argumentumokkal  tények pl. anyja(‘Diana’,’Andrew’). Horn-klóz  szabály/klóz a pozitív literál: B – következmény - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Logikai programozás

Logikai programozás

Prolog

Page 2: Logikai programozás

Programnyelvek

imperatív deklaratív

funkcionális logikai

Page 3: Logikai programozás

Logikai reprezentáció logikai program Predikátumok konstans argumentumokkal tények

pl. anyja(‘Diana’,’Andrew’). Horn-klóz szabály/klóz

a pozitív literál: B – következmény a klóz feje

a feltételek a klóz törzse

x, y [(apja(x,y) anyja(x,y)) szuloje(x,y)] szuloje(X,Y):-apja(X,Y). szuloje(X,Y):-anyja(X,Y).

Kérdések célok x szuloje(x,Andrew) ?-szuloje(X,Andrew).

Page 4: Logikai programozás

Logikai program ‘objektumai’

Állítások Tények

konstansok vagy univerzális változók Predikátumok vagy relációk Kérdések/Célok Szabályok – Horn-klózok

Ezekben: termek Egyszerű Összetett

Page 5: Logikai programozás

Termek

egyszerű term változó

nagybetűvel v. _ jellel kezdődnek _Valtozo: érdektelen: ha egy mondatban csak egyetlen

előfordulása (singleton) állandó (konstans) - atomok

név ’ ’ között, speciális jelsorozatok is! (pl. =<) 4 különleges név: ; (or, else,elseif), ! (cut), [ ] (nil), {} (empty)

szám egész lebegőpontos

- összetett term: struktúra = funktor alakjuk f(t1,…., tn) változómentes term: alapterm

Page 6: Logikai programozás

Típusok és osztályozó eljárások

változók – var/1 nem változók – nonvar/1

struktúrák – compound/1 egyszerűek – atomic/1

atom – atom/1 szám – number/1

egész – integer/1 lebegőpontos – float/1

minden típus – any/1

Page 7: Logikai programozás

Példák

1. A1 Fifi mindenhova követi Jánost. A2 János a parkban van. B Hol van Fifi?

2. Londoni metróhálózat

Page 8: Logikai programozás

Hol van Fifi?

HelyenVan(‘Fifi’,X):-HelyenVan(‘János’,X).

HelyenVan(‘János’,park). Hol van Fifi?

?-HelyenVan(‘Fifi’,Y).

Page 9: Logikai programozás

Londoni metró

Page 10: Logikai programozás

Tények Összekapcsolt állomások:

közvetlen szomszédok osszekapcsolt(Allomas1, Allomas2, Vonal).

osszekapcsolt(bond_street,oxford_circus,central).osszekapcsolt(oxford_circus,tottenham_court_road,central).osszekapcsolt(bond_street,green_park,jubilee).osszekapcsolt(green_park,charing_cross,jubilee).osszekapcsolt(green_park,piccadilly_circus,piccadilly).osszekapcsolt(piccadilly_circus,leicester_square,piccadilly)

.osszekapcsolt(green_park,oxford_circus,victoria).osszekapcsolt(oxford_circus,piccadilly_circus,bakerloo).osszekapcsolt(piccadilly_circus,charing_cross,bakerloo).osszekapcsolt(tottenham_court_road,leicester_square,northern

).osszekapcsolt(leicester_square,charing_cross,northern).

Page 11: Logikai programozás

Szabályok

Egymáshoz közeli állomások: azonos vonalon, köztük legfeljebb 1 állomás

ha közvetlenül össze vannak kapcsolva

kozel(X,Y):-osszekapcsolt(X,Y,L). vagy ha van egy Z állomás, amelyik össze van

kapcsolva X-szel és Y-nal is ugyanazon a vonalon

kozel(X,Y):-osszekapcsolt(X,Z,L),osszekapcsolt(Z,Y,L).

Page 12: Logikai programozás

Kérdések

Milyen állomások vannak közel a Bond Streethez??- kozel(bond_street,A).

Milyen állomások vannak egymás mellett a Central vonalon??- osszekapcsolt(A,B,central).

Page 13: Logikai programozás

Kérdések megválaszolása

Bizonyítási feladat Predikátumok egyesítésével = illesztésével Legáltalánosabb egyesítő helyettesítéssel Felülről lefele bizonyítás

A célsorozatból a legbaloldalibb célt választjuk A cél atomi formuláival egyesítünk állításfejeket (tény v.

szabály) ha ténnyel egyesítünk: kiejtjük a részcélt ha szabállyal egyesítünk: a szabály törzse lesz az új részcél 1 ilyen lépés: célredukciós lépés

Ha az összes részcélt kiejtettük, bebizonyítottuk a célt Ha több szabályfej is egyesíthető a részcéllal a

levezetések faszerűen elágazhatnak

Page 14: Logikai programozás

Bizonyítás

Keresési fa/Levezetési fa gyökere: eredeti cél csúcsok: részcélok levelek: megoldáslevelek (üres célok) vagy fail-levelek

Legbal részcélkiválasztási módszer Végtelen levezetési fákat eredményezhet A bejárás legjobb módja a problémától függ! Prolog: szándékos döntés, memóriakihasználás

érdekésben A klózokat megfelelően rendezve általában

kiküszöbölhető a végtelen fa

Page 15: Logikai programozás

A keresési fa építése

Redukciós lépés: egy célsorozatot és egy klózt kap bemenetként. 1. A klóz minden változóját új változóra cseréljük. 2. A célsorozatot felbontjuk első hívásra és maradékra. 3. Az első hívást egyesítjük a klózfejjel. 4. A szükséges behelyettesítéseket elvégezzük a klóz

törzsén és a célsorozat maradékán. 5. Ha a hívás és a klózfej nem egyesíthető, akkor a

redukciós lépés meghiúsul.

Page 16: Logikai programozás

A keresési fa felépítése Megoldás megkeresése

1. Megkeressük az eljárás 1. olyan klózát, amelyre a redukciós lépés sikeresen lefut.

Ha nincs ilyen klóz, akkor visszalépés történik (vagy meghiúsulás, ha nem lehet visszalépni)

visszalépés = keresünk egy másik állításfejet, amely az előző részcéllal esetleg egyesíthető lesz

Ha sikerült az egyesítés, és megoldást kaptunk, akkor kiírjuk, és megkérdezzük a felhasználót, kér-e újabb megoldást.

Ha kér: visszalépés, és az 1. ponttól folytatjuk Ha nem megoldás volt, akkor a klóz törzséből új célsorozat

lesz. 2. Ha nem volt visszalépés, akkor az új célsorozat

predikátumát keressük: 1. lépés Visszalépés: mindig az eggyel feljebbi szintre

Page 17: Logikai programozás

Egyesítési/illesztési algoritmus

Legáltalánosabb egyesítő helyettesítés keresése változót lehet helyettesíteni

változóval állandóval funktorral

állandót lehet helyettesíteni ugyanazzal az állandóval (pl. ‘Izsák’ – ‘Izsák’)

funktort lehet helyettesíteni funktorral

HA aritásuk és nevük megegyezik: paramétereiket illesztjük

Page 18: Logikai programozás

Kérdések megválaszolása

?- osszekapcsolt(A,B,central).

?- kozel(bond_street,A).

Page 19: Logikai programozás

Aritmetikai műveletek

Prolog eljárások – név/aritás Használhatjuk őket infix pozícióban is = / 2

A = B beépített eljáráshívás akkor és csak akkor sikerül, ha a két argumentuma egyesíthető

is / 2 Az X is Kif hívás a Kif aritmetikai kifejezés értékét

egyesíti X-szel. Pl. az 1*2+3 értékét így számíthatjuk ki: ? - X is 1*2+3. X=5 ? ; no

+, -, *, /, mod, // (egész osztás)

Page 20: Logikai programozás

Metalogikai predikátumok

Aritmetikai műveletek, beépített eljárások =<, >=, <, >, =:=, =\= +, -, *, /, mod, // Csak aritmetikai kifejezések lehetnek az

argumentumok is/2 predikátumnak a jobb oldalán csak

aritmetikai kifejezés állhat

Page 21: Logikai programozás

Termek összehasonlítása

Illesztéssel =/2 \=/2

Illesztés nélkül == \==

Rendezés: Változók, lebegőpontos, egész, név, összetett term Név: ASCII kód szerint Összetett termek: aritás, név, paraméterek neve

Page 22: Logikai programozás

Termek összehasonlítása

U V U = V U \= V U == V U \== V U is V U =:= V U =\= V

1 2 nem igen nem igen nem nem igen

a b nem igen nem igen hiba hiba hiba

1+2 +(1,2) igen nem igen nem nem igen nem

1+2 2+1 nem igen nem igen nem igen nem

1+2 3 nem igen nem igen nem igen nem

3 1+2 nem igen nem igen igen igen nem

X 1+2 X=1+2 nem nem igen X=3 hiba hiba

X Y X=Y nem nem igen hiba hiba hiba

X X igen nem igen nem hiba hbia hiba

Page 23: Logikai programozás

„Ciklusok” Prologban

Ciklus megvalósítása: rekurzióval Az eljárás saját magára hivatkozik

int faktorialis(int n)

{

if(n <= 1)

return 1;

return n * faktorialis(n-1);

}

Page 24: Logikai programozás

Elérhetőség definiálása

B állomás akkor elérhető A állomásról, ha el lehet jutni A-ból B-be (akár átszállásokkal) össze vannak kapcsolva közvetlenül van egy A1 állomás, ahonnan B állomás

elérhető

Page 25: Logikai programozás

Tényekkelelerheto(bond_street,charing_cross).elerheto(bond_street,green_park).elerheto(bond_street,leicester_square).elerheto(bond_street,oxford_circus).elerheto(bond_street,piccadilly_circus).elerheto(bond_street,tottenham_court_road).elerheto(green_park,charing_cross).elerheto(green_park,leicester_square).elerheto(green_park,oxford_circus).elerheto(green_park,piccadilly_circus).elerheto(green_park,tottenham_court_road).elerheto(leicester_square,charing_cross).elerheto(oxford_circus,charing_cross).elerheto(oxford_circus,leicester_square).elerheto(oxford_circus,piccadilly_circus).elerheto(oxford_circus,tottenham_court_road).elerheto(piccadilly_circus,charing_cross).elerheto(piccadilly_circus,leicester_square).elerheto(tottenham_court_road,charing_cross).elerheto(tottenham_court_road,leicester_square).

Page 26: Logikai programozás

Rekurzió

Elérhető egy állomás egy másikból, ha több másik állomást érintve eljuthatunk egyikből a másikba

1. megoldás (nem praktikus):elerheto0(X,Y):- osszekapcsolt(X,Z,L).

elerheto1(X,Y):- osszekapcsolt(X,Z,L1), osszekapcsolt(Z,Y,L2).

elerheto2(X,Y,Z1,Z2):- osszekapcsolt (X,Z1,L1), osszekapcsolt(Z1,Z2,L2), osszekapcsolt(Z2,Y,L3).

Page 27: Logikai programozás

Rekurzív szabályokkal

össze vannak kapcsolva közvetlenül

elerheto(X,Y):-osszekapcsolt(X,Y,L).

vagy van egy A1 állomás, ahonnan B állomás elérhető

elerheto(X,Y):-osszekapcsolt(X,Z,L),

elerheto(Z,Y).

Page 28: Logikai programozás

Rekurzív szabályok

Szabály törzsében szerepel a fejben levő predikátum

Rekurzió ne legyen végtelen: nemnegatív, monoton csökkenő függvényt kell

találni itt a függvény: a még feldolgozandó út hossza

a fában (azaz a közbülső állomások száma egyre csökken, amíg közvetlenül össze nincsenek kapcsolva)

ökölszabály: A nem rekurzív klózokat a rekurzívak elé! – jobbrekurzív programok

Page 29: Logikai programozás

Struktúrák

Funktorok, összetett termek Több objektumból álló szerkezetek

reprezentálására Beépített és saját definiálás

Beépített példák aritmetikai műveletek: +, -, *, /, mod … függvények: cos, sin, sqrt, …

Page 30: Logikai programozás

Utak két állomás közöttSaját struktúrák (listák) Út A és B állomás között: ha B állomás

elérhető A-ból, akkor a közöttük elhelyezkedő állomások listája az út hossza 0, ha közvetlenül össze vannak

kapcsolva – nincsut konstanssal jelöljük az 1 hosszú, Z állomáson át vezető út: ut(Z) 2 hosszú, Z1 és Z2 állomáson át vezető út: ut(Z1,Z2)

Page 31: Logikai programozás

Utak meghatározása (max. 2 hosszú)

elerheto1(X,Y,nincsut):-osszekapcsolt(X,Y,L).

elerheto1(X,Y,ut(Z)):- osszekapcsolt(X,Z,L1),osszekapcsolt(Z,Y,L2).

elerheto1(X,Y,ut(Z1,Z2)):- osszekapcsolt(X,Z1,L1),osszekapcsolt(Z1,Z2,L2),osszekapcsolt(Z2,Y,L3).

?-elerheto1(oxford_circus, charing_cross, R)

Page 32: Logikai programozás

Megoldások

?-elerheto1(oxford_circus, charing_cross, R)

R = ut(piccadilly_circus) ;

R = ut(tottenham_court_road, leicester_square) ;

R = ut(piccadilly_circus, leicester_square) ;

No

Page 33: Logikai programozás

Rekurzív megoldással

%rekurzioval

elerheto_ut2(X,Y,nincsut):-osszekapcsolt(X,Y,L).

%E: elso allomas, M: ut maradeka

elerheto_ut2(X,Y,ut(E,M)):-osszekapcsolt(X,E,L),

elerheto_ut2(E,Y,M).

Page 34: Logikai programozás

Megoldások

Page 35: Logikai programozás

Listák

az ut funktor megfelel a ./2 beépített funktornak: „ listaépítő” funktor

Lista: összetett adatszerkezet .(E, M) struktúrát [E | M] alakban is írhatjuk

E: lista első eleme (feje), M: a lista maradéka (törzse/farka)

az [X1, X2, …, Xn | [] alakból a [] elhagyható lista jelölése: [1, 2, 3] - ez a .(1, .(2, .(3,[])))

lista

Page 36: Logikai programozás

Listák

Közönséges adattípus

% :- type list(T) ---> .(T, list(T)) ; [].

Valódi Üres: [] Nem üres

Részleges Konstruktora: ./2

Page 37: Logikai programozás

Lista építése

.(X, Xs) konstruktort [X | Xs] alakban is írhatjuk az [X1, X2, …, Xn | [] alakból a [] elhagyható lista jelölése: [1, 2, 3] - ez a .(1, .(2, .(3,[])))

lista

Page 38: Logikai programozás

Utak keresése listával

elerheto2(X,Y,[]):-osszekapcsolt(X,Y,L).

elerheto2(X,Y,[Z|R]):-osszekapcsolt(X,Z,L),

elerheto2(Z,Y,R).

%kerdes: min. 2 hosszu utakat keres

%?- elerheto2(bond_street,

piccadilly_circus,[A,B|C]).

Page 39: Logikai programozás

Termek összehasonlítása

Beépített predikátumok Relációs műveletek: <,>,=<,=> Egyenlőség vizsgálata:

=, \= termek egyenlőségének vizsgálata és egyesítése

==, \== termek egyenlőségének vizsgálata egyesítés nélkül

=:=, =\= aritmetikai kifejezések egyenlőségének vizsgálata

Egyesítés (értékadás) is/2

term egyesítése aritmetikai kifejezéssel jobb oldalon csak behelyettesített változó!

Page 40: Logikai programozás

Elágazás

Szabály törzsében( ha -> akkor

; különben

) ha, akkor, különben: Prolog

célsorozatok Feltétel elágazás nélkül:(ha-> akkor) (egyenértékű ezzel:(ha -> akkor; fail) )

Page 41: Logikai programozás

Másodfokú egyenlet megoldóképlete

zerus0(A,B,C,X):-X is ((-B+sqrt(B*B-4*A*C))/2*A).zerus0(A,B,C,X):-X is ((-B-sqrt(B*B-4*A*C))/2*A). Hibaellenőrzéssel (1. módszer):zerus1(A,B,C,X):-diszkriminans1(A,B,C,Y),Y>=0,X is

(-B+sqrt(B*B-4*A*C)/2*A). Hibaellenőrzés elágazással:zerus2(A,B,C,X):-

diszkriminans2(A,B,C,Y),(Y>=0 -> X is (-B+sqrt(B*B-4*A*C)/2*A);write('Nincs megoldas')).

Page 42: Logikai programozás

Tagadás

X = Y X illeszthető Y-nal

X nem illeszthető Y-nal

% X \= Y : X nem illeszthető Y-nal

X \=Y :- (X=Y -> fail ; true).

Page 43: Logikai programozás

Tagadás

hallgató(‘Péter’).

hallgató(‘János’).

hallgató(‘Jakab’).

nős(‘Péter’).

nős(‘József’).

nőtlen_hallgató(X) :- hallgató(X), nőtlen(X).

nőtlen(X) : - (nős(X)->fail; true). VAGYnem(nős(X)) :- (nős(X)->fail; true).

Page 44: Logikai programozás

Tagadás sémája

nem(P):- (P -> fail; true). Metapredikátum

Egy szabályfej formális paramétere metacél (azaz pl. egy másik predikátum)

Pl. nem(P)

nőtlen_hallgató(X) :- hallgató(X), nem(nős(X)).

Beépített Prolog predikátum: \+

Page 45: Logikai programozás

\+/1 négy tulajdonsága:

1. Sohasem hagy maga után választási pontot

2. Függetlenül a P céltól, sosem példányosítja annak változóit

3. nem(P) pontosan akkor sikeres, ha P keresési fája véges, és nem tartalmaz megoldást

4. nem(P) pontosan akkor hiúsul meg, ha P keresési fája tartalmaz megoldást, de az első megoldás előtt nincs végtelen ág.

Page 46: Logikai programozás

Keresési tér csökkentése: jobbrekurzió

Nem jobbrekurzív megoldás:

length([],0).

length([H|T],N):-length(T,M),N is M+1. Jobbrekurzív megoldás (akkumulátorral):

inicializálás

length_acc(L,N):-length_acc(L,0,N). eredmény visszaadása

length_acc([],N,N). számítás

length_acc([H|T],N0,N):-N1 is N0+1,length_acc(T,N1,N).

Page 47: Logikai programozás

Keresési tér csökkentése: vágás

beépített eljárás: ! mindig sikeresen lefut a szülő céltól kezdve lefele levágja a keresési

fa egyéb ágait, és megszünteti a választási pontokat

zöld/piros vágó Oka:

egy megoldásra szorítkozni egy klóz preferálása

Page 48: Logikai programozás

Vágás

cél szülője: az őt tartalmazó klóz fejével illesztett cél p:-q, r. q:-s, t, u.

q(X):-s(X).

q(X):-t(X).

r(X):-s(X), !.

r(X):-t(X).

s(a).

s(b).

t(c). célok: ?-q(Y). és ?-r(Y).

Page 49: Logikai programozás

Vágás

Tények:apja(‘Charles’,’Andrew’).anyja(‘Diana’,’Andrew’).szuloje(X,Y):-apja(X,Y),!.szuloje(X,Y):-anyja(X,Y).

Kérdések: Kinek a szülője Charles?

?-szuloje(‘Charles’,Gy). – zöld vágó Kik Andrew szülei?

?-szuloje(Sz,’Andrew’). – piros vágó

Page 50: Logikai programozás

Feladat

Gyerek SzülőIzsák ÁbrahámIsmael ÁbrahámJákób IzsákÉzsau IzsákJózsef JákóbBenjámin JákóbJúda JákóbIzsák SáraIsmael HágárJákób RebekaÉzsau RebekaJózsef RáhelBenjámin RáhelRáhel LábánLea RáhelJúda LeaRúben Lea

Kinek ki a nagyszülője?

Page 51: Logikai programozás

C nyelvű megoldás

Page 52: Logikai programozás

SQL megoldás

Create View Nagyszulok

As select fiatal.gyerek as unoka, oreg.szulo as nagyszulo

From szulok fiatal, szulok gyerek

Where fiatal.szulo=oreg.gyerek;

Select nagyszulo, unoka from Nagyszulok;

Page 53: Logikai programozás

Prolog megoldás

%apja(X,Y). - X az Y apjaapja(’Ábrahám’,’Izsák’).apja(’Ábrahám’,’Ismael’).apja(’Izsák’,’Jákób’).apja(’Izsák’,’Ézsau’).apja(’Jákób’,’József’).apja(’Jákób’,’Benjámin’).apja(’Jákób’,’Júda’).apja(’Lábán’,’Ráhel’).apja(’Lábán’,’Lea’).

%anyja(X,Y). – X az Y anyja

anyja(’Sára’,’Izsák’).

anyja(’Hágár’,’Ismael’).

anyja(’Rebeka’,’Jákób’).

anyja(’Rebeka’,’Ézsau’).

anyja(’Ráhel’,’József’).

anyja(’Ráhel’,’Benjámin’).

anyja(’Lea’,’Júda’).

anyja(’Lea’,’Rúben’).

Page 54: Logikai programozás

%szülője(X,Y) – X az Y szülője

szülője(X,Y) :- apja(X,Y).

szülője(X,Y):- anyja(X,Y).

%nagyszülője(X,Y) – X az Y nagyszülője

nagyszülője(X,Y) :- szülője(X,Z), szülője(Z,Y).

Page 55: Logikai programozás

Kérdések

Ki Izsák apja? Kik Jákób gyerekei? Kik Ábrahám unokái? Ki kinek az apja?

Page 56: Logikai programozás

| ? – apja(’Ábrahám’,’Izsák’).

yes

| ?- apja(’Ábrahám’, X).

X=’Izsák’ ? ;

X=’Ismael’ ? ;

no

| ? – apja(X,’Izsák’).

X=’Ábrahám’ ?;

no

| ? – apja(X,Y).

X='Ábrahám', Y='Izsák' ? ;

X=’Ábrahám’, Y=’Ismael’ ? ;

Page 57: Logikai programozás

Kérdések

Ki Izsák apja? | ? – apja(X, ‘Izsák’).

Kik Jákób gyerekei?/Kinek az apja Jákób? | ? – apja(‘Jákób’,X).

Kik Ábrahám unokái? | ? – nagyszülő(‘Ábrahám’,X).

Ki kinek az apja? | ? – apja(X,Y).

Page 58: Logikai programozás

Egyszerű példa

Kérdés: Ki Izsák apja? | ?- apja(X,’Izsák’). Illesztés:

keresünk egy olyan klózt, amelyben az apja predikátum a fej

apja(‘Ábrahám’,’Izsák’). megpróbáljuk az argumentumokat illeszteni:

helyettesíteni X=Ábrahám

visszalépünk és újabb megoldást keresünk: nincs

Page 59: Logikai programozás

Aritmetikai műveletek

Prolog eljárások – név/aritás Használhatjuk őket infix pozícióban is = / 2

A = B beépített eljáráshívás akkor és csak akkor sikerül, ha a két argumentuma egyesíthető

is / 2 Az X is Kif hívás a Kif aritmetikai kifejezés értékét

egyesíti X-szel. Pl. az 1*2+3 értékét így számíthatjuk ki: ? - X is 1*2+3. X=5 ? ; no

+, -, *, /, mod, // (egész osztás)

Page 60: Logikai programozás

Vezérlésmódosítás

Ciklus helyett rekurzió Elágazás –VAGY kapcsolat

p(X) :- q(X), r(X).

p(X):- s(X).

p(X) :-

( q(X), r(X)

; s(X)

).

Page 61: Logikai programozás

Elágazás – VAGY kapcsolat

beléphet(X) :- látogató(X), van_engedélye(X).

beléphet(X):- dolgozó(X).

beléphet(X) :-

( látogató(X), van_engedélye(X)

; dolgozó(X)

).

Page 62: Logikai programozás

Metalogikai predikátumok

Aritmetikai műveletek, beépített eljárások =<, >=, <, >, =:=, =\= +, -, *, /, mod, // Csak aritmetikai kifejezések lehetnek az

argumentumok is/2 predikátumnak a jobb oldalán csak

aritmetikai kifejezés állhat

Page 63: Logikai programozás

Termek összehasonlítása

Illesztéssel =/2 \=/2

Illesztés nélkül == \==

Rendezés: Változók, lebegőpontos, egész, név, összetett term Név: ASCII kód szerint Összetett termek: aritás, név, paraméterek neve

Page 64: Logikai programozás

Rekurzív keresés

%member(X,Xs) :- X elem az Xs listának

member(X, [X | _Xs]).

%igaz, ha az 1. elem X

member(X, [_X | Xs]) :- member(X, Xs).

%ha X nem az első elem, akkor igaz, ha Xs-nek tagja

Page 65: Logikai programozás

Eredmény fokozatos közelítése

%append(Xs, Ys, XsYs) :- A 2 első lista összefűzöttje az XsYs lista

append([], Ys, Ys).

%ha az első lista üres, akkor az eredmény maga a második lista

append([X | Xs], Ys, [X | Zs]) :- append(Xs, Ys, Zs).

Page 66: Logikai programozás

Akkumulátor módszer

%rev_app(Xs,Ys,Zs):- Az Xs lista fordítottját fűzi össze Ys-sel

rev_app([],Ys,Ys).

rev_app([X|Xs], Ys,Zs) :- rev_app(Xs, [X|Ys],Zs).

%az Xs lista fordítottjának és az Ys összefűzöttje

Page 67: Logikai programozás

Általánosítás

%reverse(Xs,Ys) :- Az Xs lista fordítottja az Ys

reverse(Xs,Ys) :- rev_app(Xs,[],Ys).

Page 68: Logikai programozás

Nincs benne

%nincs_benne(Xs,Y) :- Az Xs listán nem található Y.

nincs_benne([],_Y).

nincs_benne([X|Xs],Y) :-

( X =Y -> fail

; nincs_benne(Xs,Y)

).

Page 69: Logikai programozás

NSTO programok

Not Subject To Occurs Check egyesítés: v helyettesítése t-vel, HA v nem szerepel t-ben

Prolog nem ellenőrzi 1. Az állításfejben és a vele kapcsolatos kérdésekben

is paraméterként csak egyszerű termek (állandók és változók) használatosak

2. Az állításfej nem tartalmaz kettőzött változót (minden vált. egyszer fordul elő)

3. Az állításra vonatkozó célok nem tartalmaznak kettőzött változót.