690 likes | 815 Views
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
E N D
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 • 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).
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
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
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
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
Hol van Fifi? HelyenVan(‘Fifi’,X):-HelyenVan(‘János’,X). HelyenVan(‘János’,park). • Hol van Fifi? ?-HelyenVan(‘Fifi’,Y).
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).
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).
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).
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
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
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.
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
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
Kérdések megválaszolása ?- osszekapcsolt(A,B,central). ?- kozel(bond_street,A).
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)
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
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
„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); }
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ő
Tényekkel elerheto(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).
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).
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).
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
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, …
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) • …
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)
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
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).
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
Listák • Közönséges adattípus % :- type list(T) ---> .(T, list(T)) ; []. • Valódi • Üres: [] • Nem üres • Részleges • Konstruktora: ./2
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
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]).
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ó!
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) )
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') ).
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).
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). • VAGY nem(nős(X)) :- (nős(X)->fail; true).
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: • \+
\+/1 négy tulajdonsága: • Sohasem hagy maga után választási pontot • Függetlenül a P céltól, sosem példányosítja annak változóit • nem(P) pontosan akkor sikeres, ha P keresési fája véges, és nem tartalmaz megoldást • 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.
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).
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
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).
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ó
Feladat Kinek ki a nagyszülője?