Lösungsvorschläge zum Übungsblatt 5: Fortgeschrittene Aspekte

Werbung
Prof. Dr. A. Poetzsch-Heffter
Dipl.-Inform. N. Rauch
Technische Universität Kaiserslautern
Fachbereich Informatik
AG Softwaretechnik
Lösungsvorschläge zum Übungsblatt 5: Fortgeschrittene Aspekte
objektorientierter Programmierung (SS 2007)
Aufgabe 1
Spezifikation mit JML II
a) Man kann eine model variable verwenden.
b) Dies lässt sich mit Hilfe von assignable-Klauseln regulieren.
import java.util.ArrayList;
class Behaelter {
/*
* Aufgabe 1 a): Verwendung von Model-Variablen zum Verbergen der Implementation.
* Zur Demonstration wurde die Implementierung gegen eine ArrayList ausgetauscht.
*/
/*@
@ public model instance non_null int[] elements;
@ public model instance int length;
@ private represents length <- n;
@ private represents elements <- downcast(a.toArray());
@
@ public static model pure int[] downcast( Object[] o ){
@
int[] t = new int[o.length];
@
for( int i = 0; i < o.length; i++ )
@
t[i] = ((Integer)o[i]).intValue();
@
return t;
@ }
@
@ public invariant 0 <= length && length <= elements.length;
@*/
// Zur Demonstration der Unabhaengigkeit der Modellierung von der Implementierung
// wurde die
// interne Repraesentation durch eine ArrayList vorgenommen. Der urspruengliche
// Code ist noch in Kommentaren vorhanden.
//
private /*@ non_null */ int[] a; // verlagert die Aussage "a != null" aus der Invar
private /*@ non_null */ ArrayList a; // verlagert die Aussage "a != null" aus der Inv
private int n;
/*@
@ requires input != null;
@ assignable elements, length;
@ ensures elements.length == \old(input.length) && length == elements.length
@
&& (\forall int i; 0 <= i && i < length; elements[i] == \old(input[i]) )
@
&& elements != \old(input);
@*/
Behaelter( int[] input ){
n = input.length;
a = // new int[n];
new ArrayList();
// System.arraycopy(input, 0, a, 0, n);
for( int i = 0; i < input.length; i++ )
a.add(new Integer(input[i]));
System.out.println("Laenge: " + a.size() + " " + a.toArray().length );
}
/*@
@ requires length >= 1;
@ assignable elements, length;
@ ensures length + 1 == \old(length) &&
(\forall int i; 0 <= i && i < length; \result <= elements[i]);
@*/
int extractMin() {
int m = ((Integer)a.get(0)).intValue();
int mindex = 0;
/*@
@ loop_invariant (\forall int j; 0 <= j && j < i;
elements[mindex] <= elements[j])
@
&& elements[mindex] == m;
@*/
for (int i = 1; i < n; i++) {
if (/*a[i]*/ ((Integer)a.get(i)).intValue() < m) {
mindex = i;
m = ((Integer)a.get(i)).intValue(); // a[i];
}
}
n--;
// a[mindex] = a[n];
a.set(mindex, a.get(n));
return m;
}
/*@
@ constraint length <= \old(length);
@*/
/*
* Ein Test
*/
public static void main(String[] s){
int[] input = new int[]{1,2,3,4,5};
Behaelter b = new Behaelter(input);
for( int i = 1; i <= 6; i++ )
System.out.println(i + "-ter Versuch: " + b.extractMin() );
}
}
Aufgabe 2
Spezifikation mit JML III
a) Spezifikation des Interfaces:
import java.io.FileReader;
import java.io.FileWriter;
class FileNotFoundException extends Exception {}
class FileNotOpenException extends Exception {}
class ReadOnlyViolation extends Exception {}
public interface FileAnnotated {
2
//@ model instance boolean isOpen;
//@ model instance boolean isWriteable;
/*@
public normal_behavior
requires name != null && (writeable || new java.io.File(name).exists());
assignable \everything;
ensures isOpen && isWriteable == writeable;
also
public exceptional_behavior
requires name == null || (! writeable && ! new java.io.File(name).exists());
assignable \nothing;
signals(FileNotFoundException) true;
/
*
public void open( String name, boolean writeable ) throws FileNotFoundException;
/*@
public normal_behavior
requires isOpen;
assignable isOpen;
ensures ! isOpen;
also
public exceptional_behavior
requires ! isOpen;
assignable \everything;
signals(FileNotOpenException) true;
/
*
public void close() throws FileNotOpenException;
/*@
public normal_behavior
requires isOpen && ! isWriteable;
assignable \everything;
ensures -1 <= \result && \result <= 65535;
also
public exceptional_behavior
requires ! isOpen || isWriteable;
assignable \everything;
signals(FileNotOpenException) true;
/
*
public int read() throws FileNotOpenException;
/*@
public normal_behavior
requires isOpen && isWriteable && ch >= 0;
assignable \everything;
ensures true;
also
public exceptional_behavior
requires ! isOpen || ! isWriteable;
assignable \everything;
signals (FileNotOpenException) ! isOpen;
signals (ReadOnlyViolation) isOpen && ! isWriteable;
*/
public void write( char ch ) throws FileNotOpenException, ReadOnlyViolation;
}
b) Implementierung:
3
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileImpl implements FileAnnotated {
private /*@ nullable */ FileReader reader;
private /*@ nullable */ FileWriter writer;
//@ private represents isOpen <- reader != null || writer != null;
//@ private represents isWriteable <- writer != null;
public void open( String name, boolean writeable ) throws FileNotFoundException {
// close any files that are currently open for reading or writing
try {
close();
} catch (FileNotOpenException e1) {
// ignore this exception, regard closing as service
}
if( name == null )
throw new FileNotFoundException();
java.io.File theFile = new java.io.File(name);
if( ! writeable && ! theFile.exists() )
throw new FileNotFoundException();
try {
if( writeable ){
writer = new FileWriter(theFile);
} else {
reader = new FileReader(theFile);
}
} catch (IOException e) {
throw new FileNotFoundException();
}
}
public void close() throws FileNotOpenException {
if( reader == null && writer == null )
throw new FileNotOpenException();
try {
if( reader != null ){
reader.close();
}
if( writer != null ){
writer.close();
}
} catch( IOException e ){
// ignore this exception
}
reader = null;
writer = null;
}
public int read() throws FileNotOpenException {
if( reader == null )
throw new FileNotOpenException();
4
try {
return reader.read();
} catch (IOException e) {
return -1; // problem
}
}
public void write( char ch ) throws FileNotOpenException, ReadOnlyViolation {
if( writer == null ){
if( reader == null ){
throw new FileNotOpenException();
} else {
throw new ReadOnlyViolation();
}
}
try {
writer.write(ch);
} catch (IOException e) {
// ignore exception
}
}
public static void testZyklus(String name, boolean writeable )
{
// File lesen:
FileImpl f1 = new FileImpl();
System.out.println("Oeffnen des Files " + name);
try {
f1.open(name, writeable);
} catch(FileNotFoundException e){
System.out.println("Oeffnen fehlgeschlagen.");
}
System.out.println("Lesen aus dem File:");
try {
int i = f1.read();
while( i != -1 ){
System.out.print((char)i);
i = f1.read();
}
} catch(FileNotOpenException e){
System.out.println("Lesen des Files fehlgeschlagen.");
}
System.out.println("Schreiben in das File:");
try {
f1.write(’a’);
} catch (FileNotOpenException e) {
System.out.println("File nicht geoeffnet.");
} catch (ReadOnlyViolation e) {
System.out.println("File nur zum Lesen geoeffnet.");
}
System.out.println("Schlie§en des Files:");
try {
f1.close();
System.out.println("File geschlossen.");
} catch (FileNotOpenException e) {
System.out.println("File nicht geoeffnet.");
}
}
5
public static void main(String[] s) {
if( s.length != 2 ){
System.out.println("Usage: Ein File zum Lesen und ein File zum " +
"Schreiben angeben!");
return;
}
//////////////////////////////////////////////////
FileImpl.testZyklus(s[0], false);
FileImpl.testZyklus(s[1], true);
FileImpl.testZyklus("blabla1", false);
FileImpl.testZyklus("blabla2", true);
}
}
6
Herunterladen