Opsamling Loops Klassedesign Immutable Lister shallowCopy() Projekt 2 FEN KbP/seminar3: Opsamling
FEN KbP/seminar3: Opsamling2 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: Checklisten giver os: Find P og B ud fra: P B R Find initiering, så P etableres ({Q} S 0 {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} {Q} S 0 do {P} B S od {R} Checklisten: 1. {Q} S 0 {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) Heltalsdivision Øvelse 3 Loops:
De seks principper: 1.Adskil forespørgsler og kommandoer 2.Adskil basale forespørgsler fra afledte 3.Specificer postbetingelser for de afledte forespørgsler vha. de basale 4.Specificer kommandoers postbetingelser gennem deres effekt på de basale forespørgsler 5.Specificer prebetingelser på alle operationer 6.Specificer invariante egenskaber i en klasseinvariant Kun de basale forespørgsler er afhængige af datarepræsentationen Konstruktører skal etablere klasseinvarianten Implementerende klasser skal specificere en repræsentationsinvariant Programmér mod et interface FEN KbP/seminar3: Opsamling
Immutable lister 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); } Grundlæggende forespørgsler Opbygger listen ved at elementer ind foran den eksisterende (evt. tomme) liste FEN KbP/seminar3: Opsamling
Specifikationen public interface ImmutableList { // Basic queries public boolean isEmpty(); requires public Object head(); requires public ImmutableList tail(); // Derived queries ensures isEmpty() ==> ensures (!isEmpty()) ==> (\result == public int size(); A= (a, b, c, d) A.head() = a A.tail() = (b, c, d) Bemærk, rekursion FEN KbP/seminar3: Opsamling
ensures ensures (\result).tail() == ensures (\result).head() == public ImmutableList precededBy(Object o); requires l != ensures (l.isEmpty() != isEmpty()) ==> ensures (!isEmpty()) ==> (\result == (l.head()==head() public boolean equals(ImmutableList l); requires 0<=i && ensures (i==0) ==> ensures (i>0) ==> public Object item(int i); requires 0<=from && from<=to && ensures ensures (from!=to) ==> ensures (from!=to) ==> public ImmutableList sublist(int from, int to); A= () A.precededBy(a) = (a) A.precededBy(b) = (b, a) … Bemærk, rekursion FEN KbP/seminar3: Opsamling
FEN KbP/seminar3: Opsamling7 Brug af immutable lister i specifikation: Queue public interface Queue2 { invariant // Basic queries public ImmutableList items(); // Derived queries ensures \result == public int size(); ensures public boolean isEmpty(); requires ensures public Object head(); Returnerer en liste med køens elementer items() anvendes ved specifikation af de øvrige operationer Burde være ”pure”, men det acceptere JML ikke umiddelbart
FEN KbP/seminar3: Opsamling8 // Commands ensures ensures public void put(Object o); requires ensures ensures public void remove(); } Operationer på ImmutableList anvendes
Specifikation af shallowCopy() ensures ensures (\forall int i; 0<=i && public Queue shallowCopy(); Bemærk, ’==’ Dvs. samme objektreference skal returneres af kopien som af originalen FEN 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(); } FEN KbP/seminar3: Opsamling
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(); } Princip 1 og 2: 1.Adskil forespørgsler og kommandoer 2.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. FEN KbP/seminar3: Opsamling
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(); } Princip 3: Specificer postbetingelser for de afledte forespørgsler vha. de basale FEN KbP/seminar3: Opsamling
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(); } Princip 4: Specificer kommandoers postbetingelser gennem deres effekt på de basale forespørgsler FEN 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 FEN 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 FEN KbP/seminar3: Opsamling
Programmer mod et interface! public class ArrayDeque implements Deque{ private invariant repr!=null && size() == private ArrayList repr; ensures public ArrayDeque(){ repr= new ArrayList(); } // Basic queries public int size(){ return repr.size(); } public Object get(int i){ return repr.get(i); } //---- Ny datarepræsentation == Ny repræsentationsinvariant FEN 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); } } FEN KbP/seminar3: Opsamling