Funkcionális és logikai programozás { Márton Gyöngyvér, 2012} { Sapientia, Erdélyi Magyar Tudományegyetem } http://www.ms.sapientia.ro/~mgyongyi ` 1
Jelenlét: Követelmények, osztályozás Az első 4 előadáson való részvétel plusz 1 pontot jelent a vizsgán. A laborgyakorlat kötelező, hiányzás esetén kötelező az óra pótlása, ellenkező esetben csak a fizetéses vizsgán lehet részt venni. Vizsga (Kollokvium): A vizsga 9 pontos elméleti tételsorból áll. A vizsgázás időpontja megegyezik az utolsó előadás időpontjával. Az összes laborfeladat bemutatása (max 2 hetes késéssel) 10-es vizsgajegyet jelent. A vizsgán való részvétel követelménye, hogy a kitűzött labor feladatok 50%-ban legyenek leadva. Akik nem érik el a 7-es osztályzatot az elméleti vizsgán, azok kötelező gyakorlati vizsgát kell tegyenek, mely közvetlenül az írásbeli után következik. A fizetéses vizsgán való részvételhez nem kötelező a laborfeladatok bemutatása. 2
Funkcionális programozás: Könyvészet Horváth Zoltán: Programnyelvek/ A funkcionális programozási nyelvek elemei http://www.cs.ru.nl/~clean/ http://people.inf.elte.hu/csz/0506/funkimp.html Logikai programozás: Szeredi Péter, Benkő Tamas: Deklaratív programozás, oktatási segédlet Ásványi Tibor: A logikai programozás és a Prolog Peter Flach: Logikai programozás J.M.Spivey: An introduction to logic programming through Prolog http://www.swi-prolog.org/ http://aszt.inf.elte.hu/~asvanyi/pl/jegyzetek ELTE:http://people.inf.elte.hu/divip/ BME: http://dp.iit.bme.hu 3
Funkcionális és logikai programozáshoz szükséges install állományok, windows alá, a belső hálózaton, az alábbi szerveren Funkcionális programozás ( Clean2.1.1 ) \\kelemen\kit\programozás\clean2.1.1 Logikai programozás ( Prolog ) \\kelemen\kit\programozás\prolog Funkcionális és logikai programozáshoz szükséges segédanyag, a belső hálózaton: \\kelemen\tanaroktoldiakoknak\martongy\funkcionális \\kelemen\tanaroktoldiakoknak\martongy\logikai 4
Bevezető Funkcionális programozás Clean 2.1. 1. környezetben Jellemzők Listák Magasabb rendű függvények Operátorok Adatszerkezetek, algoritmusok I/O műveletek Témakörök Algoritmusok hatékonysága Eseménykezelés, grafikus felület Hálózati kommunikáció Logikai programozás Prolog környezetben, bevezető Alapfogalmak: aritmetika, listák, operátorok Algoritmusok I/O műveletek 5
Bevezető Programozási módszerek: imperatív programozás programozási nyelvek: assembly, Java, C, C++, alapeszköze: a ciklus utasítás deklaratív programozás Funkcionális programozás programozási nyelvek: Lisp, Haskell, Clean alapeszköze: a függvény Logikai programozás programozási nyelvek: Prolog, SQL alapeszköze: a reláció -tények, szabályok 6
az imperatív programozás sajátosságai: felszólító mód: parancsok, utasítások a lényeg az algoritmus megtalálása ( hogyan oldjuk meg a feladatot) pontosan követhetőek a végrehajtott lépések a változó: egy adott memória helyen tárolt aktuális érték, mely ismételten újabb és újabb értéket vesz fel 7
a deklaratív programozás sajátosságai: kijelentő mód: állítások, egyenletek a lényeg: az algoritmus leírása ( mit kell megoldanunk ) a végrehajtás, a nyelv értelmező, fordító programjától függ nem mindig követhetőek a végrehajtott lépések a változó: a matematikából ismert fogalomnak felel meg, tulajdonképpen egy ismeretlen, ami segítségével felírjuk az adott relációt, rekurzív összefüggést alkalmazási terület: Cad rendszerek, telekommunikáció, mesterséges intelligencia 8
C kód: 1 változat : int fakt0 ( int n ) { int i, res; if ( n<0 ) return -1; if ( n==0n ) return 1; for( i=1, res=1; i<=n; i++) res *= i; return res; } 2 változat: int fakt1 ( int n ) { if ( n<0 ) return -1; if ( n==0 n ) return 1; else return n * fakt1(n-1); } 3 változat: int fakt2 ( int res, int n) { if ( n<0 ) return -1; if ( n==0 n ) return res; return fakt2(n*res, n-1); } függvény hívások ok: X = fakt0 (10); X = fakt1 (10); X = fakt2 (1, 10); 9
Clean kód: 1 változat : fakt1 :: Int -> Int fakt1 0 = 1 fakt1 n = n * fakt1 (n-1) függvény hívás: Start = fakt1 10 2 változat : fakt2 :: Int -> Int fakt2 n n < 0 = -1 n == 0 = 1 = n * fakt2 (n-1) 3 változat: fakt3 :: Int Int -> Int fakt3 res n n < 0 = -1 n == 0 = res = fakt3 (n*res) (n-1) függvény hívás: Start = fakt3 1 10 függvény hívás: Start = fakt2 10 10
Prolog kód: fakt(0, 1). fakt(n, Res) :- N >0, N1 is N - 1, fakt(n1, Res1), Res is N * Res1. a formula kiértékelése: fakt(10, X). 11
Funkcionális programozás Clean 2.1.1. környezetben 12
Jellemzők feltételek megadása ( definition by cases ) : a függvény értékét az első, igaz egyenlőséghez tartozó kifejezés adja, mely kifejezést az aktuális paraméter értéke alapján kapjuk Pl: az argumentum előjelének a meghatározása alapok1.icl module alapok1 import StdEnv signum :: Int -> Int signum x x < 0 = -1 x > 0 = 1 x == 0 = 0 Start = signum -10 13
rekurzivitás ( definition by recursion ): a függvények hivatkozhatnak önmagukra és kölcsönösen egymásra Pl: két egész szám legnagyobb közös osztójának a meghatározása lnko :: Int Int -> Int lnko a b a > b = lnko (a-b) b a < b = lnko a (b-a) a == b = a Start = lnko 18 56 14
az argumentumok mintaillesztése ( definition by patterns ): a függvény értékét az a függvénytörzs határozza meg, amelyre a formális paraméter egy megadott minta alapján illeszkedik Pl1: egy három elemű lista elemeinek összeadása osszeg :: [Int] -> Int osszeg [] = 0 osszeg [x] = x osszeg [x,y] = x+y osszeg [x,y,z] = x+y+z //futási hibát ad Start = osszeg [2,3,4,5] Pl2: egy szám számjegyeinek összege isum :: Int -> Int isum 0 = 0 isum szam = ( szam rem 10 ) + isum (szam /10) Start = isum 123 a mintaillesztést és a feltételek megadását lehet együttesen alkalmazni 15
szigorú, statikus típusosság : a kifejezések típusát a fordítóprogram meghatározza úgy is, ha nincs az feltüntetve Pl: az argumentum abszolut értékének a meghatározása abszolut x x < 0 = ~x //az x értékének a negáltja = x Start = abszolut -10 abszolut :: Int -> Int abszolut :: Real -> Real abszolut x abszolut x x < 0.0 = ~x x < 0 = ~x x < 0 = x = x abszolut :: a -> a zero, <, ~ a abszolut x x < zero = ~x = x 16
Zermelo-Fraenkel halmazkifejezések: iteratív adatszerkezetek (listák, halmazok, sorozatok) elemeinek megadására alkalmazott jelölésrendszer Pl: egy szam osztóink a sorozata osztok :: Int -> [ Int ] osztok n = [ i \\ i <- [1..n] n rem i ==0] Start = osztok 100 17
speciális kifejezések: #, (let-before expression) az imperatív programozási stílushoz hasonló szerkezet egy feltétel, vagy a függvénytörzs előtt definiálható alkalmazható amikor a kiértékelési sorrend jól meghatározott Pl. gyok :: Real Real Real -> (Real, Real) gyok a b c #delta = sqrt(b*b-4.0*a*c) #d = 2.0*a = ( (~b + delta) / d, (~b - delta) / d ) Start = gyok 1.0 2.0 1.0 Megjegyzés: az sqrt könyvtárfüggvény 18
margó szabály: az összetartozó kifejezések meghatározására a baloldali margó változtatását kell alkalmazni PL.: másodfokú egyenlet gyökeinek a meghatározása gyok :: Real Real Real -> (Real, Real) gyok a b c = ( (~b + delta) / d, (~b - delta) / d ) where delta = sqrt(b*b-4.0*a*c) d = 2.0*a delta a = 3*a Start = gyok 1.0 2.0 1.0 Melyik delta kifejezés értékelődik ki? Start = delta 2 19
különböző típusok együttes alkalmazása Pl. gyok :: Real Real Real -> (String, [Real]) gyok a b c #delta = sqrt(b*b-4.0*a*c) #d = 2.0*a delta < 0.0 = ("komplex gyokok", []) delta == 0.0 = ("egy gyok", [~b/d]) = ("ket gyok", [ (~b + delta) / d, (~b - delta) / d ]) Start = gyok 1.0 3.0 1.0 20
magasabb rendű függvények ( high order function ) I argumentumuk lehet függvény visszatérítési értékük lehet függvény, mely más függvénynek is szolgálhat argumentumul Pl 1. my_inc x = x+1 my_twice f x = f (f x) Start = my_twice my_inc 0 Pl 2. Start = map sqrt [ 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 ] Megjegyzés: a map könyvtárfüggvény, két argumentuma van: az első egy függvény, melyet alkalmaz a listaként megadott második argumentumára 21