Sunteți pe pagina 1din 19

Programare Logica Cu Constrangeri

Padurean Florina-Alexandra

2017
Abstract

Programare logica cu constrangeri imbina programarea logica si programarea


cu constrangeri, si anume stilul declarativ al programarii logice impreuna cu
eficienta rezolvarii constrangerilor. Acest referat are scopul de a prezenta
o introducere generala in Programarea logica cu constrangeri, precum si
prezentarea unor notiuni si tehnici prin exemple specifice.[3]
Cuprins

0.1 Introducere . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
0.1.1 Istorie . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
0.1.2 Despre Programarea Logica . . . . . . . . . . . . . . . 2
0.2 Prolog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
0.2.1 Despre Prolog . . . . . . . . . . . . . . . . . . . . . . . 3
0.2.2 SWI-Prolog . . . . . . . . . . . . . . . . . . . . . . . . 3
0.2.3 Sintaxa de baza . . . . . . . . . . . . . . . . . . . . . . 4
0.2.4 Liste in Prolog . . . . . . . . . . . . . . . . . . . . . . 7
0.2.5 Operatori . . . . . . . . . . . . . . . . . . . . . . . . . 7
0.2.6 Unificare . . . . . . . . . . . . . . . . . . . . . . . . . . 8
0.2.7 Recursivitate . . . . . . . . . . . . . . . . . . . . . . . 9
0.2.8 Conjunctii . . . . . . . . . . . . . . . . . . . . . . . . . 10
0.2.9 Predicatul cut . . . . . . . . . . . . . . . . . . . . . . . 11
0.2.10 Predicatul fail . . . . . . . . . . . . . . . . . . . . . . . 12
0.2.11 Regula de manipulare a constrngerilor . . . . . . . . . 12
0.2.12 Threaduri . . . . . . . . . . . . . . . . . . . . . . . . . 13
0.3 Bibliografie . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

1
0.1 Introducere
0.1.1 Istorie
In prima jumatate a secolului al XX-lea, cercetatorii inteligentei arti-
ficiale au pus bazele Programarii logice, incepand de la ideeile uni profesor
din Anglia,Universitatea din Edinburgh.
Primul limbaj logic a fost realizat de Carl Hewitt in 1969 si era numit
Planner, mai tarziu in 1970 Alain Colmerauer si Robert Kowalski au dez-
voltat Prolog, care este cel mai cunoscut limbaj logic folosit, fiind evoluat
din System Q. [1]

0.1.2 Despre Programarea Logica


In Programarea Logica este mai importanta corectitudinea progra-
mului ,si abia apoi eficienta pe care o are, mai exact exista doua tipuri de
interpretari a programelor logice: tipul declarativ ”ce” trebuie calculat si
tipul procedural ”cum” trebuie calculat[4]. Logica folosita este logica predi-
catelor(first order predicate logic), aceasta ajuntand la deducerea unor ade-
varuri dintr-un set de adevaruri deja existent.
Scopul programarii logice este acela de a imbina logica cu programarea,
calculele facute fiind defapt o serie de deductii logice.Pentru realizarea aces-
tor deductii, sunt necesare:
Programarea logica are aplicari in diferite domenii precum: sisteme de
baze de date care pot realiza deduceri cu ajutorul unor reguli si fapte date
si deducerea rationamentelor. In programarea logica cu constrangeri,
relatiile dintre variabile pot fi definite sub forma de constrangeri, acestea
specificand caracteristicile solutiei finale. Comparat cu limbajele de progra-
mare imperative, limbajele care folosesc constrangeri nu specifica secventa
de pasi care trebuie exectutata.[3]
• Seturile de obiecte folosite pentru calcule

• Relatiile dintre obiecte

• Constrangerile problemei
[3] Programul contine puncte de decizie, unde calculele pot sa ia cai
alternative, in cazul in care se ajunge la ceva eronat, programul se intoarce

2
la ultimul punct de decizie si merge pe urmatorea cale.

0.2 Prolog
0.2.1 Despre Prolog
Denumirea limbajului de programare este defapt o abreviere la ”progra-
mare in logica” din limba franceza ”Programmation en Logique”, preluandu-
se primele trei litere din primul si al treilea cuvant, astfel formandu-se ”PRO-
LOG”.
Prolog este un limbaj de programare considerat high-level, initial fiind
conceput pentru procesarea limbajului natural,apoi descoperindu-se si alte
utilizari pentru Prolog in diverse domenii precum: biologia moleculara, sis-
teme VLSI.[4]
Exista mai multe implementari ale acestui limbaj precum: GNU Pro-
log, SWI-Prolog, ECLiPSe, SICStus, Quintus, Oz, Poplog Prolog, dar acestea
sunt cele mai cunoscute din ele.

0.2.2 SWI-Prolog
SWI-Prolog este una din cele mai populare open-source implementari,
bazata pe sintaxa Edinburgh Prolog, dar foarte apropiata de ISO-Prolog,
avand si cateva extensii ale sintaxei de baza .
Una din extenii este procesorul de set de caractere, folosit pentu parsarea
fisierelor text. De asemenea sunt introduse comentariile multiple( nested
comments), marcare cu ”/* ..... */”.
In cazul in care se doeste folosirea caracterelor speciale, este obli-
gatoriu ”\” in fata caracterului.Exemple:”\b”- backspace, ”\” -linie noua,
”\r”-return, etc.
SWI Prolog reprezinta textul sub forma de sir de caractere de 8 bit,
iar caracterele largi ca un sir de caractere de 32 de biti si suporta codificari
precum: octet, ascii, utf8, text, iso latin 1, ”Little Endian” si ”Big Endian”,
dar nu toate pot reprezenta toate caracterele.
Exista mai multe locatii de memorie: stiva locala, stiva globala si stiva
trail care pot fi marite pana la o anumita limita.Exista comenzi predefinite
pentru a schimba limitele : ”set prolog stack/2” si optiunile ”-L”, ”-G”, ”-

3
T” pentru fiecare stiva, toate avand setate lungimea de 120 Mbytes initial
fiecare.
Extensiile fisierelor Prolog pot fi ”.pl”,”.p” sau ”.pro”.[11]

0.2.3 Sintaxa de baza


Termenii de baza pe care ii foloseste prolog sunt:

• Variabile

• Atomi

• Constante

• Reguli

• Fapte

• Intrebari

[2]

Variabile
Numele unor variabile in Prolog sunt incepute cu litera mare sau under-
score, urmand orice alt tip de caractere. Orice variabila poate sa reprezinte
un numar, un string, un arbore,o lista sau chiar o procedura sau un intreg
program.[2]
Exemple:
X=2
Var
var
X var2
->variabila speciala, singura este considerata variabila anonima

Constante
Orice atom sau numar este considerat fiind o constanta.

4
Atomi
Atomii sunt secvente de caractere care incep cu litera mica, restul sim-
bolurilor fiind orice alt tip de caractere: numere, litere, cifre si simboluri. De
asemenea ceea ce se alfa intre ghilimele este considerat un atom.[2]
Exemple:
x
x34 F
’Ana are mere$’

Reguli
Regulile sunt relatii noi care depinde de fapte deja existente. Regulile
au forma:
A :-B1,B2,...Bn. , unde A este capul regulii, iar tot ce se afla dupa ” :-” se
numeste corpul regulii.[5]
Exemplu:
fiu(X,Y):-tata(Y,X),barbat(X).
Aceasta regula poate fi citita din doua moduri.Primul mod, cel pro-
cedural: ”Pentru a raspunde la intrebarea este X fiul lui Y?, trebuie sa
raspundem la intrebarea Y este tatal lui X si X este barbat?”. A doua inter-
pretare este vizualizarea regulii ca o axioma logica: ”X este fiul lui Y daca Y
este tatal lui X si X este barbat.”, in prolog ”:-” fiind identificat cu ”daca”
in limbaj natural , precum virgula cu cuvantul ”si”.[5]

Fapte
Faptele sunt predicate de ordinul intai, care stabilesc relatii intre
obiecte, aceste relatii fiind mereu adevarate.Numele relatiei este numit predi-
cat,iar in paranteza se regasesc atomi.Cel mai simplu program prolog poate fi
alcatuit doar din mai multe fapte, acestea avand scopul de a reda legaturiile
din unviversul problemei. In general program logic este alcatuit din fapte si
reguli.[5]

Exemple:

• Maria este femeie.

5
femeie(Maria). ->Acest fapt este adevarat, definit de programator.Numele
relatiei(predicatul) este ”femeie”,iar ”Maria” reprezinta atomul.

• Maria este mama lui Ion


mama(Maria,Ion). ->Acest fapt este definit, considerat adevarat.

• X este mama lui Y.


mama(X,Y). ->Acest fapt este adevarat doar daca X este mama lui Y
,X si Y fiind doua variabile diferite si un fapt fiind definit anterior.

Intrebari
Intrebarile sunt modul de a primi informatii de la un program logic,acestea
fiind numite si scopuri.Raspunsul la intrebari se numeste tinta.Intrebarile
arata la fel cu faptele, dar faptele ”P.” si faptul P este considerat adevarat ,
iar intrebarile au ”P?” si verifica daca faptul P este adevarat.
Pentru a raspunde la intrebari, programul aplica regulile logice ale de-
ductiei, si anume identitatea, sau in cazul intrebarilor simple, se cauta un
fapt care sa implice intrebarea. In cazul in care un fapt P exista si intre-
barea este P, raspunsul dat va fii true, in caz contrar false. Raspunsurile
la intrebarile puse nu sunt tot timpul adevare, doarece totul se bazeaza pe
faptele descrise anterior, de exemplu femeie(maria)? va returna false in cazul
in care faptul: femeie(maria). nu a fost stabilit, ceea ce este adevarat doar
in concordanta cu programul logic descris.[5]

Exemple:
Considerand urmatoarele fapte:
femeie(maria).
mama(maria,ion).
?- femeie(maria).
Intrebarile urmatoare in prolog au un raspuns true/false:
true.
?- femeie(ana).
false.
?- mama(ana,ion).
false.

6
Table 1: Impartirea listei
Lista Head Tail
[a,b,c,d] a [b,c,d]
[a] a []
[X,b,Y,c] a [X,b,Y,c]
[[a,b],c,d] [a,b] [c,d]

0.2.4 Liste in Prolog


Lista este un sir ordonat de elemente sau o secventa.In Prolog, argu-
mentele faptelor si regulilor pot fi scrise sub forma de lista. Exemple:
[a,b,c]
[b,a,c]->nu e acelasi lista cu cea anterioara,listele sunt ordonate!
[a,X,b,Y,c]
[[a,b],X,b,[a,b,c],Z,c]
In interiorul listei, elementele pot fi: constante, variabile, reguli, fapte,
chiar si alte liste.
Lista este compusa dintr-un cap(HEAD) si restul liste, numita coada(TAIL)
[Cap—Coada].Lista formata prin inlaturarea capului reprezinta coada si aceasta
este reprezentata printr-o alata lista, fara cap, care poate fi folosita mai de-
parte.
De asemenea, dintr-o lista [x,y,z] putem accesa primele doua elemente:
[H1,H2—Coada], astfel putem identifica H1=x, H2=y si coada=[z].Aceasta
metoda este folosita pentru a ”sterge” elemente din lista curenta, pastrand
doar coada.
Adaugarea de elemente la o lista deja existenta L, se poate face prin
acelasi mod in care putem sterge un element dintr-o lista: Y=[X,L] ; Y fi-
ind acum o lista continand elementul X, urmat de lista L. Pentru a
construi o lista L, care contine n elemente: X1,X2,...XN iar apoi o alta lista
numinta L2, L=[X1,X2,..XN—L2]. De asemenea, exista lista vida: [ ]. [6]

0.2.5 Operatori
Operatorii in Prolog sunt majoritatea operatorii clasici: ”+”, ”-”, ”/”,
”*”, ”<”, ”>”, ”==”, ”<=”, ”>=”, ”,”, ”\=”, ” \==”, ”as”, ”is”, ”mod”,
”div”, ”ˆ”, ”;”, ”—”, ”:-”, ”?-” etc.
Pozitia operatorilor in Prolog poate fi de trei tipuri:

7
• Infix: operatorii care sunt asezati intre argumente: ”a+b”

• Prefix: operatorii care se afla in fata argumentului: ”-a” ; ”+20”

• Postfix: operatorii care sunt scrisi dupa argumente: ”x!”

Ordinea efectuarii operatiilor pentru expresia ”x+y*z”, consideram in-


multirea pioritara, inmultind y cu z, apoi adunam x cu rezultatul obtinut.Aceasta
expresie scrisa in Prolog sub forma: ”+(x,*(y,z))”, impune ca adunarea este
prima regula folosita, ”*” fiind un argument al structurii ”+”.
Calculele efective nu se efectueaza in cazul in care predicatul ”is” nu
este folosit.[7]
?- X = 3 + 4.
X = 3+4 ; ->nu se evalueaza

?- X is 3+4
X=7 ; ->se evalueaza
Precedenta operatorilor dintr-o expresie Prolog se poate reprezenta sub
forma unui arbore, in functie de precedenta si pozitia operatorului, com-
parata cu alt operator mai inalt.

0.2.6 Unificare
Procesul de unificare este acela in care variabilelor le sunt asignate
valori, prin substitutie, numit cel mai general unificator, iar procesul in care
se alfa cel mai general unificator se numeste Unificare.
Acest concept fundamental pentru programarea logica, a fost descoperit
de Robinson, in timpul demonstrarii teoremei automate. In cazul in care se
doreste sa se descida daca doi termeni sunt unificabili, aceastea problema
se numeste problema unificarii si se poate rezolva prin intermediul a unor
algoritmi.Acesti algoritmi returneaza eroare in cazul in care temenii nu se
pot unifica sau cel mai general unificator al temenilor.Exemplu de algoritmi:
algoritmul lui Martelli-Montanari ,algoritmul lui Robinson, algoritmul non-
deterministic al lui Robinson.[4]
In cazul instructiunii: ?- X=Y, Prolog incarca sa unifice X cu Y, avem
urmatoarele cazuri:
1.X nu este initializat si Y este instantiat cu orice, X va fi initalizat cu
ceea ce contine Y.

8
?- femeie(Ana)=X.
?-X.
X=femeie(Ana).
2.Comparand doua numere sau atomi cu el insusi mereu vor returna ade-
varat, false in celalalt caz.
123 = 123 ->true
paper = pencil ->false
pencil =pencil ->true
123 = 124 ->fail
3.Doua structuri sunt considerate egale daca au acelasi functor si acelasi
numar de componente.
?-tata(ion,ana)=tata(ion,X).
Aceasta intructiune duce la instantierea lui X cu ana.
Exista o regula speciala, in care se ajunge ca doua variabile saincerce
sa fie unificate, iar niciuna sa nu fie instantiate.In acest caz, aceste variabile
vor depinde una de cealalta, in momentul in care una va avea fi instatiata,
cealalta va avea aceeasi valoare.Orice X=Y, unde X si Y nu sunt instatiate,
o sa returneze true mereu.[7]

0.2.7 Recursivitate
Prolog foloseste Recursivitatea pentru a gasi solutii multiple la intre-
bari. In cazul unificarii cand se ajunge la esuare, Prolog incearca sa mearga
inapoi in cazul in care exista alte clauze care nu au fost incercate, incercand
sa le unifice.
Scenariile posibile in cazul recursivitatii :

• In cazul in care tinta este gasita si inca exista tinte care trebuie atinse,
trebuie memorate toate alternativele care nu au fost incercate si tre-
cerea la urmatoarea tinta posibila

• Daca tinta este gasita si nu mai sunt tine care trebuie verificate, atunci
s-a ajuns la cazul success

• Daca tinta nu este gasita si exita tinte alternative, acelea trebuie folosite

• In cazul in care nu s-a ajuns la success, dar exista tinte care nu au fost
incercate, programul se intoarce la acea tinta si se verifica mai departe

9
• Daca nu s-a gasit tinta si nu exista cai alternative de rezolvare sau tinte
neverificate, s-a ajuns la esuare/ nu au fost gasite tinte

[3] Exemplu pentru Recursivitate:


member(X,[X, ]). member(X,[Head—Tail]):-member(X,Tail).
?- member(c,[a,b,c]).
Se doreste sa se afle raspunsul la intrebarea ”Este c membru al listei [a,b,c]?”
Primul apel, identificam X=c,Head=a si Tail=[b,c]; X nu e egal cu Head =
>se mergem la utmatorul apel
Apoi se apeleaza member(c,[b,c]).
Identificam X=c,Head=b si Tail=[c]; X nu e egal cu Head= >se mergem la
utmatorul apel
Se apeleaza member(c,[c])
Identificam X=c,Head=c si Tail=[]; X e egal cu Head=>dam raspunsul in
mod recusiv, in ordinea inversa apelarii
[].
”c” este membru al listei [c]
”c” este membru al listei [b,c]
”c” este membru al listei [a,b,c]
=>la apelul ?- member(c,[a,b,c]). returneaza TRUE. [6]

0.2.8 Conjunctii
In cazul in care se pun intrebari complexe despre relatii, aceasta intre-
bare trebuie impartita in mai multe tinte, intre care se face conjunctie: ca sa
satisfaci toate tintele, se scriu cu ”,” intre ele, virgula tine locul cuvantului
”si”. Folosindu-se de faptele date, Prolog afiseaza raspunsul la intrebare,
true daca toate tintele sunt adevarate sau false in caz contrar.
Avand urmatoarele fapte:
likes(mary,food).
likes(mary,wine).
likes(john,wine).
likes(john,mary).
Daca vrem sa aflam ce au Mary si John in comun, intrebarea se pun
sub forma:
?- likes(mary,X),likes(john,X).
Din cauza faptului ca X nu este instantiat, se poate unifica cu orice=>se
ia fiecare fapt deja stabilit, si se unifica;X=food, in acest moment, X se va

10
inlocui si in cea de-a doua tinta: likes(john,food). Acest fapt nu a fost definit
anterior, in concluzie va returna false.
In acest moment Prolog seteaza X ca fiind neinstantiat si incearca sa
aleaga din restul faptelor, ceea ce ii place lui mary, urmatorul X fiind wine.
Daca X=wine in prima tinta, atunci X=wine si in ce-a dea doua:
likes(john,wine). =>true. Acum ambele tinte sunt satisfacute si X=wine.
In cazul in care sunt mai multe posibilitati pt X,Prolog va cauta acestea in
momentul cand ”;” este tiparit. [7]

0.2.9 Predicatul cut


Predicatul taietura/cut se noteaza cu ”!” si atunci cand apare, nu este
posibil sa revii la alte tinte plasate inaintea tintei curente, deci recursivitatea
nu este posibila dupa aparitia predicatului cut, toate punctele de decizie
alternative care se afla dupa taietura fiind eliminate.
Exista doua tipuri de taieturi:

• Taieturi verzi(Green cut) folosita cand stim dinainte ca anuminte posi-


bilitati nu duc la solutii

• Taieturi rosii (Red cut) folosita pentru a prevenii solutii eronate,eliminandu-


se considerarea tintelor alternative.

Exemple:
Taietura Verde
parent(X,Y):-father(X,Y),!.
parent(X, Y):-mother(X,Y).
father(john,paul).
father(john,peter).
mother(mary,paul).
mother(mary,peter).
Pentru intrebarea: ?- parent(john,X). A doua posibilitate: X=peter este ta-
iata de predicatul cut.

Taietura Rosie
Maximul dintre doua numere intregi poate fi calculat astfel:
max(M,N,M):- M¿=N.
max(M,N,N):-M=¡N.
Dar in cazul in care N si M sunt egale, atunci amandoua structuri vor reusii.

11
max(M,N,X):- M¿=N,!,M=X.
max(M,N,N).
In cazul in care Scoatem ”!”, programul nu mai calculeaza maximul corect,
din acest motiv taieturile rosii sunt considerate periculoase, dar necesare. [9]

0.2.10 Predicatul fail


Acest predicat este unul predefinit in Prolog, care are valoarea false sau
esec.Orice predicat se afla dupa fail, nu va fi executat niciodata.[6]
Fail este folosit pentru a forta programul sa foloseasca recursivitate.
Exemple:
go:-n1,
write(’Ce tara vrei sa vezi?’),
n1,
read(Country),n1,
spoken(Language,Country),
write(Language),write(’is spoken in’),
write(Country),n1,
fail.
In acest program, Prolog este obligat sa inceapa recursivitatea,intorcandu-se
pentru a incerca sa gaseasca o limba noua, pana cand nu mai poate gasi
alte solutii, de fiecare data cand se ajunge la predicatul fail, procesul fiind
repetat.[10]

0.2.11 Regula de manipulare a constrngerilor


Regula de manipulare a constrngerilor(Constraint handling rule- nu-
mit CHR) este un limbaj integrat in Prolog, bazat pe reguli. Acest limbaj
a fost integrat si in alte implementari precum SISCtus, Eclipse, Haskell si
Java. CHR a fost implementat pentru a rezolva proble cu constrangeri.

Semantica
In momentul in care o constrangere este apelata, aceasta este consid-
erata activa, iar sistemul incearca fiecare regula pentru aceasta contrangere,
secvential, in ordinea aparitiei lor.

12
Initial, pentru constrangerea activa se aplica capul regulii, iar daca ex-
ista reguli pasive(care apar in capul regulii) se incearca si acele reguli. Pro-
cesul se incheie in momentul in care una din reguli a inlaturat constrangerea
sau nu mai sunt reguli de incercat.
Exista trei tipuri de reguli:

• Simplificarea- sterge constrangerea din propiul corp si isi apeleaza cor-


pul

• Propagarea- apeleaza corpul sau o data pentru constrangerile din capul


regulii

• Simpagarea- sterge constrangerea din capul regulii dupa \si apoi ape-
leaza corpul: constraints1\constraints2<=>body

Regulile nu este necesar sa aiba nume.Pragmas-urile pot fi: passive(Identificator)


sau :-chr option(+Optine,+Valoare). In cazul chr option exista trei posibile
optiuni: check guard bindings;optimize si debug.
Toate constrangerile folosite terbuie sa fie declarate prin intermediul
:-chr constraint(+Specifier).
Exemple:
:-module(dom,[dom/2]).
:-use module(library(chr)).
:-chr constraint dom(?int,+list(int)).
:-chr type list(T) —>[ ] ; [T—list(T)].

dom(X,[ ]) <=>X=Y.
dom(X,L) <=>nonvar(X) — memberchk(X,L).
dom(X,L1), dom(X,L2) <=>intersection(L1,L2,L3), dom (X,L3).

Daca este pusa urmatoarea intrebare:


?- dom(A,[1,2,3]), dom(A,[3,4,5]).
Raspunsul va fi: A=3.[12]

0.2.12 Threaduri
In Swi-Prolog se pot crea si aplicatii ce folosesc multithreading, Prolog
foloseste o impementare bazata pe structura multithread standard a limbaju-
lui C, fiind diferit de alte implementari paralele in limbajele Prolog. Fiecare

13
thread avand propria lui stiva, doar coada continand predicate,flaguri, ce pot
fi impartasite global cu restul threaduri-lor, acest lucru neinfluentand buna
lor functionare.
Pentru a creea un nou thread exista: ”thread create(:Goal,-Id,+Options)”.Acest
thread nou creat, executa Goal-ul mentionat la inceput.Daca totul decurge
bine si este executat cu succes, threadul nou este unificat cu Id.Ultimul argu-
ment, Options reprezinta optiunile care pot sa fie adaugata threadului pre-
cum: ”alias(AliasName)”, ”inherit from(+ThreadId)”, ”global(K-Bytes)”,
”local(K-Bytes)”,etc.
La comanda ”thread self(-Id)” este returnat Id-ul unic al threadului
curent, precum si aliasul lui daca acesta exista.
”thread join(+Id,-Status)” este folosit pentru a afla statusul sau, cand
acesta este terminat, unificand statusul de terminare a threadului cu id-ul Id
cu Status.
Pentru a opri un thread, se foloseste ”thread exit(+Term)”, aces-
tea terminandu-se imediat, statusul in care iasa acesta este dat de ”ex-
ited(Term)”.
Pentru a initializa thread-ul, exista ”thread initalization(:Goal)”, acest
predicat executa Goal-ul cand porneste, creeat pentu initalizarea variabilelor
globale de exemplu, si tot ceea ce tine de stiva de runtime.In acest caz, Goal-
ul este apelat de patru ori: cand se apeleaza predicatul ”thread initalization”,
cand se revine la o stare salvata a thread-ului, in momentul inceperii unui
nou thread si atunci cand se creeaza motorul Prolog din interfata limajului
C.
Comunicarea intre threaduri se realizeaza prin intermediul cozilor de
mesaje, threadurile asteptand mesajele , dar fara a folosi CPU-ul calcula-
torului. Fiecare thread are propria lui coada de mesaje, dar se pot creea si
cozi aditionale.
Exista predicate pentru a trimite si primii mesaje: ”thread send message
(+QueueOrThreadId,+Term)” - pentru a adauga mesaje in coada mention-
ata sau in coada implicita a threadului cu ThreadId. In cazul de a primi
mesajele exista ”thread get message(?Term)” ,care se uita in coada de mesaje
si in cazul necesar o blocheaza pana ajunge in coada un termen ce se unifica cu
Term.Se poate lua un mesaj si din alte cozi ”thread get message(+Queue,?Term)”,
dar nu este indicat sa iei mesajele altor thread-uri.
Operatiile folosite de Prolog sunt considerate ca fiind thread-safe, doua
threaduri folosind aceleasi predicate fara a se afecta unul pe altul.Pentru a
realiza asta, sunt folosite mutexurile. Pentru a creea un multex cu id-ul Id,

14
exista predicatul ”mutex create(?Id,+Optiuni)”, acesta putand avea si un
alias ca optiune, dar este optional. In cazul in care un mutex nu mai este
necesar, se poate sterge ”mutex destroy(+MutexId)”.
Pentru a bloca o resursa, mutexurile se blocheaza ”mutex lock(+MutexId)”.Aceste
mutexuri pot fi blocate de mai multe ori pentru acelasi thread, apoi dupa
ce se deblocheaza de ceate ori a fost blocat devine activ pentru alte thread-
uri.Pentru a debloca mutexul exista ”mutex unlock(+MutexId)”.
Exemple:
:-initialization
mutex create(addressbook).

change address(Id,Address):-
mutex lock(addressbook),
retractall(address(Id, )),
assert(address(Id,Address)),
mutex unlock(addressbook).
In acest exemplu, se poate vedea clar creearea mutexului, blocarea lui pe
parcursul creearii operatiilor, precum si deblocarea lui cand s-au terminat de
efectuat operatiile ce necesitau sa fie blocate.
:-use module(library(socket)).
make server(Port,Workers):-
create socket(Port,Workers):-
message queue create(Q),
forall(between(1,Workers, ),
thread create(worker(Q), ,[ ]),
thread create(acceptor(S,Q), ,[ ]).

create socket(Port,Socket):-
tcp socket(Socket),
tcp bind(Socket,Port),
tcp listen(Socker,5).

acceptor(Socket,Q):-
tcp accept(Socket,Client, Peer),
thread send message(Q,Client),
acceptor(Socket,Q).

worker(Q):-

15
thread get message(Q,Client),
tcp open socket(Client,In,Out),
read(In,Command),
close(In),
process(Command,Out),
close(Out),
cworker(Q).

process(hello,Out):-
format(Out,’Hello world!’,[ ]).
Acesta este un exemplu pentru un server multithreading, folosind si comuni-
carea prin socketuri.”make server” si ”create socket” creeaza serverul si ini-
talizeaza conexiunea socketului, iar ”worker” contine codul pentru un client.
[12]

16
0.3 Bibliografie
[1]Distributed constraint logic programming- Ho-Fung Leung World Scien-
tific Publishing, 1993

[2]Constraint logic programming using eclipse, Krzysztof R. Apt and Mark


Wallace, 2007

[3]Introduction to the History of Computing: A Computing History Primer,


Gerard O’Regan,2016

[4]From Logic Programming to Prolog , Krzysztof R. Apt,Prentice Hall ,1997

[5]The Art of Prolog: Advanced Programming Techniques,Leon Sterling,Ehud


Saphiro,1986

[6]Functional Grammar in Prolog: An Integrated Implementation for En-


glish,Simon C. Dik, 1992

[7]Programming in Prolog, William F. Clocksin,Christopher S. Mellish,1994

[8]http://www.math.md/studlib/informatica/prolog/capitol2.pdf

[9]Simply Logical: Intelligent Reasoning by Example,Peter Flach, Univer-


sity of Bristol,United Kingdom,1994

[10]An Introduction to Natural Language Processing Through Prolog,Clive


Matthews

[11]SWI-Prolog Reference Manual 7.1, Leslie De Koninck, Thom Fruehwirth,


Markus Triska, Marcus Uneson,2014

[12]SWI Prolog Reference Manual 6.6.6,Jan Wielemaker,2014

17

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