logică şi structuri discrete - ac.upt.ro · 1 logică şi structuri discrete 1. presupunem că...

42
1 Logică şi structuri discrete 1. Presupunem că există 200 de studenţi din anul I care participă la cursurile de calculatoare, matematică şi fizică. Rezultatele au arătat că 90 de studenţi participă la calculatoare, 110 la matematică şi 60 la fizică. Mai departe 20 de studenţi participă la calculatoare şi matematică. 20 de studenţi participă la calculatoare şi fizică şi 30 la matematică şi fizică. Ne interesează să aflăm cati studenţi participă la toate cele trei cursuri. Soluţie: Să numim cele trei grupe C, M, P. Prin urmare vrem să aflăm P M C . 90 C 110 M 60 P 20 M C 20 P C 30 P M P M C P M P C M C P M C 200 90 + 110 + 60 20 20 30 + P M C = 190 + P M C . 10 P M C 2. Folosind regulile de inferenţă din logica propoziţională, să se stabilească valoarea de adevăr a următoarei afirmaţii: Dacă fie soţia mea fie eu am fi adus banii cu noi, atunci am fi putut plăti şi cina la restaurant şi taxiul. Dacă am fi plătit taxiul n-ar fi trebuit să mergem pe jos acasă. Dar a trebuit să mergem pe jos acasă. Deci, soţia mea nu a adus banii. Soluţie: Notăm cu S = soţia a adus banii, E = eu am adus banii, C = cina plătită, T = taxiul plătit, MA = mers pe jos acasă. Facem următoarele inferenţe: 1. (S E)=> (CT) 2. T=>MA 3. MA > S 4. (MA) din 3, prin dublă negaţie 5. T din 2,4, prin modus tollens 6. (CT) => T tautologie 7. (CT) din 6,5, prin modus tollens 8. (S E) din 1,7, prin modus tollens 9. S E din 8, prin De Morgan 10. S din 9, prin simplificare

Upload: others

Post on 10-Sep-2019

16 views

Category:

Documents


0 download

TRANSCRIPT

1

Logică şi structuri discrete

1. Presupunem că există 200 de studenţi din anul I care participă la cursurile de calculatoare,

matematică şi fizică. Rezultatele au arătat că 90 de studenţi participă la calculatoare, 110 la

matematică şi 60 la fizică. Mai departe 20 de studenţi participă la calculatoare şi matematică. 20

de studenţi participă la calculatoare şi fizică şi 30 la matematică şi fizică. Ne interesează să aflăm

cati studenţi participă la toate cele trei cursuri.

Soluţie: Să numim cele trei grupe C, M, P. Prin urmare vrem să aflăm PMC .

90C

110M

60P

20MC

20PC

30PM

PMCPMPCMCPMC200 90 + 110 + 60 – 20 – 20 – 30

+ PMC = 190 + PMC .

10 PMC

2. Folosind regulile de inferenţă din logica propoziţională, să se stabilească valoarea de adevăr a

următoarei afirmaţii: Dacă fie soţia mea fie eu am fi adus banii cu noi, atunci am fi putut plăti şi

cina la restaurant şi taxiul. Dacă am fi plătit taxiul n-ar fi trebuit să mergem pe jos acasă. Dar a

trebuit să mergem pe jos acasă. Deci, soţia mea nu a adus banii.

Soluţie: Notăm cu S = soţia a adus banii, E = eu am adus banii, C = cina plătită, T = taxiul plătit,

MA = mers pe jos acasă.

Facem următoarele inferenţe:

1. (S E)=> (CT)

2. T=>MA

3. MA > S

4. (MA) din 3, prin dublă negaţie

5. T din 2,4, prin modus tollens

6. (CT) => T tautologie

7. (CT) din 6,5, prin modus tollens

8. (S E) din 1,7, prin modus tollens

9. S E din 8, prin De Morgan

10. S din 9, prin simplificare

2

3. Să se aplice rezoluţia pentru a rezolva următoarea problemă de inferenţă:

Să presupunem că:

(a) Există un dragon.

(b) Dragonul doarme în peştera sa sau vânează în pădure.

(c) Dacă dragonul este flămând, atunci nu poate dormi.

(d) Dacă dragonul este obosit, atunci nu poate vâna.

(i) Ce face dragonul când este flămând?

Soluţie: Introducem predicatele:

Dragon(x) : x este un dragon

Poate(x,y,z): y poate să facă x în z

Face(x,y,z) : y face x în z

Flămând(x) : x este flămând

Obosit(x) : x este obosit

Presupunem, de asemenea, Poate(x,y,z) ← Face(x,y,z). (*)

Transformăm presupunerile (a), (b), (c) şi (d) în clauze:

(a) Dragon(A) ←

(b) Face(doarme,A,peşteră), Face(vânează, A, pădure) ←

(c) ¬Poate(doarme,A peşteră) ← Flămând(A)

(d) ¬Poate(vânează,A ,pădure) ← Obosit(A)

Transformăm presupunerile (a)-(d) şi (*) în formă de mulţime-teoretică:

(1) Dragon(x)

(2) Face(doarme, A, peşteră), Face(vânează,A ,pădure)

(3) ¬Flămând(A), ¬Poate(doarme,A ,peşteră)

(4) ¬Obosit(A), ¬Poate(vânează,A, pădure)

(5) Poate(x,y,z), ¬Face(x,y,z)

(i) Adăugăm următoarele clauze clauzelor de la (1) la (5):

(6) Flămând(A)

(7) ¬Face(x,y,z)

Clauza (7) reprezintă scopul rezoluţiei. Vom încerca să concluzionăm , prin instanţierea

adecvată a variabilelor x,y şi z.

(8) Face(doarme, A, peşteră), x = vânează, y = A, z = pădure din (2) şi (7)

(9) Poate(doarme, A, peşteră) din (5) şi (8)

(10) ¬Poate(doarme, A, peşteră) din (3) şi (6)

(11) din (9) şi (10)

(ii) Adăugăm următoarele clauze clauzelor (1)-(5).

3

(6) (Obosit(A)

(7) ¬Face(x,y,z) apoi

(8) Face(vânează, A, pădure), x = doarme, y = A, z = peşteră din (2) şi (7)

(9) Poate(vânează, A, pădure) din (5) şi (8)

(10) ¬Poate(vânează, A, pădure) din (4) şi (6)

(11) din (9) şi (10)

Tehnici de programare

1. Daţi o soluţie recursivă, în limbajul de programare C, pentru Algoritmul lui Euclid de aflare a

celui mai mare divizor comun a două numere întregi.

Formularea în cuvinte a algoritmului este următoarea:

Dacă unul dintre numere este zero, c.m.m.d.c. al lor este celălalt număr.

Dacă nici unul dintre numere nu este zero, atunci c.m.m.d.c. nu se modifică dacă se înlocuieşte

unul dintre numere cu restul împărţirii sale cu celălalt.

Soluţie:

int cmmdc(int m, int n)

int r;

r=m % n;

while (r != 0)

m=n;

n=r;

r=m % n;

return n;

2. Să se scrie o funcţie care inversează in situ conţinutul unui şir de caractere. Se vor folosi

operaţii cu pointeri.

Soluţie:

char *strrev (char *sir)

char *initial = sir;

char *urmator = sir;

char temp;

while (*sir) sir++;

while (urmator < sir)

temp = *(--sir);

*sir = *urmator;

*urmator++ = temp;

return (initial);

4

3. Folosind operaţiile pe biţi din limbajul de programare C, să se scrie o funcţie,

contorbiti,care să numere biţii cu valoarea 1 din argumentul său x, de tipul întreg fără

semn.

Soluţie: /* contorbiti: numara bitii cu valoarea 1 din x */

int contorbiti (unsigned x)

int b;

for(b=0; x!=0; x>>=1)

if (x & 01)

b++;

return b;

Programarea orientată pe obiecte

1. Să se creeze o clasă MyException derivată din clasa Exception ce conţine:

- un constructor ce are ca parametru un şir de caractere ce va fi furnizat de serviciul

getMessage() al excepţiei. Serviciul getMessage() nu va fi suprascris.

- o metodă ce returnează de câte ori a fost instanţiată, atât ea (clasa MyException) cât şi orice

subclasă a sa. După ce aţi implementat metoda precum şi mecanismul de numărare, explicaţi

datorită cărui fapt metoda returnează şi câte instanţe ale subclaselor au fost create.

Creaţi într-o metodă main trei obiecte de tip MyException care vor fi ataşate pe rând aceleiaşi

referinţe. Apelaţi pentru fiecare obiect creat două servicii furnizate de acesta.

Rezolvare:

class MyException extends Exception

private static int instanceNo = 0;

//acest constructor trebuie sa se apeleze la

//fiecare instantiere a clasei, precum si a eventualelor subclase

public MyException(String message)

super(message);

instanceNo++;

public static int getInstanceNo()

return instanceNo;

public static void main(String[] argv)

MyException e;

//serviciile ce se doresc a fi apelate sunt

//mostenite de la clasa Exception

//getMessage(), toString(), printStackTrace()...

//se poate apela si getInstanceNo(), dar aceasta fiind statica, nu se recomanda

//apelul prin intermediul referintei unui obiect

e = new MyException("primul caz");

5

System.out.println(e.getMessage());

System.out.println(e.getInstanceNo());

e = new MyException("al doilea caz");

System.out.println(e.getMessage());

System.out.println(e.toString());

e = new MyException("al treilea caz");

e.printStackTrace();

System.out.println(e.toString());

2. Folosind clasa ArrayList creaţi o clasă Biblioteca ce poate stoca un număr nelimitat de obiecte

de tip Carte. O carte are două atribute ce stochează titlul precum şi autorul cărţii iar afişarea

acesteia pe ecran va furniza utilizatorului valorile atributelor menţionate.

Clasa Biblioteca oferă doar două servicii, unul pentru adăugarea de elemente de tip Carte şi altul

pentru afişarea elementelor conţinute. Se cere implementarea claselor menţionate precum şi

crearea într-o metodă main a unei biblioteci ce are trei cărţi. Cărţile ce există în bibliotecă vor fi

tipărite.

Rezolvare:

import java.util.*;

class Carte

private String autor, titlu;

public Carte(String autor, String titlu)

this.autor = autor;

this.titlu = titlu;

public String toString()

return autor + " " + titlu;

class Biblioteca

private ArrayList<Carte> carti = new ArrayList<Carte>();

public void add(Carte c)

carti.add(c);

public String toString()

//se poate si parcurge colectia cu iteratori, dar ar fi inutil din moment ce exista

//metoda toString() din ArrayList care face acest lucru

return carti.toString();

public static void main(String[] argv)

Carte c1 = new Carte("colectiv", "abecedar");

Carte c2 = new Carte("UPT", "Java");

Carte c3 = new Carte("INFO", "Java");

Biblioteca b = new Biblioteca();

6

b.add(c1);

b.add(c2);

b.add(c3);

System.out.println(b);

3. Respectând cerinţele enunţate şi principiile POO, să se implementeze în Java interfaţa

şi clasele descrise mai jos.

Interfaţa Intrare conţine:

- o metodă denumită continut, fără argumente şi care returnează o referinţă String

Clasa Fisier implementează interfaţa Intrare şi conţine:

- un atribut de tip String denumit informatie, specific fiecărui obiect Fisier în parte

- un constructor ce permite setarea atributului anterior cu o valoare String dată ca parametru

constructorului

- implementarea metodei continut întoarce valoarea atributului informatie descris mai sus

Clasa Director implementează interfaţa Intrare şi conţine:

- un atribut denumit intrari de tip ArrayList<Intrare>; câmpul este specific fiecărei instanţe a

acestei clase si se va iniţializa cu un obiect listă gol

- o metoda adauga cu un singur parametru; acesta trebuie să fie declarat în aşa fel încât să poată

referi atât obiecte a clasei Director, cât şi obiecte a clasei Fisier dar să NU poată referi orice fel

de obiect Java (ex. NU va putea referi un obiect String); metoda introduce în lista anterioară

referinţa primită ca parametru

- obligatoriu în implementarea metodei continut se parcurge lista intrari şi se apelează metoda

continut pe fiecare referinţă din lista concatenându-se String-urile întoarse de aceste apeluri;

metoda va returna o referinţă spre String-ul rezultat în urma concatenării

În toată această ultimă clasă, obiectele Fisier si obiectele Director din listă trebuie să fie tratate

uniform.

Rezolvare:

interface Intrare

String continut();

class Fisier implements Intrare

private String informatie;

public Fisier(String informatie)

this.informatie = informatie;

public String continut()

return informatie;

class Director implements Intrare

private ArrayList<Intrare> intrari = new ArrayList<Intrare>();

public void adauga(Intrare intr)

intrari.add(intr);

public String continut()

7

String tmp = "";

for(Intrare i : intrari)

tmp = tmp + i.continut();

return tmp;

Arhitectura calculatoarelor

1. Se consideră următorul format ipotetic inspirat de formatul de virgulă flotantă IEEE 754,

prezentat prin lungimea câmpurilor specifice în următorul tabel:

Semn Exponent Mantisă

<1 bit> <5 biţi> <10 biţi>

Considerând ca normalizarea se face similar formatului IEEE 754, se cere să se calculeze cel mai

mic si cel mai mare număr pozitiv normalizat care se pot reprezenta utilizând formatul propus.

Rezolvare:

Valoarea bias-ului corespunzătoare codului binar de reprezentare a exponentului pentru formatul

ipotetic este: 1 5 12 1 2 1 15nbias

În consecinţă, numerelor normalizate le corespund exponenţi din intervalul [-13, 15]

Cel mai mic număr pozitiv normalizat:

x3=2-13

*1.0000000000=2-13

Cel mai mare număr pozitiv normalizat:

x4=215

*1.1111111111=215

*(2 - 2-10

)= 216

- 25

2. Se considera următorul algoritm de implementare a operaţiei de înmulţire binară după

procedura lui Booth cu creşterea bazei sistemului de numeraţie la baza 4, redat prin ordinograma

din figura următoare.

8

Begin

BEGIN

?No

A[8:0] :=0, COUNT:=0,

M:=INBUS

Yes

S0

S1 c0

Q[7:0]:=INBUS,

Q[-1]:=0

S2 c1

Q[1]Q[0]Q[-1]="001"

or

Q[1]Q[0]Q[-1]="010"

Q[1]Q[0]Q[-1]="101"

or

Q[1]Q[0]Q[-1]="110"

No

A:=A+M

YesS3 c2

Q[1]Q[0]Q[-1]

=

"011"

No Q[1]Q[0]Q[-1]

=

"100"

No

A:=A-M

YesS4 c2,c3

A:=A+2*M

YesS5 c2,c4

A:=A-2*M

YesS6 c2,c3,c4

COUNT3=1

?

No

A[8]:=A[8], A[7]:=A[8],

A[6:0].Q:=A.Q[7:1],

COUNT:=COUNT+1

NoS7 c5

OUTBUS:=A[8:1],

Q[1]:=0

S8 c6

Yes

OUTBUS:=A[0].Q[7:1]

S9 c7

End

S0 END

Se cere sinteza unităţii de control asociată dispozitivului de înmulţire care implementează

algoritmul Booth radix 4, prin metoda Sequence Counter. Se urmăreşte proiectarea optimă prin

prisma latenţei de execuţie a procedurii.

Rezolvare:

În figura următoare este sintetizată unitatea de control prin metoda Sequence Counter pentru

algoritmul de înmulţire a numerelor binare Booth radix 4.

9

Modulo-2

Sequence Counter

S

R

Qc0

c1

Cycle0

Begin

Clock

Reset

END

S

R

Q

Cycle1

Q[-1]

Q[0]

Q[1]

c2

c3

c4

COUNT3c5

S

R

Q

Cycle2

c6

c7

3. Să se înmulteasca după procedura lui Booth numerele -101 si -11, organizând rezolvarea sub

formă tabelară, prin indicarea pas cu pas a conţinutului regiştrilor şi a semnalelor de control

activate.

Rezolvare:

Cei 2 operanzi, reprezentaţi în complement de 2 au următoarea configuraţie:

-101(10)=10011011(2)

-11(10)=11110101(2)

Operaţia de înmulţire după procedura lui Booth este prezentată în următorul tabel:

10

A Q M Count

Control

signals

0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 1 0 0 0 c0(input)

1 0 0 1 1 0 1 1 0 c1(input)

- 1 1 1 1 0 1 0 1

0 0 0 0 1 0 1 1 c2,c3(-)

0 0 0 0 0 1 0 1 1 1 0 0 1 1 0 1 1 0 0 1 c4(shift)

0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 0 1 0 1 0 c4(shift)

+ 1 1 1 1 0 1 0 1

1 1 1 1 0 1 1 1 c2(+)

1 1 1 1 1 0 1 1 1 1 1 1 0 0 1 1 0 0 1 1 c4(shift)

- 1 1 1 1 0 1 0 1

0 0 0 0 0 1 1 0 c2,c3(-)

0 0 0 0 0 0 1 1 0 1 1 1 1 0 0 1 1 1 0 0 c4(shift)

0 0 0 0 0 0 0 1 1 0 1 1 1 1 0 0 1 1 0 1 c4(shift)

+ 1 1 1 1 0 1 0 1

1 1 1 1 0 1 1 0 c2(+)

1 1 1 1 1 0 1 1 0 1 0 1 1 1 1 0 0 1 1 0 c4(shift)

1 1 1 1 1 1 0 1 1 0 1 0 1 1 1 1 0 1 1 1 c4(shift)

- 1 1 1 1 0 1 0 1

0 0 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 c2,c3(-)

0 0 0 0 0 1 0 0 0 1 0 1 0 1 1 1 1 c4(shift)

0 0 0 0 0 1 0 0 0 1 0 1 0 1 1 1

Rezultatul operaţiei de înmulţire, evidenţiat si in tabelul anterior, este:

0000010001010111(2)=1111(10).

Circuite şi semnale numerice

1. Se da schema din fig. 1

a. Se cere sa se ridice diagramele de timp din punctele Vi, VA, VB, VC, VD.

b. Sa se determine duratele de timp de la iesirea VD pentru urmatoarele: P1, P2, P3 sunt porti

TTL, VH = 3,5 V, VL = 0,2 V, VT = 1,5 V, T1=T2=10µs. Timpul de propagare pe porti se

poate neglija in raport cu ceilalti timpi din figura.

P1

R

0.3 kΩ

C1 nF

P2P3

AB

C D

11

Fig. 1

Raspuns:

12

13

2. Se da urmatoarea schema:

VCC

P1

P2

P3

P4

Q1

Q2

Q3

X

RE

Se cere sa se dimensioneze rezistenta RE, unde portile P1, P2, P3, P4 sunt porti TTL cu

collector in gol, iar Q1, Q2, Q3 sunt porti TTL standard.

Se da: VCC = 5 V, VOH = 3,5 V, VOL = 0,2 V, IOL = 16 mA, I00 = +250 µA, IiL = -1,6 mA,

IiH = 40 µA, IC0 = 0.

Raspuns:

a) Pentru VX = VOH = 3,5 V VCC

P1

P2

P3

P4

Q1

Q2

Q3

XIiH

IiH

IiH

I00

I00

I00

I00

IRE

RE

14

b) Pentru VX = VL = 0,2 V. Cazul cel mai defavorabil este cand o singura poarta P are la

iesire VOL. Fie P1

VCC

P1

P2

P3

P4

Q1

Q2

Q3

XIiL

IiL

IiL

IC0

IC0

IC0

IC0

IRE

RE

c)

15

3. Se da urmatoarea schema de interconectare la o magistrala

P1

P2

P3

P4

Q1

QN

C1

A1

C2

A2

C3

A3

C4

A4

Portile P1, P2, P3, P4 sunt porti cu impedanta ridicata din cadrul familiei de circuite TTL. Pentru a

nu exista coliziuni pe magistrala o singura poarta P trebuie sa furnizeze valoarea logica “0” sau

“1”, celelalte porti P trebuie sa fie pe impedanta ridicata. Fie parta P1 activa si P2, P3, P4 sunt

comandata cu semnalele C2, C3, C4 sa functioneze cu iesirile pe impedanta ridicata.

Se cere sa se specific cate porti TTL standard (Q) mai pot fi conectate pe magistrala de mai sus.

Se da pentru portile TTL: IOH = -5,2 mA, IOL= 16 mA, IOLZ(impedanta ridicata) = -40 µA.

Raspuns:

a) Pentru cazul cand pe magistrala se doreste transmiterea “1” logic VMAG=VH=3,5 V (VZ –

iesire cu impedanta ridicata)

16

P1

P2

P3

P4

Q1

QN

VC1=VH

A2

A3

A4

VA1=VL

VC2=VL

VC3=VL

VC4=VL

VH

VHZ

VHZ

VHZ

IOH

IOHZ

IOHZ

IOHZ

IiH

IiH

Schema curentilor pe magistrala este:

Se mai pot conecta pentru acest caz 127 de porti (utilizatori)

b) Pentru cazul cand pe magistrala se doreste transmiterea “0” logic

VMAG=VL=0,2 V

17

P1

P2

P3

P4

Q1

QN

VC1=VH

A2

A3

A4

VA1=VH

VC2=VL

VC3=VL

VC4=VL

VH

VHZ

VHZ

VHZ

IOL

IOLZ

IOLZ

IOLZ

IiL

IiL

Suma curentilor pe magistrala trebuie sa satisfaca conditia

Se ia numar intreg Nb = 9

Numarul de porti Q ce pot fi conectate la magistrala este

N=9 este numarul de utilizatori e pot fi conectati simultan pe magistrala.

Proiectarea şi analiza algoritmilor

1. Să se scrie funcţia de suprimare a unui nod dintr-un arbore binar ordonat implementat cu

pointeri. Se vor trata cele trei cazuri specifice: i) nodul de şters nu are fii, este terminal; ii) nodul

de şters are un singur fiu; iii) nodul de şters are ambii fii. Pentru cazul iii) se va alege nodul

înlocuitor ca fiind maximul din subarborele stâng sau minimul din subarborele drept al nodului

de şters.

Rezolvare

typedef struct nod

int cheie;

struct nod *st;

struct nod *dr;

18

NOD;

NOD *rad=NULL;

NOD* sterge(NOD *p,int cheie)

NOD *q=NULL;

NOD *r=NULL;

if(p)

if(cheie<p->cheie)

// cautare in subarborele stang

p->st=sterge(p->st,cheie);

else

if(cheie>p->cheie)

// cautare in subarborele drept

p->dr=sterge(p->dr,cheie);

else

if(cheie==p->cheie)

// nodul de sters nu are fii

if(p->st==NULL && p->dr==NULL)

free(p);

return NULL;

// nodul de sters are fiu stang

if(p->st!=NULL && p->dr==NULL)

q=p->st;

free(p);

return q;

// nodul de sters are fiu drept

if(p->st==NULL && p->dr!=NULL)

q=p->dr;

free(p);

return q;

19

// nodul de sters are ambii fii

if(p->st!=NULL && p->dr!=NULL)

// se merge pe subarborele drept

// ce contine cheile mai mari

q=p->dr;

r=q;

// subarborele drept se parcurge pe stanga

// pentru a gasi minimul

while(q->st!=NULL)

// nodul q este minimul din subarbore

// nodul r este parintele nodului q

r=q;

q=q->st;

// se salveaza un eventual nod din dreapta lui q in stanga lui r

r->st=q->dr;

// se leaga nodul q de fiii lui p

q->st=p->st;

q->dr=p->dr;

// se leaga nodul q de parintele lui p

return q;

return p;

2. Să se scrie structura de date şi funcţia ce afişează factorul de umplere pentru fiecare pagină a

unui arbore B de ordin N. Factorul de umplere este dat de raportul dintre numărul de chei dintr-o

pagină şi capacitatea maximă a paginii. Pentru o pagină a unui arbore de ordinul 2, ce conţine 3

chei procentul de umplere este 0.75.

Rezolvare

#define N 2

#define NN (2*N)

typedef struct nod

20

int chei[NN];

int nn;

struct nod* fii[NN+1];

NOD;

void factor_umplere(NOD *p)

if(p)

printf("%lf",p->nn/(double)NN);

for(int i=0;i<p->nn+1;i++)

factor_umplere(p->fii[i]);

3. Să se scrie rutinele pentru: i) inserţia unui nod de tip PARCARE într-o listă înlănţuită de

parcări modelată prin nume; ii) inserţia unui nod de tip AUTOMOBIL modelat prin număr de

înmatriculare de forma AA-00-AAA (de exemplu TM-01-UPT) la un nod PARCARE creat

anterior şi identificat prin nume.

Rezolvare

typedef struct automobil

char numar[16];

struct automobil *urm;

AUTOMOBIL;

typedef struct parcare

char nume[16];

struct automobil *prim_a,*ultim_a;

struct parcare *urm;

PARCARE;

PARCARE *prim=0, *ultim=0;

void adaugare_parcare(char *nume)

PARCARE *p=0;

p=(PARCARE*)malloc(sizeof(PARCARE));

strcpy(p->nume,nume);

p->prim_a=0;

p->ultim_a=0;

p->urm=0;

if(prim==NULL)

21

prim=ultim=p;

else

ultim->urm=p;

ultim=p;

void adaugare_automobil(char *numar,char *nume)

PARCARE *p=0;

AUTOMOBIL *a=0;

for(p=prim;p;p=p->urm)

if(strcmp(p->nume,nume)==0)

break;

if(p)

a=(AUTOMOBIL*)malloc(sizeof(AUTOMOBIL));

strcpy(a->numar,numar);

a->urm=0;

if(p->prim_a==NULL)

p->prim_a=p->ultim_a=a;

else

p->ultim_a->urm=a;

p->ultim_a=a;

Fundamente de inginerie software

1. Pentru codul de mai jos desenati diagrama de secventa incepand cu apelul din linia marcata cu

*** si pana la revenirea din acel apel. Nota: Apelurile catre System.out se ignora. In plus, NU

trebuie trasate bare de activare si valori returnate interface DispozitivAlarma

public int start();

22

class Senzor

private DispozitivAlarma alarma;

public Senzor(DispozitivAlarma alarma) this.alarma = alarma;

private void declanseaza()

int i = alarma.start();

System.out.println("Informari:" + i);

public void alarmare() declanseaza();

class Simplu implements DispozitivAlarma

public int start()

System.out.println("Alarma!");

return 1;

class Lant implements DispozitivAlarma

private DispozitivAlarma next;

public Lant(DispozitivAlarma disp) this.next = disp;

public int start()

proceseaza();

return (1 + next.start());

public void proceseaza()

System.out.println("Alarma intermediara!");

class Test

public static void main(String argv[])

Simplu s = new Simplu();

Lant l1 = new Lant(s);

Lant l2 = new Lant(l1);

Lant l3 = new Lant(l2);

Senzor sen= new Senzor(l3);

/***/sen.alarmare();

RASPUNS: Solutia este data de diagrama de secventa de mai jos:

23

2. Sa se scrie o suita de teste white-box (glass-box) prin care sa se faca testarea cailor pentru

pseudo-codul de mai jos. Justificati alegerea facuta.

Nota: se puncteaza doar testcase-urile concrete justificate. Discutia abstracta, fara date de test

concrete nu se puncteaza.

Nota: nu se cere deloc implementare in jUnit / cppUnit! int error;

int max(int tab[], int entries)

if(entries <= 0)

error = 1;

return -1;

error = 0;

int max = tab[0];

for(int i = 1; i < entries; i++)

if(max < tab[i])

max = tab[i];

return max;

RASPUNS: Fiind vorba de testare whitebox, va trebui sa alegem datele de test astfel incat sa fie

exersate toate caile din functie. In plus, avand in vedere ca avem un ciclu (“for”) va trebui sa

alegem date de test astfel incat sa sa parcurga instructiunea “for” de zero, unu si respectiv mai

mult de o data (ex. de 2 ori).

Alegem astfel urmatoarele cazuri de test:

24

1. entries = 0 ; tab[] = - multimea vida - aceste test exerseaza cazul in care se intra in primul

“if”.

2. entries = 1 ; tab[] = 7 - acest test exerseaza cazul in care nu se intra in primul “if”, si

deasemenea nu se intra in “for”

3. entries = 2 ; tab[] = 3, 7 - testul exerseaza cazul in care ciclul “for” se executa o singura

data, si in care se intra in al doilea “if” (cel imbricat in “for”)

4. entries = 2 ; tab[] = -2, -5 - testul exerseaza cazul in care ciclul “for” se executa o singura

data, si in care NU se intra in al doilea “if” (cel imbricat in “for”).

5. entries = 3 ; tab[] = 0; -2; 5 - acest test vizeaza cazul in care ciclul “for” se executa de doua

ori.

3. Se da urmatorul document de specificare a cerintelor pentru un sistem de gestionare a unui

magazin: Cumparatorii vor avea acces on-line la sistem, pentru a consulta oferta de produse a magazinului. La cerere, un cumparator poate alege online un numar de produse si poate cere tiparirea descrierii acelor produse, incluzand si pretul fiecarui produs. Vanzatorii vor accesa sistemul pentru a realiza, daca este posibil, marcarea ca rezervata a unui anumit produs, pe o anumita cantitate specificata. In cazul efectuarii rezervarii, sistemul va calcula costul, pe baza unor tabele de tarife. Vanzatorul va confirma plata in avans, iar sistemul va tipari un bon. Cumparatorii, prin intermediul vanzatorilor, vor avea posibilitatea sa renunte total sau partial la o rezervare de produse, caz in care sistemul va trebui sa calculeze suma de rambursat. Gestionarea bazei de date cu informatii legate de produse si preturi va fi efectuata de catre un sef de raion. Informatiile despre produse vor putea fi modificate si de catre vanzatori. Toate operaţiile cu excepţia consultării ofertei de produse de către cumparator presupun o loginare prealabilă in sistem. Se cere:

a. Identificaţi toţi actorii şi use-case-urile (user stories) pentru sistemul descris mai sus. Justificaţi alegerea făcută!

b. Reprezentaţi actorii şi use-case-urile identificate în UML sub forma unei Use-Case Diagram

c. Daca dorim sa “dam factor comun” descrierea functionalitatii de loginare intre diferitele use-case-uri care o contin, cum se reprezenta acest lucru intr-o Use-Case Diagram?

RASPUNS:

a. Actorii si use-case-urile identificate sunt redate in diagrama de mai jos. Cei trei actori au

fost indentificati pe baza faptului ca (1) sunt exteriori sistemului si (2) introduc informatii

in sistem si/sau beneficiaza de use-case-urile sistemului. Cele 6 use-case-uri principale

(toate mai putin cel de loginare) au fost identificate pe baza faptului ca reprezinta acele

functionalitati majore ale sistemului care produc un beneficiu direct pentru (cel putin) un

actor.

b. A se vedea diagrama UML de Use Case desenata mai jos

25

c. Pentru a da “factor comun” functionalitatea de loginare se foloseste relatia “uses”,

reprezentata in UML printr-o sageata indreptata spre use-case-ul secundar (de tip “fish

level”) denumit “Loginare in Sistem”. Utlizarea relatiei este reprezentata in diagrama de

mai jos:

Solutie Alternativa

26

Fundamente de ingineria calculatoarelor

1. Se da urmatorul cod MIPS care operează pe întregi:

L: ADD R1, R2, R3

SUB R3, R1, R2

AND R2, R2, R5

SW 0(R2), R3

SW 16(R2), R1

XOR R9, R7, R2

BZ R1, L

Aratati, marcand fiecare artificiu utilizat, precum si fiecare stall, cum se executa codul in

pipeline-ul MIPS daca:

Beneficiem doar de artificiul cu tactul

Stagiul de MEM pentru instructiunile de tip Load/store se executa intr-o unitate distincta

(e diferit de MEM-ul corespunzator celorlate instructiuni) si dureaza 2 cc in loc de 1,

neparalelizabil (ca si la DIV). Notati aceste doua impulsuri cu MEM1, respectiv MEM2

Branch-ul este tratat in maniera freeze & flush si se decide in ciclul de EX

27

Soluţie:

Notaţii:

(s) – stall in acel stagiu

(t) – artificiul cu tactul utilizat

Punctaj

Ce se puncteaza Punctaj Unde se afla Cum e marcat Total

Artificiul cu tactul marcat

corect

2 puncte

/marcaj

cc5 si cc9 (t) 2x2=4 p

Stall 0.5

puncte/marcaj

corect

cc3, cc4, cc7,

cc8, cc12(toate

3), cc15 (toate

3)

(s) 6x0.5=3p

Tratare branch 2 puncte Ultimele 2 linii 1x2p=2p

Oficiu 1 punct 1p

Total= 10 p

2. Se dă următorul cod. Se consideră pipeline-ul MIPS standard, beneficiind de artificiul cu

tactul, forwarding şi bypassing. Unităţile de multiply au nevoie de 4 cc pt execuţia efectivă a

înmulţirii, în loc de 7(standard), iar cele de adunare de fp au nevoie doar de 2cc, în loc de 4

(standard). Branch-urile se tratează în maniera predict as taken.

XOR R3,R3,R3

foo L.D F6, 0(R1)

L.D F8, 0(R2)

MUL.D F10, F6, F8

ADD.D F4, F4, F10

ADDI R1, R1, #-8

ADDI R2, R2, #-8

ADDI R3, R3, #16

BZ R3, foo

Arătaţi cum se execută următorul cod în pipeline. Marcati toate artificiile folosite si stall-urile,

iar la branch precizați care este ramura folosită.

Soluţie:

28

Initial R3 =0 (din R3=R3 XOR R3), apoi R3=R3+16=0+16=16 => bucla se executa cat timp

R3=0, dar cum R3=16 => nu se sare niciodata=> se alege ramura de jos a branch-ului

Punctaj

Ce se puncteaza Punctaj Unde se afla Cum e marcat Total

artificiul cu tactul marcat

corect

2 puncte/marcaj cc6 (t) 1x2=2 p

Stall 0.5

puncte/marcaj

corect

cc5,

cc8(ambele),

cc9(ambele),

cc10(ambele),

cc13 (toate 3)

(s)/stall 5x0.5=2.5p

Tratare branch 2 puncte Ultimele 2 linii 1x2p=2p

Forwarding 0.5 puncte 6 ->7; 10->11,

15->16

sageata 3x0.5=1.5p

Selectare ramură corectă

branch

1 punct 1p

Oficiu 1 punct 1p

Total= 10 p

3. Se dă următorul cod. Se consideră pipeline-ul MIPS standard, beneficiind de artificiul cu

tactul, forwarding şi bypassing. Unităţile de multiply au nevoie de 4 cc pt execuţia efectivă a

înmulţirii, în loc de 7 (standard), iar cele de adunare de fp au nevoie doar de 3cc, în loc de 4

(standard). Branch-urile se tratează în maniera predict as taken.

SUB R3, R3, R3

foo ADDI R1, R1, #-8

L.D F8, 0(R2)

L.D F6, 0(R1)

ADD.D F10, F6, F8

ADDI R2, R2, #-8

MUL.D F4, F4, F10

ADDI R3, R3, #-1

BGEZ R3, foo

Arătaţi cum se execută următorul cod în pipeline. Marcati toate artificiile folosite si stall-

urile, iar la branch precizați care este ramura folosită.

29

Soluţie:

Initial R3 =0 (din R3=R3 - R3), apoi R3=R3+(-1)=0+(-1)=-1 => bucla se executa cat timp

R3>=0, dar cum R3=-1 => nu se sare niciodata => se alege ramura de jos a branch-ului

Punctaj

Ce se puncteaza Punctaj Unde se afla Cum e marcat Total

artificiul cu tactul marcat

corect

2 puncte/marcaj cc7 (t) 1x2=2 p

Stall 1 punct/marcaj

corect

cc5,

cc10(ambele)

(s)/stall 2x1=2p

Tratare branch 2 puncte Ultimele 2

linii

Stalll/stagiu, if 1x2p=2p

Forwarding 0.5 puncte 5 ->6; 7 ->8,

10->11, 12-

>13

sageata 4x0.5=2p

Selectare ramură corectă

branch

1 punct 1p

Oficiu 1 punct 1p

Total= 10 p

Sisteme de operare

1. Scrieti un program care rulează, una câte una, comenzile date ca şi argumente în linia de

comandă până când una din ele întoarce o valoare de ieşire diferită de zero.

Programul va fi scris în limbajul C, folosind apelurile sistem şi funcţiile din biblioteca standard

POSIX. Nu este necesar să includeţi fişiere antet.

Indicaţii:

pot fi utile:

int execl(char *file, const char *arg0, ... );

//idem execlp

pid_t fork(void);

pid_t wait (int *status);

30

Răspuns: #include <string.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/stat.h>

#include <sys/wait.h>

#define err_sys(expr,cmp) do\

if ((expr) cmp) \

perror("eroare");\

exit(EXIT_FAILURE);\

while(0);

#define err_neg(expr) err_sys(expr, < 0)

#define err_null(expr) err_sys(expr, == NULL)

int executa(char *cmd)

pid_t pid;

int status;

err_neg( pid = fork() );

if (pid == 0)

execlp(cmd,cmd,NULL);

exit(0);

err_neg( wait(&status) );

return WIFEXITED(status) && (WEXITSTATUS(status) == 0);

int main(int argc, char *argv[])

int i;

for (i=1; i<argc; i++)

if (!executa(argv[i]))

break;

exit(EXIT_SUCCESS);

2. Scrieţi un program care execută două comenzi primite ca şi argumente în linia de comandă

astfel încât ieşirea standard a primei comenzi să ajungă să fie citită la intrarea standard a celei de-

a doua.

De exemplu: ./program ls sort

va rula comenzile ls si sort similar cu linia de comanda shell: ls | sort

Programul va fi scris în limbajul C, folosind apelurile sistem şi funcţiile din biblioteca standard

POSIX. Nu este necesar să includeţi fişiere antet.

Indicaţii:

pot fi utile: int execl(char *file, const char *arg0, ... );

31

//idem execlp

int dup2(int old, int new);

int pipe(int fildes[2]);

pid_t fork(void);

pid_t wait (int *status);

Răspuns: #include <string.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/wait.h>

#define err_sys(expr,cmp) do\

if ((expr) cmp) \

perror("eroare");\

exit(EXIT_FAILURE);\

while(0);

#define err_neg(expr) err_sys(expr, < 0)

#define err_null(expr) err_sys(expr, == NULL)

int main(int argc, char *argv[])

int pipe1[2];

int pid1, pid2;

if (argc != 4)

exit(EXIT_FAILURE);

err_neg( pipe(pipe1) );

pid1 = fork();

err_neg(pid1);

if (pid1 == 0)

close(pipe1[0]);

dup2(pipe1[1], STDOUT_FILENO);

execlp(argv[1], argv[1], NULL);

exit(EXIT_FAILURE);

close(pipe1[1]);

pid2 = fork();

err_neg(pid2);

if (pid2 == 0)

dup2(pipe1[0], STDIN_FILENO);

execlp(argv[2], argv[2], NULL);

exit(EXIT_FAILURE);

close(pipe1[0]);

wait(NULL);

wait(NULL);

exit(EXIT_SUCCESS);

3. Să se scrie un program format din două procese, cu comportamentul descris în continuare.

Aproximativ o dată la secundă, primul proces îl informează pe al doilea de scurgerea acestui

interval de timp. Al doilea proces numără continuu începând de la 1, iar când se adună un număr

de 7 notificări de la primul proces, afişează numărul curent şi se termină.

32

Programul va fi scris în limbajul C, folosind apelurile sistem şi funcţiile din biblioteca standard

POSIX. Nu este necesar să includeţi fişiere antet.

Indicatie:

semnalele utilizator sunt SIGUSR1 si SIGUSR2;

pot fi utile: typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

pid_t fork(void);

pid_t wait(int *status);

int kill(pid_t pid, int sig);

unsigned int sleep(unsigned int seconds);

Răspuns #include <stdio.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <signal.h>

#include <unistd.h>

#include <stdlib.h>

int count=0;

long num;

void cntev(int sig)

count++;

printf(" %d",count); fflush(stdout);

if(count==7)

printf(".\nThe number: %ld.\n", num);

exit(0);

int main()

long i;

int pid, status;

if((pid=fork())<0)

perror("fork_err");

exit(67);

if(pid==0)

signal(SIGUSR1,cntev);

printf("Notification:");

fflush(stdout);

for(num=0;;num++);

33

for(i=0;i<=15;i++)

sleep(1);

kill(pid, SIGUSR1);

wait(&status);

printf("Parent ends.\n");

return 0;

Bazele inteligenţei artificiale

1. Se cere

Descrieţi succint tehnica căutării în adâncime într-un graf definit printr-un obiect compus

de forma:

Arce is [m(a,b), m(b,d), m(a,c), m(b,e),... ]

Reprezentaţi graphic procedura de căutare în adâncime într-un graf.

Scrieti utilizând limbajul Prolog procedura de căutare în adâncime într-un graf.

Răspuns

Desenul sugerează următoarea procedură recursivă de căutare a unui drum : găsesc drumul de la

Y la Z şi găsesc un drum de la A la X, care continuă cu drumul parţial astfel încât nodul X

(extremitatea muchiei ce conţine pe y) să nu fie prezent în drumul parţial.

drum( A, z, G, Drum ) if

drum_partial( A, [z ], G, Drum ).

drum_partial( A, [ A | Rest_drum ], _, [ A | Rest_drum ] ).

drum_partial( A, [ Y | Rest_drum ], G, Drum) if

adiacent( X, Y, G ),

not( aparţine( X, Rest_drum ) ),

drum_partial( A, [ X, Y | Rest_drum ], G, Drum ).

34

adiacent( X, Y, g( _, Arce ) ) if

aparţine( m( X, Y ), Arce );

aparţine( m( Y, X ), Arce).

Comentarii :

1. not( aparţine( ... ) ) implementează un mecanism de detecţie a unui ciclu în cadrul unui drum

parţial.

2. Predicatul adiacent furnizează ca rezultat un nod ce defineşte extremitatea muchiei căutate.

Deoarece în definirea grafului nu se impune o restricţie privind ordinea de scriere a nodurilor,

devine necesară prezenţa dublei verificări de apartenenţă ( determininată de prezenţa unei

simetrii în scrierea unuei muchii, o muchie poate apare de forma m(a,b) sau m(b,a)).

2. Se cere

Descrieţi succint tehnica căutării în adâncime într-un graf definit printr-un set de axiome

de forma:

s(a,b). s(b,d). s(a,c). s(b,e)....

atunci când adâncimea de căutare este limitată

Reprezentaţi graphic procedura de căutare în adâncime într-un graf când adâncimea de

căutare este limitată

Scrieti utilizând limbajul Prolog procedura de căutare în adâncime într-un graf când

adâncimea de căutare este limitată

Răspuns

Desenul sugerează următoarea procedură recursivă de căutare a unui drum : găsesc drumul de la

Y la Z şi găsesc un drum de la A la X, care continuă cu drumul parţial astfel încât nodul X

(extremitatea muchiei ce conţine pe y) să nu fie prezent în drumul parţial.

Spre deosebire de cazul în care nu se pune problema găsirii unui cost, simultan cu construcţia

drumului parţial se va calcula şi costul acestuia, definit de suma costurilor muchiilor din drum. In

descrierea muchiei este inclus costul acesteia sub forma : s( nod1, nod2, cost ).

Pentru exemplul dat, tehnica cautarii in adancime cu limitarea adancimii de cautare apare de

forma:

rezolva(Start, Solutie) if

caut_a([ ], Start, Solutie, Adancime_max).

caut_a(Drum, Nod, [Nod|Drum] ) if

apartine(Nod,Tinte).

caut_a(Drum,Nod,Sol,Max)if

Max>0,

s(Nod, Nod1),

not(apartine(Nod1,Drum)),

Max1=Max-1,

caut_a([Nod|Drum], Nod1, Sol, Max1).

3. Se cere

Descrieţi succint tehnica căutării în lătime într-un graf definit printr-un set de axiome de

forma:

s(a,b). s(b,d). s(a,c). s(b,e)....

Reprezentaţi graphic procedura de căutare în lăţime într-un graf.

Scrieti utilizând limbajul Prolog procedura de căutare în lăţime într-un graf.

35

Răspuns

Căutarea în lăţime

Tehnica de căutare asigură parcurgerea acelor noduri care sunt mai apropiate de nodul de start.

Ca urmare rezultă un proces ce tinde să se dezvolte în laţimea spaţiului alternativelor posibile, (v.

figura de mai jos). Apelul in acest caz este de forma:

?-rezolvă(a,Sol).

Sol=[a, c, f]

Strategia ridică problema menţinerii în atenţie a unui set de noduri ( si nu a unuia singur ca in

cazul cautarii in adancime) care reprezintă vârfurile arborelui la care s-a ajuns cu operaţia de

căutare la un moment dat. Acest set de noduri nu este suficient, motiv pentru care se menţine în

atenţie un set de drumuri posibile. Acestea drumuri posibile, sunt reprezentate fiecare printr-o

listă de noduri, al căror prim element va fi intotdeauna nodul cel mai recent generat, iar ultimul

element va fi intotdeauna nodul de strat. La un moment dat, căutarea este iniţiată de un singur

drum şi respectiv de un singur element de forma [ [Nod_Start ] ], care este dezvoltat in unul sau

mai multe drumuri din care la un moment dat se selecteaza drumul solutie.

Pentru a exemplifica procedeul, pentru exemplul dat în figură avem:

1) primul drum conţine nodul de start de la care se iniţiază procesul de căutare:

[ [ a ] ]

2) se generează o extensie a nodului de start rezultand

[ [b, a], [c, a] ]

3) se scoate primul drum din set şi se generează o extensie a acestuia rezultand

[ [d, b, a] , [e , h, a] ].

Drumurile noi rezultate se amplasează la sfarsitul drumului iniţial sub forma:

[ [c, a], [d, b, a], [e ,h, a] ]

4) Se scoate [c, a] si extensiile care apar se adauga la drum

[ [d, b, a], [e, b, a], [f, c, a], [g, c, a ] ]

5) operaţia continuă până în momentul în care drumul ce urmează a fi extins prezintă ca nod de

creştere nodul ţintă. Pentru exemplul dat, situaţia apare sub forma:

[ [f, c, a], [g, c, a], [h, d, b, a], [i, e, b, a], [j, e, b, a] ]

Cu observatia ca Soluţie reprezintă un drum ce pleacă din start şi ajunge în ţintă şi Drum este o

36

lista a drumurilor ce se dezvolta pe parcurs strategia de cautare prezinta aspectul.

rezolvă (Start, Solutie) if

caut_l([ [Start] ], Solutie).

caut_l ([ [Nod|Drum]| _ ], [Nod|Drum]) if

apartine(Nod,Tinte).

caut_l ([ [Nod|Drum]| Drumuri], Solutie) if

findall (Nod1,s(Nod,Nod1), Noi_noduri),

adaug ([Nod|Drum], Noi_noduri, Noi_drumuri),!,

conc (Drumuri, Noi_drumuri, Drumuri1),

caut_l (Drumuri1,Sol) ;

caut_l (Drumuri,Sol).

adaug ( _, [ ], [ ]).

adaug (Drum, [Nod1|Rest], [ [Nod1|Drum] | Drumuri_noi]) if

not(apartine(Nod1,Drum)),

adaug(Drum,Rest,Drumuri_noi).

%conc implementeaza procedura de concatenare

Comentarii

1) Prin findall se generează toţi succesorii(alternative) posibili ai unui nod dat. Acestea sunt

incluse intr-o listă de noi alternative.

2) adaug utilizează noile alternative pentru a crea noi drumuri posibile plecând de la drumul care

a iniţiat construirea alternativelor not(apartine) verifică dacă nu există alternative identice, caz în

care se renunţă la direcţia de dezvoltare în cauză (drum este o variantă moartă, care se

abandonează).

3) conc pune noile drumuri găsite la sfârşitul listei iniţiale.

4) deoarece este posibil ca prin findall să nu se determine nici o alternativă posibilă (nu mai

există succesori), operaţia de căutare va continua pe lista iniţială, minus drumul abandonat.

Dezavantaj : cantitatea mare de memorie.

Avantaj : soluţie optimă

5) aceeaşi problemă se poate pune şi pentru căutarea în lăţime, referitoare la limitarea adâncimii

de căutare.

Sisteme încorporate

1. Prezentaţi soluţia pentru conectarea unui circuit de memorie externă de 64 KO la un

microcontroler care nu are magistrale externe.

Răspuns:

Circuitul de memorie se va lega la microcontroler prin intermediul liniilor de port. Toate

transferurile între microcontroler şi circuitul de memorie, precum şi tranziţiile semnalelor de

comandă se vor realiza prin program. Dezavantajele soluţiei:

a. nu se poate aplica la memorie de program, întrucît microcontrolerul nu dispune de resursele

interne necesare pentru a prelua şi interpreta cod de instrucţiune;

b. soluţia este lentă, întrucît toate tranziţiile semnalelor de comandă se fac prin program.

37

2. Desenaţi schema pentru comanda a 8 LED-uri şi citirea a 8 semnale externe de către un

microcontroler 8051.

Răspuns:

Există 2 soluţii:

a. conectarea în spaţiul de I/E, utilizînd liniile de port;

b. conectarea în spaţiul de memorie, utilizînd magistralele de adrese/date.

Schema în cazul a. este:

38

3. Prezentaţi soluţia pentru conectarea unui circuit de memorie de 64 KO ca memorie externă de

program şi a unui alt circuit de 64 KO ca memorie externă de date.

Răspuns:

Soluţia se bazează pe caracteristica microcontrolerului 8051, valabilă la multe alte

microcontrolere, de a activa semnale de comanda diferite pentru accesul la memoria de program

şi la cea de date. Ca atare, utilizînd 16 linii de adrese se vor putea gestiona 64 KO memorie de

program şi 64 KO memorie de date. Semnalul de comandă /PSEN va fi folosit pentru comanda

memoriei externe de cod şi semnalele de comandă /RD şi /WR se vor folosi pentru comanda

memoriei externe de date. Întrucît circuitele de memorie, atît pentru memoria de program cît şi

pentru cea de date, acoperă în întregime spaţiul de memorie externă a microcontrolerului, nu este

necesar decodificator de memorii.

39

P0.0-7

/EA

ALE

P2.0-7

/PSEN

/RD

/WR

8

0

C

5

1

D0-7

A0-7

A8-15

/OE

/CE

Memoria

de

program

externă

(64 ko)

R

E

G

STB

D0-7

A0-7

A8-15

/CS

/WE

/OE

Memoria

de

date

externă

(64 ko)

Baze de date

Nota: Pentru rezolvarea problemelor propuse se poate folosi şi limbajul SQL sau PL/SQL, dar cu

definirea cheilor primare şi externe.

1. Se consideră două fişiere dintr-o bază de date existentă pentru rezervare locuri la avion.

Fişierul Curse conţine datele pentru fiecare cursă din orarul de zbor.

Fişierul Pasageri conţine datele pentru toţi pasagerii din toate cursele. Toţi pasagerii unei curse

vor avea acelaşi cod cursă CodC.

Curse

CodC Pilot Copilot Avion Oras1 Ora1 Oras2 Ora2 PretR NrLoc

Pasageri

CodC CNP NumeP Adresa DataN Tel Pret

40

Să se afişeze informaţiile despre o cursă de avion şi lista pasagerilor din acea cursă folosind

comenzi simpe din limbajul XBase. Se recomandă forma de afişare:

CodC Oras1 Ora1 Oras2 Ora2 Pilot Copilot TipAv

Ro234-

0609

Timisoara

TSR

8:30 Bucuresti 9:30 Popescu Adam B747

Lista Pasageri

CNP Nume Pas Adresa Telefon DataN Pret

SET TALK OFF

CLEAR

USE Curse INDEX Icodc IN 1 ALIAS CS

USE Pasageri INDEX Icodc, Inume IN 2 ALIAS PS

SET RELATION TO Codc INTO PS

ACCEPT ‟Cod cursa: ‟ TO Vcodc

SEEK VCodc

? ‟CodC Pilot Copilot Avion Oras1 Ora1 Oras2 Ora2 „

? REPL(„=‟,120)

? Codc, Pilot, Copilot, Avion, Oras1, Ora1, Oras2, Ora2

?

? „ LISTA PASAGERI „

?

SELECT PS

? „CNP Nume Pasager Adresa Tel DataN Pret „

? „ REPL(„-‟,120)

DO WHILE Codc=Vcodc

? CNP, NumeP, Adresa, Tel, DataN, Pret

SKIP

ENDDO

2. Considerăm o bază de date normalizată pentru evidenţă studenţi care cuprinde tabelele:

STUD

CodS Nume Adresa DataN Bursa Telefon CNP ......

NOTE

CodS CodC NOTA Data

CURS

CodC Titlu NumeProf

41

Folosind comenzi simple Xbase se cere afişarea notelor unui student dat prin nume sub forma:

CODS: AC321 Nume: Popescu Bogdan Adresa: Bogdanesi 3 Bursa:150

Situatia notelor

Curs Nota Data Nume prof

Sisteme de operare 9 23-01-2011 Popovici

.....................................

USE Stud INDEX Inume, Icods IN 1 ALIAS ST

USE Note INDEX Icodsn IN 2 ALIAS NT

USE CURS INDEX Icodc IN 3 ALIAS CS

SET RELATION Cods INTO Note

Select 2

SET RELATION Codc INTO Curs

Select 1

ACCEPT „ Nume Student: „ TO Vnume

SEEK Vnume

IF EOF()

? „Studentul „ + Vnume + „ Nu exista‟

ELSE

? „Cods: „ + Cods, „ Nume: „+ Nume, „ Adresa: „+ Adresa, „ Bursa: „,Bursa

?

? „ Situatia notelor „

?

? „ Curs Nota Data Nume Prof „

? „ ------------------------------------------------------------------------------------ „

Select 2

DO WHILE Cods=Vcods

? CS-->Titlu, Nota, Data, CS-->NumeProf

SKIP

ENDDO

ENDIF

3. Considerăm o bază de date normalizată pentru evidenţă studenţi care cuprinde tabelele:

STUD

CodS Nume Adresa DataN Bursa Telefon CNP ......

NOTE

CodS CodC NOTA Data

CURS

CodC Titlu NumeProf

Folosind comenzile XBase elementare pentru dialog şi SQL pentru căutarea informaţiilor, să se

scrie secvenţe de program care realizează funcţiile:

42

Afişare Cods, Nume student, Bursa, pentru toţi studenţii care au medii mai mari decât o

valoare N

Afişare pentru un student dat prin Cods toate notele, Titlul cursului pentru fiecare notă şi

Nume profesor.

Se va ţine cont că rezultatul unei comenzi SQL se obţine într-o zona de lucru din care se poate

afişa direct folosind comanda BROWSE, iar variabilele citite sunt externe precedate de “:”.

ACCEPT „ Media minima: „ TO N

SELECT ST.Cods,ST.Nume, AVG(NT.Nota) Media FROM Stud ST, Note NT

WHERE ST.Cods=NT.Cods GROUP BY ST.Cods,ST.Nume,ST.Bursa,

HAVING AVG(NT.Nota)>:N

Browse && - afisare rezultat

Wait

ACCEPT „ Dati Cod student‟ TO Vcods

SELECT ST.Cods, ST.Nume,NT.Nota,CS.Titlu,CS.NumeP Profesor

FROM Stud ST, Note NT, Curs CS

WHERE ST.Cods=:Vcods AND ST.Cods=NT.Cods AND NT.Codc=CS.CODC

BROWSE

Wait