JML Specifications for Stress Free classes Class design

  • Slides: 20
Download presentation
JML Specifications for Stress. Free classes • Class design – method identification • Method

JML Specifications for Stress. Free 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

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 ; )

Stress. Free class design: the Registrar view

Stress. Free class design: the Registrar view

Identifying methods Use cases suggest new methods in various classes. E. g. , enroll.

Identifying methods Use cases suggest new methods in various classes. E. g. , enroll. In. Courses suggests: In class System: get. Status (open or closed) In class Course. Offering: is. Full add. Student In class Schedule: add. Course view. Course. Offerings

Stress. Free class design: the course view

Stress. Free class design: the course view

Writing method specifications: E. g. , Time. Slots private /*@spec_public @*/ String days; //

Writing method specifications: E. g. , Time. Slots private /*@spec_public @*/ String days; // MTWHFSU = Mon, Tue, Wed, Thu, Fri, Sat, Sun // TBA = undefined private /*@spec_public @*/ String start. Time; // Military time. E. g. 13: 30 means 1: 30 pm private /*@spec_public @*/ String end. Time; // 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 conflicts. With (Time. Slot other) // true if other. start. Time precedes this. end. Time public boolean time. Overlap (Time. Slot other) JML specs needed here

Specifying the conflicts. With method /*@ ensures result == !days. equals("TBA") && !other. days.

Specifying the conflicts. With 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. char. At(i) == other. days. char. At(j))) && this. time. Overlap(other); @*/ public /*@ pure @*/ boolean conflicts. With (Time. Slot other) { This means “No local side effects. ” Also, days, start. Time, end. Time must be declared spec-public.

Stress. Free class design: Student view

Stress. Free class design: Student view

Specifying prerequisite satisfaction A Transcript satisfies all of a Course’s prerequisites if it has

Specifying prerequisite satisfaction A Transcript satisfies all of a Course’s prerequisites if it has at least one Course. Record whose id is in the set defined by each prerequisite. E. g. , suppose the Course c = CSCI 210 has prerequisites “both CSCI 107 and either one of MATH 200 or CSCI 189”. This shows as the Java Vector of regular expressions: [CSCI 107, MATH 200|CSCI 189] The Transcript t can satisfy this by containing a Course. Record that matches each regular expression. JML specifications for the method t. meets. Prerequisites(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 Hash. Map

What would the JML specifications look like? In the Transcript class: public Hash. Map my. Records = new Hash. Map(); /*@ requires course != null ensures result == (forall Regexp p; p == course. get. Prerequisites(). next(); (exists Course. Record r; r == my. Records. next(); p. match (r. id)); @*/ public boolean meets. Prerequisites(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

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. int. Value() > 0 && id. int. Value() <=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), or 2) too strict (what about next year’s students? )

Specifying Java collections A collection in Java can be any of several classes E.

Specifying Java collections A collection in Java can be any of several classes E. g. , Tree. Set, Vector, Hash. Map, Array. List, 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 Tree. Set that contains the keys for Course. Offerings can be traversed using an Iterator. Note: All these choices and operators can be used in JML specifications.

Hash. Maps and their keys Class Students Course. Offerings Element Student (s) Course (c)

Hash. Maps and their keys Class Students Course. Offerings Element Student (s) Course (c) Course. Offering (co) Transcripts Time. Slots Course. Records Transcript (t) Time. Slot (tm) Course. Record (cr) Instructors Instructor (in) Key Usage (in JML specs) id s. get. Id() id c. get. Id() get. Course(). id+section+labsection co. get. Key() student. id t. get. Id() id tm. get. Id() student. id+course. Offering. get. Key() cr. get. Key() name in. get. Name()

Student vs. Students can be a Hash. Map whose keys are Student. id’s. To

Student vs. Students can be a Hash. Map whose keys are Student. id’s. To retrieve a Student s from Students ss, say ss. get(s. get. Id()); 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. contains. Key(s. get. Id()); If ss has no entry with key == id, false is returned. To traverse the set of keys of a Hash. Map, use: ss. key. Set() and contains. When writing JML specs, assume all Java classes (e. g. , Hash. Map, String) are correct. So their methods can appear in the specs.

Students vs. Student. DB: the SQL interface Students is a Hash. Map. Its keys

Students vs. Student. DB: the SQL interface Students is a Hash. Map. Its keys are Student. id’s. It is not persistent. That is, it forgets all updates from past runs. Student. DB 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 Student. DB table sdb, we can define a method sdb. get(s. get. Id()); If this fails, null is returned. To see if an individual Student s appears in Student. DB sdb, we can define a method sdb. contains. Key(s. get. Id()); If sdb has no entry with key id, false is returned. To add or replace Student s in the Student. DB table sdb, we can define a method sdb. put(s).

A Sketch of some important SQL Commands Statement stmt; Result. Set rs; Retrieval –

A Sketch of some important SQL Commands Statement stmt; Result. Set rs; Retrieval – get Student s out of the Student. DB table rs = stmt. execute. Query(“select * from Student. DB where ” + “id = ” + s. get. Id()); If rs != null then the query was successful, so you can retrieve all the instance variables for that student: s. set. Name(rs. get. String(“name”)); s. set. Year(rs. get. Int(“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 Student. DB table. stmt. execute. Update(“insert into Student. DB(id, name, year) values( “ + + s. get. Id() + “, ” + s. get. Name() + “, ” + s. get. Year() + “)”);

The Student class invariant public class Student { private int id; private String name;

The Student class invariant public 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 Course. Record cr; schedule. get. My. Classes(). key. Set(). contains(cr); cr. get. Schedule(). get. Student(). get. Id(). equals(id))) @*/

Debugging conflicts. With If this method is buggy, can our JML specs help find

Debugging conflicts. With If this method is buggy, can our JML specs help find the error? public boolean conflicts. With (Time. Slot other) { if (this. days. equals("TBA") || other. days. equals("TBA")) return false; for (int i=0; i<other. days. length(); i++) if (other. days. index. Of(this. days. substring(i, i)) >= 0) if (this. time. Overlap(other)) return true; // day in common and time ovelap else return false; // day in common, no time overlap return false; // no day in common }

Recall Design by Contract The relation between a class (method) and its client (caller)

Recall Design by Contract The relation between a class (method) and its client (caller) is a formal agreement

Finding the contracts in Stress. Free Each use case has at least one contract

Finding the contracts in Stress. Free 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 view. Offerings use case – Client = Student, Registrar, or Instructor class – Supplier = Course. Offerings 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.