 | 10.13 Input/output handling |
|
| 10 C++ translator |
| |
10.14 An example |
10.14 An example
This section explains how to translate and test the following
specification of quicksort.
The parameter for QUICKSORT is the scheme QSP:
| | | | | | | | | | | | |
scheme QSP = |
| class |
| | type Elem |
| | | | |
| | value |
| | | ≤ : Elem × Elem → Bool |
| end
|
The parameterised QUICKSORT scheme is
| | | | | | | | | | | | |
QSP |
| | | | |
scheme QUICKSORT(X : QSP) = |
| with X in class |
| | value |
| | | sort : Elem* → Elem* |
| | | sort(l) ≡ |
| | | | case l of |
| | | | | 〈〉 → 〈〉, |
| | | | | 〈h〉 ^ t → |
| | | | | | let (t1, t2) = split(h, t, 〈〉, 〈〉) in |
| | | | | | | sort(t1) ^ 〈h〉 ^ sort(t2) |
| | | | | | end |
| | | | end, |
| | | | |
| | | split : |
| | | | Elem × Elem* × Elem* × Elem* → Elem* × Elem* |
| | | split(x, t, t1, t2) ≡ |
| | | | case t of |
| | | | | 〈〉 → (t1, t2), |
| | | | | 〈h〉 ^ t3 → |
| | | | | | if h ≤ x then split(x, t3, 〈h〉 ^ t1, t2) |
| | | | | | else split(x, t3, t1, 〈h〉 ^ t2) |
| | | | | | end |
| | | | end |
| end
|
To specify quicksort for integers we can create an object I for the
actual parameter:
| | | | | | | | | | | | |
object I : class type Elem = Int end
|
Quicksort is then scheme QI, which includes some test cases:
| | | | | | | | | | | | |
QUICKSORT, I |
| | | | |
scheme QI = |
| class |
| | object |
| | | Q : QUICKSORT(I) |
| | test_case |
| | | [t1] |
| | | | Q.sort(〈〉), |
| | | [t2] |
| | | | Q.sort(〈12, 45, 2, 4, 2, 8, -1, 0〉) |
| end
|
When this is compiled and the result executed, the output is as
follows:
[t1] <..>
[t2] <.-1,0,2,2,4,8,12,45.>
Checking the results for many such tests would be tedious. A better
way is to have a more abstract specification of QUICKSORT like QSPEC:
| | | | | | | | | | | | |
QSP |
| | | | |
scheme QSPEC(X : QSP) = |
| with X in class |
| | value |
| | | /* commented out for translation |
| | | sort : Elem* → Elem* |
| | | sort(l) as l′ post is_permutation(l, l′) /\ sorted(l′), */ |
| | | | |
| | | is_permutation : Elem* × Elem* → Bool |
| | | is_permutation(l1, l2) ≡ |
| | | | (∀ e : Elem • |
| | | | | e ∈ elems l1 ∪ elems l2 ⇒ |
| | | | | | count(l1, e) = count(l2, e)), |
| | | | |
| | | count : Elem* × Elem → Nat |
| | | count(l, e) ≡ |
| | | | card {i | i : Int • i ∈ inds l /\ l(i) = e}, |
| | | | |
| | | sorted : Elem* → Bool |
| | | sorted(l) ≡ |
| | | | let s = inds l in |
| | | | | (∀ i : Int • i ∈ s ⇒ |
| | | | | | (∀ j : Int • j ∈ s ⇒ |
| | | | | | | j > i ⇒ l(i) ≤ l(j))) |
| | | | end |
| end
|
Then we can instantiate both QUICKSORT and its more abstract specification and use
the latter to check the former:
| | | | | | | | | | | | |
QSPEC, QUICKSORT, I |
| | | | |
scheme QSI = |
| class |
| | object |
| | | A : QSPEC(I), |
| | | B : QUICKSORT(I) |
| | | | |
| | value |
| | | check : Int* → Bool |
| | | check(l) ≡ |
| | | | let l1 = B.sort(l) in |
| | | | | A.is_permutation(l, l1) /\ A.sorted(l1) |
| | | | end |
| | | | |
| | test_case |
| | | [t1] check(〈〉), |
| | | [t2] check(〈1〉), |
| | | [t3] check(〈1, 4, 3, 2, 7, 4, 6, 3, 8, 100, -2, -5, 8, 200〉) |
| end
|
Translating, compiling, and running QSI produces the output
[t1] true
[t2] true
[t3] true
This allows us to have many test cases (perhaps by random number
generation) without the tedium of
generating the expected results.
Chris George, April 17, 2008
10.14 An example |
 | 10.13 Input/output handling |
|
| 10 C++ translator |
| |