Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni...

26
Debugging di Astrazioni

Transcript of Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni...

Page 1: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Debugging di Astrazioni

Page 2: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Astrazionisuidati:specifica

• Ingredientitipicidiunaastrazionesuidati• Uninsiemediastrazioniproceduralichedefinisconotuttii

modiperutilizzareuninsiemedivalorio Creareo Manipolareo Osservare

• Creatorieproduttori:meccanismiprimitiviattiallaprogrammazionedelladefinizionedinuovivalori

• Mutator:modificanoilvalore(manonhannoeffettosu==,nonoperanopereffettilaterali)

• Osservatori:strumentolinguisticoperselezionarevalori

2

Page 3: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

ADT: specifica

• Specifica ADT: guida all’implementazione

• Ovviamente ADT devono poi essere implementati

• Si deve garantire che la realizzazione soddisfa la specifica

• Due strumenti essenziali – Invariante di rappresentazione – Funzione di astrazione

3

Page 4: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Implementazionevs.Specifica

RepresentationInvariant:Object→booleano Stabilisceseunaistanzaèbenformatao Stabiliscel’insiemeconcretodeivaloridell’astrazione(ovveroquelliche

sonounaimplementazionedeivaloriastratti)o Guidaperchiimplementa/modifica/verifical’implementazionedelle

astrazioni:nessunoggettodeveviolarerepinvariantAbstractionFunction:Object→abstractvalue

o Stabiliscecomeinterpretarelastrutturadaticoncretadellaimplementazione

o Èdefinitasolamentesuivaloricherispettanol’invariantedirappresentazione

o Guidaperchiimplementa/modifical’astrazione:ognioperazionedevefare“lacosagiusta”conlarappresentazioneconcreta

4

Page 5: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

5

Page 6: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Esempio:CharSet

// Overview: CharSet insieme finito modificabile di // Characters

// @effects: crea un CharSet nuovo e vuoto public CharSet( ) {...}

// @modifies: this // @effects: thispost = thispre U {c} public void insert(Character c) {...}

// @modifies: this // @effects: thispost = thispre \ {c} public void delete(Character c) {...}

// @effects: return (c ∈ this) public boolean member(Character c) {...}

// @effects: return cardinalita’ di this public int size( ) {...}

6

Page 7: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

CharSet:implementazione?

class CharSet { private ArrayList<Character> elts =

new ArrayList<Character>( ); public void insert(Character c) { if (elts.add(c)){return;} } public void delete(Character c) { int i = elts.indexOf(c); if (i > -1) elts.remove(i); } public boolean member(Character c) { return elts.contains(c); } public int size( ) { return elts.size( ); } }

7

Page 8: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

CharSet:implementazione?

class CharSet { private List<Character> elts =

new ArrayList<Character>( ); public void insert(Character c) { if (elts.add(c)){return;} } public void delete(Character c) { int i = elts.indexOf(c); if (i > -1) elst.remove(i); } public boolean member(Character c) { return elts.contains(c); } public int size( ) { return elts.size( ); } }

8

Dove è nascosto l’errore?

Page 9: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

class CharSet { private List<Character> elts =

new ArrayList<Character>( );

public void insert(Character c) { if (elts.add(c)){return;} } public void delete(Character c) { int i = elts.indexOf(c); if (i > -1) elst.remove(i); } public boolean member(Character c) { return elts.contains(c); } public int size( ) { return elts.size( ); } }

9

CharSet s = new CharSet( ); Character a = new Character('a'); s.insert(a); s.insert(a); s.delete(a); if (s.member(a)) System.out.print("wrong"); else System.out.print("right");

CharSet:implementazione?

Page 10: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Cerchiamol’errore

• Primotentativo:deleteèsbagliatao controllal’appartenenzamarimuovetutteleoccorrenze?

• Secondotentativo:insertèsbagliatao nondovrebbeinserireuncaratterequandoègiàpresente

• Comeoperiamo?o utilizziamorepresentationinvariantpermuovercieeliminarel’erroreo ilcodicebendocumentatoeglistrumentidispecificaformaleci

aiutanonell’operazionediindividuazioneerimozionedell’errore

10

Page 11: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Invariantedirappresentazione

• class CharSet { // Rep invariant: // elts non contiene elementi null e non // contiene duplicati private List<Character> elts = ...

...

Possiamoscriverloancheformalmente(conglistrumentidiLPP): ∀ indice i di elts . elts.elementAt(i) ≠ null

∀ indice i, j di elts .

i ≠ j ⇒ ¬ elts.elementAt(i).equals(elts.elementAt(j))

11

Page 12: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Oralocalizziamol’errore

// Rep invariant: // elts: no null e no duplicati

public void insert(Character c) { if (elts.add(c)){return;} }

public void delete(Character c) { int i = elts.indexOf(c); if (i > -1) elst.remove(c); }

12

Page 13: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Comesifaildebugging

L’ideacheintendiamoperseguireèlaseguente:

Progettatedelcodiceinmodotalechetutteleoperazionidi“bug-checking”sianoimplementateutilizzandocomeguidal’invariante

dirappresentazione

13

Page 14: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Verificadelrepinvariant

Ideaderivatadalletecnichediprova:controllareingressoeuscitadaimetodi

public void delete(Character c) { checkRep( ); int i = elts.indexOf(c); if (i > -1) elst.remove(c);

// Come garantire che venga sempre invocata? // (usiamo un blocco finally) checkRep( ); } ... /** elts no duplicati. */ private void checkRep( ) { ... }

14

Page 15: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

defensiveprogramming

• Assunzione:programmareèunprocessoditipo“trialanderror”• Progettaredelcodiceinmodotaleche

o allachiamatadeimetodi✓ verificarepinvariant✓ verificapre-condizioni

o all’uscitadelmetodo✓ verificarepinvariant✓ verificapost-condizioni

• Verificarerepinvariant=verificarelapresenzadierrori

• Ragionaresulrepinvariant=evitaredifareerrori

15

Page 16: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

SempreCharSet

AggiungiamounmetodoaCharSet

// restituisce una lista degli elementi che // appartengono a this.

Implementazione

// Rep invariant: elts no null e no dupl. public List<Character> getElts () { return elts; }

16

L’implementazionedigetElts preservarepinvariant? Mah?!….

Page 17: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Esporrelarappresentazione

Consideriamouncliente(semprediCharSet)CharSet s = new CharSet( ); Character a = new Character('a'); s.insert(a); s.getElts( ).add(a); // usiamo add in modo liberale s.delete(a); if (s.member(a)) ...

•Abbiamounaesposizionedellarappresentazioneconunaccessoindiretto(tramiteilmetodogetElts)

•Problema:bugdaevitare(vedremogliiteratoriinseguito)o progettarel’astrazioneinmododaevitarequestoproblemao progettaredeitestconclienti“malevoli”:usarevalorimutabilipercapire

cosaavvieneneldettaglio

17

Page 18: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

private … non basta

• L’uso di private potrebbe non bastare

– Aspetto chiave: aliasing di struttura mutabili all’interno e all’esterno della astrazione

18

Page 19: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Comesievita?

• Perevitarel’esposizionedellarappresentazioneunaprimatecnicaèquelladifarecopiedeidaticheoltrepassanolabarrieradell’astrazioneo copiain[parametrichediventanovaloridellarappresentazione]o copiaout[risultatichesonopartedell’implementazione]

• Esempio:PointADTmodificabile

19

class Line { private Point s, e; public Line(Point s, Point e) { this.s = new Point(s.x,s.y); this.e = new Point(e.x,e.y); } public Point getStart( ) { return new Point (this.s.x,this.s.y); } ... }

Page 20: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

deepcopying

• Una copia shallow (operazioni sui puntatori) non è sufficiente a causa dell’aliasing !!!

• Analizzare questo codice class PointSet { private List<Point> points = ... public List<Point> getElts( ) { return new ArrayList<Point>(points); } }

20

Page 21: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Unasecondasoluzione

• Usarestrutturedatinonmodificabili

• Esempio:Point(nonmodificabile) class Line { private Point s, e; public Line(Point s, Point e) { this.s = s; this.e = e; } public Point getStart( ) { return this.s; } ...

21

Page 22: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Strutturenonmodificabili

• Vantaggio l’aliasingnonèunproblemao nonènecessariofarecopieo repinvariantnonpuòessere“rotto”

• Richiedetuttaviasceltediprogrammazionedifferentivoid raiseLine(double deltaY) { this.s = new Point(s.x, s.y+deltaY); this.e = new Point(e.x, e.y+deltaY); }

• Classiimmutabilinellalibreria:String,Character,Integer,...

22

Page 23: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

AncorailcasogetElts

class CharSet { // rep invariant: elts: no null e no dupl. private List<Character> elts = ...

// returns: elts nell’insieme corrente public List<Character> getElts( ) { return new ArrayList<Character>(elts); //copy out } ... }

23

Page 24: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Alternative

// returns: ... public List<Character> getElts( ) { // versione 1 return new ArrayList<Character>(elts); //copy out! }

public List<Character> getElts( ) { // versione 2 return Collections.unmodifiableList<Character>(elts); }

JavaDoc:Collections.unmodifiableList:Returnsanunmodifiableviewofthespecifiedlist.Thismethodallowsmodulestoprovideuserswith"read-only"accesstointernallists.Queryoperationsonthereturnedlist"readthrough"tothespecifiedlist,andattemptstomodifythereturnedlist…resultinanUnsupportedOperationException.

24

Page 25: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Esempio:AFperStack

25

new() 0 0 0

push(17) 17 0 0

Top=1

push(-9) 17 -9 0

Top=2

Top=0

stack=<>

stack=<17>

stack=<17,-9>

pop() 17 -9 0

stack=<17>Top=1

Statiastratti stack=<17>=<17>

Staticoncreti

<[17,0,0], top=1> ≠

<[17,-9,0], top=1>

AFèunafunzioneL’inversodiAFnonloè

Page 26: Debugging di Astrazionipages.di.unipi.it/levi/PR2-19-10.pdf · Debugging di Astrazioni. Astrazioni sui dati: specifica • Ingredienti tipici di una astrazione sui dati • Un insieme

Riassuntofinale

Repinvarianto Qualisonoivaloriconcreticherappresentanovaloriastratti

Abstractionfunctiono Perognivaloreconcretorestituisceilcorrispondentevaloreastratto

Obiettivocomune:sonoentrambeindispensabilipercontrollarelacorrettezzadell’astrazione

Disolito,ladocumentazionefavederesolamenteilrepinvariant

26