-
Notifications
You must be signed in to change notification settings - Fork 1
/
093-encode.dfy
59 lines (56 loc) · 1.56 KB
/
093-encode.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
method encode(s: string) returns (t: string)
// pre-conditions-start
requires forall i :: 0 <= i < |s| ==> 'a' <= s[i] <= 'z' || 'A' <= s[i] <= 'Z'
// pre-conditions-end
// post-conditions-start
ensures |s| == |t|
ensures forall i :: 0 <= i < |s| && is_vowel(s[i]) ==> t[i] == rot2(swap_case(s[i]))
ensures forall i :: 0 <= i < |s| && !is_vowel(s[i]) ==> t[i] == swap_case(s[i])
// post-conditions-end
{
// impl-start
t := "";
var i := 0;
while i < |s|
// invariants-start
invariant 0 <= i <= |s|
invariant |t| == i
invariant forall j :: 0 <= j < i && is_vowel(s[j]) ==> t[j] == rot2(swap_case(s[j]))
invariant forall j :: 0 <= j < i && !is_vowel(s[j]) ==> t[j] == swap_case(s[j])
// invariants-end
{
if is_vowel(s[i]) {
t := t + [rot2(swap_case(s[i]))];
} else {
t := t + [swap_case(s[i])];
}
i := i + 1;
}
// impl-end
}
function swap_case(c: char): char
// pre-conditions-start
requires 'a' <= c <= 'z' || 'A' <= c <= 'Z'
// pre-conditions-end
// post-conditions-start
ensures 'a' <= c <= 'z' ==> 'A' <= swap_case(c) <= 'Z'
ensures 'A' <= c <= 'Z' ==> 'a' <= swap_case(c) <= 'z'
ensures is_vowel(swap_case(c)) == is_vowel(c)
// post-conditions-end
{
// impl-start
if 'a' <= c <= 'z' then
'A' + (c - 'a')
else
'a' + (c - 'A')
// impl-end
}
function rot2(c: char): char
requires is_vowel(c)
{
(c as int + 2) as char
}
predicate is_vowel(c: char) {
(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
|| (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U')
}