-
Notifications
You must be signed in to change notification settings - Fork 1
/
112-reverse_delete.dfy
62 lines (59 loc) · 1.5 KB
/
112-reverse_delete.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
method reverse_delete(s: string, chars: string) returns (res: string, is_palindrome: bool)
// post-conditions-start
ensures forall i :: 0 <= i < |res| ==> res[i] !in chars
ensures forall i :: 0 <= i < |res| ==> res[i] in s
ensures forall i :: 0 <= i < |s| && s[i] !in chars ==> s[i] in res
ensures is_palindrome <==> is_palindrome_pred(res)
// post-conditions-end
{
// impl-start
res := "";
var i := 0;
while i < |s|
// invariants-start
invariant 0 <= i <= |s|
invariant forall i :: 0 <= i < |res| ==> res[i] !in chars
invariant forall i :: 0 <= i < |res| ==> res[i] in s
invariant forall j :: 0 <= j < i && s[j] !in chars ==> s[j] in res
// invariants-end
{
if s[i] !in chars {
res := res + [s[i]];
}
i := i + 1;
}
is_palindrome := check_palindrome(res);
// impl-end
}
method check_palindrome(s: string) returns (result: bool)
// post-conditions-start
ensures result <==> is_palindrome_pred(s)
// post-conditions-end
{
// impl-start
if |s| == 0 {
return true;
}
result := true;
var i := 0;
var j := |s| - 1;
while (i < j)
// invariants-start
invariant 0 <= i < |s|
invariant 0 <= j < |s|
invariant j == |s| - i - 1
invariant forall k :: 0 <= k < i ==> s[k] == s[|s| - 1 - k]
// invariants-end
{
if (s[i] != s[j]) {
result := false;
break;
}
i := i + 1;
j := j - 1;
}
// impl-end
}
predicate is_palindrome_pred(s : string) {
forall k :: 0 <= k < |s| ==> s[k] == s[|s| - 1 - k]
}