Documente Academic
Documente Profesional
Documente Cultură
Logica este știința demonstrației, care studiază formele și legile generale ale
raționării corecte. Prin logică (cuvântul provine din greaca veche λογική, logike) se înțelege
folosirea rațiunii în realizarea anumitor activități. Logica se folosește în mod predominant în
filozofie, matematică și informatică. Pentru Aristotel, logica este știința legilor de raționare.
Prinicipala contribuție a lui Aristotel a fost logica termenilor care stă la baza analizei
propozițiilor. Ea se fundamentează pe un postulat care va dura până la începutul secolului
XX: orice raționament se analizează atribuind un predicat unui subiect. Aristotel a studiat
silogismele, deducții formate din două premise și o concluzie.
Premisa 1: Toți oamenii sunt muritori.
Premisa 2: Grecii sunt oameni.
Concluzie: Deci grecii sunt muritori.
Aplicații ale logicii în informatică:
arhitectura calculatoarelor (circuite logice);
software engineering (testare și verificare);
limbaje de programare (semantică, programare logică);
baze de date (algebre de relații);
inteligență artificială (demonstrare automată);
calculabilitate și complexitate.
1.1. Gândirea
Definiții
Gândirea (cugetarea) este însușirea creierului omenesc de a reflecta în mod
generalizat și abstract realitatea obiectivă prin teorii, judecăți, etc. (
http://dexonline.ro/definitie/gandire/). Gândirea reprezintă procesul psihic de reflectare a
însușirilor esențiale și generale ale obiectelor fenomenelor, arelațiilor dintre acestea, prin
intermediul noțiunilor, judecăților și raționamentelor. (Zlate M., Psihologia mecanismelor cognitive,
Ed. Polirom 1999, pag 235).
Psihologul american J.P.Guilford, a propus un model larg acceptat al structurii
gândirii, alcătuit din 3 elemente:
a) Operații: evaluare, gândire convergentă, gândire divergentă, memorie, cogniție;
b) Conținuturi: comportamental, semantic, simbolic și figural;
c) Produse: unități, clase, relații, sisteme, transformări și implicații. (Guilford, J. P., The
nature of human intelligence, New York: McGraw-Hill,1967).
Din punct de vedere structural gândirea poate fi definită, pe rând, ca:
a) Sistem de noțiuni, de judecăți și de raționamente (latura de conținut);
b) Sistem de operații (latura relațională);
c) Sistem de produse (latura operatorie a procesului).
Principala caracteristică a gândirii ca instrument de cunoaștere specific uman o
reprezintă stabilirea de relaţii / raporturi corecte în diferitele clase de obiecte. Prin gândire
este sintetizată esenţa lucrurilor în forma noţiunilor (concepte), a judecăţilor (propoziţii
logice) si a raţionamentelor (inferenţe). Formele gândirii constituie atât obiectul de studiu al
psihologiei, cât și al de logicii, însă din perspective de abordare diferite. Psihologia încearcă
să explice modul în care gândesc oamenii si să pună în evidenţă care sunt consecinţele unui
anumit mod de a gândi (o abordare descriptivă), iar logica ne arată care este modul corect de
a gândi, corectează gândirea prin raportare la normă (abordare prescriptivă).
Ipostaze ale gândirii
a) gândirea este cognitivă, dar este inferată din comportament, ea apare intern în minte sau în
sistemul cognitiv, insă trebuie inferată indiect;
b) gândirea este un proces care implică o manipulare sau un set de operaţii asupra
cunoștiinţelor din sistemul cognitiv;
c) gândirea este direcţională și rezultă în comportamentul care rezolvă o problemă sau este
orientat către soluţie.
(Richard E. Mayer, Thinking, Problem Solving, Cognition, W.H.Freeman & Co, New York,
1992)
Uneltele gândirii (după Zlate M)
conceptele, propoziţiile,
silogismele, modelele mintale,
scenariile, cuvintele,
imaginile, algoritmii.
euristicile,
1.2. Limbajul
Limbajul poate fi privit ca funcţie de utilizare a limbii în raporturile cu ceilalţi oameni. Limba
este un ansamblu de semne cu ajutorul cărora se poate comunica. Se distinge un vocabular, o
mulţime de cuvinte si operaţii asupra cuvintelor. (G. Albeanu, Logică computațională, Sinteze anul I,
Ed. FRM, București, 2004).
Unul sau mai multe cuvinte ale unei limbi (pentru comunicare) se constituie într-
o propoziţie. Propoziţiile comunică întrebări, ordine, dorinţe, dar și cunostinţe.
Propoziții cognitive = propoziții care comunică cunostinţe.
Propozitiile cognitive pot fi adevarate, false sau probabile! (G. Albeanu, Logică
computațională, Sinteze anul I, Ed. FRM, București, 2004)
O propoziţie cognitivă este adevărată numai dacă informaţia pe care o exprimă
corespunde stării de fapt despre care se vorbește (exemplu: Un trunghi isoscel are 2 laturi
egale). Propoziţia cognitivă este falsă dacă ceea ce ea susţine nu corespunde unei stări de
fapt (exemplu: Trapezul are laturile egale 2 câte 2). Propoziţia cognitivă este probabilă
dacă nu poate fi stabilit nici adevărul si nici falsitatea propoziţiei (exemplu: Numărul
numerelor întregi este impar).
Logica tradiţională se sprijină pe anumite condiţii formale numite principii logice sau
legi de raţionare/legi logice fundamentale, ce reprezintă condiţiile generale ele
raţionamentelor.
Principiul logic = o condiţie fundamentală de raţionalitate, un criteriu
fundamental prin care distingem între corect si incorect, un reper pentru alte condiţii
de raţionalitate.
Principiile logice au fost formulate pentru prima dată de Parmenide (cca. 515 – cca. 450
î.Hr.), deși nu într-o formă exactă.
I. PRINCIPIUL IDENTITĂŢII
Orice formă logică este ceea ce este.
Orice obiect este identic numai cu sine însusi, în același timp și sub acelasi raport.
Fiecare obiect are un set de trăsături care-l fac să fie ceea ce este în realitate.
Pentru om, de exemplu, el are însușiri care îi arată apartenența la clasa tuturor oamenilor, dar
în acelasi timp, fiecare om are și însușri particulare (o anumită înălţime, culoare a ochilor,
ocupaţie, dată și loc al nașterii etc.), toate acestea îl fac din fiecare individ un anumit om, și
nu un om în genere, adică ceea ce el este de fapt. La nivelul gândirii logice, această
particularitate elementară se exprimă sub forma principiului identităţii, conform căruia orice
formă logică este ceea ce este, altfel spus, are o individualitate aparte prin care ea este o
anumită formă logică (noţiune, propoziţie etc.).
Orice propoziție p este echivalentă cu sine p ∼ p
Importanţa principiului identităţii: Când operăm cu termeni sau cu propoziţii cărora nu le
cunoaștem suficient înţelesul sau valoarea de adevăr, principiul identităţii ne cere fie să ne
completăm în prealabil cunostinţele, fie să precizăm în ce sens/cu ce valoare folosim termenii
și propoziţiile respective.
Respectarea principiului identităţii asigură claritatea si precizia gândirii.
Necesare și suficiente
Exemplu: 1. Triunghiul ABC este isoscel. 2. Triunghiul ABC are unghiurile de la
bază congruente.
Relaţia de la temei la întemeiat se formulează astfel: „dacă și numai dacă …, atunci …”.
Propoziţia p este un temei necesar pentru propoziţia q, atunci când fără adevărul lui p nu se
poate dovedi adevărul lui q.
Propoziţia p este un temei suficient pentru propoziţia q dacă admiţând adevărul lui p devine
imposibil ca q să nu fie adevărată.
Logica nu acceptă ca argumente care se bazează pe: propoziții false, argumente de
autoritate de tipul pentru ca așa vreau, nici argumente care pot fi corecte, dar sunt incomplete
(precum cele inductive).
Apariția în cadrul limbajelor naturale (mai târziu, chiar în interiorul unor teorii
matematice) a unor propoziții ce nu respectă, principiul necontradicției, propoziții numite
antinomii (Constând dintr-o contradicție aparent insolubilă dintre două teze, legi sau
principii care, deși se exclud reciproc, pot fi demonstrate, fiecare în parte, la fel de
convingător) termen folosit cu precădere de filosofi, fie de paradoxuri orice propoziție corect
construită care este adevărată dacă și numai dacă este falsă, a impulsionat atât logica cât și
matematica spre rezolvarea cu prioritate a problemelor proprii de fundament.
Matematica până la un anumit punct, s-a format, dezvoltat și format pe baza logicii,
ulterior observându-se și o inversare de roluri: logica s-a formalizat utilizând metode
matematice. Există o corespondență perfectă între calculul propozițiilor și operațiile cu
submulțimile unei mulțimi nevide date.
De exemplu, disjuncției a două propoziții îi corespunde reuniunea a două mulțimi, și
reciproc. Din acest motiv, elementele de logică matematică se prezintă împreună cu cele de
teoria mulțimilor, suportul intuitiv al celei din urmă find de un real folos în înțelegerea și
aprofundarea a numeroase construcții logice abstracte. Putem să subliniem că au existat
logicieni (de exemplu Bertrand Russell- care au susținut teza că matematica este o ramură a
logicii). (Logică și teoria mulțimilor, Claudiu Volf & Ioan I. Vrabie
www.math.uaic.ro/~volf/depozit/LTM.pdf )
Definții. Propoziții
Logica operează cu definiții, propoziții (pe care le vom mai numi și enunțuri),
predicate (numite și funcții propoziționale), operatori logici, cuantificatori și reguli de
deducție.
Noțiunea reprezintă forma logică elementară care, în planul cunoașterii raționale,
reprezintă reflectarea claselor de obiecte.
Forma lingvistică ce materializează și comunică o noțiune are rol de nume pentru
elementele clasei refectate de noțiune.
Termenul este ansamblul format dintr-o noțiune și un nume.
Definiția este operația logică prin care se precizează conținutul sau sfera noțiunii,
înțelesul sau aria de aplicabilitate a unui nume.
O definiție are trei părți
1. definitul- (defniendum-lat)=noțiunea sau numele care formează obiectul definiției;
2. definitorul (definiens-lat) ceea ce spune despre obiectul definit;
3. relația de definire (notată :=, sau def ).
Clasificarea=operația logică prin care noțiuni mai puțin generale sunt grupate în baza
anumitor însușiri (sau note) în noțiuni mai generale.
Propoziția sau enunțul reprezintă o constatare spusă, scisă sau exprimată în orice alt
mod, care este fie adevărată (A sau 1), sau falsă (F sau 0). Propozițiile categorice exprimă un
raport între numai două noțiuni absolute.
Clasificare
-propoziții categorice afirmative=concordanță între S și P
-propoziții categorice negative=raport de opoziție între S și P
Exemple de propoziții
1. Parisul este capitala Franței.
2. Pătratul are toate laturile congruente.
3. Orice funcție continuă este derivabilă.
Clasificare enunțuri
-enunțuri atomice (simple)
-enunțuri compuse = enunțurile care se obțin folosind operatori logici
(Partea de logică a propozițiilor a fost sistematic construită de catre filozoful grec Aristotel în
urmă cu peste 2300 de ani.)
Definiții:
1. Negația (~p sau p) unei propoziții este falsă dacă și numai dacă p este
adevărată și este adevărată dacă și numai dacă p este falsă.
2. Conjuncția (& sau ˄) este adevărată dacă și numai dacă ambele propoziții
sunt adevărate. În caz contrar, ea este falsă.
3. Disjuncția / disjuncția neexclusivă (˅) este falsă dacă și numai dacă ambele
propoziții sunt false. Altfel, ea este adevărată.
5. Echivalența (≡ sau ↔ sau dacă și numai dacă p atunci q) este adevărată dacă
și numai dacă propozițiile au aceeași valoare de adevăr. În caz contrar, ea este falsă.
Exemplu: Dacă și numai dacă ninge, atunci voi putea face oameni de zăpadă.
Simbolurile (și = ) sunt folosite pentru a specifica modul de structurare a unui enunț
compus, atunci când nu sunt stabilite alte reguli.
Un enunț format numai cu propoziții (numite și constante propoziționale-notate A,
B,...) dă naștere tot la o propoziție.
Formă propozițională= enunț care conține variabile propoziționale (simboluri ce pot
fi substituite cu constante propoziționale).
Notații
p,q, r... variabile propoziționale.
P, Q, R,...enunțurile (indiferent de natura lor)
Propoziția este adevarată într-o zi de marți cu ninsoare și este falsa in orice zi dacă nu e marți
și în orice zi de marți în care nu ninge.
Fie F un enunţ în care varaiabila x este liberă (se mai foloseşte notaţia F(x) sau Fx, F
numindu-se variabilă predicativă, iar x variabilă individuală).
Limbajul logicii
Mulţimea constantelor propoziţionale, a variabilelor propoziţionale, a operatorilor logici,
a simbolurilor precum şi a regulilor de formare date prin definiţiile 1 - 5 care pornesc de la
propoziţii şi formează alte propoziţii, formează limbajul logicii propoziţionale. Limbajul logicii
predicatelor se obţine integrând lista de simboluri şi scheme propoziţionale de mai jos împreună
cu regulile de formare a expresiilor logice în limbajul logicii predicatelor.
3. Fx, Fy, ... scheme de funcţii propoziţionale. Funcţia propoziţională nu este încă propoziţie,
dar ea poate fi transformată în propoziţie, fie prin substituirea variabilei cu o constantă, fie prin
cuantificare.
4. F(x,y), G(x,y,z), H(x,y,z,t), ... predicate binare, ternare, şi în general n-are;
4. Dacă E(x) este o expresie logică cu x variabilă liberă atunci xE(x) şi xE(x) sunt expresii
logice.
5. Dacă E1 şi E2 sunt expresii cu proprietatea că în ele una şi aceeaşi variabilă nu apare într-una
liberă şi în cealălaltă cuantificată, atunci E1 E2, E1 E2, E1E2 şi E1E2 sunt expresii logice.
Exemple: Sunt expresii logice construcţii precum: p, q, r, ..., p, q, r, ..., Fx, G(x,y), Fx,
G(x,y), pFx, p(Fx), ..., p(Fx), ..., FxHy, ... xFxy(Hy), xyG(x,y) , ...
Valori de adevăr
Valoarea de adevăr a unei informaţii reprezintă gradul de concordanţă dintre informaţia
respectivă şi contextul în care aceasta este enunţată. Enunţurile bivalente sunt acele enunțuri
care pot avea ca valoare de adevăr: fals - simbolizat prin 0 - sau adevărat - simbolizat prin 1.
Orice propoziţie este în mod obligatoriu fie adevărată, fie falsă. Nici o propoziţie nu poate fi
simultan şi adevărată şi falsă.
Referitor la predicate, putem întâlni situaţia în care un predicat este ambivalent. Mai
precis, un predicat n-ar F(x1, x2 , ..., xn) este adevărat, respectiv fals, dacă toate propoziţiile
obţinute din acest predicat, prin precizarea variabilelor sale în toate modurile posibile sunt
adevărate, respectiv false. Deci stabilirea valorii de adevăr a unui predicat se reduce la stabilirea
valorii de adevăr pentru toate propoziţiile care generează predicatul.
Regula 1: Propoziţia p este adevărată dacă şi numai dacă propoziţia p este falsă; rezultă
că propoziţia p este falsă dacă şi numai dacă propoziţia p este adevărată.
Regula 2: Propoziţia pq este adevărată dacă şi numai dacă ambele propoziţii p şi q sunt
adevărate; rezultă că propoziţia pq este falsă dacă cel puţin una dintre propoziţiile p şi q este
falsă.
Regula 3: Propoziţia pq este adevărată dacă şi numai dacă cel puţin una dintre
propoziţiile p şi q este adevărată; rezultă că propoziţia pq este falsă dacă şi numai dacă ambele
propoziţii p şi q sunt false.
Legile logice sau tautologii sunt propoziţii compuse care sunt adevărate independent de valorile
de adevăr ale enunţurilor component. Contradicţiile sunt propoziţiile care sunt false independent
de valorile de adevăr ale componentelor. Propoziţiile care pot fi adevărate sau false în funcţie de
valorile particulare ale enunţurilor componente se numesc propoziţii realizabile.
Problema deciziei
Problema fundamentală a logicii matematizate este problema deciziei: Fiind dată o expresie
logică să se decidă dacă ea reprezintă o lege logică (tautologie), o contradicţie sau o funcţie
simplu realizabilă.
Această problemă poate fi soluţionată prin mai multe mijloace dintre care amintim:
a) prin eliminarea treptată a necunoscutelor; b) prin algoritmi; c) pe baza metodei axiomatice.
Metoda tablourilor de adevăr este utilă dar devine ineficientă dacă numărul componentelor este
mare. Pentru o propoziţie compusă care porneşte de la n enunţuri atomice sunt necesare 2n
rânduri în tabloul de adevăr, iar numărul de coloane depinde de structura propoziţiei. Pentru a
avea cât mai puţine coloane este necesară transformarea propoziţiei într-una echivalentă, dar cu
număr minim de conjuncţii.
O altă metodă elementară se bazează pe utilizarea regulilor de mai sus şi scrierea propoziţiei
supuse deciziei sub formă normală. Formele normale şi reguli utile pentru minimizarea
expresiilor logice vor fi date în lecţia 3. Metoda axiomatică, va fi prezentată într-una din lecţiile
viitoare.
Primul grup de legi logice exprimă proprietăţile funcţiilor de adevăr denumite comutativitate,
asociativitate, distributivitate, idempotenţă, reflexivitate şi tranzitivitate. Notaţia E1 = E2
înseamna că formulele E1 şi E2 sunt logic echivalente, adică formula E1 E2 este identic
adevărată (tautologie). Următoarele grupuri prezintă tautologiile clasice.
( 1) p q = q p;
( 2) p q = q p;
Conjuncţia şi disjuncţia sunt asociative:
( 3) p (q r) = (p q) r;
( 4) p (q r) = (p q) r;
( 5) p (q r) = (p q) (p r);
Întrucât sunt 3 variabile propoziționale, în tabel trebuie să avem8 linii, corespunzătoare celor
combinații ale valorilor de adevăr ale lui p, q, r.
( 6) p (q r) = (p q) (p r);
( 7) p p = p;
( 8) p p = p;
( 9) p p;
(10) p p;
Definiție: O disjunție este exclusivă dacă și numai dacă propozițiile nu au aceeași valoare de
adevăr, în caz contrar ea este falsă.
Exemplu:
(13) (p q) = (p) q;
(18) p = p / p;
(19) p q = (p / q) / (p / q);
(22) p q = ( (p / p) / (q / q) ) / ( (p / p) / (q / q));
(23) p q = (p / p ) / (q / q);
(24) p q = p / (q / q);
Legile absorbţiei:
(25) p (p q) = p;
(26) p (p q) = p;
Legile dublei negaţii:
(27) ((p)) p;
(28) ((p)) = p;
(35) (p q) p;
(36) (p q) q;
(37) p (p q);
(38) q (p q);
Legea “modus ponens”: “Dacă este adevărat p q şi este adevărat p, atunci este adevărat q.”
(39) ((p q) p) q;
Legile excluderii:
(43) (p q) (p (q)) = p;
(44) (p q) (p (q)) = p;
Legea contrapoziţiei:
(45) (p q) ((q) (p));
Legea silogismului:
(46) (p q) ((q r) (p r)).
( 1) xF(x) = (x(F(x)));
( 3) xF(x) = (x(F(x)));
( 5) xyG(x,y) = yxG(x,y);
( 6) xyG(x,y) = yxG(x,y);
Într-o formulă cuantificatorii ocupă diverse locuri. Pentru cuantificatori de acelaşi tip
(omogeni) ordinea este indiferentă, nu acelaşi lucru se întâmplă pentru cuantificatori de tipuri
diferite după cum rezultă din:
( 7) xyG(x,y) yxG(x,y);
În membrul stâng x este pentru toţi y, iar în membrul drept x depinde de y. Rezultă că
trecerea inversă nu este posibilă.
Problema deciziei în logica predicatelor este mult mai complicată decât în calculul propoziţiilor.
Exercițiu:
p q q p q pq (p q) p q
1 1 0 1 1 1
1 0 1 1 0 0
0 1 0 0 0 1
0 0 1 1 0 0
Exemplu:
La curs, profesorul Moisil folosea frecvent exemplul: „Care este negarea propoziției „Plouă, deci
îmi iau umbrela?” ”.
Propunere temă: Demonstraţi folosind metoda tabelului valorilor de adevăr legile calculului
propoziţional (1) – (46), enunţate mai sus.
Elemente de calcul al predicatelor
Să considerăm enunţurile:
„ x+ 5 < 12";
Se vede că dacă înlocuim x cu 8, obţinem propoziţia falsă „8 + 5 < 12".
Dacă facem x =3, obţinem propoziţia adevărată „3 + 5 < 12" etc.
“x divide y".
Pentru x = 2 şi y= 6 obţinem propoziţia adevărată „2 divide 6".
Pentru x= 4 şi y= 6 obţinem propoziţia falsă „4 divide 6" etc.
Exemplu.
Predicatul p(x): " x < 8, x ∈ R " are domeniul de referinţă mulţimea
numerelor reale iar partea predicativă constă din textul " …este mai mic
decât … " Predicatul are două subiecte: "x" şi "8", dintre care unul
nedeterminat, prin urmare, este un predicat cu o variabilă.
Exerciţiu.
Fie p(x) predicatul " x < 8, x ∈R ". Care sunt valorile de adevăr ale
propoziţiilor p(2) şi p(14) ?
Exemplu.
Fie p(x, y) predicatul " x+y=5 ". Care sunt valorile de adevăr ale
propoziţiilor p(2,0) şi p(5,0) ?
Soluție:
Propoziţia p(2,0) obţinută atribuind lui x, y valorile x = 2, y = 0 este o
propoziţie falsă, în timp ce propoziţia p(5,0) obţinută atribuind lui x, y
valorile x = 1, y = 0 este o propoziţie adevărată.
Exemplu:
Să considerăm predicatul p(x): " (∃x∈N) astfel încât x+1=2 " a cărui
valoare de adevăr este adevărul. Negaţia ei este propoziţia p(x): " (∀x∈N) ,
avem x+1≠2" evident o propoziţie falsă.
1. Cuantificatorul universal ∀
Scrierea Γ P(x) poate fi interpretată ca o conjuncție extinsă a
tuturor propozițiilor P(x) după x
x P x P(x).
Într-adevăr, dacă Γ atunci ∀ x , P(x) are aceeași
valoare de adevăr cu P(1) P(2) ..... P(n).
2. Cuantificatorul existențial ∃:
(∃ x )P(x) poate fi interpretată ca o conjuncție extinsă a tuturor
propozițiilor P(x) după x
x P x P(x).
Într-adevăr, dacă Γ atunci ∃ x , P(x) are aceeași
valoare de adevăr cu P(1) P(2) ..... P(n).
- propoziție falsă
(dacă x=0 2*0-1=-1<0);
- propoziție adevărată
(dacă x=5 2*5-1=9>0).
Afirmația xP(x) este adevărată când P(x) este adevărat pentru orice x
și este falsă când există un x pentru care P(x) este fals, iar afirmația xP(x)
este adevărată când există un x pentru care P(x) este adevărat și este falsă
când P(x) este fals pentru orice x.
În schimb,
∀x P(x,y) ∃y Q(x,y ) nu este predicat deoarece variabila y apare liberă în
primul predicat și legată în al doilea predicat.
Exemplu:
Obs: când domeniul lui P(x) constă din n elemente, regulile de negare
ale afirmațiilor sunt identice cu legile lui De Morgan din logica propozițiilor.
Acesta este motivul pentru care aceste reguli se numesc legile lui De
Morgan pentru cuantificatori.
Exemple:
Soluție:
a) Notăm “x le place ciocolata” cu C(x). Afirmația se scrie xC(x) iar
domeniul este reprezentat de toți copiii. Negația afirmației este
xC(x) care este echivalentă cu x C(x) care se exprimă astefl: ”
Există un copil căruia nu îi place ciocolata”;
b) Notăm “x este cinstit” cu D(x). Afirmația se exprimă xD(x) , iar
domeniul este reprezentat de toți politicienii. Negația afirmației este
xD(x) care este echivalentă cu x D(x), ce se exprimă “Orice
politician este necinstit”;
c) “Pentru orice număr natural avem f(x) ≤ 2”.
Soluție:
Propoziția universală este: x p(x): “oricare ar fi ”
– propoziția este falsă deoarece pentru x = 0 obținem propoziția “p(0): 6=0”
care este falsă.
Propoziția existențială x p(x): “există R astfel încât ”
– propoziția este adevărată deoarece pentru x1 = -2 și x2= -3 obținem
propoziția “p(-2): 0=0” care este adevărată și “p(-3): 0=0” care este
deasemenea adevărată, așadar există cel puțin un x pentru care propoziția
este adevărată .
Soluție:
Din negarea pentru expresii cuantificate avem
x (P(x)→Q(x)) ≡ x (P(x)→Q(x))
(P(x)→Q(x)) ≡ ( P(x) Q(x)) dar din legile lui De Morgan
( P(x) Q(x)) ≡ (P(x) Q(x)) pentru orice x
Datorită faptului că putem subsitui o expresie logică cu una echivalentă
x (P(x)→Q(x)) ≡ x(P(x) Q(x))
1. Preliminarii
- complet sintactic;
- complet semantic;
- independent;
- deductiv.
2. Sistemul axiomatic Hilbert-Ackerman [1950]
Lista de simboluri:
Variabile propoziţionale: p, q, p1 , p2, …
şi paranteze pentru a indica ordinea de efectuare a operaţiilor.
Operatorii (de bază) : (or) , (not).
Se acceptă că este mai prioritar decât .
Operatori introduşi prin definiţie: , ,
Reguli de formare:
1. Variabilele propoziţionale sunt formule;
2. Dacă A este formulă atunci A este de asemenea o formulă;
3. Dacă A şi B sunt formule atunci AB, AB, AB, AB, A B, A B sunt de
asemenea formule.
Definiţii:
D1: p q = p q;
D2: p q = ( p q)
D3: p q = ( ( pq) ( qp) )
D4: p / q = p q
D5: p q = (pq).
Axiome:
A1: (p p) p;
A2: p (p q);
A3: (p q) (q p);
A4: ( p q) ((r p) (r q))
Reguli de deducţie:
1. Regula detaşării (modus ponens): Dacă este demonstrat A şi dacă este demonstrat
A B, atunci este demonstrat B. Scriere prescurtată: {A, AB ├ B}.
Exemplu:
Dacă este duminică, mergem la plimbare.
Este duminică, deci mergem la plimbare.
Teoreme: Teorema este orice propoziţie (resp. formulă) dedusă din axiome pe baza
regulilor de deducţie. Se poate introduce noţiunea de formulă demonstrabilă sau teoremă că
fiind o formulă pentru care există o demonstraţie formală, adică un şir de formule compus din
substituţii în axiome sau formule demonstrabile şi formule obţinute prin reguli de deducţie din
termeni anteriori ai şirului. Dacă este formulă demonstrabilă numai din axiome scriem├ .
Observăm că teoremele sunt formule demonstrabile din axiome. Dacă în afară de axiome, în
deducerea formulei , se adaugă şi alte formule dintr-o mulţime H (pe care le vom numi
ipoteze) atunci spunem că este deductibilă din familia de ipoteze H şi scriem H ├ .
Teorema 1: |- (p q) (( r p) (r q))
Justificare: Demonstraţia formală are următorii termeni (cei din coloana a doua):
A4: ( p q) ((r p) (r q))
S(r, r) : ( p q) (( r p) ( r q))
D1: ( p q) (( r p) ( r q)).
Teorema 3: ├ (p p)
Justificare: Rezultă din teorema 2 şi Regula comutativităţii disjuncţiei.
Teorema 4: ├ p ( p).
Justificare: Conform teoremei 3, formula (p p) este demonstrabilă. Aplicăm
s(p, p), adică ├ p p, iar prin D1 obţinem ├ p p.
Teorema 5: ├ ( p) p.
Justificare: Avem succesiv: ├ p ( p) (teorema 4); aplicăm s(p, p) şi rezultă ├ p p.
Aplicăm regula extinderii disjunctive a termenmilor implicaţiei. Rezultă: p p p p. Dar
├ p p (teorema 3), aplicăm regula modus ponens şi obţinem: ├ p p. Prin regula
comutativităţii disjuncţiei obţinem:
├ p p, iar din definiţia D1 rezultă: ├ p p.
Regula substituirii expresiilor echivalente. Dacă două formule se deduc una din alta
atunci pot fi puse una în locul alteia.
Teorema de consistență:
Propoziția 4.1:
a) Pentru ∀m > 0, A1, A2, ….Am ├ Ai, i=1,...m
b) Pentru ∀ N dacă
A1, A2, ...., Am ├ Bi, i=1,...m
iar B1, B2, ....Bp ├ C
atunci A1 , A2, ...., Am ├ C
Teorema deducției:
a) Dacă A ├ B, atunci ├ A →B;
b) Dacă A1, A2, ….Am-1 , Am ├ B, atunci A1, A2, ….Am-1 ├ Am →B.
Propoziția 4.5: Fie E o formulă cu atomii P1 , P2 , ...., Pn . Considerăm tabelul de adevăr pentru E.
Atunci pentru fiecare din cele 2 n rânduri ale tabelului există o deducție.
Propoziția 4.6: Dacă formula E din propoziția 4.5 este tautologie, atunci P1 ˅ P1,..., Pn˅ Pn ├ E.
Scheme de ordinul I:
- rezulta prin aplicarea variabilelor predicative asupra unor variabile individuale;
- aplicarea cuantificatorilor asupra variabilelor individuale conduce la scheme de
ordinul întâi.
FORMA CAUZALĂ
Exemplul 5.2:
Formula “Orice om are o mamă”
[xOm(x) yMama(x,y)]
poate fi prelucrată
[xOm(x) Mama(x,G(x)]
unde
G(x) furnizează Mama (x)
Exemplul 5.3:
Fx (G(y,x) Py Qy) se transformă în
(Fx G(y,x) (Fx (Py Qy))
predicates
persoana(string)
mama(string, string)
clauses
persoana(“Adam”).
persoana(“Eva”).
persoana(X) :- mama(X, Y), persoana(Y).
- Reguli depre obiecte și relațiile dintre ele (o regulă exprimă un fapt care
depinde de alte fapte);
O regulă, în limbaj natural, este o frază de forma: Dacă ipoteza1 și . . . și
ipoteza n atunci concluzie ↔ concluzie dacă ipoteza1 și . . . și ipoteza n. Regula
corespunzătoare în PROLOG este expresia: concluzie :- ipoteza1; : : : ;
ipoteza n, unde ipoteza1, . . . , ipoteza n, concluzie sunt atomi.
- Scopuri = întrebări = răspunsul la o întrebare (poate fi afirmativ, yes, sau
negativ, no).
Exemplul 5.6: Tom este părintele lui Bob se scrie: parent(tom,bob) unde parent este
numele relației, iar tom și bob sunt argumentele relației.
Arborele familiei este:
pam tom
bob liz
ann pat
jim
parent(pam,bob)
parent(tom,liz)
parent(tom,bob)
parent(bob,ann)
parent(bob,pat)
parent(pat,jim) – acest program are 6 clauze. Fiecare clauză arată un lucru despre
relația de părinte. De exemplu: parent(tom,bob) este un exemplu/ caz particular
pentru relația de părinte. Un astfel de caz se numește relație. În general, o relație este
definită de toate cazurile sale.
Se pot pune mai multe întrebări depre relația părinte.
- De exemplu: Bob este părintele lui Pat? scriem: ?-parent(bob,pat). După
găsirea acestui fapt în program, Prolog va răspunde: YES.
- Întrebarea : este Liz părintele lui Pat? se scrie ?-parent(liz,pat). Răspunsul pe
care Prolog îl va afișa este NO, deoarece în program nu se precizează nimic
despre faptul că Liz ar fi părintele lui Pat.
- Pentru întrebarea: este Tom părintele lui Sam?, care se scrie sub forma: ?-
parent(tom,sam) Prolog va răspunde NO deoarece Sam nu apare nicăieri.
- La întrebarea: cine este părintele lui Liz, care se scrie sub forma: ?-
parent(X,liz), Prolog va răspunde X=tom deoarece aceasta este valoarea
pentru care propoziția este adevărată.
- La întrebarea: cine sunt copiii lui Bob, care se scrie sub forma: ?-
parent(bob,X), Prolog va răspunde X=ann. Putem cere o altă soluție (scriind o
semicoloană) și Prolog va răspunde și cu X=pat. Dacă mai cerem soluții,
Prolog va răspunde NO deoarece toate soluțiile au fost afișate deja.
- Pentru a scrie întrebarea: “Cine este părintele cui?” mai întâi reformulăm:
găsește X,Y astfel încât X este părintele lui Y și acum putem să scriem
întrebarea: ?-parent(X,Y). Prolog găseste și afișează toate perechile părinte-
copil una după alta dacă îi cerem să afișeze mai mult de o soluție.
Răspunsurile vor fi:
- X=pam
Y= bob;
- X=tom
Y=bob;
- X=tom
Y=liz;
Prin apăsarea tastei ENTER oprim șirul soluțiilor.
Reguli recursive
Programarea în Prolog depinde mult de recursivitate. Prolog-ul ne învață să
gândim recursiv. Recursivitatea implică definirea unui predicat în funcţie de el însuşi.
Mecanismul recursivității constă în faptul că întotdeauna definim predicatul la o scală
mai mică. Recursivitatea în Prolog este echivalentă cu demonstrarea prin inducţie din
matematică.
O definiție recursivă are două părți: condiția elementară și partea recursivă.
Condiţia elementară defineşte un caz simplu, care ştim că este întotdeauna adevărat.
Partea recursivă simplifică problema eliminând iniţial un anumit grad de complexitate şi
apoi apelându-se ea însăşi. La fiecare nivel, condiţia elementară este verificată:
▫ dacă s-a ajuns la ea, recursivitatea se încheie;
▫ altfel, recursivitatea continuă.
1
Definițiile unor operații sau funcții pot fi analitice sau recursive.
1, dacă n 0
n! .
n(n 1)!, dacă n 0
2
Considerăm următorul arbore clauzal construit pentru interogarea „?- factorial
(3,X).” . Un arbore clauzal nu conține orice variabilă liberă, dar în schimb are valori ale
variabilelor. Fiecare ramificare de sub un nod este determinată de o clauză din programul
original, folosind valori relevante ale variabilelor; nodul este determinat de unele valori
ale capului clauzei iar corpul clauzei determină „copiii” nodurilor în arborele clauzal.
factorial(3,6)
adevărat
Toate frunzele aritmetice sunt adevărate prin evaluare iar instrucțiunea cea mai joasă
corespunde primei clauze din program.
2. PREDECESOR
Introducem relația predecesor cu ajutorul relației părinte. Definim mai întâi
predecesorii direcți iar apoi pe cei indirecți. X este un predecesor indirect al lui Z dacă
există o legătură parentală între X și Z
parent
X
parent
Z parent
Tom este predecesor direct al lui Liz și predecesor indirect al lui Pat.
Putem scrie prima regulă (predecesor direct) sub forma: For all X and Z
X is a predecessor of Z if
X is a parent of Z.
În limbajul Prolog această regulă se va scrie sub forma: predecessor (X,Z):-
parent(X,Z).
predecessor (X,Z):-
parent(X,Z).
predecessor (X,Z):-
parent(X,Y),
parent(Y,Z).
sau
predecessor (X,Z):-
parent(X,Y),
parent(Y,W),
parent(W,Z).
Exprimată astfel, relația de predecesor este definită doar pentru o anumită adâncime în
arborele familiei. Pentru a face această relație să fie valabilă pentru orice
adâncime/lungime în arborele familiei, o scriem sub forma:
for all X and Z
X is a predecesor of Z if
there is a Y such that
1. X is a parent of Y and
2. Y is a predecesor of Z.
4
În limbaj Prolog:
predecessor (X,Z):-
parent(X,Y),
predecessor(Y,Z).
Interogare: Care sunt succesorii lui Pam?. Interogarea se poate reformula: pentru cine
este Pam predecesor?
În Prolog:
?-predecessor(pam,X).
X=bob;
X=ann;
X=pat;
X=jim;
false.
5
predecessor(X,Z):- % Rule pr2: X is a predecessor of Z if
parent(X,Y),
predecessor(Y,Z).
Relația predecesor se definește prin două clauze. Un set de clauze despre aceeași
relație se numește procedură.
Comentariile sunt marcate prin % și sunt ignorate de Prolog în general. Ele sunt
utile celui care citește programul.
6
predecessor(X’,Z’):-
parent(X’,Z’).
Capul (head-ul) trebuie să se potrivească goal-ului predecessor(bob,pat).
Așadar: X’=bob, Z’=pat
Goal-ul devine: parent(bob,pat). Acest goal este satisfăcut imediat deoarece apare
ca un fapt în program.
Predecessor(tom,pat)
Parent(tom,pat) Parent(tom,Y)
Predecessor (Y,pat)
No Y=bob prin faptul parent(tom,bob)
Predecessor(bob,pat)
Regula pr1
Parent(bob,pat)
Yes
Mecanismul Backtracking.
Procesul de căutare porneşte de la începutul bazei de cunoștinte (fapte și clauze)
pentru a se putea răspunde la întrebarea formulată. Într-o listă de predicate, verificarea
predicatului curent pornește de la începutul listei. Dacă nu sunt soluții posibile se revine
la predicatul anterior. Procesul de căutare a soluțiilor bazat pe revenire în vederea
explorării tuturor alternativelor se numeste backtracking.
Fie urmatoarea bază de cunoştinţe:
frumoasa(ana). %1
bun(vlad). %2
cunoaste(vlad, maria). %3
cunoaste(vlad, ana). %4
iubeste(mihai, maria). %5
7
iubeste(X, Y):- bun(X), cunoaste(X, Y), frumoasa(Y). %6
Pentru a prezenta mecanismul de backtracking în Prolog, vom folosi baza de fapte
dată ca exemplu mai sus. Vom urmari în continuare pașii realizați pentru satisfacerea
scopului:
?- iubeste(X, Y).
Căutarea pornește de la începutul bazei de cunoștințe. Prima potrivire va fi la linia 5, cu
faptul: iubeste(mihai, maria). %5
În urma unificării, variabilele X și Y se vor instanția la constantele mihai și maria
și se va realiza un marcaj la linia respectivă. Pentru a încerca resatisfacerea scopului,
căutarea va începe acum după marcajul făcut anterior. Următoarea potrivire va fi la linia
6, cu regula:
iubeste(X, Y):- bun(X), cunoaste(X, Y), frumoasa(Y). %6
La unificarea scopului cu antetul unei reguli, pentru a putea satisface acest scop trebuie
satisfăcută regula. Aceasta revine la a satisface toate faptele din corpul regulii, deci
conjuncţia de scopuri. Scopurile din corpul regulii devin subscopuri a căror satisfacere se
va încerca printr-un mecanism identic cu cel al satisfacerii scopului iniţial.
În continuare se va încerca satisfacerea scopului bun(X).
Fiind vorba de un nou scop, căutarea va avea loc de la începutul bazei de cunoștințe.
Acest scop va unifica cu predicatul de la linia 2: bun(vlad). %2
În urma unificării, varibila X se va instanția la valoarea vlad.
În continuare se va încerca satisfacerea scopului cunoaste(vlad, Y). care va unifica cu
faptul de la linia 3 și va duce la legarea variabilei Y la maria:
cunoaste(vlad, maria). %3
Ultimul scop care mai trebuie satisfăcut este frumoasa(maria), dar acesta eșueaza
deoarece nu unifică cu niciunul dintre faptele sau regulile din baza de cunoștințe.
Aici intervine mecanismul de backtracking. Se va reveni la scopul satisfăcut anterior,
cunoaste(vlad, Y). și se va încerca resatisfacerea acestuia. Dacă aceasta ar eșua, ne-am
întoarce la scopul dinaintea sa ș.a.m.d. Acest lucru se va repeta pană când se epuizează
toate scopurile din corpul regulii, caz în care unificarea scopului inițial cu antetul regulii
ar eșua, iar raspunsul ar fi false.
În cazul nostru, însă, este necesar un singur pas de întoarcere deoarece
cunoaste(vlad, Y). poate fi resatisfăcut prin unificarea cu faptul de la linia 4:
cunoaste(vlad, ana). %4
În urma unificării, variabila Y va fi legată la ana, iar următorul scop ce va trebui
satisfăcut este frumoasa(ana). Acesta va reuși deoarece unifică cu faptul de la linia 1:
frumoasa(ana). %1
Astfel am obtinut o noua soluție pentru scopul iubeste(X, Y)., având X = vlad și Y = ana.
Procesul nu se oprește însă pana când nu s-au încercat toate unificările posibile pentru
satisfacerea scopului. Tot prin intermediul mecanismului de backtracking, se va reveni la
scopurile anterioare și se va observa dacă acestea pot fi resatisfăcute. În exemplul nostru
acest lucru nu este posibil, deci răspunsul va fi false.
Prin urmare, rezultatul final va fi:
?- iubeste(X, Y).
X = mihai, Y = maria;
X = vlad, Y = ana;
false.
8
Semnificații ale programului Prolog
1. Semnificația declarativă - se referă la relațiile definite în program;
- determină ce va fi output-ul programului
2. Semnificația procedurală - determină cum se obține output-ul
cum sunt relațiile evaluate de Prolog.
IDEI PRINCIPALE:
1. Programarea în Prolog constă în definirea relațiilor și interogarea asupra
acestora;
2. Un program Progog constă în clauze. Acestea sunt de trei tipuri: fapte, reguli,
întrebări;
3. O relație poate fi descrisă declarând n-apelurile ale obiectelor care satisfac
relația sau prin declararea regulilor regulilor despre relații;
4. O procedură este un set de clauze despre aceeași relație;
5. Interogarea asupra relațiilor prin intermediul întrebărilor se aseamănă
interogării asupra unei baze de date. Răspunsul Prolog-ului constă ăntr-un set de
obicte care satisfac întrebarea;
6. În Prolog, stabilirea faptului dacă un obiect satisface o cerință, este un
proces ce implică inferențe logice, explorarea alternativelor sau procedura de
back-tracking. Acestea sunt executate de sistemul Prolog și de obicei sunt ascunse
pentru utilizator;
9
7. Se disting două tipuri de sensuri (semnificații) ale programelor Prolog:
declarativ și procedural. Viziunea declarativă este avantajoasă din punct de vedere
al programării, totuși detaliile procedurale trebuie deseori să fie luate în
considerare de către programator.
10
TIPURI DE DATE ȘI MECANISME PROLOG
OBIECTE DE DATE
CONSTANTE VARIABILE
ATOMI NUMERE
I. Atomi și numere
Simbolurile propoziționale A, A1, A2, ...B, B1, B2, ...sunt propoziții numite propoziții
atomice sau atomi.
- Litere mari: A, B, ....
- Litere mici: a, b, ...
- Cifre: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
- Caractere speciale: +, -, *, / (÷), <, >, =, :, ., &, _ , ~ .
======>
::=
3. Șiruri de caractere între ghilimele simple (se folosesc pentru atomi ce încep cu literă
mare):
‘Andreea’
‘South_America’
‘Tudor_Ștefan’
II. Numerele folosite în Prolog sunt întregi sau reale.
Prolog nu este un program numeric computațional, este un limbaj simbolic. În
calculul simbolic, numerele întregi sunt deseori folosite, de exemplu, pentru a număra itemii
unei liste, iar numerele reale nu se folosesc adeseori.
Majoritatea implementărilor admit o gamă de valori cuprinse între – 214 și +214+1.
Când o variabilă apare doar într-o clauză, nu trebuie să dăm un nume pentru ea.
Putem folosi așa-numita variabilă anonimă care se scrie cu un singur caracter underscore.
Utilizarea unei variabile anonime semnifică faptul că nu interesează valoarea la care se va
instanția acea variabilă
De exemplu:
hasachild(X):-parent(X,Y). % orice X are copil dacă X este părinte pentru un Y.
Regula nu depinde de numele copilului deci folosim variabila anonimă.
Clauza se rescrie:
hasachild(X):-parent(X,_).
De fiecare dată când apare un caracter underscore în clauză, el va reprezenta o nouă
variabilă anonimă.
De exemplu:
somebody_has_child:- parent (_,_).
este echivalent cu:
somebody_has_child:- parent (X,Y). ,
este diferit de:
somebody_has_child:- parent (X,X).
IV. Structuri
Structurile sunt obiecte ce desemnează o colecție de obiecte corelate logic, care formează
componentele structurii. Componentele, pot fi chiar ele, la rândul lor structuri.
O structură se definește prin specificarea:
numelui structurii ( functorul structurii);
elementelor sau componentelor structurii.
Exemplu:
Scrierea datei poate fi o structură cu 3 componente: zi, lună, an
date(21, july, 2007)
functor argumente
Componentele din exemplu sunt formate din doi întregi și un atom.
Deși alcătuite din mai multe componente, sunt tratate de program ca obiecte unice.
Pentru combinarea componentelor într-un unic obiect, este folosit un functor. Acesta va fi
rădacina arborelui într-o reprezentare arborescentă.
Alegem functorii:
Point pentru puncte;
Seg pentru segmente de dreaptă;
Triangle pentru triunghiuri.
P1=point(1,1)
P2=point(2,3)
S=seg(P1,P2)=seg(point(1,1), point(2,3))
T=triangle(point(4,2),point(6,4),point(7,1))
P1=point S=seg
1 1 point point
1 1 2 3
T=triangle
4 2 6 4 7 1
V. Operatori:
1. Operatori aritmetici:
- sunt o rescriere infixată a unor structuri și de aceea valoarea expresiei definite cu ei nu este calculată;
- evaluarea expresiei se face la cerere în cazul în care se folosește operatorul predefinit infixat is , ca în
exemplul: X is 1+2 (în acestcaz se instanțiază variabila X la valoarea 3).
2. Operatori relaționali:
- cel mai important este operatorul de egalitate, care funcționează ca și când ar fi definit prin
următorul fapt: X = X.
Un exemplu:
?- X = 1+2. ?- X is 1+2.
deoarece, în primul caz, expresia 1+2 denota o structura (termen) Prolog, unde + este functorul, iar 1 și 2
sunt argumentele sale. Nimic din acest scop nu declanșează adunarea, care este declanșată de operatorul
is.
- Operatorul de inegalitate =\= se definește ca un predicat opus celui de egalitate; scopul X=\=Y
reușește dacă scopul X=Y nu este satisfăcut și eșuează dacă X=Y reușește (semnificație: valorile lui X
și Y nu sunt egale).
- Predicatul = = testează echivalența a două variabile; X==Y reușește ori de câte ori X=Y reușește, dar
reciproca este falsă. Este vorba de egalitatea literală doi termeni.
- X= = Y este adevărat dacă termenii X și Y sunt identici, adică au aceeași structură și toate
componentele corespunzătoare coincid. În particular, numele de variabile trebuie să fie aceleași.
- Relația complementară (de non-identitate) este \= =.
Exemplu:
?-f(a,X) ==f(a,Y).
No
- Operatorul =:= face numai evaluare aritmetică și nici o instanțiere; semnificația lui
X=:=Y este: valorile expresiilor aritmetice X și Y sunt egale.
?- 1+2=:=2+1. ?=1+2=2+1.
yes no
Clauses conține fapte şi reguli. Argumentele unei clauze sunt într-o ordine bine definită,
fiecare argument având un anumit tip. Tipul argumentelor, numele predicatului care descrie
un fapt sau o regulă și numărul argumentelor rezultă din declaraţiile specificate în secțiunea
predicates. Dacă mai multe predicate au același nume, dar aritate (număr de argumente)
diferită atunci predicatele sunt diferite. Identificarea va fi corectă datorită implementării
mecanismului polimorfic.
Numele unui predicat este un șir (cu maxim 250) de litere, cifre şi “_” care începe
obligatoriu cu o literă mică. Argumentele pot fi: unul, mai multe sau nici unul. Un predicat
este de forma:
nume_predicat(tip_arg1, tip_arg2, …, tip_argn)
Argumentele pot fi şi variabile. Ele apar, de obicei, în expresia logică din membrul drept.
O expresie logică utilizează conjuncţii (specificate prin virgulă (,) sau and), disjuncţii
(specificate prin punct_și_virgulă (;) sau or), operatorul not aplicat câte unui predicat (pentru
a specifica negația), predicatul fail (pentru a introduce nedeterminismul) şi predicatul cut
(tăietură, specificat prin !) care are rolul de a oprii căutarea prin mecanismul
backtracking.
Dacă goal nu apare în program, spunem că se lucrează în mod interactiv, prin
interpretarea și identificarea entităţilor din program. La executare se activează fereastra
Dialog și putem lansa interogări.
Când secțiunea goal apare într-un program Turbo Prolog, ea trebuie să fie plasată
după predicates, înainte de clauses. Ea este o clauză sau un şir de clauze conectate logic prin
and (,) sau or (;). Se va termina cu punct. La executarea se va obține o singură soluție (prima
care s-a “potrivit”). Nu se face “backtracking”.
Secțiunea constants permite declararea unor constante. Secțiunea poate apărea
oriunde în program, cu condiția ca o constantă să fi fost declarată înainte de a fi utilizată.
Funcţii aritmetice
Expresia este calculabilă dacă toate variabilele ce apar în ea (când apar) sunt legate.
Operaţiile sunt executate respectând prioritatea operanzilor. Tipul rezultatului depinde de
tipul operanzilor şi al operatorilor.
Tipul rezultatului:
Operatori relaţionali:
Alţi operatori sunt operatorii relaţionali. Ei pot compara nu doar expresii numerice ci şi
caractere (se compară codurile ASCII).
< mai mic
<= mai mic sau egal
= egal
> mai mare
>= mai mare sau egal
<> sau >< diferit
Funcţii şi predicate PROLOG
Funcţie returnează
X mod Y restul împărţirii lui X la Y:
X div Y parte întreagă a lui X împărţit la Y
abs(X) valoare absolută a lui X
cos(X) cosinus de X
sin(X) sinus de X
tan(X) tangenta de X
arctan(X) arctangentă de X
exp(X) e la puterea X
ln(X) logaritm natural din X
log(X) logaritm în baza 10 din X
sqrt(X) radical din X
random(X) obţine în X un număr aleator din intervalul [0, 1]
random(X,Y) X dat, Ygenerat aleator 0<=Y<X
round(X) X rotunjit
trunc(X) trunchiazăX
Exemple:
1. Presupunând că nu există operatorul predefinit mod, se poate scrie un predicat Prolog cu
efect similar. O definiţie posibilă a predicatului modulo(X, Y, Z), cu semnificaţia
argumentelor Z = X mod Y , presupunând X, Y > 0, este:
% modulo(X, Y, Z)
modulo(X, Y, X) :- X < Y.
modulo(X, Y, Z) :- X >= Y, X1 is X - Y, modulo(X1, Y, Z).
2. Plecând de la predicatul modulo definit anterior, se poate defini predicatul de calcul al
celui mai mare divizor comun al două numere, conform algoritmului lui Euclid,
presupunând X > 0, Y >0, astfel:
% cmmdc(X, Y, C)
cmmdc(X, 0, X).
cmmdc(X, Y, C) :- modulo(X, Y, Z), cmmdc(Y, Z, C).
La întrebarea
?- cmmdc(15, 25, C).
C=5
răspunsul sistemului este corect. În cazul în care se încearcă obţinerea unor noi soluţii (pentru
semnificaţia cmmdc acest lucru este irelevant, dar interesează din punctul de vedere al
funcţionării sistemului Prolog) se observă ca sistemul intră într-o buclă infinită datorita
imposibilităţii resatisfacerii scopului modulo(X, Y, Z) pentru Y = 0. Dacă la definiţia
predicatului modulo se adaugă faptul:
modulo(X, 0, X).
atunci predicatul modulo(X, Y, Z) va genera la fiecare resatisfacere aceeaşi soluţie, respectiv
soluția corectă, la infinit. Cititorul este sfătuit să traseze execuţia predicatului cmmdc în
ambele variante de implementare a predicatului modulo.
3. Calculul ridicării unui număr natural la o putere naturală se poate face definind
următorul predicat:
% expo(N, X, XlaN)
expo( _ , 0, 0).
expo(0, _ , 1).
expo(N, X, Exp) :- N > 0, N1 is N - 1, expo(N1, X, Z), Exp is Z * X.
5.
6. Anecdotă:
“Cerere de lăsare la vatră pe motiv de incompatibilitate legală.
Stimate Domnule Ministru,
Situația mea familială și familiară, ma determină să solicit sprijinul Domniei voastre
în vederea lăsării la vatră. Vă rog să analizați cu atentie, ce mi s-a întâmplat:
(a) Înaintea incorporării, m-am căsătorit cu o vaduvă de 44 de ani.
(b) După scurt timp fiica soției mele, deși avea doar 25 de ani, s-a căsătorit cu tatăl
meu, pe care l-a indrăgit la prima vedere cu prilejul casătoriei mele.
În urma acestei duble căsătorii, tatăl meu mi-a devenit ginere fiindcă s-a căsătorit
cu fiica mea, iar fata mea vitregă mi-a devenit soacră, ea fiind soția tatălui meu.
(c) De Crăciun, soția mea a născut un băiat. Băiatul a devenit astfel fratele soției
tatălui meu, deci cumnat cu tatăl meu. Prin urmare, băiatul meu, fiind frate cu
soacra mea, mi-a devenit unchi.
(d) Culmea face ca în ianuarie anul acesta, și soția tatălui meu a născut un băiat, care
este pe de-o parte fratele meu (fiind fiul tatălui meu) și pe de altă parte nepotul
meu (fiindcă este fiul fiicei soției mele). Am devenit astfel fratele nepotului meu,
și cum soțul unei mame devine tatăl copiilor ei, și eu am devenit tatăl soției mele
și fratele fiului meu. Cu alte cuvinte eu sunt propriul meu bunic! Având în vedere
că legea interzice ca tătal, fiul și nepotul să fie mobilizați în același timp, vă rog
respectuos, stimate Domnule Ministru, să mă lasați la vatră. Contând pe amabilul
dvs. sprijin și binevoitoarea dvs. înțelegere de tată și adult, vă rog să agreați,
stimate Domnule Ministru, salutarile mele de înaltă considerație.
Semnatura indescifrabilă"
Exemplu:
1. parent(pam,bob).
parent(tom,liz).
parent(tom,bob).
parent(eva,liz).
parent(eva,bob).
parent(bob,ann).
parent(bob,pat).
parent(pat,jim).
Controlul recursivității în Prolog cu ajutorul predicatelor CUT și FAIL
Sistemul Prolog intră automat într-un proces de backtraking dacă acest lucru este necesar
pentru satisfacerea unui scop. Acest comportament poate fi în unele situaţii deosebit de util, dar
poate deveni foarte ineficient în alte situaţii.
Predicatul cut (tăietură, specificat prin !) este un predicat standard, fără argumente,
care este întotdeauna adevărat și nu poate fi resatisfăcut. Are rolul de a oprii căutarea prin
mecanismul backtracking.
Toate selecțiile făcute între scopul antet de regulă și cut sunt înghețate la
întâlnirea predicatului cut, ceea ce implică emilinarea oricăror altor soluții
alternative pe această porțiune. Orice încercare de satisfacere a unui scop între
scopul antet și scopul curent va eșua.
Dacă clauza în care s-a introdus predicatul cut reușește, toate clauzele cu același
antet cu acesta, care urmează clauzeiîn care a apărut cut vor fi ignorate.
Cu alte cuvinte, când execută predicatul cut, calculatorul ignoră alternativele descoperite
înaintea sau după apelul acestei clauze.
Dacă predicatul cut este introdus pentru a crește eficiența programului dar fără a
modifica seminificația procedurală, atunci el se numește green cut. Dacă prin introducerea
predicatului cut se modifică semnificația procedurală a programului, atunci el se numește red
cut.
Exemplu:
Codul Prolog pentru a afișa minimul unui număr este:
min(X,Y,X):- X=<Y.
min(X,Y,Y):- X>Y.
Predicatul fail este folosit pentru a introduce nedeterminismul / pentru a determina eșecul unui
goal/scop. Fail este un predicat standard, fără argumente, care eșuează întotdeauna.
Dacă predicatul fail se introduce după predicatul cut, atunci nu se mai face backtracking.
După fail, nu se mai poate satisface nici un goal. Dacă un predicat fail este introdus într-o
conjuncție de scopuri, atunci el determină intrarea în procesul de backtracking.
Exemple:
?- var(3).
no
?- var(alex).
no
?- var(X).
yes
novar(X) - este adevărat dacă X nu este o variabilă neinstanţiată. Acest predicat este
opusul predicatului var(X) şi îl putem defini astfel:
Exemple:
novar(X) :- var(X), !, fail.
novar( _ ).
atom(X) - reuşeşte dacă X este un atom Prolog şi eşuează în caz contrar.
Exemple:
?- atom(3).
No
?- atom(alex).
yes
?- atom(X).
No
Problemele de inteligență artificială fac parte din diverse domenii. Există tehnici specifice
rezolvării problemelor de inteligență artificială. Cum se pot caracteriza aceste tehnici și cum se
poate decide dacă aceste tehnici pot fi utilizate și în rezolvarea unor probleme care nu sunt
considerate a fi probleme de inteligență artificială? Cel mai important este punerea în evidență a
rolului fundamental al cunoștintelor într-un sistem inteligent. Caracteristicile cunoștintelor impun
necesitatea găsirii unor modalități adecvate de reprezentare și prelucrare a cunoștintelor în
sistem.
Programarea în Prolog depinde mult de recursivitate. Prolog-ul ne învață să gândim
recursiv. Recursivitatea implică definirea unui predicat în funcţie de el însuşi. Mecanismul
recursivității constă în faptul că întotdeauna definim predicatul la o scală mai mică.
Recursivitatea în Prolog este echivalentă cu demonstrarea prin inducţie din matematică.
O definiție recursivă are două părți: condiția limită și partea recursivă. Condiţia limită
defineşte un caz simplu, care ştim că este adevărat întotdeauna. Partea recursivă simplifică
problema eliminând iniţial un anumit grad de complexitate şi apoi apelându-se ea însăşi. La
fiecare nivel, condiţia elementară este verificată:
dacă s-a ajuns la ea, recursivitatea se încheie;
altfel, recursivitatea continuă.
Limbajul Prolog este total diferit de celelalte limbaje de programare. El intră în
categoria limbajelor descriptive (nu procedurale, ca marea majoritate a celor cunoscute), atât
datele cât și comenzile putând fi manipulate după aceleași reguli.
Limbajul Prolog și orice alt limbaj descriptiv, nu se bazeazã pe un algoritm de rezolvare a
problemei pas cu pas, ci pe un sistem de deducții și inducții logice care, bazându-se pe niște
cunoștințe anterioare și niste reguli de inferentă logică, conduc logic la rezolvarea problemei.
Iată, pe scurt, cum decurg lucrurile în cazul programării logice:
- programatorul formează o bază de cunoștinte, care nu este altceva decât un set de
reguli și acțiuni legate de domeniul tratat;
- programatorul descrie apoi problema de rezolvat;
- limbajul este capabil sã caute informațiile necesare și să facă deducții pentru a rezolva
problema (găsirea soluției);
Sunt mai multe criterii pentru a stabilii dacă un program este bun. Criteriile general
acceptate sunt:
1. Definiția problemei trebuie să fie bine înțeleasă, soluția trebuie dată folosind termenii
cei mai relevanți;
2. Corectitudine;
3. Eficiență;
4. User-friendly;
5. Ușor de citit / înțeles;
6. Documentarea;
Trebuie să spuneţi ce face un program chiar dacă nu spuneţi cum face ceva. Chiar dacă nu
scrieţi programe pentru vînzare este un obicei extrem de util să scrieţi scurte documentaţii pentru
utilizatorii lor sau cei care vor să le modifice. Un model împămîntenit este pagina de manual
interactivă din UNIX (sau comanda „help'' din DOS, într-un fel). O descriere a programului
dumneavoastră ar trebui să conţină următoarele informaţii:
a) numele programului;
b) modul de lansare (argumente, etc);
c) o descriere a comportării;
d) pentru programe interactive indicaţii sumare de folosire;
e) informaţii despre fişierele pe care le foloseşte şi structura lor;
f) versiunea curentă;
g) autorul programului cu adresa lui (nu se recomandă dacă programul este un virus);
h) defecţiuni cunoscute;
i) documentaţii înrudite.
Cum găsim subproblemele optime? Ceea mai des întâlnită metodă este, folosind
recursivitatea. Descompunem problema în:
Cazuri limită
Cazuri generale unde soluția este construită pe baza soluțiilor mai simple (vezi Cursul 6:
calculul factorialului)
Exemplu:
maplist(List,F,Newlist) unde
List =lista originală;
F = relație binară (regula de transformare);
Newlist = lista itemilor transformați.
Problema transformării List trebuie separată în două cazuri:
a) Cazul limită: List = [ ]
If List = [ ] then Newlist = [ ] fără a lua în considerare F
b) Cazul general: List = [ X Tail]
În Prolog
G = .. [F, X, NewX],
call(G),
Folosind maplist:
square (X,Y):-
Y is X*X.
?-maplist([2,6,5],square, Squares).
Squares = [4,36,25].
Un motiv pentru care recursivitatea se aplică natural în Prolog este definirea relaţiilor,
deoarece obiectele de date au o structură recursivă.
obiectele
gol
2 subarbori
Operator /
Semantica
Functie
A + B, A - B,
adunare, scadere, inmultire, impartire
A * B, A / B
A // B împărțire cu rest (div)
Remainder (returnează restul împărțirii lui a la b, unde a este
deîmpărțitul și b împărțitorul. Această funcție este des îtâlnită sub
A rem B
denumirea „remainder operation” / „funcția rest” .
Liste
Exemple:
1. Se poate defini următoarea structură de listă:
[carte(eminescu, poezii), carte(creanga, amintiri_din_copilarie)]
2. Considerând următoarele fapte existente în baza de cunoştinţe Prolog
pred([1, 2, 3, 4]).
pred([maria, sta, in, [banca, treia]]).
se pot pune următoarele întrebări obţinând răspunsurile specificate:
?- pred([Prim | Rest]).
Prim = 1, Rest = [2, 3, 4];
Prim = maria, Rest = [sta, in, [banca, treia]];
no
?- pred([ _, _ , _ , [ _ | Rest]])
Rest = [treia].
Dacă se consideră că lista vidă nu este o listă sortată crescător atunci se poate elimina
faptul: sortcresc([ ]). din definiţia predicatului sortcresc, comportarea lui pentru liste
diferite de lista vidă
rămânând aceeaşi.
6. Adăugarea și eliminarea elementelor în / din listă (select,delete).
Select- permite atât inserarea cât și ștergerea elementelor din listă. Acest
predicat selectează elementul indicat din listă și returnează elementele rămase în lista
Rest.
O listă este o structură de date ce reprezintă o secvenţă ordonată de zero sau mai multe
elemente.
O listă poate fi definită recursiv astfel:
(1) lista vidă (zero elemente);
(2) o listă este o structură cu două componente: primul element din listă: capul listei
(head) şi corpul sau coada listei (tail: formată din următoarele elemente din listă). De obicei,
sfârşitul listei este reprezentat ca listă vidă.
Folosind liste, putem acumula o sumedenie de informaţii într-un singur obiect PROLOG.
De exemplu faptele:
luna (1, ianuarie).
luna(2, februarie).
luna(3, martie).
luna(4, aprilie).
luna(5, mai).
luna(6, iunie).
pot fi redate folosind o singură listă sub forma faptului:
luni_prima_jumatate_an([ianuarie, februarie, martie, aprilie, mai, iunie]).
Cele mai frecvente operații asupra listelor se realizează cu ajutorul următoarelor predicate:
1. Predicat ce testează apartenenţa unui element la o listă: membru/member.
Obs: Predicatul membru poate fi utilizat atât pentru testarea apartenenţei unui element la
o listă, cât şi pentru generarea, pe rând, a elementelor unei liste prin resatisfacere succesivă. În
anumite contexte de utilizare această facilitate poate fi folositoare, iar în altele ea poate genera
efecte nedorite atunci când predicatul membru este utilizat în definirea altor predicate.
5. Predicatul sublist / incluziunea listelor: returnează adevăr / true dacă o listă este
sublista unei alte liste. Acest predicat se bazează pe același principiu ca și predicatul membru.
S este sublistă a lui L dacă L se poate descompune în două liste L1 și L2 iar L2 se
poate descompune în două liste S și L3.
Exemplu:
Exemplu:
7. Predicatul sumlist este folosit pentru a calcula suma elementelor unei liste. Predicatul
este scris sub forma: sumlist(Lista,Suma).
Exemplu:
Exemplu:
Exemplu:
10. Predicatul sort - returnează într-o listă nouă, în ordine crescătoare și eliminând
valorile care se repetă, toate elementele unei liste.
Exemplu:
Sortarea listelor este o operaţie frecvent folosită în aplicaţii. Sortarea listelor înseamnă aranjarea
elementelor listei în ordine crescătoare sau descrescătoare relativ la o anumită relaţie de ordine.
Prezentăm în continuare câţiva algoritmi de sortare care fac apel la strategia “divide et impera”.
“Divide et impera” este o metodă generală de programare care constă în împărţirea repetată a
unor probleme de dimensiune mai mare în două sau mai multe subprobleme de acelaşi tip,
urmată de combinarea soluţiilor subproblemelor rezolvate în scopul obţinerii soluţiei problemei
iniţiale. Algoritmii de sortare care utilizeazăstrategia “divide et impera” presupun divizarea listei
în două subliste, sortarea recursivă a fiecărei subliste şi combinarea rezultatelor într-o singură
listă sortată. În funcţie de metodele de divizare, respectiv de combinare există două posibilităţi:
ƒ
divizare dificilă şi combinare uşoară - abordare utilizată de sortarea prin selecţie (constă
în alegerea celui mai mic element din listă, sortarea recursivă a restului listei şi adăugarea
apoi în faţă a elementului eliminat) şi de sortarea rapidă (presupune alegerea unui
element oarecare din listă, de regulă primul element, divizarea listei în două subliste
formate din elementele mai mici şi respectiv mai mari decât elementul ales. Cele două
subliste se sortează recursiv şi rezultatele se concatenează, obţinându-se astfel lista
sortată;
divizare uşoară şi combinare dificilă - abordare utilizată de sortarea prin inserţie (constă
în eliminarea unui element din listă, sortarea listei obţinute şi în final reinserarea
elementului în listă astfel încât lista să rămână sortată) şi de sortarea prin interclasare
(presupune divizarea listei în două subliste aproximativ egale: dacă lista iniţială are n
elemente, atunci una din subliste va fi formată din primele [n/2] elemente iar cealaltă din
următoarele n-[n/2] elemente. Cele două subliste se sortează şi se interclasează rezultatele
(interclasarea este operaţia de obţinere a unei liste sortate din două liste sortate)).
11. Predicatul msort - returnează într-o listă nouă, în ordine crescătoare dar fără a
elimina dublurile, toate elementele unei liste.
Exemplu:
12. Predicatul in_list - returnează true atunci când termenul este o listă reprezentată
prin [ ] sau prin functorul “.” sau false în caz contrar.
Exemplu:
13. Predicatul length – reutrnează un număr întreg care reprezintă lungimea unei liste
(numărul de elemente dintr-o listă).
Exemplu:
Exemplu:
Exemplu:
16. Predicatul merge – returnează într-o listă nouă (Lista 3) elementele din Lista 1 și
Lista 2 sortate crescător, fără a elimina elementele care se repetă, cu condiția ca elementele
Listei 1 și elementele Listei 2 să fie sortate crescător.
Exemplu:
17. Predicatul permutation generează toate premutările posibile ale elementelor dintr-o
listă dată. Acest predicat are două liste ca argumente, iar una din liste este permutarea celeilalte.
Exemplu:
Lista [1,2,3] are 6 permutări posibile:
[1,2,3]
[1,3,2]
[2,1,3]
[2,3,1]
[3,1,2]
[3,2,1]
Problema 1:
Rezolvare:
a) (x)(om(x)→puternic(x)).
b) (x)(inteligent(x) puternic(x)→reușește(x)).
c) (x)(puternic(x)→ reușește(x) pierde_puterea(x)).
d) (x)(om(x)inteligent(x)).
e) Om(‘Tudor’).
Concluzie:
Alex este partener cu Tudor.
% Ipoteza 1
corect(tudor).
% Ipoteza 2
not_partener(bogdan, tudor).
% Ipoteza 3
partener(X, Y):- corect(X), corect(Y), X \= Y.
% Ipoteza 4, se foloseşte şi ipoteza 3, inversată conform principiului reducerii la absurd: formula
p →q este echivalentă cu !q →!p.
corect(alex) :- not_corect(bogdan).
not_corect(X):- not_ambii_corecţi(X, Y), corect(Y).
% din ipoteza 3
not_ambii_corecţi(X, Y):- not_partener(X, Y).
% Ipoteza 5 este reprezentată în definiţia lui partener (ipoteza 3), care include simetria.
Concluzia
?- partener(alex, tudor).