-
Notifications
You must be signed in to change notification settings - Fork 1
/
081-numerical_letter_grade.dfy
75 lines (74 loc) · 3.78 KB
/
081-numerical_letter_grade.dfy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
method numerical_letter_grade(grades: seq<real>) returns (letters: seq<string>)
// pre-conditions-start
requires forall i :: 0 <= i < |grades| ==> 0.0 <= grades[i] <= 4.0
// pre-conditions-end
// post-conditions-start
ensures |letters| == |grades|
ensures forall i :: 0 <= i < |grades| && grades[i] == 4.0 ==> letters[i] == "A+"
ensures forall i :: 0 <= i < |grades| && grades[i] < 4.0 && grades[i] > 3.7 ==> letters[i] == "A"
ensures forall i :: 0 <= i < |grades| && grades[i] <= 3.7 && grades[i] > 3.3 ==> letters[i] == "A-"
ensures forall i :: 0 <= i < |grades| && grades[i] <= 3.3 && grades[i] > 3.0 ==> letters[i] == "B+"
ensures forall i :: 0 <= i < |grades| && grades[i] <= 3.0 && grades[i] > 2.7 ==> letters[i] == "B"
ensures forall i :: 0 <= i < |grades| && grades[i] <= 2.7 && grades[i] > 2.3 ==> letters[i] == "B-"
ensures forall i :: 0 <= i < |grades| && grades[i] <= 2.3 && grades[i] > 2.0 ==> letters[i] == "C+"
ensures forall i :: 0 <= i < |grades| && grades[i] <= 2.0 && grades[i] > 1.7 ==> letters[i] == "C"
ensures forall i :: 0 <= i < |grades| && grades[i] <= 1.7 && grades[i] > 1.3 ==> letters[i] == "C-"
ensures forall i :: 0 <= i < |grades| && grades[i] <= 1.3 && grades[i] > 1.0 ==> letters[i] == "D+"
ensures forall i :: 0 <= i < |grades| && grades[i] <= 1.0 && grades[i] > 0.7 ==> letters[i] == "D"
ensures forall i :: 0 <= i < |grades| && grades[i] <= 0.7 && grades[i] > 0.0 ==> letters[i] == "D-"
ensures forall i :: 0 <= i < |grades| && grades[i] == 0.0 ==> letters[i] == "E"
// post-conditions-end
{
// impl-start
letters := [];
var i := 0;
while i < |grades|
// invariants-start
invariant 0 <= i <= |grades|
invariant |letters| == i
invariant forall j :: 0 <= j < i && grades[j] == 4.0 ==> letters[j] == "A+"
invariant forall j :: 0 <= j < i && grades[j] < 4.0 && grades[j] > 3.7 ==> letters[j] == "A"
invariant forall j :: 0 <= j < i && grades[j] <= 3.7 && grades[j] > 3.3 ==> letters[j] == "A-"
invariant forall j :: 0 <= j < i && grades[j] <= 3.3 && grades[j] > 3.0 ==> letters[j] == "B+"
invariant forall j :: 0 <= j < i && grades[j] <= 3.0 && grades[j] > 2.7 ==> letters[j] == "B"
invariant forall j :: 0 <= j < i && grades[j] <= 2.7 && grades[j] > 2.3 ==> letters[j] == "B-"
invariant forall j :: 0 <= j < i && grades[j] <= 2.3 && grades[j] > 2.0 ==> letters[j] == "C+"
invariant forall j :: 0 <= j < i && grades[j] <= 2.0 && grades[j] > 1.7 ==> letters[j] == "C"
invariant forall j :: 0 <= j < i && grades[j] <= 1.7 && grades[j] > 1.3 ==> letters[j] == "C-"
invariant forall j :: 0 <= j < i && grades[j] <= 1.3 && grades[j] > 1.0 ==> letters[j] == "D+"
invariant forall j :: 0 <= j < i && grades[j] <= 1.0 && grades[j] > 0.7 ==> letters[j] == "D"
invariant forall j :: 0 <= j < i && grades[j] <= 0.7 && grades[j] > 0.0 ==> letters[j] == "D-"
invariant forall j :: 0 <= j < i && grades[j] == 0.0 ==> letters[j] == "E"
// invariants-end
{
if grades[i] == 4.0 {
letters := letters + ["A+"];
} else if grades[i] > 3.7 {
letters := letters + ["A"];
} else if grades[i] > 3.3 {
letters := letters + ["A-"];
} else if grades[i] > 3.0 {
letters := letters + ["B+"];
} else if grades[i] > 2.7 {
letters := letters + ["B"];
} else if grades[i] > 2.3 {
letters := letters + ["B-"];
} else if grades[i] > 2.0 {
letters := letters + ["C+"];
} else if grades[i] > 1.7 {
letters := letters + ["C"];
} else if grades[i] > 1.3 {
letters := letters + ["C-"];
} else if grades[i] > 1.0 {
letters := letters + ["D+"];
} else if grades[i] > 0.7 {
letters := letters + ["D"];
} else if grades[i] > 0.0 {
letters := letters + ["D-"];
} else {
letters := letters + ["E"];
}
i := i + 1;
}
// impl-end
}