Upload
avalon
View
21
Download
1
Embed Size (px)
DESCRIPTION
JML Specifications for StressFree classes. Class design method identification Method specification in JML preconditions postconditions Class invariant specification in JML. More JML Language. non-null - designates that a variable cannot be null for any object in this class. - PowerPoint PPT Presentation
Citation preview
JML Specifications for StressFree classes
• Class design– method identification
• Method specification in JML– preconditions– postconditions
• Class invariant specification in JML
More JML Language
non-null - designates that a variable cannot be null for any object in this class.
spec_public - required for private instance variables that are mentioned in JML method specifications (since methods themselves are public, so are their specs).
pure - designates a method that has no local side effects (assignments to class variables) and no infinite loops
assignable \nothing ; - designates that no variables can be assigned by the method (similar to pure).
assignable v ; - designates that only variable v can be assigned by a method (default = assignable \everything ; )
StressFree class design: the Registrar view
Identifying methods
Use cases suggest new methods in various classes. E.g., enrollInCourses suggests:
In class System:
getStatus (open or closed)
In class CourseOffering:
isFull
addStudent
In class Schedule:
addCourse
viewCourseOfferings
StressFree class design: the course view
Writing method specifications: E.g., TimeSlots
private /*@spec_public @*/ String days; // MTWHFSU = Mon, Tue, Wed, Thu, Fri, Sat, Sun // TBA = undefined
private /*@spec_public @*/ String startTime; // Military time. E.g. 13:30 means 1:30pm
private /*@spec_public @*/ String endTime;
// true if neither this nor other is TBA, // this.days and other.days has a day in common, and // this and other have a time overlap. public boolean conflictsWith (TimeSlot other)
// true if other.startTime precedes this.endTime public boolean timeOverlap (TimeSlot other) JML specs
needed here
Specifying the conflictsWith method
/*@ ensures \result == !days.equals("TBA") && !other.days.equals("TBA") &&
(\exists int i; 0 <= i && i < days.length();
(\exists int j; 0 <= j && j < other.days.length(); days.charAt(i) == other.days.charAt(j))) &&
this.timeOverlap(other);
@*/
public /*@ pure @*/ boolean conflictsWith (TimeSlot other) {
This means “No local side effects.” Also, days, startTime, endTime must be declared spec-public.
StressFree class design: Student view
Specifying prerequisite satisfaction
A Transcript satisfies all of a Course’s prerequisites if it has at least one CourseRecord whose id is in the set defined by each prerequisite.
E.g., suppose the Course c = CSCI210 has prerequisites “both CSCI107 and either one of MATH200 or CSCI189”.
This shows as the Java Vector of regular expressions:[CSCI107, MATH200|CSCI189]
The Transcript t can satisfy this by containing a CourseRecordthat matches each regular expression.
JML specifications for the method t.meetsPrerequisites(c) should be added to the Transcript class before the code is written.
What would the JML specifications look like?
In the Transcript class: public HashMap myRecords = new HashMap();
/*@
requires course != null
ensures result == (\forall Regexp p; p == course.getPrerequisites().next();
(\exists CourseRecord r; r == myRecords.next();
p.match (r.id));
@*/
public boolean meetsPrerequisites(Course course) {
// your code here
return false;
}
Note: In this case, the specs may be easier to write than the code (these quantifiers suggest loops).
JML class invariant
A class invariant defines all the valid states (values of the instance variables) of any object in the class.
E.g. Consider the class Student, with instance variables id, name, and year. An invariant could embody the following ideas: id = an integer in the range 1..1620. name = a nonempty string. year = a valid graduation year (e.g., 2006).
In JML, this can be written:/*@ invariant id.intValue() > 0 && id.intValue() <=1620 &&
name != null && name.length() > 0 &&(\exists int i; 2006 <= i && i <= 2009; i == year)
@*/
Notes: A specification can be: 1) too lenient (some instance variables can be null), or2) too strict (what about next year’s students?)
Specifying Java collections
A collection in Java can be any of several classesE.g., TreeSet, Vector, HashMap, ArrayList, etc.
Picking the best collection for an implementation includes the following:
1. Unique keys: Some collections have the feature that each member’s key is distinct. E.g., Hashtable.
2. Ordering: A collection may require that its members be sorted, in which case they must be Comparable. E.g., Students
3. Traversal: An Iterator allows visiting the members of a collection, one at a time. E.g., the TreeSet that contains the keys for CourseOfferings can be traversed using an Iterator.
Note: All these choices and operators can be used in JML specifications.
HashMaps and their keys
Class Element Key Usage (in JML specs)
Students Student (s) id s.getId()
Courses Course (c) id c.getId()
CourseOfferings CourseOffering (co) getCourse().id+section+labsection
co.getKey()
Transcripts Transcript (t) student.id t.getId()
TimeSlots TimeSlot (tm) id tm.getId()
CourseRecords CourseRecord (cr) student.id+courseOffering.getKey()
cr.getKey()
Instructors Instructor (in) name in.getName()
Student vs. Students
Students can be a HashMap whose keys are Student.id’s.
To retrieve a Student s from Students ss, say ss.get(s.getId());If ss has no entry whose key is id, null is returned.
To see if an individual Student s appears in Students ss, say ss.containsKey(s.getId());If ss has no entry with key == id, false is returned.
To traverse the set of keys of a HashMap, use:ss.keySet() and contains.
When writing JML specs, assume all Java classes (e.g., HashMap,
String) are correct. So their methods can appear in the specs.
Students vs. StudentDB: the SQL interface
Students is a HashMap. Its keys are Student.id’s. It is not persistent. That is, it forgets all updates from past runs.
StudentDB is an SQL Table. Its keys are Student.id’s. It is persistent. That is, it remembers updates from past runs.
To retrieve an individual Student s from StudentDB table sdb, we can define a method sdb.get(s.getId());If this fails, null is returned.
To see if an individual Student s appears in StudentDB sdb, we can define a method sdb.containsKey(s.getId());If sdb has no entry with key id, false is returned.
To add or replace Student s in the StudentDB table sdb, we candefine a method sdb.put(s).
A Sketch of some important SQL Commands
Statement stmt;ResultSet rs;
Retrieval – get Student s out of the StudentDB tablers = stmt.executeQuery(“select * from StudentDB where ” + “id = ” +
s.getId());If rs != null then the query was successful, so you can retrieve all the instance variables for that student:
s.setName(rs.getString(“name”));s.setYear(rs.getInt(“year”));
Query – The above can also be used to query a Table, by testing if rs == null.
Update – insert new values for Student s into a row of the StudentDB table.stmt.executeUpdate(“insert into StudentDB(id, name, year) values( “ +
+ s.getId() + “,” + s.getName() + “,” + s.getYear() + “)”);
The Student class invariantpublic class Student { private int id; private String name; private String year; public Instructor advisor; public Schedule schedule; public Transcript transcript;
/*@ id > 0 && id <=1620 && name != null && name.length() > 0 &&
(\exists int i; 2006 <= i && i <= 2009; i == year) && transcript != null &&
(schedule == null || (\forall CourseRecord cr;
schedule.getMyClasses().keySet().contains(cr); cr.getSchedule().getStudent().getId().equals(id))) @*/
Debugging conflictsWith
public boolean conflictsWith (TimeSlot other) { if (this.days.equals("TBA") || other.days.equals("TBA"))
return false; for (int i=0; i<other.days.length(); i++) if (other.days.indexOf(this.days.substring(i, i)) >= 0)
if (this.timeOverlap(other)) return true; // day in common and time ovelap
else return false; // day in common, no time overlap return false; // no day in common }
If this method is buggy, can our JML specs help find the error?
Recall Design by Contract
The relation between a class (method) and its client (caller) is a formal agreement
Obligations Benefits
Client Satisfy preconditions Result satisfies postconditions and class invariant
Class Satisfy postconditions and class invariant
Code can rely on satisfaction of preconditions
Finding the contracts in StressFree
Each use case has at least one contract– Who is the client?– Who is the supplier?– What are the client’s obligations?– What are the supplier’s obligations?(The benefits are usually implicit)
Example: the viewOfferings use case– Client = Student, Registrar, or Instructor class – Supplier = CourseOfferings class– Client obligations: to provide a valid set of course ids.– Supplier obligations: to display the id, title, time slot,
prerequisites, distribution, capacity, and enrollment for all courses in the set.