1 of 23

CSE 331�Software Design & Implementation

​

Autumn 2026

Section 1 – Specifications

2 of 23

Welcome!

  • Let’s all introduce ourselves:
    • Name and pronouns
    • Year
    • Anything fun you’re going to be doing this quarter?
    • Would you rather be a dinosaur or a unicorn and why?

​

3 of 23

Homework Cycle

  • Section:
    • Every Tuesday
    • Content review & practice problems

​

  • Participation:
    • Lecture & section graded on participation (half-sheets)
      • 5 absences, and a 90% coursework grade is full credit, see syllabus for details

​

  • Homework:
    • Released Friday @ 12:00am
    • Due on Gradescope @ 11:59pm Friday
      • make progress & submit by Friday gives one late day

4 of 23

Review - Abstraction

  • Hides unnecessary details from clients via specification
  • Creates an Abstraction Barrier between clients and implementers
    • Implementers promise that the code follows the specification
    • Clients promise not to rely on details outside the specification

5 of 23

Documenting Methods w/ JavaDoc

*Note: @requires, @modifies, and @effects are all unique to 331

​

JavaDoc comments use “tags” to describe what methods do

/**

* High level description of what function does

* @param a + What "a" represents + any conditions about a

* @requires Rules about multiple params

* @returns Detailed description of return value

* @throws Condition when errors will be thrown

*/

For methods that mutate variables/state, will have 2 additional tags to describe mutation

* @modifies states what could be mutated by function

* @effects Detailed description of guaranteed changes

​

6 of 23

Spec/Impl Lecture Exercise

// Spec B

// @requires 0 <= lo <= hi <= a.length

// @returns the *smallest* index i with lo <= i < hi and a[i] == x,

// or -1 if no such index exists

​

// Spec D

// @requires 0 <= lo <= hi <= a.length

// @returns *some* index i with lo <= i < hi and a[i] == x,

// or -1 if no such index exists

​

// Impl 1

public static int indexOf(int[] a, int lo, int hi, int x) {

for (int i = lo; i < hi; i++) {

if (a[i] == x) {

return i;

}

}

return -1;

}

When spec B is satisfied, spec D is also satisfied!

(311 implication)

What do you notice about these two specs and Impl 1?

7 of 23

Review: Stronger vs Weaker Assertions

An assertion is stronger if and only if it holds in a subset of states

  • A stronger assertion implies the weaker one
  • This means that if the stronger assertion is true, then the weaker assertion must also be true.

​

Below, Q2 is the stronger assertion as knowing Q2 is true tells us that Q1 is true. However, knowing Q1 is true doesn’t tell us Q2 is true.

8 of 23

Review: Stronger vs Weaker Specs

  • Specification S1 is stronger than S2 if it has…
    • a weaker (or equal) precondition, and
    • a stronger (or equal) postcondition
  • In this case, we also say S2 is weaker than S1
  • If neither is stronger than the other, then they are incomparable

P2

P1

precondition

postcondition

Q1

Q2

9 of 23

Question - Specifications

Which of the two specs is stronger?:

​

/** Returns the square root of a given number x

* @requires x >= 0

* @return the integer y such that y^2 = x

*/

​

Or

/** Returns the square root of a given number x

* @requires x >= 0

* @return the integer y such that y^2 = x and y >= 0

*/

10 of 23

Question - Specifications

Which of the two specs is stronger?:

​

/** Returns the square root of a given number x

* @requires x >= 0

* @return the integer y such that y^2 = x

*/

​

Or

/** Returns the square root of a given number x

* @requires x >= 0

* @return the integer y such that y^2 = x and y >= 0

*/

11 of 23

Specification Strength: Precondition

  • Accepting more generic @params increases specification strength (same params w/ less restrictions)
    • We’ll talk about this later with generics

​

  • Adding more to @requires decreases specification strength
    • Strengthens the precondition (takes in less inputs)
    • Ex: param List lst must be sorted is more restrictive = stronger precondition = weaker spec than no requirement about order

12 of 23

Specification Strength: Postcondition

  • Adding more to @returns increases specification strength
    • Strengthens the postcondition

​

  • @throws still specifies behavior, so it is stronger than @requires
    • Still accepts that input and defines the behavior for it

​

​

13 of 23

New Notation for Task 1 & 2

We use the notation a[i..j] to refer to the elements of an array a from index i (inclusive) to j (exclusive). So a[0..n] is the elements of a at indices 0, 1, ..., n-1.

​

14 of 23

Task 1: Spec Comparisons

​

A

B

C

D

E

A

X

​

​

​

​

B

​

X

​

​

​

C

​

​

X

​

​

D

​

​

​

X

​

E

​

​

​

​

X

Using the specs listed, fill in the following table explaining the relationships between each pair of specifications. Write an “S” if the spec on left (the row) is stronger than the spec on top (the column), a “W” if the left spec is weaker, and “-” if the specs are incomparable.

15 of 23

Task 2: Mutable Spec/Impl Satisfaction

  • First, what does each implementation do?
  • Second, determine which implementations satisfy which specifications and explain your reasoning.

​

We use the notation a[i..j] to refer to the elements of an array a from index i (inclusive) to j (exclusive). So a[0..n] is the elements of a at indices 0, 1, ..., n-1.

16 of 23

Task 2: Mutable Spec/Impl Satisfaction

​

This is the common prefix of each spec.��/**

* Removes x from the prefix a[0..n] (but see below for details)

*

* @param a the non-null array to remove from

* @param n the length of the prefix

* @param x the value to remove

* @requires 0 <= n <= a.length

* @modifies a

*/

17 of 23

Task 2: Mutable Spec/Impl Satisfaction

// Spec A

// @effects if the first occurrence of x in a[0..n] is at index i,

// then the new values in a[0..n-1] will be the old values of a[0..i]

// followed by the old values of a[i+1..n], and the new value of a[n-1]

// is unspecified. else, if x does not occur in a[0..n], leaves a unchanged;

// @return n - 1 if x was removed, else n

​

// Spec B

// @effects if x does not occur in a[0..n], leaves a unchanged;

// otherwise, the new values in a[0..n-1] are a possibly reordered version

// of the old values of a[0..n] with one fewer occurrence of x,

// and the new value of a[n-1] is unspecified

// @return n - 1 if x was removed, else n

​

18 of 23

Task 2: Mutable Spec/Impl Satisfaction

// Spec C

// @effects if x does not occur in a[0..n], leaves a unchanged;

// otherwise, if x occurs k > 0 times in a[0..n], then remove all k

// occurrences of x, leaving remaining elements in the same relative

// order as before; the new value of elements in a[n-k..n] is unspecified

// @return n - k

​

// Spec D

// @requires a[0..n] contains no duplicates

// @effects if x does not occur in a[0..n], leaves a unchanged;

// otherwise, if x occurs in a[0..n] at index i, then the new values

// in a[0..n-1] will be the old values of a[0..i] followed by the

// old values of a[i+1..n], and the new value of a[n-1] is unspecified.

// @return n - 1 if x was removed, else n

19 of 23

Task 2: Implementation 1

// Impl 1

int w = 0;

for (int r = 0; r < n; r++) {

if (a[r] != x) {

a[w] = a[r];

w++;

}

}

return w;

20 of 23

Task 2: Implementation 2

// Impl 2

for (int i = 0; i < n; i++) {

if (a[i] == x) {

for (int k = i; k < n - 1; k++) {

a[k] = a[k + 1];

}

return n - 1;

}

}

return n;

21 of 23

Task 2: Implementation 3

// Impl 3

for (int i = n - 1; i >= 0; i--) {

if (a[i] == x) {

for (int k = i; k < n - 1; k++) {

a[k] = a[k + 1];

}

return n - 1;

}

}

return n;

​

22 of 23

Task 2: Implementation 4

// Impl 4

for (int i = 0; i < n; i++) {

if (a[i] == x) {

a[i] = a[n - 1];

return n - 1;

}

}

return n;

​

23 of 23

End

Please turn in your half sheets to us as you leave!!!!