pp

S-ar putea să vă placă și

Descărcați ca pdf sau txt
Descărcați ca pdf sau txt
Sunteți pe pagina 1din 11

Haskell CheatSheet

Laborator 6

Tipuri de bază Operatori pe liste Definire funct, ii


(++) head tail last init take drop takeWhile
5 :: Int -- if .. then .. else
’H’ :: Char
dropWhile
factorial x =
"Hello" :: String [1, 2] ++ [3, 4] [1, 2, 3, 4] if x < 1 then 1 else x * factorial (x - 1)
True :: Bool
False :: Bool head [1, 2, 3, 4] 1 -- guards
tail [1, 2, 3, 4] [2, 3, 4] factorial x
| x < 1 = 1
Determinarea tipului unei expresii last [1, 2, 3, 4] 4 | otherwise = x * factorial (x - 1)
init [1, 2, 3, 4] [1, 2, 3]
:t -- case .. of
> :t 42 take 2 [1, 2, 3, 4] [1, 2] factorial x = case x < 1 of
42 :: Num a => a take 2 "HelloWorld" "He" True -> 1
_ -> x * factorial (x - 1)
a reprezintă o variabilă de tip, restrictionată la toate drop 2 [1, 2, 3, 4] [3, 4]
-- pattern matching
tipurile numerice. factorial 0 = 1
null [] True
> :t 42.0 null [1, 2, 3] False factorial x = x * factorial (x - 1)
42 :: Fractional a => a
takeWhile (<5) [1..8] [1, 2, 3, 4]
In acest exemplu, a este restrictionată la toate tipurile dropWhile (<5) [1..8] [5, 6, 7, 8] Curry
numerice fract, ionare (e.g. Float, Double).
In Haskell funct, iile sunt, by default, in formă curry.
Alte operat, ii :t (+)
Constructori liste
(+) :: Num a => a -> a -> a
[] (:) .. length elem notElem reverse
length [1, 2, 3, 4] 4 :t (+ 1)
[] -- lista vida
(+ 1) :: Num a => a -> a
(:) -- operatorul de adaugare
elem 3 [1, 2, 3, 4] True
-- la inceputul listei
elem 5 [1, 2, 3, 4] False
1 : 3 : 5 : [] -- lista care contine 1, 3, 5 Funct, ionale uzuale
notElem 3 [1, 2, 3, 4] False
[1, 3, 5] -- sintaxa echivalenta map filter foldl foldr zip zipWith
notElem 5 [1, 2, 3, 4] True
[1..10] -- lista care contine toate map :: (a -> b) -> [a] -> [b]
reverse [1, 2, 3, 4] [4, 3, 2, 1] filter :: (a -> Bool) -> [a] -> [a]
-- numerele naturale de la 1 la 10
foldl :: (b -> a -> b) -> b -> [a] -> b
foldr :: (a -> b -> b) -> b -> [a] -> b
Operatori logici Tupluri zip :: [a] -> [b] -> [(a, b)]
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
not && || Spre deosebire de liste, tuplurile au un număr fix de ele-
mente, iar acestea pot avea tipuri diferite. map (+ 2) [1, 2, 3] [3, 4, 5]
not True False filter odd [1, 2, 3, 4] [1, 3]
not False True import Data.Tuple
True || False True foldl (+) 0 [1, 2, 3, 4] 10
True && False False ("Hello", True) :: (String, Bool)
(1, 2, 3) :: (Integer, Integer, Integer) foldl (-) 0 [1, 2] -3 (0 - 1) - 2
foldr (-) 0 [1, 2] -1 1 - (2 - 0)
fst ("Hello", True) "Hello" foldl (flip (:)) [] [1, 2, 3] [3, 2, 1]
Funct, ii anonime (lambda) snd ("Hello", True) True foldr (:) [] [1, 2, 3] [1, 2, 3]
\arg1 arg2 → corp swap ("Hello", True) (True, "Hello")
zip [1, 2] [3, 4] [(1, 3), (2, 4)]
\x -> x functia identitate zipWith (+) [1, 2] [3, 4] [4, 6]
(\x y -> x + y) 1 2 3 zip = zipWith (,)
let f = \x y -> x + y legare la un nume -- zip nu este propriu-zis o functionala, dar se
(f 1 2) 3 poate obtine pe baza functionalei zipWith
Sintaxa Let Liste infinite List comprehensions
Putem exploata evaluarea lenes, ă a expresiilor ı̂n Has- Cu ajutorul list comprehensions, putem genera liste pe
let id1 = expr1
id2 = expr2 kell pentru a genera liste infinite. (un element nu este baza altor liste, construite pe baza unor modele s, i a unor
... construit până când nu ı̂l folosim efectiv). condit, ii.
idn = expr3 Exemplu: definirea lazy a mult, imii tuturor numerelor [x | x <- [1..5]] [1, 2, 3, 4, 5]
in expr
naturale
Exemplu: [x + 2 | x <- [1..5]] [3, 4, 5, 6, 7]
naturals = iter 0
where iter x = x : iter (x + 1)
g = let x = y + 1 [x | x <- [1..10], x ‘mod‘ 2 == 0] [2,4,6,8,10]
y = 2 -- Pentru a accesa elementele multimii putem
(z, t) = (2, 5) [(x, y) | x <- [1..4], y <- [10..12]]
folosi operatorii obisnuiti de la liste
f n = n * y -- aici se va construi o lista de perechi -
in (x + y, f 3, z + t) [(1,10),(1,11),(1,12),(2,10),(2,11),(2,12)
> head naturals
,(3,10),(3,11),(3,12),(4,10),(4,11),(4,12)]
0
Observat, ie: Let este o expresie, o putem folosi ı̂n orice > take 10 naturals
[(x, y) | x <- [1..8], y <- [10..16], mod x 2 ==
context ı̂n care putem folosi expresii. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
0, mod y 3 == 0 ]
Domeniul de vizibilitate al definit, iilor locale este -- [(2,12),(2,15),(4,12),(4,15),(6,12),(6,15)
ı̂ntreaga clauza let. (e.g. putem sa li includem pe ’y’ ,(8,12),(8,15)]
ı̂n definit, ia lui ’x’, des, i ’y’ este definit ulterior. Cele Funct, ionale s, i alte funct, ii utile
iterate, repeat, intersperse, zip, zipWith take 10 [x | x <- [1..], mod x 2 == 0]
doua definit, ii nu sunt vizibile ı̂n afara clauzei let). -- flux de numere pare -
iterate generează o listă infinită prin aplicarea repetată [2,4,6,8,10,12,14,16,18,20]
Sintaxa Where a lui f: iterate f x == [x, f x, f (f x), ...]

def = expr Exemplu: Operatorul ’$’


where naturals = iterate (+ 1) 0
id1 = val1 powsOfTwo = iterate (* 2) 1 -- [1, 2, 4, 8, ..] În anumite situat, ii, putem omite parantezele folosind
id2 = val2 ’$’.
... repeat :: a -> [a]
idn = valn > ones = repeat 1 -- [1, 1, 1, ..] > length (tail (zip [1,2,3,4] ("abc" ++ "d")))
-- este echivalent cu
Exemple: intersperse :: a -> [a] -> [a] > length $ tail $ zip [1,2,3,4] $ "abc" ++ "d"
> intersperse ’,’ "abcde" -- "a,b,c,d,e" 3
inRange :: Double -> Double -> String
inRange x max zip :: [a] -> [b] -> [(a, b)]
| f < low = "Too_low!" zip naturals ["w", "o", "r", "d"] Operatorul de compunere a funct, iilor ’.’
| f >= low && f <= high = "In_range" -- [(0, "w"), (1, "o"), (2, "r"), (3, "d")]
| otherwise = "Too_high!" (f . g)(x) – echivalenta cu f(g(x))
where zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] > let f = (+ 1) . (* 2)
f = x / max
> map f [1, 2, 3]
(low, high) = (0.5, 1.0) evens = zipWith (+) naturals naturals [3, 5, 7]
-- [2, 4, 6, ..]
-- with case
> length . tail . zip [1,2,3,4] $ "abc" ++ "d"
listType l = case l of fibo = 1 : 1 : zipWith (+) fibo (tail fibo) 3
[] -> msg "empty" -- sirul lui Fibonacci
[x] -> msg "singleton"
_ -> msg "a_longer" concat :: [[a]] -> [a]
where > concat ["Hello","World", "!"]
msg ltype = ltype ++ "_list" "HelloWorld!"
Haskell CheatSheet
Laborator 8
type data
type ne permite definirea unui sinonim de tip, similar data permite definirea de noi tipuri de date algebrice.
cu typedef din C. data PointT = PointC Double Double deriving Show
type Point = (Int, Int)
Tipuri enumerate.
p :: Point
p = (2, 3) data Colour = Red | Green | Blue | Black
deriving Show
nonColour :: Colour -> Bool
newtype nonColour Black = True
nonColour _ = False
newtype este similar cu data, cu diferent, a că ne permite
crearea unui tip de date cu un singur constructor, pe Tipuri ı̂nregistrare.
baza altor tipuri de date existente.
data PointT = PointC
newtype Celsius = MakeCelsius Float deriving Show { px :: Double
, py :: Double
newtype Fahrenheit = MakeFahrenheit Float } deriving Show
deriving Show px (PointC x _) = x
py (PointC _ y) = y
celsiusToFahrenheit :: Celsius -> Fahrenheit
celsiusToFahrenheit (MakeCelsius c) =
MakeFahrenheit $ c * 9/5 + 32
Tipuri parametrizate.
data Maybe a = Just a | Nothing
deriving (Show, Eq, Ord)
maybeHead :: [a] -> Maybe a
maybeHead (x : _) = Just x
maybeHead _ = Nothing

Tipuri recursive.
data List a = Void | Cons a (List a) deriving Show

data Natural = Zero | Succ Natural deriving Show


Prolog CheatSheet
Laborator 10

Aflarea tuturor solut, iilor pentru satisfacerea unui scop Aflarea tuturor solut, iilor pentru satisfacerea unui scop
findall/3 forall/2
findall(+Template, +Goal, -Bag) forall(+Cond, +Action)

Predicatul findall creează o listă de instant, ieri ale lui Template care satisfac Predicatul forall verifică dacă pentru orice legare din Cond, care reprezintă un
Goal s, i apoi unifică rezultatul cu Bag domeniu ce cont, ine legări de variabile, se pot ı̂ndeplini condit, iile din Action.
higherThan(Numbers, Element, Result):- ?- forall(member(X,[2, 4, 6]), X mod 2 =:= 0).
findall(X, (member(X, Numbers), X > Element), Result). true.
?- higherThan([1, 2, 7, 9, 11], 5, X).
X = [7, 9, 11] ?- forall(member(X,[2, 4, 3, 6]), X mod 2 =:= 0).
false.
?- findall([X, SqX], (member(X, [1,2,7,9,15]), X > 5, SqX is X **
2), Result). % ı̂n argumentul Template putem construi ?- forall(member(X, [6, 12, 18]), (X mod 2 =:= 0, X mod 3 =:= 0))
structuri mai complexe .
Result = [[7, 49], [9, 81], [15, 225]]. true.

Aflarea tuturor solut, iilor pentru satisfacerea unui scop


bagof/3
bagof(+Template, +Goal, -Bag)

Predicatul bagof este asemănător cu predicatul findall, cu except, ia faptului că


predicatul bagof construies, te câte o listă separată pentru fiecare instant, iere
diferită a variabilelor din Goal (fie că ele sunt numite sau sunt ı̂nlocuite cu
underscore.
are(andrei,laptop,1). are(andrei,pix,5). are(andrei,ghiozdan,2).
are(radu,papagal,1). are(radu,ghiozdan,1). are(radu,laptop,2).
are(ana, telefon, 3). are(ana, masina, 1).

?- findall(X, are(_, X, _), Bag).


Bag = [laptop, pix, ghiozdan, papagal, ghiozdan, laptop, telefon,
masina]. % laptop s, i ghiozdan apar de două ori pentru că
sunt două posibile legări pentru persoană s, i pentru cantitate

?- bagof(X, are(andrei, X, _), Bag).


Bag = [laptop] ;
Bag = [ghiozdan] ;
Bag = [pix].
% bagof creează câte o solut, ie pentru fiecare posibilă legare
pentru cantitate. Putem aici folosi operatorul existent, ial ˆ
?- bagof(X, Cˆare(andrei, X, C), Bag).
Bag = [laptop, pix, ghiozdan]. % am cerut lui bagof să pună toate
solut, iile indiferent de legarea lui C ı̂n acelas, i grup

?- bagof(X, Cˆare(P, X, C), Bag).


P = ana, Bag = [telefon, masina] ;
P = andrei, Bag = [laptop, pix, ghiozdan] ;
P = radu, Bag = [papagal, ghiozdan, laptop].

Dacă aplicăm operatorul existent, ial pe toate variabilele libere din scop,
rezultatul este identic cu cel al lui findall.
?- bagof(X, XˆPˆCˆare(P, X, C), Bag).
Bag = [laptop, pix, ghiozdan, papagal, ghiozdan, laptop, telefon,
masina].

Aflarea tuturor solut, iilor pentru satisfacerea unui scop


setof/3
setof(+Template, +Goal, -Bag)

Predicatul setof este asemănător cu bagof, dar sortează rezultatul (s, i elimină
duplicatele) folosind sort/2.
?- setof(X, Cˆare(P, X, C), Bag).
P = ana, Bag = [masina, telefon] ; %se observă sortarea
P = andrei, Bag = [ghiozdan, laptop, pix] ;
P = radu, Bag = [ghiozdan, laptop, papagal].

?- setof(X, PˆCˆare(P, X, C), Bag).% setof elimină duplicatele


Bag = [ghiozdan, laptop, masina, papagal, pix, telefon].
Prolog CheatSheet
Laborator 9

Fapte s, i Structuri Operatori Pattern matching

papagal(coco). Aritmetici: + - * / Haskell:


iubeste(mihai, maria). Relationali: = \= < > =< >= =:= == =\= sum [] = 0 %1
iubeste(mihai, ana). Logici: \+ sau not sum (x:xs) = x + sum xs %2
deplaseaza(scaun, camera1, camera2).
are(ion,carte(aventuri,2002)). ?- 1 + 2 =:= 2 + 1. Prolog: (pentru predicatul sum(+L, -Sum)
merge(ion,facultate(upb)). true. sum([], 0). % dacă primul argument este lista vidă, al
?- 1 + 2 = 2 + 1. doilea argument trebuie să fie / este legat la 0
Faptele sunt predicate de ordinul ı̂ntâi de aritate n, considerate adevărate. false. % nu au aceeas, i formă (nu se evaluează) ?- sum([H|T], S) :- sum(T, ST), S is ST + H. % dacă primul
Structurile sunt ı̂nlănt, uiri de fapte. ?- 2 + 1 = 2 + 1. argument este o listă construită prin adăugarea unui element
Obt, inerea primei solut, ii este de obicei numită satisfacerea scopului iar obt, inerea true. % au aceeas, i formă (nu se evaluează) H la ı̂nceputul unei liste T, s, i dacă suma listei T este ST, S
altor solut, ii, resatisfacerea scopului. ?- X = 2 + 1. este ST plus H.
X = 2+1.
Dacă ı̂n satisfacerea scopului s-au găsit alternative ı̂ncă neexplorate pentru sa- ?- X is 2 + 1. În Haskell se realizează pattern matching intr-o singură direct, ie: odata legate
tisfacerea unor predicate, se poate cere resatisfacerea scopului tastând ;. Dacă X = 3. variabilele, se produce act, iunea descrisă ı̂n dreapta.
utilizatorul nu este interesat de resatisfacere poate apăsa tasta . sau Enter. ?- X =:= 2 + 1. În Prolog pattern matching se efectuează ı̂n ambele direct, ii: folosirea
ERROR: =:=/2: Arguments are not sufficiently instantiated variabilelor pentru a executa regulile s, i produce un raspuns true sau false,
?- iubeste(mihai, X).
sau se pot căuta atât variabile care satisfac regulile scrise.
X = maria; % mai există solut, ii, utilizatorul poate tasta ; • \+ echivalent cu not, s, i ı̂ntoarce true dacă scopul care urmează după
X = ana. % nu mai există alte solut, ii, Prolog nu va mai cere
nu poate fi satisfăcut ı̂n niciun fel (nu se poate demonstra că scopul este
input de la utilizator.
adevărat).
Errors/Warnings
• = unifică partea din stânga cu partea din dreapta (dacă este posibil),
Variabile realizând toate legările necesare. De exemplu: X-Y:Z = 5-[a, b, c]:y uni- my_length1([],0).
fică astfel X = 5, Y = [a, b, c], Z = y (observat, i că nu realizează nicio my_length1([H|L],N) :- my_length1(L,N1), N1 is N - 1.
?- papagal(coco). evaluare).
true. ?- my_length([a, b, c])
?- papagal(CineEste). • \= este opusul lui =, s, i este adevărat dacă partea din stânga nu unifică Error: Arguments are not sufficiently instantiated
CineEste = coco. cu partea din dreapta. Ex: A \= B este echivalent cu (\+ (A = B))
?- deplaseaza(_, DeUnde, Unde). N nu are o valoare instant, iată pentru a putea scădea 1 s, i a da valoarea lui N1.
DeUnde = camera1, Unde = camera2 • == verifică dacă partea din stânga s, i partea din dreapta sunt legate la
N1 va primi valoarea 0 din apelul my length2([], 0), iar N trebuie calculat ı̂n
aceeas, i valoare.
Numele argumentelor variabile ı̂ncepe cu literă mare iar numele constantelor funct, ie de N1 existent.
• =:= evaluează numeric expresiile din stânga s, i dreapta s, i verifică dacă
simbolice ı̂ncepe cu literă mică. my_length2([],0).
rezultatele au aceeas, i valoare numerică. Ambele părt, i trebuie să fie com- my_length2([H|L],N) :- my_length2(L,N1), N is N1 + 1.
O variabilă poate fi instant, iată (legată) dacă există un obiect asociat acestei
plet instant, iate.
variabile, sau neinstant, iată (liberă) dacă nu se s, tie ı̂ncă ce obiect va desemna
variabila. • =\= evaluează numeric expresiile din stânga s, i dreapta s, i returnează Warning: Singleton Variables: [H]
true dacă valorile sunt diferite. Ambele părt, i trebuie să fie complet O variabilă singleton este o variabilă care apare o singură dată ı̂ntr-o regulă.
Wildcard ’ ’ poate fi orice.
instant, iate. Dacă variabila nu apare de mai multe ori ı̂n regulă, ı̂nseamnă că numele res-
Reguli • is evaluează numeric partea dreaptă (care trebuie să fie complet pectiv nu este folosit pentru a transmite o legare dintr-o parte ı̂n alta, deci este
instant, iată, s, i: inutil.
frumoasa(ana). %1 Correct:
– dacă partea stângă este instant, iată s, i este o valoare, verifică egali-
bun(vlad). %2 my_length3([],0).
cunoaste(vlad, maria). %3 tatea valorilor.
my_length3([_|L],N) :- my_length3(L,N1), N is N1 + 1.
cunoaste(vlad, ana). %4 – dacă partea stângă este o variabilă, leagă variabila la valoarea din
iubeste(mihai, maria). %5 dreapta.
iubeste(X, Y):- bun(X), %6
– altfel, false. Documentarea predicatelor s, i a argumentelor
cunoaste(X, Y),
frumoasa(Y).
predicat/nrArgumente
Regula ’iubes, te(X,Y)’ se poate traduce: ”X iubes, te pe Y dacă X e bun s, i dacă Liste predicat(+Arg1, -Arg2, ?Arg3, ..., +ArgN)
X cunoas, te pe Y s, i dacă Y este frumoasă”.
[] - lista vida Pentru a diferent, ia intrările (+) de ies, iri (-), se prefixează argumentele cu in-
O regulă Prolog exprimă un fapt care depinde de alte fapte. [a,b,c] - elementele a, b, c dicatori. Acele argumente care pot fi fie intrări, fie ies, iri se prefixează cu (?)
Faptele se pot ı̂nlănt, ui folosind virgula(, - s, i logic) s, i punct s, i virgula(; - sau [Prim|Rest] - element concatenat la rest
Unele predicate nu au parametrii
logic) [X1,X2,...,XN|Rest] - n elemente concatenate la restul listei
Ex: Predicatul fail/0 care se va evalua mereu la false.

Evaluare ı̂n Prolog


Prolog este optimist: atunci când Prolog primes, te o interogare, Prolog
ı̂ncearcă să demonstreze că interogarea este adevărată.
Prolog este perseverent: dacă interogarea cont, ine variabile sau wild-
cards, ı̂ncercă să găsească valori pentru elementele neinstant, iate (ı̂n do-
menii care pot fi desprinse din program) ı̂n as, a fel ı̂ncât să poată demons-
tra că interogarea este adevărată.
Prolog face backtracking: ı̂n timp ce ı̂ncearcă demonstrarea unui scop,
anumite predicate pot avea mai multe variante de demonstrare (e.g. mai
multe reguli, sau folosesc operatori sau). Astfel se creează alternative,
care vor fi explorate de Prolog prin backtracking pentru satisfacerea /
resatisfacerea scopului.
Prolog CheatSheet
Laborator 11

Liste s, i funct, ii utile pe liste Backtracking când calea are un număr nedeterminat de stări

[] - lista vida
În această situaţie nu este posibil să definim un template care descrie forma
[a,b,c] - elementele a, b, c soluţiei problemei. Vom defini o căutare mai generală, după modelul următor:
[Prim|Rest] - element concatenat la rest
solve(Solution):-
[X1,X2,...,XN|Rest] - n elemente concatenate la restul listei
initial_state(State),
search([State], Solution).
append(?List1, ?List2, ?List1AndList2) % List1AndList2 este
concatenarea ı̂ntre List1 s, i List2 search(+StăriVizitate,-Soluţie) defines, te mecanismul general de căutare astfel:
?- append([1,2,3], [4,5], X).
X = [1, 2, 3, 4, 5]. • căutarea ı̂ncepe de la o stare init, ială dată (predicatul initial state/1)
?- append([1,2,3], X, [1,2,3,4]). • dintr-o stare curentă se generează stările următoare posibile (predicatul
X = [4].
?- append([1,2,3], X, [2,3,4]).
next state/2)
false. • se testează că starea ı̂n care s-a trecut este nevizitată anterior (evitând
astfel traseele ciclice)
member(?Elem, ?List) % Adevărat dacă Elem esre prezent ı̂n List
?- member(1, [1,2,3]). • căutarea continuă din noua stare, până se ı̂ntâlneşte o stare finală (pre-
true ; dicatul final state/1)
false.
?- member(X, [1,2,3]). search([CurrentState|Other], Solution):-
X = 1 ; final_state(CurrentState), !,
X = 2 ; reverse([CurrentState|Other], Solution).
X = 3.
search([CurrentState|Other], Solution):-
length(?List, ?Int) % Adevărat dacă Int reprezintă numărul de next_state(CurrentState, NextState),
elemente din List \+ member(NextState, Other),
?- length([1,2,3], X). search([NextState,CurrentState|Other], Solution).
X = 3.

reverse(?List1, ?List2) % Adevărat atunci când elementele din Mecanism BFS


List2 sunt ı̂n ordine inversă fat, ă de List1
?- reverse([1, 2, 3], X). bfs(+CoadaStărilorNevizitate,+StăriVizitate,-Soluţie) va defini mecanismul
X = [3, 2, 1]. general de căutare ı̂n lăţime, astfel:

sort(+List, -Sorted) % Adevărat atunci când Sorted cont, ine toate • căutarea ı̂ncepe de la o stare init, ială dată care n-are predecesor ı̂n spaţiul
elementele din List (fără duplicate), sortate ı̂n ordinea stărilor (StartNode cu părintele nil)
standard • se generează toate stările următoare posibile
?- sort([2, 3, 1, 2], X).
X = [1, 2, 3]. • se adaugă toate aceste stări la coada de stări ı̂ncă nevizitate
• căutarea continuă din starea aflată la ı̂nceputul cozii, până se ı̂ntâlneşte
o stare finală
Backtracking când se cunoas, te lungimea căii către solut, ie
Regulă: Atunci când calea către soluţie respectă un anumit template (avem de bfs([(StartNode,nil)], [], Discovered).
instanţiat un număr finit, predeterminat, de variabile), este eficient să definim
un astfel de template ı̂n program.
Mecanism A*
De exemplu, pentru problema celor opt regine putem scrie astfel:
astar(+End, +Frontier, +Discovered, +Grid, -Result) va defini mecanismul
template([1/_, 2/_, 3/_, 4/_, 5/_, 6/_, 7/_, 8/_]). general de căutare A*, astfel:
correct([]):-!. • căutarea ı̂ncepe de la o stare init, ială dată care n-are predecesor ı̂n spaţiul
correct([X/Y|Others]):- stărilor (StartNode cu părintele nil) s, i distant, a estimată de la acesta până
correct(Others), la nodul de final printr-o euristică (exemplu: distant, a Manhattan)
member(Y, [1, 2, 3, 4, 5, 6, 7, 8]),
safe(X/Y, Others). % predicat care verifică faptul că • se generează toate stările următoare posibile s, i se calculează costul aces-
reginele nu se atacă ı̂ntre ele tora adăugând costul act, iunii din părinte până ı̂n starea aleasă cu costul
real calculat pentru a ajunge ı̂n părinte (costul părintelui ı̂n Discovered)
solve_queens(S):-template(S), correct(S).
• dacă starea aleasă nu este ı̂n Discovered sau dacă noul cost calculat al
acesteia este mai mic decât cel din Discovered, se adaugă ı̂n acesta, apoi
va fi introdusă ı̂n coada de priorităt, i (Frontier) cu prioritatea fiind costul
cu care a fost adaugată ı̂n Discovered + valoarea dată de euristică din
starea curentă până ı̂n cea finală
• căutarea continuă din starea aflată la ı̂nceputul cozii, până se ı̂ntâlneşte
o stare finală

astar_search(Start, End, Grid, Path) :-


manhattan(Start, End, H),
astar(End, [H:Start], [Start:("None", 0)], Grid, Discovered),
get_path(Start, End, Discovered, [End], Path).
Racket CheatSheet
Laborator1

Sintaxa Racket Constructori liste Funct, ii anonime (lambda) s, i funct, ii cu nume


(nume functie arg1 arg2 ...) null ’() cons list (lambda (arg1 arg2 ...) rezultat) (define nume val)
1 (max 2 3) 3 1 '() () 1 (lambda (x) x) functia identitate
2 (+ 2 3) 5 2 null () 2 ((lambda (x) x) 2) 2 aplicare functie
3 3 (define idt (lambda (x) x)) legare la un nume
4 (cons 1 null) (1) 4 (define (idt x) x) sintaxa alternativa
Tipuri de bază 5 (cons 'a '(b c)) (a b c) 5 (idt 3) 3
6

Valori booleene: #t #f (sau true false) 7 (list 1) (1)


Numere: 1 2 3 3.14 ... 8 (list 1 2 3 4) (1 2 3 4)
Sintaxa if
Simboli (literali): ’a ’b ’abc ’non-alnum?!
1 (if test exp1 exp2)
Operatori pe liste 2
Operatori aritmetici (if (< a 0)
car cdr first rest null? length member reverse 3

+ - * / modulo quotient add1 sub1 4 a


append
5 (if (> a 10) (* a a) 0))
1 (+ 1 2) 3 1 (car '(1 2 3 4)) 1
2 (- 7 2) 5 2 (first '(1 2 3 4)) 1
3 (* 2 11) 22 (cdr '(1 2 3 4)) (2 3 4)
3
Sintaxa cond
4 (/ 5 2) 2.5 4 (rest '(1 2 3 4)) (2 3 4)
5 (quotient 5 2) 2 5 (cadr '(1 2 3 4 5)) 2 1 (cond (test1 exp1) (test2 exp2) ... (else exp))
6 (modulo 5 2) 1 6 (cdar '(1 2 3 4 5)) eroare 2
7 (add1 4) 5 7 (cddr '(1 2 3 4 5)) (3 4 5) 3 (cond
8 (sub1 4) 3 8 (caddr '(1 2 3 4 5)) 3 4 ((< a 0) a)
9
5 ((> a 10) (* a a))
10 (null? null) #t (true) 6 (else 0))
Operatori relationali 11 (null? '(1 2)) #f (false)
12
< <= > >= = eq? equal? zero? 13 (length '(1 2 3 4)) 4
14 (length '(1 (2 3) 4)) 3 AS, A DA / AS, A NU
1 (< 3 2) #f
15
2 (>= 3 2) #t
3 (= 1 1) #t (numere) 16 (member 'a '(b c a d a e)) '(a d a e) 1 DA: (cons x L) NU: (append (list x) L)
4 (= '(1 2) '(1 2)) eroare 17 (member 'f '(b c a d a e)) #f 2 NU: (append (cons x '()) L)
5 (equal? '(1 2) '(1 2)) #t (valori) 18 3 DA: (if c vt vf) NU: (if (equal? c #t) vt vf)
6 (eq? '(1 2 3) '(1 2 3)) #f (referinte) 19 (reverse '(1 (2 3) 4)) (4 (2 3) 1) 4 DA: (null? L) NU: (= (length L) 0)
7
20 5 DA: (zero? x) NU: (equal? x 0)
8 (define x '(1 2 3)) 21 (list? '()) #t 6 DA: test NU: (if test #t #f)
9 (eq? x x) #t 22 (list? 2) #f 7 DA: (or ceva1 ceva2) NU: (if ceva1 #t ceva2)
10
23 8 DA: (and ceva1 ceva2) NU: (if ceva1 ceva2 #f)
11 (zero? 0) #t (true) 24 (append '(1 2 3) '(4) '(5)) (1 2 3 4 5)
12 (zero? 1) #f (false) 25 (append 1 '(2 3 4)) eroare
Programare cu funct, ii recursive
take s, i drop 1. După ce variabilă(e) fac recursivitatea? (ce varia-
Operatori logici
bilă(e) se schimbă de la un apel la altul?)
not and or 1 (take '(1 2 3 4) 2) '(1 2) 2. Care sunt condit, iile de oprire ı̂n funct, ie de aceste va-
1 (not true) #f 2 (drop '(1 2 3 4 5) 2) '(3 4 5) riabile?(cazurile “de bază”)
2 (not false) #t 3
4 (take-right '(1 2 3 4) 2) '(3 4) 3. Ce se ı̂ntâmplă când problema nu este ı̂ncă elemen-
3 (or true false) #t
4 (and #f #t) #f 5 (drop-right '(1 2 3 4 5) 2) '(1 2 3) tară? (Obligatoriu aici cel put, in un apel recursiv)

Folositi cu incredere!
http://docs.racket-lang.org/
Racket CheatSheet
Laborator 2

Recursivitate pe stivă Recursivitate pe coadă Sintaxa Racket


(nume_functie arg1 arg2 ...)
1 ; suma elementelor unei liste 1 ; suma elementelor unei liste
2 ( d e f i n e ( s u m - l i s t L) 2 ( d e f i n e ( s u m - l i s t L) 1 (max 2 3) 3
3 3 ( s u m - l i s t - t a i l 0 L) ) ; <-- funcție ajutătoare 2 (+ 2 3) 5
4 4 ; ^ valoarea inițială pentru sumă
5 ; aici nu avem nevoie de funcție auxiliară 5
6 6 ; în sum construim rezultatul AȘA DA / AȘA NU
7 7 ( d e f i n e ( s u m - l i s t - t a i l sum L)
8 ( i f ( n u l l ? L) 8 ( i f ( n u l l ? L)
9 0 ; la sfârșit creăm valoarea inițială 9 sum ; la sfârșit avem rezultatul gata 1 DA: ( cons x L) NU: ( append ( l i s t x ) L)
10 (+ ( car L) ( s u m - l i s t ( cdr L) ) ) 10 ( sum-list-tail 2 NU: ( append ( cons x ' ( ) ) L)
11 ; ^ construim rezultatul pe revenire 11 (+ sum ( car L) ) 3 DA: ( i f c vt v f ) NU: ( i f ( equal ? c #t ) vt v f )
12 ; (după întoarcerea din recursivitate) 12 ; ^ construim rezultatul pe avans 4 DA: ( n u l l ? L) NU: (= ( l e n g t h L) 0)
13 )) 13 ; (pe măsură ce intrăm în recursivitate) 5 DA: ( zero ? x) NU: ( equal ? x 0)
14 ; fiecare apel recursiv întoarce rezultatul corespunzător 14 ( cdr L) ) ) ) 6 DA: test NU: ( i f t e s t #t #f )
argumentelor 15 ; funcția întoarce direct rezultatul apelului recursiv – toate 7 DA: ( or ceva1 ceva2 ) NU: ( i f ceva1 #t ceva2 )
15 apelurile recursive întorc același rezultat, pe cel final 8 DA: ( and ceva1 ceva2 ) NU: ( i f ceva1 ceva2 #f )
16 16
17 17
18 18 ; concatenarea a două liste Imagini în Racket
; concatenarea a două liste ( d e f i n e ( app A B)
overlay, image-height, beside, above
19 19
20 ( d e f i n e ( app L1 L2) 20 ( a p p - i t e r B ( r e v e r s e A) ) )
21 21 ; nevoie de funcție ajutătoare
22 22 ; rezultatul este construit în ordine inversă
23 23
24 24 ( d e f i n e ( a p p - i t e r B Result ) 1 ( overlay ) ; =>
25 25 ( i f ( n u l l ? B) ; la sfârșit rezultatul e complet 2 ( image-height ( c i r c l e 20 ” s o l i d ” ” red ” ) ) ; => 40
26 ( i f ( n u l l ? L1) 26 ( r e v e r s e Result ) ; inversăm rezultatul
27 L2 ; când L1 este vidă, întoarcem L2 27 ( a p p - i t e r ( cdr B) ( cons ( car B) Result ) ) ) )
28 ( cons ( car L1) ( app ( cdr L1) L2) ) 28 ; construim rezultatul pe avans
29 ; ^ construim rezultatul pe revenire)) 3 ( image-height ) ; => 60
• apelurile recursive nu consumă spațiu pe stivă –
• fiecare apel recursiv se pune pe stivă execuția este optimizată știind că rezultatul ape-
• complexitate spațială O(n) lului recursiv este întors direct, fără operații supli-
4 ( image-width ) ; => 60
mentare.
• scriere mai simplă
• complexitatea spațială este dată doar de spațiul 5 ( beside ) ; =>
necesar pentru acumulator – de exemplu la sum-
list-tail complexitatea spațială este O(1).
• scriere mai complexă, necesită de multe ori funcție 6 ( above ) ; =>
auxiliară pentru a avea un parametru suplimentar
pentru construcția rezultatului (rol de acumula-
tor), mai ales dacă tipul natural de recursivitate Folosiți cu încredere!
al funcției este pe stivă. http://docs.racket-lang.org/
– Atenție: uneori, rolul acumulatorului poate
fi preluat de unul dintre parametri, caz în care
nu este nevoie nici de funcția suplimentară.
• rezultatul este construit în ordine inversă
Racket CheatSheet
Laborator 3

Funct, ii anonime (lambda) s, i funct, ii cu nume Funct, ionalele foldl s, i foldr Funct, ionala map
(lambda (arg1 arg2 ...) rezultat) (fold* funct, ie acumulator listă) (map funct, ie listă)
(define nume val) funct, ie → (lambda (element acumulator’) (map funct, ie lista1 lista2 ...)
1 (lambda (x) x) functia identitate acumulator”) Transformă independent elementele de pe pozit, ii diferite
2 ((lambda (x) x) 2) 2 aplicare functie Îmbină toate elementele unei liste pentru a construi o ale uneia sau mai multor liste. Întoarce o listă cu acelas, i
3 (define idt (lambda (x) x)) legare la un nume
4 (define (idt x) x) sintaxa alternativa valoare finală, pornind de la un acumulator init, ial. Într- număr de elemente ca lista/ listele date ca parametru.
5 (idt 3) 3 un pas, funct, ia dată ca parametru combină elementul
6 curent din listă cu acumulatorul, ı̂ntorcând un nou acu- • Pentru o singură listă, aplică funct, ia, pe rând asu-
7 ((if true + -) (+ 1 2) 3) 6 if-ul se evaluează
mulator. Acumulatorul final este ı̂ntors ca rezultat al pra fiecărui element: (map f (list e1 . . . en )) →
8 la o funct, ie (list (f e1 ) . . . (f en ))
9
funct, ionalelor fold*. Acesta poate fi chiar o listă.
10 (define (comp f g) funct, ia de
• foldr (right) poate fi ı̂nt, eleasă cel mai us, or • Pentru mai multe liste de aceeas, i lungime,
11 (lambda (x) compunere (◦)
12 (f (g x)))) a altor 2 funct, ii prin faptul că funct, ia dată ca parametru se sub- funct, ia este aplicată la un moment dat asu-
13
stituie lui cons, iar acumulatorul init, ial, lis- pra tuturor elementelor de pe aceeas, i pozit, ie:
14 ((comp car cdr) '(1 2 3)) 2 car ◦ cdr (map f (list e11 . . . e1n ) . . . (list em1 . . . emn )) →
15
tei vide de la finalul listei. Prin urmare, ele-
mentele listei sunt prelucrate de la dreapta la (list (f e11 . . . em1 ) . . . (f e1n . . . emn ))
16 ((comp (lambda (x) (+ x 1)) 11 inc ◦ dublare
17 (lambda (x) (* x 2))) stânga: (foldr f acc (list e1 . . . en )) → Există s, i funct, ionalele andmap s, i ormap. Prima se asi-
18 5) (f e1 (f . . . (f en acc) . . .)) gură că, ı̂n urma aplicării lui map, toate rezultatele sunt
Funct, ii curried / uncurried • foldl (left) prelucrează elementele de la stânga diferite de false, iar a doua, că cel put, in un rezultat
la dreapta: (foldl f acc (list e1 . . . en )) → este diferit de false.
1 (define add-uncurried parametri luat, i
2 (lambda (x y) simultan
(f en (f . . . (f e1 acc) . . .)) 1 (map (lambda (x) (* x 10)) '(1 2 3)) '(10 20 30)
2 (map * '(1 2 3) '(10 20 30)) '(10 40 90)
3 (+ x y)))
4
Se pot furniza mai multe liste, caz ı̂n care comportamen- 3 (map list '(1 2 3)) '((1) (2) (3))
tul este similar cu cel al lui map pe mai multe liste. 4 (map list '(1 2) '(3 4)) '((1 3) (2 4))
5 (add-uncurried 1 2) 3
5
6
6 (define (mult-by q) ; Curried
7 (define add-curried parametri luat, i
7 (lambda (x)
8 (lambda (x) succesiv
8 (* x q)))
9 (lambda (y)
9 (map (mult-by 5) '(1 2 3)) '(5 10 15)
10 (+ x y))))
11
12 ((add-curried 1) 2) 3
13
Funct, ionala apply
14 (define inc (add-curried 1)) aplicat, ie part, ială (apply funct, ie listă arg)
Perspective asupra funct, iilor binare curried : 1 (foldr + 0 '(1 2 3)) 6 (apply funct, ie arg 1 ... arg n listă arg)
• Iau parametrii pe rând”, fiind aplicabile part, ial. Aplică o funct, ie asupra parametrilor dat, i de elementele
” unei liste. Opt, ional, primii parametri ai funct, iei ı̂i pot fi
• Iau un parametru s, i ı̂ntorc o altă funct, ie de un
furnizat, i individual lui apply, ı̂naintea listei cu restul
parametru.
parametrilor. (apply f x1 . . . xm (list e1 . . . en )) →
(f x1 . . . xm e1 . . . en )
Funct, ionala filter
1 (apply + '(1 2 3)) 6 suma
(filter funct, ie listă) 2 (apply + 1 '(2 3)) 6 la fel
2 (foldl + 0 '(1 2 3)) 6
Păstrează dintr-o listă elementele pentru care funct, ia 3 (foldr cons '() '(1 2 3)) '(1 2 3) identitate! 3 (apply list '(1 2 3)) '(1 2 3)
4 (foldl cons '() '(1 2 3)) '(3 2 1) inversare 4 (apply list '(1 2 3) '(5 6 7)) '((1 2 3) 5 6 7)
NU ı̂ntoarce false. (filter f (list e1 . . . en )) →
5 (foldl (lambda (x y acc) 21 2 liste
(list ei1 . . . eim ), cu (f eik ) 6→ false. 6 (+ x y acc))
1 (filter even? '(1 2 3)) '(2) 7 0 '(1 2 3) '(4 5 6))
Racket CheatSheet
Laborator4

let letrec Alte funct, ii


Colorată - zona de vizibilitate pentru id1 Colorată - zona de vizibilitate pentru id2 sort remove assoc andmap findf splitf-at
Valoare de retur - exprn Valoare de retur - exprn 1 (sort '(5 2 1 6 4) >) (6 5 4 2 1)
1 (let ((id1 val1) 1 (letrec ((id1 val1) 2 (remove 2 '(1 2 3 4 3 2 1)) (1 3 4 3 2 1)
2 (id2 val2) 2 (id2 val2) 3 (assoc 3 '((1 2) (3 4) (3 6) (4 5))) (3 4)
3 ... 3 ... 4 (andmap positive? '(1 2 3)) #t
4 (idn valn)) 4 (idn valn)) 5 (andmap number? '(1 b 3)) #f
5 expr1 5 expr1 6 (findf (lambda (x) (> x 4)) '(1 3 5 6 4)) 5
6 expr2 6 expr2 7 (findf (lambda (x) (> x 6)) '(1 3 5 6 4)) #f
7 ... 7 ... 8 (splitf-at '(1 3 4 5 6) odd?) (1 3)
8 exprn) 8 exprn) 9 (4 5 6)
9 9 10 (splitf-at '(1 3 4 5 6) even?) ()
10 (define a 10) 10 ;; cand evaluez b, b trebuie sa fi fost definit 11 (1 3 4 5 6)
11 11 (letrec ((a b) (b 1))
12 (let ((a 1) (b (+ a 1))) 12 (cons a b)) eroare
13 (cons a b)) (1 . 11) 13 Folositi cu incredere!
14 ;; corpul unei inchideri functionale
15 ;; nu se evalueaza la momentul definirii http://docs.racket-lang.org/
let* 16 (letrec
17 ((even-length?
Colorată - zona de vizibilitate pentru id1 18 (lambda (L)
Valoare de retur - exprn 19 (if (null? L)
20 #t
1 (let* ((id1 val1) 21 (odd-length? (cdr L)))))
2 (id2 val2) 22 (odd-length?
3 ... 23 (lambda (L)
4 (idn valn)) 24 (if (null? L)
5 expr1 25 #f
6 expr2 26 (even-length? (cdr L))))))
7 ... 27 (even-length? '(1 2 3 4 5 6))) #t
8 exprn)
9
10 (define a 10)
11
let-values
12 (let* ((a 1) (b (+ a 1))) Ca let, pentru expresii care ı̂ntorc valori
13 (cons a b)) (1 . 2) multiple
1 ;; val-expr este o expresie care intoarce n valori
named let 2 (let-values ( ((id1 id2 .. idn) val-expr)
3 ... )
nume - apare ı̂n corp ca un apel recursiv al funct, iei 4 corp)
cu parametrii id1 .. idn s, i corpul corp 5
6 (let-values (((x y) (quotient/remainder 10 3)))
1 (let nume ((id1 val1)
7 (cons x y)) (3 . 1)
2 (id2 val2)
3 ...
4 (idn valn))
5 corp)
6
7 (let loop ((n 5)
8 (fact 1))
9 (if (zero? n)
10 fact
11 (loop (sub1 n) (* n fact)))) 120
Racket CheatSheet
Laborator 5

Promisiuni Fluxuri definite explicit Fluxuri definite implicit


delay force Generator recursiv cu oricât, i parametri Fără generator explicit
(define p (delay (+ 1 2))) definit ı̂n mod uzual cu named let
1 Dă explicit primii 1-2 termeni, apoi init, iază
2 p #<promise:p> 1 ;; fluxul puterilor lui 2 o prelucrare folosind (de obicei)
3 2 (define powers-of-2
4 ;; force forteaza evaluarea
funct, ionale pe fluxuri
3 (let loop ((n 1))
5 (force p) 3 4 (stream-cons n (loop (* n 2))))) 1 ;; stream-zip-with este definita de voi
6 5 2 ;; in laborator, nu exista in Racket
7 ;; un force subsecvent ia rezultatul din cache 6 ;; fluxul Fibonacci 3
8 (force p) 3 7 (define fibonacci 4 ;; fluxul puterilor lui 2
8 (let loop ((n1 0) (n2 1)) 5 (define powers-of-2-a
9 (stream-cons n1 (loop n2 (+ n1 n2))))) 6 (stream-cons
Constructori fluxuri 10 7 1
11 ;; fluxul 1/(n!) 8 (stream-zip-with +
empty-stream stream-cons
12 ;; (cu care putem aproxima constanta lui Euler) 9 powers-of-2-a
1 empty-stream #<stream> 13 (define rev-factorials 10 powers-of-2-a)))
2 (stream-cons 1 empty-stream) #<stream> 14 (let loop ((term 1) (n 1)) 11

3 15 (stream-cons term (loop (/ term n) (add1 12 (define powers-of-2-b


4 (define ones (stream-cons 1 ones)) fluxul de 1 n))))) 13 (stream-cons
5 16 14 1
6 ;; fluxul numerelor naturale 17 ;; testare: stream-take este definita de noi 15 (stream-map (lambda (x) (* x 2))
7 (define naturals 18 ;; in laborator, nu cel definit in Racket 16 powers-of-2-b)))
8 (let loop ((n 0)) 19 17

9 (stream-cons n (loop (add1 n))))) 20 ;; rezultat '(1 2 4 8 16 32 64 128 256 512) 18 ;; fluxul Fibonacci
21 (stream-take powers-of-2 10) 19 (define fibonacci
22 20 (stream-cons
23 ;; rezultat '(0 1 1 2 3 5 8 13 21 34) 21 0
Operatori pe fluxuri
24 (stream-take fibonacci 10) 22 (stream-cons
stream-first stream-rest stream-empty? 25 23 1
26 ;; rezultat 2.7182815255731922 24 (stream-zip-with +
1 (stream-first naturals) 0 fibonacci
27 (apply + 0.0 (stream-take rev-factorials 10)) 25
2 (stream-rest (stream-cons 2 ones)) fluxul de 1 26 (stream-rest fibonacci)))))
3
27
4 (stream-empty? empty-stream) #t 28 ;; fluxul 1/(n!)
5 (stream-empty? ones) #f AS, A DA / AS, A NU
29 (define rev-factorials
Folosit, i interfat, a Racket pentru fluxuri! 30 (stream-cons
31 1
Funct, ionale pe fluxuri 1 DA: (stream-cons x S) NU: (cons x (lambda () S)) 32 (stream-zip-with /
2 NU: (cons x (delay S)) 33 rev-factorials
stream-map stream-filter 3 DA: (stream-rest S) NU: ((cdr S)) 34 (stream-rest naturals))))
4 NU: (force (cdr S))
1 ;; stream-map merge numai cu functii unare
2 (stream-map sqr naturals) fluxul 0, 1, 4..
3 Folositi cu incredere!
4 (stream-filter even? naturals) fluxul nr pare
http://docs.racket-lang.org/

S-ar putea să vă placă și