Sunteți pe pagina 1din 72

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 1 1.

INTRODUCERE

Ecuaiile sunt importante n matematic i n tiin. Uneori se ncearc s se determine dac o identitate rezult logic din nite axiome date, alteori se caut soluiile unei ecuaii date. Aceste capaciti de raionamente sunt importante n multe aplicaii computerizate, incluznd calcule simbolice algebrice, demonstrarea automat a teoremelor, specificarea i verificarea programelor, limbajelor i mediilor de programare de nivel nalt. Sistemele de rescriere sunt ecuaii orientate, utilizate pentru a calcula nlocuirea repetat a subtermenilor dintr-o formul dat cu termeni egali pn cnd se obine cea mai simpl form posibil. Ideea simplificrii ecuaiilor a fost prezentat n toat evoluia algebrei. Ca interpretare n informatic, sistemele de rescriere i-au fcut apariia n anii 60; multe programe moderne pentru manipulare simbolic continu s foloseasc reguli de rescriere pentru simplificare n maniera ad hoc. Ca formalism, sistemele de rescriere au puterea unei maini Turing. Teoria sistemelor de rescriere n esen este o teorie a formelor normale; ntr-o oarecare msur este o prelungire privind studiul calculul lui lambda. Pentru a introduce cteva idei principale n teoria rescrierii considerm mai multe variante a Problemei cutiei de cafea. S

Lucrare de diplom

pagina

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 1


ne imaginm o cutie de cafea coninnd dou varieti: alb i negru, aranjat dup o anumit ordine. Repezentnd coninutul cutiei ca o secven de boabe colorate, de exemplu: alb alb negru negru alb alb negru negru regulile primului joc sunt urmtoarele: negru alb alb negru -> negru -> negru

negru negru -> alb Acest set de reguli este un exemplu de sistem de rescriere. Fiecare regul descrie o micare permis: primele dou reguli spun c n oricare moment al jocului boaba alb dintr-o pereche de boabe adiacente diferite poate fi neglijat; ultima regul spune c doua boabe negre adiacente pot fi nlocuite cu una alb. De exemplu ceea ce urmeaz este o posibil secven de micri (boabele subliniate particip la micarea curent): alb alb negru negru alb alb negru negru alb alb negru negru alb negru negru alb alb alb alb negru negru alb alb alb negru negru alb alb negru negru alb negru negru

Lucrare de diplom

pagina

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 1


negru negru alb Scopul jocului este s termini cu ct mai puine boabe posibile. Nu este greu de vzut c un numr impar de boabe negre termin jocul cu un bob negru, deci paritatea boabelor negre este invariant. Jucnd corect (pstrnd cel puin o boab neagr peste tot pna cnd se termin) un numr par de boabe negre conduc la o boab alb, dar i alte rezultate (numai cu boabe albe) sunt posibile. De exemplu, aplicnd a treia regul, ambelor perechi de boabe negre ne rmn ase boabe albe. Prin adugarea unei reguli adiionale n jocul de sus, acesta poate fi modificat astfel nct s se termine ntotdeauna cu o singur boab: negru alb alb negru -> negru -> negru

negru negru -> alb alb alb -> alb

Ceea ce este diferit la noul joc, este c una dintre reguli se aplic la orice cutie. Ceea ce este interesant este c rezultatul jocului este complet independent de alegerea momentului n care se face mutarea. Ordinea n care micrile la locaiile nesuprapuse sunt fcute, este important deoarece oricare mutare care nu a fost

Lucrare de diplom

pagina

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 1


fcut poate fi fcut ulterior. Cazurile critice apar cnd mutrile posibile se suprapun peste altele. De exemplu, din alb negru negru, poate rezulta fiecare dintre negru negru sau alb alb. nelesul este c aceste dou situaii pot amndou duce la aceeai stare alb unic. Acelai lucru este adevrat pentru alte divergene de suprapunere. Avnd n vedere aceast independen este uor s precizm rezultatul deterministic al oricrui joc alegnd o secven supus la o analiz simpl. ntradevr orice stare iniial cu un numr par de boabe negre trebuie s se termine ntr-una alb. Este evident c jocul de mai sus nu poate fi continuat mereu, deoarece numrul boabelor este redus cu fiecare mutare. Un joc potenial mai lung, dar de asemenea finit, este: negru alb alb negru -> -> alb alb alb negru negru alb alb alb alb alb

negru negru -> alb alb ->

Noile reguli au acelai rezultat final ca i cele originale, indiferent ct de des se face o micare care conduce la creterea numrului de boabe. n analiza final, cutia trebuie golit pn la o boab. n final se consider varianta n care se aplic reguli pentru orice dou boabe ( nu neaprat adiacente). Noile reguli sunt:

Lucrare de diplom

pagina

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 1


negru...alb alb...negru -> negru... -> negru...

negru...negru -> alb... alb...alb -> alb...

unde un semn de lips din dreapta se refer la aceleai boabe care apar n stnga. Din nou se poate arta c rezultatul este unic determinat de configuraia iniial i este n consecin acelai ca n jocurile anterioare. Rezultatul final constnd dintr-o secven netransformabil prin reguli se numete form normal. Cnd calculul pentru termeni egali se termin ntotdeauna ntr-o aceeai form normal, sistemul de rescriere poate fi utilizat ca un program funcional nedeterministic (Goguen&Tardo[92]). Un astfel de sistem de asemenea servete ca procedur dac doi termeni sunt egali ntr-o teorie ecuaional definit prin reguli i n particular rezolv problema cuvntului pentru aceste teorii. Knuth [149] a elaborat un test efectiv (bazat pe o suprapunere critic) pentru a determina dac un sistem are proprietate de terminare, caz n care toate calculele converg la o form canonic, indiferent de alegerea nedeterministic fcut. Knuth a demonstrat c eecul testului adesea sugereaz reguli adiionale care pot fi utilizate pentru a completa un sistem neconvergent ntr-unul convergent.

Lucrare de diplom

pagina

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 1


Metodele de rescriere s-au dovedit a fi printre cele mai eficiente abordri ale demonstrrii teoremelor ecuaionale. n acest context, completarea este utilizat pentru raionamentul nainte, n timp ce rescrierea este o form al raionamentului napoi. Completarea utilizeaz o ordonare pe termeni care furnizeaz un ghid puternic n timpul raionamentului nainte i simplificarea ecuaiilor. n urmtorul capitol, vom face o trecere n revist scurt a sintaxei i semanticii ecuaiilor din punct de vedere algebric, logic i operaional. Pentru a folosi sistemul de rescriere ca procedur de decizie, acesta trebuie s fie convergent. Pentru a folosi un sistem de rescriere pentru calcul sau ca o procedur de decizie pentru verificarea identitilor, proprietatea de a fi terminist este crucial.

Lucrare de diplom

pagina

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2 2. SISTEME DE RESCRIERE A TERMENILOR

Tipurile de date algebrice reprezint un domeniu de aplicare important pentru raionamentul ecuaional bazat pe rescriere. ntr-un mod abstract, privind specificarea datelor, datele sunt preluate ca obiecte abstracte iar semantica funciilor de operare asupra datelor sunt descrise de o mulime de constrngeri. n acest capitol se va vorbi despre sintaxa ecuaiilor i despre demonstraii ecuaionale. Deci dup cum vom vedea, orientnd ecuaiile de la snga la dreapta, se va obine un concept de demonstraie direcionat. 2.1. TERMENI S presupunem c dorim s definim operaiile standarde asupra stivelor top i pop, ca i o operaie alternat care combin cele dou stive. Stivele de numere naturale pot fi reprezentate prin termeni de forma push(s1,push(s2,...,push(sn,)...)),unde este stiva vid iar si indic reprezentarea numerelor naturale, 0, succ(0), succ(succ(0)), i aa mai departe. Sintaxa precis a acestor reprezentri poate fi dat pe urmtoarea cale inductiv: Zero = {0} Nat = Zero succ(Nat) Empty = {} Stack = Empty push(Nat, Stack)

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


Partea stng numete mulimile diferitor tipuri de termeni. O expresie ca succ(Nat) indic mulimea tuturor termenilor succ(s), cu sNat. Simbolurile 0, succ, i push, utilizate pentru construirea datelor sunt denumite constructori; orice termen construit conform acestor reguli este un termen constructor. Pentru a defini operaiile de stiv cerute, mai trebuie s definim sintaxa termenilor non-constructor: top pop : Stack -> Nat : Stack -> Stack

alternate: Stack*Stack -> Stack Dup acesta vom da semantici noilor funcii, prin constrngerea s satisfac urmtorul set de ecuaii: top(push(x,y)) = x pop(push(x,y)) = y alternate(,z ) = z alternate(push(x,y),z)= push(x,alternate(z,y)) (unde x, y i z reprezint variabile lund valori pe mulimea tuturor datelor corespondeni). Inversele constructorilor, ca top i pop se numesc "selectoare". Cu aceste ecuaii, se poate arta, de exemplu urmtoarea egalitate: alternate(push(top(push(0,)),),pop(push(succ(0),))) push(0,) n general dintr-o mulime F=n 0Fn de simboluri de funcie numite vocabular sau siganatur - i o mulime numrabil X de =

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


simboluri de variabile, mulimea termenilor (F,X) peste X i F, este cea mai mic mulime coninnd pe X astfel ca (t1,...,tn) n (F,X) atunci cnd Fn i ti(F,X) pentru i=1,...,n . Exemplul cu stiva folosete F0={0,}, F1={top,pop,succ}, F2={push,alternate} i X={x, y, z}. Fiecare simbol din F are o aritate care este indicele n al mulimii Fn cruia i aparine (Vom presupune c Fn sunt disjuncte). ntr-un termen bine format fiecare simbol de aritate n are n subtermeni imediai. Elementele de aritate zero se numesc constante, din care presupunem c exist cel puin unul. Termenii din (F0F1,X) se numesc monadici; ei sunt cuvinte ncepnd cu simboluri unare (din F1) sau constante (din F0) sau variabile (din X). Termenii care nu conin variabile se numesc de baz; mulimea (F,) a termenilor de baz va fi notat cu g(F). S notm c g(F) este nevid datorit presupunerii anterioare n legtur cu F0 (c aceasta conine cel puin un element). Vom nota adesea pentru a ne referii la mulimea de tremeni (F,X), cu F i X nespecificai i g corespunznd la mulimea de termeni de baz. n exemple ocazional se vor folosi notaii cu prefix sau postfix pentru F1 i infix pentru F2. Un termen t n (F,X) poate fi vzut ca un arbore finit ordonat, frunzele cruia sunt etichetate cu variabile (din X) sau constante (din F0) iar nodurile interne sunt etichetate cu simboluri de funcie (din F1F2...) cu aritate pozitiv. Poziia nuntrul unui termen poate fi reprezentat ca o secvent de ntregi pozitivi reprezentnd calea spre o extrem simboluri rdcin din capul

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


subtermenului. Prin t vom nelege subtermenul lui t care are p rdcina n poziia p. De exemplu, dac t=push(0,pop(push(y,z))), atunci t reprezint primul subtermen al celui de al doilea 2,1 subtermen al lui t care este push(y,z). Poziiile adesea sunt numite apariii. Vom folosi aceast ultim denumire pentru a ne referi de exemplu la subtermenul t . Scriem s t dac s este p subtermen al lui t. Spunem c p are o poziie superioar lui q ntrun termen t dac p (reprezentat printr-o secven de numere) este un prefix al lui q, deci dac apariia t este n interiorul lui q t . Un subtremen al lui t se numete propriu p distinct de t. A raiona cu ecuaii implic nlocuirea de subtermeni prin ali termeni. Termenul t cu subtermenul t nlocuit cu un termen p s se noteaz t[s]p. Ne referim la orice termen u care este acelai cu t peste tot cu excepia lui p, scriind u[s]p=t. Contextul n care nlocuirea are loc; este termenul u cu un gol (variabila ) n poziia p. O substituie este o operaie special de nlocuire, definit unic printr-o aplicaie de la variabile la termeni i scris ca {x1s1, ..., xmsm} (exist numai un numr finit de xi care nu sunt aplicate la ele nsui). Formal, o substituie este o funcie de la X la (F,X), extins la o funcie din spre sine nsi (de asemenea notat i pentru care se folosete notaia prefix) astfel nct are loc (t1,...,t2). = (t1,...,tn) pentru oricare (aritatea n) din F i pentru orice termen ti. Un termen t este asemntor cu termenul s dac s = t pentru o anumit substituie ; n acest dac el este

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


caz vom scrie s . t i de asemenea spunem c t este o instan al lui s, sau s subsum pe t. Relaia . este o cvasiordonare pe termeni numit subsumare. Compunerea a dou substituii numit juxtapunere este chiar compunerea celor dou funcii, adic dac x = s pentru o anumit variabil x atunci x = s. Spunem c substituia este cel puin la fel de general ca substituia dac exist o substituie astfel ca =. Ne vom ocupa cu relaii binare pe termeni care posed urmtoarea proprietate fundamental: Definiie O relaie binar pe mulimea termenilor este o relaie de rescriere dac ea este nchis att la proprietatea de nlocuire ct i de substituie. O relaie de rescriere se numete o relaie de rescriere ordonat dac ea este tranzitiv i reflexiv. Cu alte cuvinte este o relaie de rescriere dac s t implic u[s]p u[t]p pentru orice termeni s i t din F, orice context u, poziie p i substituie . Inversa nchiderii simetrice, reflexive i tranzitive a unei relaii de rescriere este de asemenea o relaie de rescriere. Pentru a fixa exemplele care urmeaz, literele a pn la h vor fi utilizate pentru simboluri de funcii; l,r,s pn la w vor reprezenta termeni arbitrari; x,y,z vor fi rezervate pentru variabile ; p,q pentru poziii, literle mici greceti pentru substituii. Relaiile binare vor fi notate prin sgei. Dac este o relaie

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


binar atunci este inversa sa, este nchiderea sa simetric ( ), -=> este nchiderea reflexiv , ( =), -*> este nchiderea reflexiv tranzitiv ( ... ) i -+> este nchiderea tranzitiv ( -*>).

2.2. ECUAII O relaie de echivalen ~ pe o mulime de termeni este o congruen dac (s1,...,sn) ~ (t1,...,tn) de cte ori si ~ ti pentru i=1...n. n particular nchiderea reflexiv simetric-tranzitiv notat <-*> a oricrei relaii de rescriere este o congruen. Pe noi ne intereseaz congruenele generate de instane ale ecuaiilor. Pentru scopurile noaster o ecuaie este o pereche neordonat {s,t} de termeni (Pentru alte scopuri ecuaiile pot fi privite ca perechi ordonate). Ecuaiile vor fi scrise n forma s = t. Cei doi termeni pot conine variabile care sunt considerate ca fiind cuantificate universal. Dat o mulime de ecuaii A peste o mulime de termeni , teoria ecuaional a lui E, notat h(E) este mulimea tuturor ecuaiilor care pot fi obinute considernd reflexivitatea, simetria i tranzitivitatea ca reguli de inferen iar apariiile ecuaiilor din E ca axiome. Vom scrie Es = t dac s = t h(E). Un sistem mai compact de inferen este bazat pe noiunea familiar de nlocuirea egalilor prin egali . Vom scrie s <-E> t pentru termenii s,t dac s are un subtermen care este o apariie a unui membru al unei ecuaii din E iar t este rezultatul

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


nlocuirii acestui subtermen cu apariia corespunztoare a

celuilalt membru al ecuaiei. Vom scrie formal s <-E> t dac s = u[l]p i t = u[r]p pentru un anumit context u pentru poziia p din u, pentru ecuaia l = r din E i substituia . Se tie c Es = t dac i numai dac s <-*E> t unde <-*E> este nchiderea reflexivtranzitiv a relaiei <-E> ; cu alte cuvinte se poate demonstra c doi termeni sunt egali dac unul dintre ei poate fi obinut din cellat printr-un numr finit de nlocuiri a unor subtermeni egali. Relaia <-E> este nchiderea prin rescriere a lui E cnd acesta este privit ca o relaie simetric i <-*E> este nchiderea congruenei lui <-E> adic <-*E> este cea mai mic congruen peste astfel c l <-*E> r pentru toate ecuaiile l = r din E i toate substituiile

peste . Vom scrie [s]E pentru clasa

congruenei unui termen s i vom nota prin /E mulimea tuturor claselor de congruen. O derivaie
E

din E este orice secven s0<-E>s1<-E>...<ale axiomelor ecuaionale din E.

>si<-E>...

de

aplicaii

Demonstraia n E a unei ecuaii s = t este o derivare finit s = s0<-E>s1<-E>...<-E>sn = t (n 0), fiecare pas si<-E>si+1 este justificat printr-o referin la o axiom l = r din E, o poziie p n termenul si, i o substituie astfel c si |p=l i si+1|p= si [r]p. S ne ntoarcem la exemplul nostru anterior, i s notm cu E axiomele sale. Atunci urmtoarea secvent este un exemplu de derivare: alternate (push(top(push(0,z)),z),) <-E> alternate(push(0,z),)

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


<-E>alternate(push(0,pop(push(succ(y),z))),). Primul pas poate fi justificat prin axioma top(push(x,y)) =x poziia 1,1 i substituia {x 0, y z }; al doilea pas prin axioma pop(push(x,y)) =y (utilizat de la dreapta la stnga), poziia 1,2 i substituia { x succ(y), y z }. 2.3. REGULI DE RESCRIERE

Ideea central a rescrierii este s impun o direcie de utilizare a ecuaiilor n demonstraii. Spre deosebire de ecuaiile care sunt neordonate , o regul peste o mulime de termeni este o pereche ordonat <l,r> de termeni pe care vom scrie ca l r. Regulile difer de ecuaii prin utilizarea lor. Ca i la ecuaii, regulile sunt utilizate pentru a nlocui apariii ale lui l prin apariii corespunztoare ale lui r. Spre deosebire de ecuaii, regulile nu sunt utilizate pentru a nlocui apariii ale lui r. O mulime finit de reguli R peste T este numit un sistem de rescriere sau TRS(Term Rewriting System). Un sistem R poate fi gndit ca o relaie binar nesimetric pe T; nchiderea acestei relaii descrie efectul aplicaiei de la stnga la dreapta a unei reguli din R. Definiie Un sistem de rescriere a termenilor (TRS) R este o mulime de reguli : R={ lr | l,r (F,X), fiecare variabil care apare n

termenul r apare i n termenul l }. Acesta definete o relaie de rescriere -R>. Definiie Pentru un TRS R un termen s din se rescrie ntrun termen t din i se noteaz s-R>t dac s|p = l i t = s[r]p,

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


pentru o anumit regul l r din R, o anumit poziie p din s i o anumit substituie . Acesta este acelai lucru cu a spunem c s = u[l]p i t = u[r]p, pentru un anumit context u i o anumit poziie p din u. Un subtermen s|p n care rescrierea se poate face se numete redex; spunem c s este ireductibil sau n form normal dac nu are nici un redex, adic nu exist nici un t din astfel ca s-R> t.Relaia -R> este compatibil cu structura de termeni n (F,X) i cu substituiile.Notm prin -R*>, <-R*> nchiderea reflexivtranzitiv i nchiderea reflexiv-tranzitiv-simetric a lui -R>. Sistemele de rescriere sunt utilizate pentru a calcula rescrieri repetate pn cnd eventual se atinge o form normal. O derivare din R este orice secven t0 -R> t1 -R>...-R> ti -R>... de aplicare a regulilor de rescriere din R. Vom nota t -R> t! dac t -*R> t! i t! este ireductibil, caz n care spunem c t! este forma normal al lui t. Spunem c un TRS se poate normaliza dac oricare termen are cel puin o form normal. Un TRS este de baz dac este un TRS pentru care toate regulile sunt de baz ( adic elemente din g x g ). Primul exemplu al Cutiei de cafea poate fi formulat ca sistem de rescriere care are ca i simboluri alb i negru. Un sistem left-linear (liniar la stnga) este un sitem n care nici o variabil nu apare mai mult dect o dat n orice mebru stng. Pentru scopul lucrrii de fa una dintre cele mai importante proprieti a unui TRS R este normalizarea unic adic faptul c orice termen t din posed exact o form normal. Relaia de

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


normalizare -!R> pentru sistem de normalizare unic definete o funcie, i se noteaz R(t), valoarea acestei funcii pentru un termen t din . Dac toate secvenele de rescriere conduc la o form normal unic sistemul se va numi convergent. Un sistem de rescriere este redus dac pentru orice regul l r dect l ntr-o anumit relaie de ordine notat > ce uneori canonic este folosit sinonim cu convergent. Orientnd ecuaiile din exemplul cu memoria obinem un sistem de rescriere canonic R: top(push(x,y)) pop(push(x,y)) alternate(,z) -> x -> y -> z din R membrul drept r este ireductibil n R i nici un termen s mai mic nu este reductibil. Vom numi canonic un sistem convergent redus n timp

alternate(push(x,y),z) -> push(x,alternate(z,y)) Un exemplu de derivare este: alternate(push(top(push(0,z)),z),) -R> alternate(push(0,z),) -R> push(0,alternate(,z)) -R> push(0,z). Primul pas este o aplicare a reguli top-push pentru apariia top(push(0,z)); al doilea pas este o aplicare a regulii alternatepush cu 0 pentru x, z pentru y i pentru z; al treilea pas este o aplicare a regulii alternate(,z) -> z. S notm c este posibil i o alt derivare care conduce la aceeai form normal :

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


alternate(push(top(push(0,z)),z),) -R> push(top(push(0,z)),alternate(,z)) -R> push(top(push(0,z)),z) -R> push(0,z). Din punct de vedere operaional, rescrierea este un calcul nedeterminist cu alegerea reguli i a poziiei lsat arbitrar. Pentru un sistem convergent alegerea ntre rescrieri posibile la fiecare pas nu afecteaz forma normal calculul a unui termen de intrare. Definiie O relaie binar pe o mulime T are

proprietatea de terminism dac nu exist nici o secven infinit t1-> t2 -> t3 ->... de elemente ale lui T. Proprietatea de terminism are o condiie suplimentar fa de aceea c sistemul s fie normalizat, deoarece ultima permite anumite derivaii s fie infinite. O ordine parial notat pe o mulime T este well-founded dac nu exist nici un lan infinit descresctor t1t2 de elemente ale lui T. Adic o relaie are proprietatea de terminism dac ea este nchiderea tranzitiv -+> a unei ordine well-founded. Importana relaiei cu proprietatea de terminism const n posibilitatea demonstrrii inductive n care se presupune c ipoteza este satisfcut de toate elementele t astfel c s-+> t atunci cnd ea se demonstreaz pentru un s arbitrar. Un TRS R are proprietatea de terminism pentru o mulime de termeni dac relaia -R> peste are proprietatea de terminism adic nu exist o derivare infinit t1 -R> t2 -R> t3 -R>... de termeni n . Dac un TRS are proprietatea de terminist atunci

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


orice termen are cel puin o form normal. S notm c un sistem cu proprietatea de terminism nu poate avea nici o regul ca de exemplu urmtoarea alternate(y,) -> pop(push(x,y)), cu o variabil n membrul drept care nu apare n membrul stng ( deoarece x poate de exemplu s fie nlocuit prin top(alternate(y,))) i nici nu poate avea n membrul stng o variabil cum este de exemplu z -> alternate(,z). Aceste dou restricii sunt adesea plasate apriori asupra TRS-urilor. O demonstraie prin rescriere a unei ecuaii s = t pentru un sistem din R ia forma s-*R> v <
R *

- t, n care acest termen v este

obinut att prin rescrierea lui s ct i a lui t. Vom da mai jos un exemplu utiliznd sistemul de mai sus: alternate(push(top(push(0,z)),z,) alternate(push(0,pop(push(y,z))),) -R> push(0,alternate(,pop(push(y,z)))) <R-R> push(0,alternate(,z)) <RCu un sistem care are proprietatea de terminism i are un numr finit de reguli lungimea unei demostraii prin rescriere este finit. Evident nu exist garania c exist o demonstraie direct pentru o consecin a unei ecuaii din R. n cazul n care exist o astfel de garanie sistemul este denumit Church-Rosser. 2.4. METODE DE DEMONSTRARE A TEOREMELOR CU TRS alternate(push(0,z),)

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


Mulimea ecuaiilor (E) definete o relaie de egalitate sintactic =E(=E = <-E*>) pe (F,X), de obicei definit de conceptul nlocuirea egalului cu egal. Relaia are i o definiie semantic (logic) n teoria ecuaional E notat prin E s=t. O problem fundamental este problema validitii sau problema cuvntului,care este n general nedecidabil: Fiind dat s,t (F,X), are loc s =E t ? Definiie Transpunerea problemei cuvntului ntr-un TRS este: Fiind dat o teorie ecuaional E, s se determine un TRS R astfel nct s =E t este echivalent cu s <-R*> t. Problema calculrii lui R este o procedur de completare fiindc R este construit pas cu pas, colecionnd noi reguli n R, care n acelai timp sunt aduse ntr-o form ct mai simpl posibil. Fie t! forma normal a lui t. Dac R are proprietatea c fiecare termen are o form normal unic, atunci : s <-R*> t dac i numai dac s! t! (pentru c s <-R*> t este s -R*> s! t! <*R- t). Propoziie Dac n R fiecare termen are o form normal unic, atunci s =E t dac s! t!. Definiie Un TRS R convergent are urmtoarele proprieti: a) R este terminist

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


b) R este confluent, adic : t1 -R*> t2, t1 -R*> t3 implic faptul c exist u astfel nct t2 -R*> u, t3 -R*> u (fiecare termen are cel mult o form normal t!). Teorem [Dershowitz,1987] Un TRS R este terminist dac i numai dac exist o relaie de ordine > astfel nct l > r pentru fiecare regul l r n R. Conform rezultatului obinut de Newman (1972) confluena este pentru TRS-uri terminist echivalent cu o proprietate de confluen local mai slab, care este : t1 -R> t2 i t1 -R> t2 implic faptul c exist u astfel nct t2 -R*> u, t3 -R*> u. Astfel, un TRS R terminist este confluent dac i numai dac este local confluent. Definiie Fie l1 r1 i l2 r2 dou reguli n R. Prin renumire de variabile presupunem c ele nu conin variabile comune. Dac

1 i 2 sunt dou substituii astfel nct 1(l1) = 2(l2) atunci (1(r1) ,


2(r2)) este o pereche critic pentru R. Fie CP(R) mulimea tuturor perechilor critice pentru R ca ecuaii. Lema perechilor critice [Knuth i Bendix, 1970] afirm: Pentru orice TRS R dac t1 -R> t2 i t1 -R> t3, atunci sau exist un termen u astfel nct t2 -R*> u, confluent) sau t1 =CP(R) t2 . Astfel dac pentru fiecare (1,2) CP(R) avem 1 -R*> 2 sau 2 -R*> 1 , atunci R este local confluent. Aceast idee poate fi testat prin procedura de completare. Vom da o form simpl a procedurii de completare: INPUT : o mulime E de ecuaii, o relaie de ordine >, t3 -R*> u (dac R este local

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


OUTPUT : a) un TRS RE convergent, astfel nct =E = <-RE*> b) FAILURE (insucces) c) algoritmul nu se oprete niciodat Algoritmul de completare: R= Dac fiecare ecuaie n E poate fi orientat (cu respectarea condiiei variabilelor) atunci R := {l r l > r, {l = r} E} altfel FAILURE. STOP. Se calculeaz CP(R). Pn cnd CP(R) execut (t1,t2) := un element din CP(R) Se calculeaz t1! i t2! Dac t1! t2! atunci Dac not(t1! >t2!) i not(t2! >t1!) atunci FAILURE.STOP altfel CP(R)=CP(R)\{(t1,t2)}.

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


R := R{ t1! t2!} sau R := R{ t2! t1!} altfel CP(R) := CP(R)\{(t1,t2)} STOP. Cteva observaii: a) Dac CP(R) este transformat n , atunci procedura se oprete cu succes. b) Procedura se poate opri cu FAILURE. c) Procedura poate s nu se termine niciodat dac CP(R) nu se poate transforma n . ( CP(R) se mrete i scade ntr-un singur pas). Exemplu de demonstraie de teorem 1) Fie E definit de E = {e * x = x, i(x) * x = e, x * (y * z) = (x * y) * z }, astfel E coninnd axiomele pentru un grup. Dac ordonarea este i > * > e, atunci R iniial este : r1: e * x x R r2: i(x) * x e r3: (x * y) * z x * (y * z) Din r2 i r3 obinem: r4 : i(x) * (x * y) y

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 2


fiindc: (i(x) * x) * y -r2> e * y -r1> y (i(x) * x) * y -r3> i(x) * (x * y) astfel (i(x) * (x * y), y) este o pereche critic i r4 este regula nou corespunztoare. n final, obinem urmtorul TRS convergent: R = { r1,..., r10} unde r1, r2, r3, r4 sunt cele deja descrise i r5: i(e) e r6 : x * e x r7: i(i(x)) x r8: x * i(x) e r9: x(i(x) * y) y r10: i(x * y) i(y) * i(x) Ca exemplu de demonstrare de teorem cu ajutorul lui R vom avea: i(i(x * y) * e) * i(y * y) = i(y * i(x)) i(i(x * y) * e) * i(y * y) -r10> i(e) * i(i(x * y)) * i(y * y) -r5,r7> (e * (x * y)) * i(y * y) -r1> (x * y) * i(y * y) -r10> ((x * y) * i(y)) * i(y) -r3> (x * y) * (i(y) * i(y)) Pentru membrul doi: i(y * i(x)) -r10> i(i(x)) * i(y) -r7>x * i(y) Aceast teorem este demonstrat, ambi membri avnd aceai form normal x * i(y). -r3> x * (y * (i(y) * i(y))) -r9>x * i(y)

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3 3.ELEMENTE DE LIMBAJ TURBO PROLOG

Turbo Prolog este un program care este structurat n mod riguros pe seciuni. Fiecare seciune program este identificat printr-un cuvnt cheie aa cum este artat n felul urmtor: opiune de compilare - este dat la nceputul fiecrui program seciunea constants - zero sau mai multe constante seciunea domains - zero sau mai multe declaraii de domenii seciunea database - zero sau mai multe predicate de baze de date seciunea predicates - zero sau mai multe declaraii de predicate seciunea goal - zero sau mai multe goal-uri seciunea clauses - zero sau mai multe clauze Nu este nevoie a include toate seciunile n program. De exemplu dac omitem seciunea goal putem s dm toate goal-urile n timpul rulrii. Pe de alt parte programul poate s conin doar o singur seciune goal. Pentru a genera o aplicaie executabil de sine stttoare programul trebuie s conin un goal. Goal-ul este singurul opional cnd rulm un program de dezvoltare. n mod uzual programul recurge cel puin la seciunile predicates i clauses. Pentru cele mai multe programe, seciunea domains este

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


folosit pentru declararea listelor, a structurilor compuse i a numelor proprii pentru domenii de baz. Constantele, domeniile i predicatele trebuie definite nainte de utilizarea lor. Ori de cte ori n cadrul unei seciuni domains ne putem referi la un domeniu care este declarat ulterior. Un singur goal poate determina compilarea. Oricnd un goal poate s apar oriunde dup seciunea predicatelor declarnd subgoal. Toate predicatele definite n seciunea predicats trebuie s se gseasc descrise n seciunea clauses. Toate declaraiile globale trebuie s apar naintea oricrei declaraii locale. Seciunea database poate fi numit, dar numele dat poate s apar o singur dat. Pentru c numele implicit este dbasedom nedenumit. 3.1. SECIUNEA DOMAINS Seciunea domains conine declaraiile domeniilor. Ca format generic se folosete: name=d standard*/ mylist=elementDom* list*/ /*domeniu /*domeniu acesta poate fi singura seciune database

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


myCompDom=f1(d11,d12,...,d1n);f2(d21,d22,...,d2n);... obiect file=name1;name2;...;nameN /*domeniu fiier*/ 3.1.1. Domeniu standard name=d Aceast declaraie declar un domeniu name, care conine elemente a unui domeniu standard de tip d; domeniul de tip d trebuie s fie integer, char, real, ref, string sau symbol. Aceast declaraie este folosit pentru obiecte care sintactic sunt asemntoare dar semantic sunt diferite. De exemplu, NoOfApples i HeightInFect amndou pot fi reprezentate ca un ntreg, dar ele n consecin sunt diferite una de cealalt. Se poate evita aceasta prin declaraia a dou domenii diferite de tip ntreg ca n exemplul urmtor: apples, height = integer Declarnd domenii diferite n acest fel Turbo Prolog asigur verificarea domeniilor, de exemplu acest apples i height nu o s fie amestecate niciodat n mod inadvertent. Oricnd cele dou domenii pot fi interschimbate dac sunt nlocuite cu ntregi i se poate folosi egalitatea pentru a face conversie ntre apples i height. 3.1.2. Domeniu list mylist = elementDom* /*domeniu compus*/

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


Acesta este o convenie de notaie pentru a declara un domeniu list. mylist este un domeniu care este construit din list de elemente din domeniul elementDom. Domeniul elementDom poate fi att domeniu definit de utilizator ct i domeniu de tip standard. Se citete asteriscul ca list. De exemplu declararea urmtorului domeniu: numberlist = integer* declar un domeniu de list de ntregi, ca i [1, -5,2,-6].

3.1.3. Domeniu obiect compus myCompDom = f1(d11,d12,...,d1N);f2(d21,d22,...,d2N);... A declara un domeniu care conine obiecte compuse au statut de functori i domenii pentru toate subcomponentele. De exemplu, se poate declara un domeniu owners constituit din elemente ca: owns(john,book(wuthering_heights,broute)) cu declaraii: owners = owns(symbol,book) book = book(symbol,symbol) unde owns este un functor al obiectelor compuse i symbol i book sunt domenii ai subcomponentelor. Partea dreapt al acestui tip de declaraie domains poate defini mai multe alternative, separate prin punct i virgul (;) sau prin cuvntul cheie or. Fiecare alternativ poate s conin un unic functor i o descriere a domeniilor pentru actualele subcomponente a functorului. De exemplu urmtoarea declaraie

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


de domeniu poate fi folosit pentru a declara Pentru orice predicat key poate fi oricare din up, down, left, right sau o valoare caracter. key = up;down;left;char(char) 3.1.3. Domeniu fiier file = name1;name2;...;nameN Domeniul fiier trebuie s fie definit cnd este nevoie de a ne referi la fiiere ( altele dect cele predefinite) prin nume simbolice. Programul poate s aib un unic domeniu de acest tip, care trebuie s fie numit file. Fiiere cu nume simbolice dau alternativ pentru domeniul file. De exemplu, declaraia: file = sales;salaries introduce dou fiiere simbolice numite sales i salaries. Urmtoarele alternative sunt predefinite n domeniul

file:keyboard, screen, printer, com1, stdin, stdout, stderr. 3.2. SECIUNEA PREDICATES n Turbo Prolog seciunea introdus de cuvntul cheie predicates conine declaraiile predicatelor. Declararea unui predicat const din numele lui i domeniile argumentelor lui. predicates predname(domain1,domain2,...,domainN) n acest exemplu predname reprezint un nou nume de predicat iar domain1,domain2,...,donainN domenii definite de utilizator sau domenii standard.

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


Sunt de asemenea permise declaraiile multiple pentru un singur predicat. De exemplu, se poate declara un predicat member care poate lucra att pe numere ct i pe nume i se poate urmri pe urmtoarele declaraii: predicates member(name,namelist) member(number,numberlist) n acest exemplu, argumentele name, namelist, number i numberlist sunt domenii definite de utilizator. Alternativele pentru member trebuie s aib acelai numr de argumente. Se poate declara un predicat cu mai multe ariti diferite. hanoi % alegerea a 10 piese implicit

hanoi(integer) % mut N piese Dac se declar mai multe declaraii cu acelai nume, aceste declaraii trebuie declarate corect una dup cealalt. Se pot declara predicate deterministice astfel ca declaraia predicatului s fie precedat de determ, sau se pot declara predicate nondeterministe astfel ca declaraia predicatului s fie precedat de nondeterm. Dac se declar un predicat deterministic, compilarea se va termina cu un avertizment dac va fi gsit o clauz nondeterminist pentru predicat. Aceste funcii sunt exacte dac se utilizeaz directiva de compilare check_determ. Pe de alt parte, dac se declar predicatul ca

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


nondeterministic, compilatorul nu va semnala nimic dac

adugm check_determ pentru verificarea celorlalte predicate. nondeterm repeat prin proiectare*/ determ menuact(integer,string) deterministic */ /* menuact este /* repetiia este nondeterministic

3.3. SECIUNEA DATABASE Seciunea database declar perdicatele exact cum o face seciunea predicates. Cu toate acestea, predicatele n seciunea database de fapt pot fi singurele fr variabile. Acestea ns pot fi introduse n timpul rulrii prin assert, asserta, assertz sau consult, i pot fi retrase cu retract sau retractall. n cadrul unui program pot fi mai multe seciuni database; unele dintre ele pot fi globale iar altele locale. Trebuie s avem un nume al seciunilor database din program, i fiecare nume trebuie s fie unic n modul. Dac nu se d un nume seciunii database, compilatorul va da implicit numele dbasedom. Se poate precede predicatul database cu determ dac se cunoate c el este singurul fapt pentru acel predicat. Acestea sunt validate de compilator pentru a produce un cod mai bun, i nu se va primi un mesaj de analizare nondeterminist la apelul unui astfel de predicat. Acesta este folositor n flags, contoare i alte variabile globale.

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


Cnd seciunea database este declarat, compilatorul va declara intern un domeniu component cu acelai nume cu numele seciunii database; acesta permite predicatelor, s se poarte de fapt ca termeni. Forma seciunii database este: [global] database [<databasename>] [determ] dbpred1(...) dbpred2(...)

3.4. SECIUNEA CLAUSES O clauz este ori un fapt ori o regul corespunznd ununia dintre predicatele declarate. ntr-o clauz primul predicat este urmat de dou puncte i linie (:-), iar dup aceea apare lista predicatelor separate de virgule sau punct i virgule. Ambele, fapte i reguli, trebuie s se termine prin punct (.) - cteodat acesta se refer la terminare final. Fapta same_league(uda,usc). conine numele predicatului (same_league) i n paranteze, lista argumentelor (uda,usc). Altele: -Cuvntul cheie if poate fi substituit de :-Cuvntul cheie and poate fi substituit de , -Cuvntul cheie or poate fi substituit de ;

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


Pentru o compatibilitate cu o versiune viitoare Turbo Prolog, se recomand utilizarea simbolurilor (:- ; i ,) n locul cuvintelor cheie. 3.4.1. Constante simple Constantele simple aparin unuia din cele 6 domenii standard: char Un caracter ( un caracter ASCII pe 8 bii ncadrat ntr-o pereche de apostroafe ) aparinnd domeniului char. Un caracter ASCII este indicat de caracterul \ urmat de codul ASCII pentru acel caracter. \n i \t produc trecerea la rnd nou sau tab. Un backslash urmat de orice alt caracter, rezult acel caracter ( \\ produce \ i \ produce ). integer Un ntreg aparine domeniului integer i este un numr cuprins n intervalul real Un numr real apartine domeniului real i este cuprins n intervalul +1e-307 la +1e+308. Un numr real se scrie: semn urmat de mantis, punct zecimal, partea fracional, e, semn, exponent, toate scrise una dup alta fra spaiu ntre ele. De exemplu, valoarea real -12345.6789*1014 poate fi scris ca -1.23456789e+18. Semnul, partea fracional i exponentul sunt opionale, (deci dac omitem partea fracional atunci nu trebuie utilizat i punctul zecimal). Turbo Prolog convertete automat ntregii ntr-un numr real atunci cnd este nevoie. -32,768 la 32,767.

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


string Un ir ( orice secven de caractere cuprinse ntre ghilimele ) aparin domeniului string. irurile pot conine caractere create prin secvena escape; irurile nu pot fi mai lungi de 64K. symbol O constant simbolic ( un nume care ncepe cu o liter mic ) aparinnd domeniului de tip symbol. irurile sunt acceptate ca i simboluri, dar simbolurile sunt pstrate ntr-un tabel intern pentru operaiile rapide. n capul tabelelor symbol se afl cteva spaii de stocare, care sunt folosite n timpul introduceri n tabel. Oricnd, dac simboluri asemntoare sunt comparate, acesta necesit o alocare de timp minim. file Un nume simbolic de fiier aparine domeniului file ; Acesta poate fi orice nume care ncepe cu o liter mica i apare n partea dreapt a declaraiilor a domeniului file, ori una din numele de fiiere predefinite: printer, screen, keyboard, stdin, stdout i stderr. 3.4.2. Termeni Un termen poate fi oricare din char, integer, real , string, symbol (mai este cunoscut ca atom), o variabil, o list sau un termen compus. 3.4.3 Variabile

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


Numele variabilelor ncepe cu o liter mare, sau liniu de subliniere sau este reprezentat de o variabil anonim, o singur liniu de subliniere. Variabila anonim este folosit cnd valoarea variabilei nu este folosit. Variabila se numete liber (free) cnd nu este imediat asociat cu un termen, i se numete legat (bound) cnd este asociat cu un termen. 3.4.4. Obiecte compuse Un obiect compus (sau o structur de date) este un simplu obiect care conine i o un colecie nume de alte obiecte numite subcomponente descriptor (functorul).

Subcomponentele sunt incluse ntre paranteze i sunt separate prin virgul. Functorul este scris doar nainte de paranteza stng. De exemplu, urmtorul termen compus conine functorul author i trei subcomponente: author(emily, bronte,1818) Obiectul compus aparine domeniului definit de utilizator. Declaraia domains corespunznd obiectului compus author, poate s arate n felul urmtor: domains author_dom year_of_birth) firstname,lastname =symbol year_of_birth = integer 3.4.5. Liste - Un tip special al obiectelor compuse = author (firstname, lastname,

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


Listele au structuri de date comune n Turbo Prolog; lista este n realitate un obiect compus. O list este o secven de argumente incluse ntre paranteze drepte i separate prin virgul. O list de ntregi apare ca n felul urmtor: [1, 2, 3, 9, -3, 2] Deasemenea o list aparinnd domeniului defint de utilizator este ca mai jos: domains ilist = integer* Dac elementele din list sunt de tip mixt ( de exemplu o list care conine att caractere ct i ntregi) aceast stare trebuie s fie n coresponden cu domeniul de declaraii. De exemplu: domains element = c(char); i(integer) list = element* O list de acest fel arat ca : [i(12), i(34), i(-567), c(x), c(y), c(z), i(987)] 3.5. SECIUNEA CONSTANTS Se pot defini i se pot folosi constante n programele Turbo Prolog. O declaraie de constante este indicat prin cuvntul cheie constants, urmat de declaraia nsi, folosind urmtoarea sintax: < Id > = < Macro definition >

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


Fiecare < Macro definition > se termin prin caracterul de rnd nou, deci se poate face o singur declaraie pe linie. Consatantele declarate n acest fel pot fi referite ulterior n program. Considerm urmtorul fragment de program: constants blue =1 green = 2 red = 4 bgi_path = c:\\tprolog2\\bgi grayfill50 = [$aa,$55, $aa,$55, $aa,$55, $aa,$55] language = english project_module = true nainte de compilarea programului, Turbo Prolog va poziiona fiecare constant mpreun cu actualul ir cu care corespunde. Exemplu: .............. menu_colors (red, green, blue), find_bgi (bgi_path), my_fill_pattern (gray_fill,50), text_convert(tprolog, language), status (project_module), ...............

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


va fi compilat de compilator exact n urmtorul fel: ............... menu_colors(4, 2, 1) find_bgi (c:\\tprolog2\\bgi ), my_fill_pattern = [$aa,$55, $aa,$55, $aa,$55, $aa,$55] text_convert (tprolog, english), status( true), ................ Prezentm cteva restricii n folosirea constantelor simbolice. Definiia unei constante nu se poate referi la el nsi. De exemplu: list = [1, 2| list] /* nu este permis*/

va genera un mesaj de eroare recursie n definiia de constant. Sistemul nu poate face distincie ntre litere mici i litere mari n declaraia constants . Consecvent cnd un identificator constants este folosit n seciunea clauses a programului, prima liter trebuie s fie mic pentru a evita ambiguitatea cu variabilele. Deci ca exemplu, urmtoarea este o costrucie corect: constants Two =2 goal A = two, write(A).

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


De asemenea pot fi cteva seciuni de declaraie constants, dar fiecare constant trebuie sa fie declarat nainte de afi utilazat. Identificatorii de constant sunt globale pentru tot restul fiierului i pot fi declarate doar o singur dat. Mai multe declarai al aceluiai identificator va genera un mesaj de eroare identificator de constant poate fi declarat o singur dat . Se pot folosi constantele pentru a redefinii nume de domenii i predicate cu excepia predicatelor speciale. 3.6. PREDICATE PREDEFINITE WRITE Funcia: Produce un numr de argumente. Declaraia: write(e1, e2, e3, ..., eN) Metode de I/O: (i, i, i, ..., i) Observaii: write scrie constantele sau variabilele date n fereastra curent sau n procedeul curent de scriere. write poate fi apelat cu un numr arbitrar nenul Argumentele lui write nu pot fi libere. Eec: Nu sunt. Eroare: 2001 Nu se poate executa operaia de scriere. Exemplu: goal write(\n Tu , ,trebuie s cunoti, deja acest predicat). FAIL de argumente ei.

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


Funcie: Totdeauna provoac backtracking. Declaraia: fail Observaii: fail folosete eecul i din acest motiv ntotdeuna cauzeaz backtracking. Eec: ntotdeauna eueaz. Erori: Nu sunt. Exemplu: domains name, addr = string database person(name, addr) predicates clear_database print_all clauses clear_database :- retract(person(_, _)), fail. clear_database. print_all :person(Name, Addr), write("\n Name=",Name,",Address=",Addr), fail. READLN

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


Funcia: Citete o linie de caractere. Declaraia: readln(Variabilir) Domenii: (string) Metode de I/O: (o) Observaii: readln citete caracterele din procedeul curent de citire pn cnd citete codul ASCII a caracterului de linie nou CR ( cod ASCII 13 ). Procedeul curent de citire este tastatura, dac nu este iniializat se schimb prin ( procedeul de citire ) readdevice. Apsarea tastei ESC cauzeaz lui readln. Eec: Cnd se apas tasta ESC n timpul introduceri de la tastatur. Cnd se ajunge la sfrit de fiier n timpul intrri de la fiier. Erori: Nu sunt. Exemplu: goal: readln(L) Acesta este o linie. L=Acesta este o linie. 1 Solution goal: readln(L) <-Se apas ESC No Solution goal: readln(L) <-Se apas ENTER L= omiterea imediat a

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


1 Solution CONCAT Funcia: Concatenarea a dou iruri. Declaraia: concat(ir1, ir2, irlung) Domenii: (string, string, string) Metode de I/O: (i, i, o), (o, i, i), (i, o, i), (i, i, i) Observaii: Operaia de concatenare este definit de ecuaia: irlung = ir1 + ir2 Eec: Din observaie. Erori: 2008 irul rezultat n 'concat' sau 'fronttoken' nu poate fi mai mare de 64k. Exemplu: goal: concat("aaa", "bbb", X) X = aaabbb 1 Solution goal: concat("aaa", X, "aaa---bbb") /*(i, o, i)*/ X = ---bbb 1 Solution goal: concat(X, "bbb", "aaa---bbb") /*(o, i, i)*/ X = aaa--1 Solution goal: concat("aaa", "bbb", "aaabbb") Yes /*(i, i, i)*/ /*(i, i, o)*/

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


goal: concat("aaa", "bbb", "aaa---bbb") No /*(i, i, i)*/

NOT Funcia: Se termin cu succes dac subgoalul negat eueaz i eueaz dac subgoalul negat se termin cu succes. Declaraia: not( <ApelPredicat> ) Observaii: not se termin cu succes dac <ApelPredicat> reprezint un goal care eueaz cnd este evaluat. Variabilele not pentru c variabilele s ne de ieire nu sunt permise ntr-un apel

nu pot fi legate de o operaie not. Este o idee bun succes dac condiia este fals ".

gndim la not ca " eec dac condiia este adevrat " sau "

Eec: Dac apelul ApelPredicat se termin cu succes. Erori: Nu sunt. Exemplu: goal: not(2>3) Yes goal: not(2<3) No goal: not(concat("aaa", "bbb", "aaa_bbb")) Yes goal: not(not(concat("aaa", "bbb", "aaa_bbb")))

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


No goal: not(concat("aaa", "bbb", X)) 704 Variabilele libere nu sunt permise n 'not' sau 'retractall'. CURSOR Funcia: Seteaz sau citete poziia cursorului n fereastr. Declaraia: cursor(Linie, Coloan) Domenii: (integer, integer) Metode de I/O: (i, i), (o, o) Observaii: (i, i) Mut cursorul n fereastra curent pe poziia indicat (Line,Coloan) relativ (o,o) Leag Linia i Coloana de poziia curent a cursorului. Eec: Nu sunt. Eroare: 1001 Valorile cursorului sunt nepermise. Exemplu: goal makewindow(1, 7, 7, "cursor test", 1, 1, 20, 70), cursor(5, 20),write("Hello"), cursor(Row, Col), Row1 = Row + 1, cursor(Row1, Col), write("you"), cursor("_", Col2), Row3 = Row1 + 1, cursor(Row3, Col2), de (0,0).

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


write("folks"), cursor(0,0). CLEARWINDOW Funcia: terge fereastra actual. Declaraie: clearwindow Observaii: 0). Eec: Nu sunt. Erori: Nu sunt. Exemplu: goal makewindow(1, 7, 7, "test window", 1, 1, 20, 70), cursor(5, 20), write("Hello"), cursor(10, 10), write("Apas orice tast"), readchar(_), clearwindow, write("Cursorul sa mutat la (0, 0)"), readchar(_). STR_LEN Funcia: Returneaz lungimea unui ir. Declaraia: str_len(ir, Lungime) Domenii: (string, integer) clearwindow terge textul curent din fereastr

umplnd acesta cu culoarea fondului. Cursorul este setat la (0,

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


Metode de I/O: (i, i), (i, o), (o, i) Observaii: (i, i) Reuete dac ir are Lungime caractere. (i, o) Reuete prin legarea lui Lungime de numrul de caractere din ir.

(o, i) Returneaz un ir de Lungime spaii. Eec: Rezult din observaii. Exemplu: goal: str_len("abc", Len) Len = 3 1 Solution goal: str_len("abc", 3) Yes goal: str_len(Str, 15), writef("|%|\n", Str) ' Str = 1 Solution STR_INT Funcia: Face conversia ntre iruri i ntregi. Declaraii: str_int (Argir, Argntr) Domenii: (string, integer) Metode de I/O: (i, o), (o, i), (i, i) Observaii: (o, i) Leag Argir de un ir ce reprezint un numr valoarea variabilei legate Argntr. '

zecimal care este

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


(i, o) Leag pe Argntr care reprezint echivalentul intern (n form binar) a numrului zecimal care este variabila legat Argir. (i, i) Se termin cu succes dac Argntr este legat de reprezentarea intern a numrului ntreg zecimal care este legat de Argir. Eec: (i, o) i (i, i) sunt versiuni de eec dac Argir nu conine un ntreg valid. sunt ignorate. Erori : Nu sunt. Exemplu: goal: str_int("123", Int) Int = 123 1 Solution goal: str_int(Str, 123) Str = 123 1 Solution goal: str_int("123", 123) Yes goal: str_int(" Int = -123 1 Solution goal: str_int(" -12x3 ", Int) -123 ", Int) Semnul din fa este opional i spaiile din fa

No Solution

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


FRONTCHAR Funcia: ntoarce primul caracter dintr-un ir. Declaraie: frontchar(ir, PrimulCar, Restir) Domenii: (string, char, string) Metode de I/O: (i, o, o), (i, i, o), (i, o, i), (i, i, i), (o, i, i) Observaii: frontchar are efect dac este definit prin ecuaia: ir = (concatenarea lui PrimCar i Restir). frontchar are 3 argumente: primul este un ir, al doilea este un caracter i al treilea este restul din despri un ir ntrcaractere (primul caracter al primului ir)

primul ir. frontchar poate fi folosit pentru a

o serie de caractere, sau a crea un ir dintr-o serie de

i pentru a testa dac anumite caractere fac parte dintr-un ir. Dac argumentul ir este legat de un ir de lungime zero, predicatul se termin cu eec.

Eec: Rezult din observaii. Erori: 5110 irul rezultat a predicatului frontchar nu poate avea lungime mai mare de 64K.

Exemplu: goal: frontchar("TPROLOG", Ch, Rest) Ch = T, Rest = PROLOG 1 Solution goal: frontchar("TPROLOG", 'T', Rest) Rest=PROLOG 1 Solution

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


goal: frontchar("TPROLOG", 'P', "PROLOG") No goal: frontchar(X, 'T', "PROLOG") X = TPROLOG 1 Solution FRONTSTR Functia: Desparte un ir n dou iruri. Declaraii: frontstr(NumrCaracter, ir1, irnceput, irSfrit) Domenii: (integer, string, string, string) Metode de I/O: (i, i, o, o) Observaii: frontstr desparte ir1 n dou pri. irnceput conine primele NumrCaracter caractere din ir1 i irSfrit conine restul din ir1. Eec: Rezult din observaii. Erori: Nu sunt. Exemplu: goal: frontstr(3, "All kids of fine", Str1, Str2) Str1 = All, Str2 = kids of fine 1 Solution goal: frontstr(9, "All kids of fine", Str1, Str2) Str1 = All kids, Str2 = of fine 1 Solution goal: frontstr(0, "All kids of fine", Str1, Str2)

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


Str1 = , Str2 = All kids of fine 1 Solution goal: frontstr(-1, "All kids of fine", Str1, Str2) No Solution goal: frontstr(20, "All kids of fine", Str1, Str2) No Solution MAKEWINDOW Funcia: Creaz o nou fereastr pe ecran, cadrul implicit. Declaraii: makewindow(WindowNo, ScrAtt, FrameAttr, FrameStr, linie, lime) Domenii: (integer, integer, integer, string, integer, integer, coloan, nlime,

integer, integer) Metode de I/O: (i, i, i, i, i, i, i, i) i (o, o, o, o, o, o, o, o) Observaii: (i, i, i, i, i, i, i, i) makewindow definete o arie pe ecran care devine o fereastr. Argumentele urmtoarele: WindowNo: Fiecare fereastr este identificat printr-un numr WindowNo, activ. ScrAtt: Atributul de ecran. care este folosit cnd se selecteaz fereastra instruciunii 'makewindow' sunt

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


FrameAttr: Dac FrameAttr este diferit de zero, makewindow deseneaz un chenar n jurul ariei definite (ncadreaz fereastra). FrameStr: Este irul de caractere care va fi plasat n cadrul liniei de sus a chenarului n mod centrat, dac Frame Str = "" ( este un ir vid), n partea de sus a chenarului nu va apare de sus a nici un text. Dac textul este mai lung dect linia chenarului atunci acesta va fi trunchiat. linie: Poziia liniei care compune chenarul stnga-sus a ferestrei relativ la ecran.

coloan: Poziia liniei care compune chenarul stnga-sus a ferestrei relativ la ecran.

nlime: nlimea ferestrei n uniti de linie. lime: Limea ferestrei n uniti de coloan. Odat definit, fereastra este tears, i cursorul va fi mutat n poziia din stnga-sus a chenarului. Combinaiile linie i obligatorii pentru a defini Dac afiare. nlime i coloan i lime, sunt

complet o fereastr n cadrul formatului de

valorile de definire a ferestrei depete formatul de afiare, se va genera un mesaj de eroare. Dimensiunea formatului de afiare poate fi standard. (o, o, o, o, o, o, o, o) n acest caz makewindow ntoarce valoarea curent a ferestrei curente. modificat cu predicatul textmode, predicat

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


Eec: Fr eec. Erori: 1000 Argumentele n makewindow sunt nepermise. 1016 Numrul maxim a ferestrelor este depit. Exemple: predicates nondeterm repeat delay(integer) goal makewindow(1, 1, 7, "one", 5, 0, 10, 20), write("ONE"), makewindow(2, 2, 7, "two", 1, 10, 10, 20), write("TWO"), makewindow(3, write("THREE"), makewindow(4, write("FOUR"), makewindow(5, 5, 7, "five", 4, 40, 10, 20), write("FIVE"), makewindow(6, 6, 7, "six", 5, 50, 10, 20), write("SIX"), makewindow(7, write("SEVEN"), makewindow(8, write("EIGHT"), makewindow(9, write("NINE"), 9, 7, "nine", 15, 20, 10, 20), 8, 7, "eight", 1, 10, 10, 20), 7, 7, "seven", 9, 5, 10, 20), 4, 7, "four", 8, 30, 10, 20), 3, 7, "three", 2, 20, 10, 20),

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 3


repeat, random(9, X), N = N + X, shiftwindow(N), framewindow(112), delay(1000), framewindow(7), keypessed. clauses repeat. repeat :- repeat. delay(0) :- !. delay(n) :- N1 = N1 - 1, delay(N1).

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4 4. IMPLEMENTAREA UNUI SISTEM DE

RESCRIERE A

TERMENILOR

4.1. PROBLEMA Partea practic a lucrrii o constituie utilizarea unui sistem canonic de rescriere a termenilor, i realizat n limbajul Turbo Prolog. Problema, pe care o rezolv programul, se poate formula astfel (noiunile teoretice fiind descrise n capitolul precedent) : Find dat un sistem canonic de rescriere a termenilor (TRS - Term Rewriting Sistem), s se execute rescrierea unui termen, s se verifice despre o ecuaie dac este o teorem, aducnd ambii termeni la o form normal. 4.2. DE CE TURBO PROLOG ? Natura problemei a impus folosirea acestui limbaj de generaia a cincea. Un limbaj "clasic", procedural, cum ar fi Pascalul sau C-ul, cere programatorului cunoaterea exact a pailor care conduc la rezolvare. n contrast Prologul este un limbaj declarativ, care nseamn c dndu-se faptele i regulile necesare, limbajul va folosi deducia pentru a rezolva problema. Natura problemei ce trebuia rezolvat cerea exact ceea ce este punctul forte al Prologului: din descrierea problemei i a regulilor, s se ajung la soluie. 4.3. CUM SE FOLOSETE PROGRAMUL

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


Progaramul are o interfa foarte simpl (natura problemei nu necesit o interfa complex), prietenoas cu utilizatorul. Progaramul rulat n mediul Turbo Prolog poate furniza mai multe faciliti dect prin goal-uri interne, definite de programator. Interfaa a fost introdus doar pentru a citi termenul pentru care se aplic regulile de rescriere. Deci la pornirea programului pe ecran va apare : " Introducei termenul: " Dar printr-o simpl modificare, prin scoaterea goal-ului intern (sau transformarea lui n comentariu) se pot exploata facilitile de a ajunge la clauzele programului prin mediul Turbo Prolog, goal-ul putnd fi introdus de utilizator. Pentru a vedea cum se introduce un termen, avem nevoie s descriem mai nti sistemul de rescriere a termenilor pe care-l implementeaz programul. Mai nti descriem cele 9 ecuaii, care vor constitui regulile de rescriere (exemplul GROUPC, capitolul 3): r1 : e + x = x r2 : -x + x = e r3 : (x + y) + z = x + (y + z) r4 : x + e = x r5 : -e = e r6 : -x (-x) = x r7 : x + (-x) = e

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


r8 : x + (-x + y) = y r9 : - (x + y) = (-y) + (-x) r10 : (-x) + (x +y) = y Dup cum se observ, avem doi operatori, " + " i " - ", adunarea a doi termeni i inversa unui termen. n programul nostru cele dou operaii au fost realizate n form de funcii, f (adunarea) i g (inversa). De aceea de exemplu termenul -(x + y) +x, cu ajutorul funciilor se poate scrie f ( g ( f (x, y)), x). n programul realizat un termen este declarat n urmtorul fel: term = var (symbol); con (symbol); cmp(symbol, term1) unde term1 este list de termeni (terml = term*). Vom avea i list de list de termeni (term11 = terml*). Deci un termen este o variabil, o constant sau o compunere de nume de funcie i argumentul su, o list de termeni. Dac utilizatorul vrea s introduc o variabil, va scrie var(x), o consatant ( n cazul nostru singura constant fiind e ) con(e). Dac vrem s scriem un termen de forma: nume_funcie (arg1,...,argn), va trebui s introducem: cmp("nume_funcie",[arg1,...,argn]).

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


De exemplu, termenul -(x + y) + x n cazul programului nostru se scrie cmp("f", [cmp("g", [cmp("f" ,[var(x), var(y)])]), var(x)]) Pentru a uura munca utilizatorului (fiindc introducerea unui astfel de termen este dificil, consumatoare de timp i din cauza lungimii termenelor, cauza unor erori de introducere), n program s-au realizat predicate care fac conversia dintr-un ir de caractere ntr-o reprezentare de termen i invers. De asemenea lucrul cu iruri n loc de termeni uureaz munca programatorului. n acest fel trecerea de la termen la ir i invers este univoc. Termenul descris mai sus se va converti n urmatorul ir de caractere: f2g1f2xyx. n acest progaram variabilele se noteaz cu caracterele x, y, z, a, b i c, singura constant cu e, operatorul de adunare cu f , iar operatorul de inversare cu g. Dup un caracter care noteaz o operaie, ntr-un ir care codific un termen, va urma o cifr, care reprezint aritatea operaiei respective. Adunarea este o operaie binar (f2), iar inversarea este unar (g1). Avantajul reprezentrii termenilor sub aceast form de ir de caractere este evident: este mai simpl, scurt i ansa de a comite greeli la introducere, scade considerabil, mpreun cu timpul consumat de aceast operaie de transmitere a datelor iniiale.

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


Rezultatul rescrierilor succesive va apare pe ecran n aceeai form de ir de caractere. Dac ns folosim mediul Turbo Prolog, introducnd de la tastatur predicatele pe care vrem s le folosim, rezultatul ne poate parveni i sub forma descris la nceput. Dar prin predicatul transf_term_sir, putem transforma termenul ntr-un sir, foarte rapid ca de exemplu: Goal: transf_term_sir(cmp(f, [var(x), var(y)]), S) S = f2xy 1 Solution Vom descrie predicatele care pot fi folosite de utilizator pentru a rezolva diferite probleme. aplic(sir1, sir2, int): se aplic la rescrierea (un singur pas) termenului introdus sub form de ir (sir1), sir2 reprezentnd irul corespunztor termenului n care s-a rescris termenul iniial, iar numrul ntreg int preciznd numrul regulei care s-a utilizat. Prin goal-ul interior, definit de programator, unui termen se aplic rescrierea succesiv, pn cnd nu se mai poate rescrie cu nici una dintre regulile definite. rescrie(term1, term2, int): recrie termenul term1 n termenul term2 cu regula cu numrul int. Face acelai lucru ca i predicatul aplic, singura diferen fiind faptul c n aplic s-a executat i transformarea din ir n ir. S vedem cum se realizeaz rescrierea:

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


rescrie (X, Y, N) :- dac X se rescrie n Y cu regula N. X are ca subtermen membrul stng al regulei N, termenul X se transform n irul S dup ce s-a fcut n el substituia dat de perechea (L1, L2), predicatul s(Z, N) soluia membrului stng al regulei N, s-a executat n Z substituia (L1, L2) iar apoi acesta se transform n irul S1; analog pentru predicatul d(V, N), unde V se transform n irul S2, se nlocuiete n S irul S1 cu irul S2, rezultatul se convertete n termen, i el furnizeaz pe Y. Predicatul membru_st(X, L1, L2, N) se execut substituia (n X) dat de perechea (L1, L2). Are semnificaia c un subtermen a lui X (sau X) se unific cu membrul stng al regulei N cu listele de unificare L1 (variabile), L2 (cu ce se nlocuiete). N = indicele regulei N. Printr-un predicat s(Z,N) se nelege c membrul stng al regulei N este termenul Z, iar prin d(U,N), se nelege c membrul drept al regulei N este U. n predicatul rescrie se folosesc i alte predicate, care realizeaz de fapt o rescriere corect a termenului. Astfel, trebuie s se verifice dac numrul variabilelor distincte dup rescriere este mai mic sau egal cu cel din termenul rezultat. Numele predicatelor i a parametrilor formali au fost alese astfel nct s sugereze aciunea pe care le execut. Pentru lucrul cu irurile de caractere s-au definit predicatele: - prima_poz(Sir, Subsir, Pos): prima apariie a subirului Subsir n irul Sir ncepe pe poziia Pos. Exemplu:

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


Goal: prima_poz(bbaaccaa, aa, 4) No Goal: prima_poz(gtrenre, re, P) P=3 1 Solution - ramas(Sir, Subsir, N, L): lungimea subirului Subsir este N, L este lungimea subirului obinut prin tergerea din irul Sir a caracterelor situate naintea subirului Subsir, precum i a lui Subsir. Exemplu: Goal: ramas(bbggrtewe, ggr, 3, L) L=4 1 Solution - ins_sir(S1, S2, X, S): irul S se obine prin inserarea irului S2 n irul S1 ncepnd cu poziia X. Exemplu: Goal: ins_sir(bbbb, aa, 3, S) S = bbaabb 1 Solution - setare_par_ins(Int1, Int2, Int3): testeaz condiiile de eroare i ajusteaz poziia de inserare n situaia n care acesta este n afara irurlui n care se face inserarea. Exemplu: Goal: setare_par_ins(3, 2, P) P=2 1 Solution

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


Goal: setare_par_ins(2, 6, P) P=1 1 Solution Goal: setare_par_ins(-1, 3, P) P=0 1 Solution tai_sir(S1, Pos, N, S2): irul S2 este irul obinut prin

tergerea din irul S1 ncepnd cu poziia Pos a N caractere. Exemplu: Goal: tai_sir(sssretaa, 4, 2, S) S = ssstaa 1 Solution subst_prima_ap(S1, S2, S3, S): irul S este obinut prin

nlocuirea n irul S1 a prime apariii a subirului S2 cu irul S3. Exempu: Goal: subst_prima_ap(eeere, er, ttt, S) S = eetttr 1 Solution Goal: subst_prima_ap(eernerj, er, tttt, S) S = etttnerj 1 Solution

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


Predicatul aplic_sbst(Term1, Term2, Terml1, Terml2), dup cum sugereaz i numele, aplic substituia dat de lista Terml1 i Terml2 n Term1, rezultatul fiind Term2. Substituia se realizeaz cu ajutorul predicatelor subst_term i subst_list, prima executndu-se n cazul cnd substituia se execut unui termen simplu, iar al doilea unei liste de termeni. (Term1) = Term2 = [x1 t1, ..., xn tn] Terml1 = [x1, ..., xn] Terml2 = [t1, ..., tn] Predicatele unific, unific_toate_arg i unific_un_arg verific dac argumentele se pot unifica, i dac da, realizeaz acest lucru. unific(X,Y,L1,L2) - X se unific cu Y i substituia = [x1 t1, ..., xn tn] este dat L1 = [x1, ..., xn] i L2 = [t1, ..., tn]. Celelalte predicate, cum ar fi membru, concatena, dim, nu_apare, elem sunt explicate de numele lor, execut diferite operaii cu termeni, verific unele condiii. membru - se verific dac un termen se afl ntr-o list de termeni. concatena - concateneaz dou liste de termeni. dim - determin numrul termenilor dintr-o list. functor(cmp(X,Y),X,N) - se determin numrul de argumente pentru termenul care are simbolul X.

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


nu_apare - verific dac primul termen se afl sau nu n al doilea ca subtermen. argument_fct(N,cmp(_,Y),ArgX) - verific dac n lista de argumente Y sunt N argumente ArgX. elem(N,L,X) - N este numrul de termeni X n L. subtermen - verific dac primul termen este subtermen n cel de al doilea. lista_var - construite lista variabilelor unui termen compus. elimdupl - pstreaz doar primul termen dintr-o list de termeni dac acesta se repet. nr_var_dist(X,N) - Determin numrul de variabile distincte care apar n termenul X. compus - verific dac termenul reprezint o funcie. 4.4. EXEMPLU La nceput pe ecran apare textul " Introduce-ti termenul: " dup care programul ateapt introducerea termenului care trebuie rescris. Termenul trebuie introdus n forma descris mai sus, un ir de caractere, n care termenul este transcris ntr-o form polonez prefixat. Programul va aplica rescrierea succesiv a acestui termen, pn cnd va ajunge la un termen care nu se mai poate rescrie. Dup introducerea de la tastatur a termenului n format de ir f2f2xeg1x, pe ecran va apare: f2f2xeg1x se rescrie n f2f2eg1x folosind regula 3 [(x+y) + z -> x + (y+z)]

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


f2f2xeg1x se rescrie n f2xg1x folosind regula 4 [ x + e -> x ] f2xg1x se rescrie n e folosind regula 7 [ x + (-x) -> e ] Press the SPACE bar Dac introducem un termen greit (ex. f2x) sau dac termenul nu poate fi rescris dup nici o regul, pe ecran va apare numai mesajul sistemului (Press the SPACE bar). Dar dac introducem aplic(Sir, Sirrez, N) programul va da rspuns afirmativ dac termenul se rescrie n termenul Sirrez, i precizeaz numrul regulei care a fost aplicat ultima oar. Dac se specific i numrul N, primim rsuns afirmativ numai n cazul n care rescrierea s-a realizat cu acea regul. Se poate observa unul dintre avantajele limbajului: un program Prolog are aproximativ de zece ori mai puine linii de program ca un program realizat ntr-un limbaj procedural. 4.5. CODUL SURS AL PROGRAMULUI
domains term=var(symbol);con(symbol);cmp(symbol,terml) terml=term* termll=terml* lista=string* constants regl=["[ e+x -> x ]","[ -x+x -> e ]","[ (x+y)+z -> x+(y+z) ]","[ x+e -> x ]","[ -e -> e ]","[ -(-x) -> x ]","[ x+(-x) -> e ]","[ x+(-x+y) -> y ]","[ -(x+y) -> (-y)+(-x) ]","[ (-x)+(x+y) -> y ]"] predicates membru(term,terml) concatena(terml,terml,terml) dim(terml,integer)

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


transf_term_sir(term,string) transf_terml_sir(terml,string) transf_sir_term(string,term) transf_sir_terml(string,terml) cauta(integer,string,lista) s(term,integer) d(term,integer) Functor(term,symbol,integer) Nu_apare(term,term) Nu_ap(integer,term,term) Argument_fct(integer,term,term) Elem(integer,terml,term) Unific_toate_arg(integer,term,term,terml,terml) Unific(term,term,terml,terml) Unific_un_arg(integer,term,term,terml,terml) Subst_term(term,term,term,term) Subst_list(term,term,terml,terml) Aplic_subst(term,term,terml,terml) subtermen(term,term) membru_st(term,terml,terml,integer) prima_poz(string,string,integer) ramas(string,string,integer,integer) ins_sir(string,string,integer,string) setare_par_ins(integer,integer,integer) tai_sir(string,integer,integer,string) subst_prima_ap(string,string,string,string) lista_var(term,terml) lista_var_l(terml,terml) elimdupl(terml,terml) nr_var_dist(term,integer) compus(term) scot_lista(terml,terml,terml,terml) rescrie(term,term,integer) aplic(string,string,integer) execut goal execut. clauses membru(X,[X|_]). membru(X,[_|L]):-membru(X,L). /* Se verifica daca un termen se afla intr_o lista de termeni */ concatena([],X,X). concatena([H|T],X,[H|Y]):-concatena(T,X,Y). /* Concateneaza doua liste de termeni */

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4

dim([],0). dim([_|T],N):-dim(T,N1),N=N1+1. /* Determina numarul termenilor dintr-o lista */ functor(cmp(X,Y),X,N):-dim(Y,N). /* Se determina numarul de argumente pentru termenul care are simbolul X */ subst_term(_,var(_),con(X),con(X)):-!. subst_term(Term,var(X),var(X),Term):-!. subst_term(_,var(X),var(Y),var(Y)):-X<>Y,!. subst_term(Term,Var,Functor,Nou_functor):Functor=cmp(X,Y), subst_list(Term,Var,Y,Nou_list), Nou_functor=cmp(X,Nou_list),!. /* In Functor se inlocuieste Var cu Term daca Var exista in Term si rezulta Nou_functor */ subst_list(Term,Var,[H|T],[H1|T1]):subst_term(Term,Var,H,H1), subst_list(Term,Var,T,T1). subst_list(_,_,[],[]):-!. /* Face acelasi lucru ca si subst_term pentru o lista de termeni */ nu_apare(var(U),var(V)):-U<>V. nu_apare(var(_),con(_)). nu_apare(var(_),cmp(_,[])). nu_apare(X,Y):-functor(Y,_,N), N>0, nu_ap(N,X,Y). /* Verifica daca primul termen exista sau nu in al doilea ca subtermen */ nu_ap(0,_,_). nu_ap(N,X,Y):-N>0, argument_fct(N,Y,Arg), nu_apare(X,Arg), N1=N-1, nu_ap(N1,X,Y). /* Predicat ajutator pentru nu_apare pentru cazul in care se verifica o lista de argumente a unei functii */ argument_fct(N,cmp(_,Y),ArgX):-elem(N,Y,ArgX). /* Verifica daca in lista de argumente Y sunt N argumente ArgX */ elem(1,[H|_],H). elem(N,[_|T],ArgX):-M=N-1, elem(M,T,ArgX). /* N este numarul de termeni ArgX in T */

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


unific(X,X,[],[]):-!. unific(X,Y,[],[]):-X=con(U),Y=con(U),!. unific(X,Y,[var(U)],[con(V)]):-X=var(U),Y=con(V),!. unific(X,Y,[var(U)],[con(V)]):-Y=var(U),X=con(V),!. /* = [var(U)con(V)] */ unific(X,Y,[var(U)],[var(V)]):-Y=var(U),X=var(V),!. unific(X,Y,[var(U)],[Y]):-X=var(U),nu_apare(X,Y). unific(X,Y,[var(U)],[X]):-Y=var(U),nu_apare(Y,X). unific(X,Y,Lista_var,Lista_term):functor(X,F,N), functor(Y,F,N), unific_toate_arg(N,X,Y,Lista_var,Lista_term). /* unific(X,Y,L1,L2) - X se unifica cu Y si substitutia = [x1 t1, ..., xn tn] este data L1 = [x1, ..., xn] si L2 = [t1, ..., tn] */ unific_toate_arg(N,X,Y,U,V):-N>0, unific_un_arg(N,X,Y,U1,V1), aplic_subst(Y,Yvar,U1,V1), aplic_subst(X,Xvar,U1,V1), N1=N-1, unific_toate_arg(N1,Xvar,Yvar,U2,V2), concatena(U1,U2,U), concatena(V1,V2,V). unific_toate_arg(0,_,_,[],[]). unific_un_arg(N,X,Y,U,V):argument_fct(N,X,ArgX), argument_fct(N,Y,ArgY), unific(ArgX,ArgY,U,V). transf_terml_sir([H|T],Y):transf_term_sir(H,Y1), transf_terml_sir(T,Y2), concat(Y1,Y2,Y). transf_terml_sir([],""). /* Transforma o lista de termeni in sir */ transf_term_sir(X,Y):-X=var(Z),Y=Z. transf_term_sir(X,Y):-X=con(Z),Y=Z. transf_term_sir(X,Y):-X=cmp(N,U),/* In cazul unui functor desparte pe X in numele functiei si lista de argumente. Pentru lista de argumente face conversia, determina numarul de argumente a listei, concateneaza numele functiei cu numarul de argumente si cu rezultatul sirului obtinut din lista de argumente */ transf_terml_sir(U,Z), dim(U,L), str_int(S,L), concat(N,S,N1),

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


concat(N1,Z,Y). /* Transforma termenul in sir */ transf_sir_term(X,Y):-X="x",Y=var(x). transf_sir_term(X,Y):-X="y",Y=var(y). transf_sir_term(X,Y):-X="z",Y=var(z). transf_sir_term(X,Y):-X="a",Y=var(a). transf_sir_term(X,Y):-X="b",Y=var(b). transf_sir_term(X,Y):-X="c",Y=var(c). transf_sir_term(X,Y):-X="e",Y=con(e). transf_sir_term(X,Y):-str_len(X,L),L>0, frontstr(1,X,S1,S2), /* primul caracter din X este functia */ frontstr(1,S2,C,C1),/* al doilea caracter din X=nr. argument*/ str_int(C,N), /* numarul transformat din sir */ transf_sir_terml(C1,Y1), /* conversia listei de argumente */ dim(Y1,N), /*verifica daca a fost corect introdus nr. de arg. */ Y=cmp(S1,Y1). /*rezultatul */ /* Conversia din sir in termen */ transf_sir_terml("",[]). transf_sir_terml(X,Y):-str_len(X,L),/* daca X nu e functie */ L>0, frontstr(1,X,E1,E2), transf_sir_term(E1,Y1), transf_sir_terml(E2,Y2), Y=[Y1|Y2]. transf_sir_terml(X,Y):-str_len(X,L), /* daca X e functie */ L>0, frontstr(1,X,F1,F2), frontstr(1,F2,SN,F3), str_int(SN,N), transf_sir_terml(F3,Y1), concatena(V1,V2,Y1), dim(V1,N), G=cmp(F1,V1),Y=[G|V2]. /* Conversia din sir in lista de termeni */ s(cmp(f,[con(e),var(x)]),1). s(cmp(f,[cmp(g,[var(x)]),var(x)]),2). s(cmp(f,[cmp(f,[var(x),var(y)]),var(z)]),3). s(cmp(f,[var(x),con(e)]),4). s(cmp(g,[con(e)]),5). s(cmp(g,[cmp(g,[var(x)])]),6). s(cmp(f,[var(x),cmp(g,[var(x)])]),7). s(cmp(f,[var(x),cmp(f,[cmp(g,[var(x)]),var(y)])]),8). s(cmp(g,[cmp(f,[var(x),var(y)])]),9). s(cmp(f,[cmp(g,[var(x)]),cmp(f,[var(x),var(y)])]),10). /* Reprezentarea ca termen a membrului stang a regulilor */ d(var(x),1).

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


d(con(e),2). d(cmp(f,[var(x),cmp(f,[var(y),var(z)])]),3). d(var(x),4). d(con(e),5). d(var(x),6). d(con(e),7). d(var(y),8). d(cmp(f,[cmp(g,[var(y)]),cmp(g,[var(x)])]),9). d(var(y),10). /* Reprezentarea ca termen a membrului drept a regulilor */ aplic_subst(X,Y,[H|T],[H1|T1]):subst_term(H1,H,X,Z), aplic_subst(Z,Y,T,T1). aplic_subst(X,X,[],[]). /* = [x1 t1, ..., xn tn] */ subtermen(X,Y):-Y=cmp(_,Z), membru(X,Z). subtermen(X,Y):-Y=cmp(_,Z), membru(U,Z), subtermen(X,U). /* Verifica daca X este subtermen a termenului Y */ membru_st(X,L1,L2,N):-s(Z,N),unific(X,Z,L1,L2). membru_st(X,L1,L2,N):-subtermen(S,X), s(Z,N), unific(S,Z,L1,L2). /* membru_st(X,L1,L2,N) are semnificatia ca un subtermen a lui X (sau X) se unifica cu membrul stang al regulei N cu listele de unificare L1(variabile), L2(cu ce se inlocuieste) N = indicele regulei N */ prima_poz(X,Y,0):-X="",!,Y="",!. prima_poz(Sir,Subsir,Pos):str_len(Sir,Sdim), str_len(Subsir,Sbdim), ramas(Sir,Subsir,Sbdim,Sub),!, Pos=Sdim-(Sbdim+Sub)+1. prima_poz(Sir,Subsir,0):str_len(Subsir,Sbdim), not(ramas(Sir,Subsir,Sbdim,_)),!. /* Determina prima pozitie a celui de al doilea sir in primul sir */ ramas(Sir,_,_,_):Sir="",fail. ramas(Sir1,Sir2,Sdim,Sub):frontstr(Sdim,Sir1,Prim,Rest), Prim=Sir2,

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


str_len(Rest,Sub). ramas(Sir1,Sir2,Sdim,Sub):frontchar(Sir1,_,Rest), ramas(Rest,Sir2,Sdim,Sub). /* Sub contine numarul de caractere care se afla in Sir1 dupa ultimul caracter din Sir2 */ ins_sir(Sir,Subsir,Index,Tsir):str_len(Sir,Sdim), setare_par_ins(Index,Sdim,Pos),!, frontstr(Pos,Sir,S1,S2), concat(S1,Subsir,Temp), concat(Temp,S2,Tsir). /* Insereaza in sirul Sir, sirul Subsir in pozitia Index => Tsir */ setare_par_ins(Index,Sdim,Pos):Index>0, Index<=Sdim+1, Pos=Index-1. setare_par_ins(Index,Sdim,Pos):- /* inserare la sfirsitul sirului */ Index>Sdim+1, Pos=Sdim. setare_par_ins(Index,_,Pos):- /* inserare le inceputul sirului */ Index<=0, Pos=0. /* In Pos este pozitia caracterului dupa care se insereaza */ tai_sir("",_,_,""):-!. tai_sir(Sir,Index,Nr,Tsir):str_len(Sir,Sdim), Index>0, Nr>0, Index+Nr<=Sdim+1,!, Pos=Index-1, frontstr(Pos,Sir,Prim,Rest), frontstr(Nr,Rest,_,S2), concat(Prim,S2,Tsir). tai_sir(Sir,Index,Nr,Tsir):str_len(Sir,Sdim), Index>0, Nr>0, Index<=Sdim+1, Index+Nr>Sdim+1,!, /* Pastreaza primele Index-1 caractere */ Pos=Index-1, frontstr(Pos,Sir,Prim,_), Tsir=Prim. tai_sir(Sir,Index,Nr,Tsir):str_len(Sir,Sdim),

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


Index<=0, /* Pastreaza caracterele de dupa pozitia Nr */ Nr>0, Nr<=Sdim,!, frontstr(Nr,Sir,_,S), Tsir=S. tai_sir(Sir,Index,Nr,""):str_len(Sir,Sdim), Index<=0,Nr>Sdim,!. /* sir vid */ tai_sir(Sir,Index,Nr,Sir):str_len(Sir,Sdim), Index>Sdim, /* intreg sirul */ !,Nr<=0,!. /* Elimina caracterele din Sir dintre pozitiile (Index-1) - (Index+No-1) */ subst_prima_ap("",X,_,""):str_len(X,L),L<>0,!. subst_prima_ap("","",X,X):-!. subst_prima_ap(Sir,Subsir,Nousir,Tsir):prima_poz(Sir,Subsir,Pos), Pos>0,!,str_len(Subsir,Sdim), tai_sir(Sir,Pos,Sdim,Tmpsir), ins_sir(Tmpsir,Nousir,Pos,Tsir). subst_prima_ap(Sir,_,_,Sir):-!. /* Inlocuieste prima aparitie a lui Subsir cu Nousir in Sir => Tsir */ lista_var(con(_),[]). lista_var(var(X),[var(X)]). lista_var(cmp(_,Y),X):-lista_var_l(Y,X). /* Construieste lista de variabile unui termen compus */ lista_var_l([H|T],Z):-lista_var(H,Z1), lista_var_l(T,Z2), concatena(Z1,Z2,Z). lista_var_l([],[]). elimdupl([],[]). elimdupl([H|T],X):-membru(H,T),!, elimdupl(T,X). elimdupl([H|T],[H|T1]):-elimdupl(T,T1). /* Pastreaza doar primul element, daca acesta se repeta */ nr_var_dist(X,N):-lista_var(X,Y), elimdupl(Y,Z), dim(Z,N). /* Determina numarul de variabile distincte care apar in termenul X */ compus(H):-H=cmp(_,[_]). /* Verifica daca e functie */

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


scot_lista([H|T],[_|T1],T2,T3):compus(H), scot_lista(T,T1,T2,T3). scot_lista([H|T],[_|T1],T2,T3):-H=con(_), scot_lista(T,T1,T2,T3). scot_lista([var(U)|T],[H|T1],[var(U)|T2],[H|T3]):scot_lista(T,T1,T2,T3). scot_lista([],[],[],[]). /* Elimina variabilele */ rescrie(X,Y,N):-s(X,N),d(Y,N),!. rescrie(X,Y,N):-membru_st(X,L1,L2,N), nr_var_dist(X,K), aplic_subst(X,Xnou,L1,L2), nr_var_dist(Xnou,K), transf_term_sir(Xnou,S), s(Z,N), aplic_subst(Z,Znou,L1,L2), transf_term_sir(Znou,S1), d(V,N), aplic_subst(V,Vnou,L1,L2), transf_term_sir(Vnou,S2), subst_prima_ap(S,S1,S2,Snou), transf_sir_term(Snou,Yint), scot_lista(L2,L1,L2nou,L1nou), aplic_subst(Yint,Y,L2nou,L1nou). /* rescriere(X,Y,N) term(X) se rescrie in Y cu regula de rescriere N. X are ca subtermen membrul stang al regulei N (conform predicatului membru_st(X,L1,L2,N)), termenul X se transforma in sirul S (dupa ce s-a facut in el substitutia data de perechea (L1,L2)), predicatul s(Z,N), solutia membrului stang al regulei N s-a executat in Z substitutia (L1,L2) iar apoi acesta se transforma in sirul S1; analog pentru predicatul d(V,N), unde V se transforma in sirul S2, se inlocuieste in sirul S sirul S1 cu sirul S2, rezultatul se converteste in termen, si el furnizeaza pe Y. */ cauta(M,H,[H|_]):-M=1. cauta(M,Lin,[_|T]):-M<>1,M1=M-1,cauta(M1,Lin,T). aplic(Sir1,Sirez,N):-transf_sir_term(Sir1,X), rescrie(X,Y,N), transf_term_sir(Y,Sirez), M=N, Reg=regl, cauta(M,Lin,Reg), write(" ",Sir1," se rescrie in ",Sirez," folosind regula ",N," ",Lin), nl,aplic(Sirez,Sirez1,N1),Sirez=Sirez1, N=N1.

Sisteme de rescriere a termenilor i implementrile lor - Capitolul 4


execut:-makewindow(1,7,7,"Rescrierea termenilor",0,0,25,80), clearwindow, cursor(5,10), write("Introduceti termenul:"), readln(X),nl, aplic(X,_,_),nl.

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