170 likes | 251 Views
Opsamling. Loops Klassedesign Immutable Lister shallowCopy() Projekt 2. Loops:. Heltalsdivision Øvelse 3. {Q} S 0 do {P} B S od {R}. Vi står med Q og R, og skal skrive en løkke: Vi skal udvikle: invarianten P vagten B “programmerne” S 0 og S Beviset er vores guide:
E N D
Opsamling Loops Klassedesign Immutable Lister shallowCopy() Projekt 2 KbP/seminar3: Opsamling
Loops: • Heltalsdivision • Øvelse 3 {Q} S0 do {P} BS od {R} Vi står med Q og R, og skal skrive en løkke: Vi skal udvikle: • invarianten P • vagten B • “programmerne” S0 og S Beviset er vores guide: Checklisten giver os: • Find P og B ud fra: P B R • Find initiering, så P etableres ({Q} S0 {P}) • Find et termineringsudtryk og sætninger, så der tages skridt mod terminering. • Hermed brydes invarianten måske, i så fald findes sætninger som genetablerer invarianten: {P B} S {P} Checklisten: 1. {Q} S0{P} (initiering) 2. {P B} S {P} (bevarelse af invariant) 3. terminering af løkken (t: nedadtil begrænset - termineringsfunktion) 4. P B R (korrekthed) KbP/seminar3: Opsamling
De seks principper: Programmér mod et interface Kun de basale forespørgsler er afhængige af datarepræsentationen • Adskil forespørgsler og kommandoer • Adskil basale forespørgsler fra afledte • Specificer postbetingelser for de afledte forespørgsler vha. de basale • Specificer kommandoers postbetingelser gennem deres effekt på de basale forespørgsler • Specificer prebetingelser på alle operationer • Specificer invariante egenskaber i en klasseinvariant Konstruktører skal etablere klasseinvarianten Implementerende klasser skal specificere en repræsentationsinvariant KbP/seminar3: Opsamling
Immutable lister Grundlæggende forespørgsler public interface ImmutableList { // Basic queries public boolean isEmpty(); public Object head(); public ImmutableList tail(); // Derived queries public int size(); public ImmutableList precededBy(Object o); public boolean equals(ImmutableList l); public Object item(int i); public ImmutableList sublist(int from, int to); } Opbygger listen ved at elementer ind foran den eksisterende (evt. tomme) liste KbP/seminar3: Opsamling
public interface ImmutableList { // Basic queries public /*@ pure @*/ boolean isEmpty(); /*@ requires !isEmpty(); @*/ public /*@ pure @*/ Object head(); /*@ requires !isEmpty(); @*/ public /*@ pure @*/ ImmutableList tail(); // Derived queries /*@ ensures isEmpty() ==> (\result==0); @ ensures (!isEmpty()) ==> (\result == 1+tail().size()); @*/ public /*@ pure @*/ int size(); Specifikationen A= (a, b, c, d) A.head() = a A.tail() = (b, c, d) Bemærk, rekursion KbP/seminar3: Opsamling
/*@ ensures !(\result).isEmpty(); @ ensures (\result).tail() == this; @ ensures (\result).head() == o; @*/ public /*@ pure @*/ ImmutableList precededBy(Object o); /*@ requires l != null; @ ensures (l.isEmpty() != isEmpty()) ==> !(\result); @ ensures (!isEmpty()) ==> (\result == (l.head()==head() && @ l.tail().equals(tail()))); @*/ public /*@ pure @*/ boolean equals(ImmutableList l); /*@ requires 0<=i && i<size(); @ ensures (i==0) ==> (\result==head()); @ ensures (i>0) ==> (\result==tail().item(i-1)); @*/ public /*@ pure @*/ Object item(int i); /*@ requires 0<=from && from<=to && to<=size(); @ ensures (\result).isEmpty()==(to==from); @ ensures (from!=to) ==> ((\result).head()==item(from)); @ ensures (from!=to) ==> ((\result).tail().equals(sublist(from+1,to))); @*/ public /*@ pure @*/ ImmutableList sublist(int from, int to); A= () A.precededBy(a) = (a) A.precededBy(b) = (b, a) … Bemærk, rekursion Bemærk, rekursion Bemærk, rekursion KbP/seminar3: Opsamling
public interface Queue2 { /*@ invariant size()>=0; @*/ // Basic queries public ImmutableList items(); // Derived queries /*@ ensures \result == items().size(); @*/ public /*@ pure @*/ int size(); /*@ ensures \result==items().isEmpty(); @*/ public /*@ pure @*/ boolean isEmpty(); /*@ requires size()>0; @ ensures \result==items().head(); @*/ public /*@ pure @*/ Object head(); Brug af immutable listeri specifikation: Queue items() anvendes ved specifikation af de øvrige operationer Burde være ”pure”, men det acceptere JML ikke umiddelbart Returnerer en liste med køens elementer KbP/seminar3: Opsamling
// Commands /*@ ensures size()==\old(size())+1; @ ensures items().item(size()-1)==o; @*/ public void put(Object o); /*@ requires size()>0; @ ensures size()==\old(size())-1; @ ensures \old(items()).tail().equals(items()); @*/ public void remove(); } Operationer på ImmutableList anvendes KbP/seminar3: Opsamling
Specifikation af shallowCopy() /*@ ensures \result.size()==size(); @ ensures (\forall int i; 0<=i && i<=size()-1; @ (\result.get(i)==get(i))); @*/ public Queue shallowCopy(); Bemærk, ’==’ Dvs. samme objektreference skal returneres af kopien som af originalen KbP/seminar3: Opsamling
Deque public interface Deque { public void insertFirst(Object e); public void insertLast(Object e); public Object removeFirst(); public Object removeLast(); public boolean isEmpty(); } KbP/seminar3: Opsamling
Princip 1 og 2: • Adskil forespørgsler og kommandoer • Adskil basale forespørgsler fra afledte • removeFirst() og removeLast() returnerer ikke noget. • Forespørgsler first() og last() er tilføjet. • get(-) og shallowCopy() af hensyn til specifikation. public interface Deque { // Basic queries int size(); Object get(int i); // Derived queries Deque shallowCopy(); Object first(); Object last(); boolean isEmpty(); // Commands void insertFirst(Object e); void removeFirst(); void insertLast(Object e); void removeLast(); } KbP/seminar3: Opsamling
Princip 3: • Specificer postbetingelser for de afledte forespørgsler vha. de basale public interface Deque { // Basic queries int size(); Object get(int i); // Derived queries //post uændret størrelse //post return skal være lig this Deque shallowCopy(); //post return skal være første element Object first(); //post return skal være sidste element Object last(); //post return skal være sand for size()==0 boolean isEmpty(); } KbP/seminar3: Opsamling
Princip 4: Specificer kommandoers postbetingelser gennem deres effekt på de basale forespørgsler public interface Deque { // Basic queries int size(); Object get(int i); // Commands //post size() er blevet 1 større //post e er indsat først //post resten af køen er rykket 1 plads bagud void insertFirst(Object e); void removeFirst(); void insertLast(Object e); void removeLast(); } KbP/seminar3: Opsamling
Princip 5 og 6: Specificer prebetingelser på alle operationer Specificer invariante egenskaber i en klasseinvariant //invariant size()>=0 public interface Deque { //pre size større end 0 Object first(); //pre size større end 0 Object last(); // Commands //pre size større end 0 void removeFirst(); //pre size større end 0 void removeLast(); } I Java/JML KbP/seminar3: Opsamling
Implementering public class LinkedDeque implements Deque { private DNode front, back; private int size; Repræsentationsinvariant er vigtig! Skal udtale sig om front, back og size I Java/JML KbP/seminar3: Opsamling
Programmer mod et interface! public class ArrayDeque implements Deque{ /*@ private invariant repr!=null && size() == repr.size(); @*/ private ArrayListrepr; /*@ ensures size()==0; @*/ public ArrayDeque(){ repr= new ArrayList(); } // Basic queries public int size(){ return repr.size(); } public Object get(inti){ return repr.get(i); } //---- Ny datarepræsentation == Ny repræsentationsinvariant KbP/seminar3: Opsamling
// Derived queries public Deque shallowCopy(){ ArrayDeque copy= new ArrayDeque(); for(int i= 0; i<repr.size();i++) copy.insertLast(repr.get(i)); return copy; } public Object first(){ return repr.get(0); } public Object last(){ return repr.get(size()-1); } public boolean isEmpty(){ return size()==0; } // Commands public void insertFirst(Object e){ repr.add(0, e); } public void removeFirst(){ repr.remove(0); } public void insertLast(Object e){ repr.add(e); } public void removeLast(){ repr.remove(size()-1); } } KbP/seminar3: Opsamling