-
Notifications
You must be signed in to change notification settings - Fork 1
/
006-parse_nested_parens.dfy
84 lines (82 loc) · 2.44 KB
/
006-parse_nested_parens.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
76
77
78
79
80
81
82
83
84
method parse_paren_group(s : string) returns (max_depth : int)
// pre-conditions-start
requires forall i :: i >= 0 && i < |s| ==> s[i] == '(' || s[i] == ')'
// pre-conditions-end
// post-conditions-start
ensures max_depth >= 0
// post-conditions-end
{
// impl-start
var depth: int := 0;
max_depth := 0;
for i := 0 to |s|
{
var c: char := s[i];
if (c == '(') {
depth := depth + 1;
if (depth > max_depth) {
max_depth := depth;
}
}
else {
depth := depth - 1;
}
}
// impl-end
}
method split(s : string) returns (res : seq<string>)
// pre-conditions-start
requires forall i :: i >= 0 && i < |s| ==> s[i] == '(' || s[i] == ')' || s[i] == ' '
// pre-conditions-end
// post-conditions-start
ensures forall s1 :: s1 in res ==> (forall i :: i >= 0 && i < |s1| ==> s1[i] == '(' || s1[i] == ')') && |s1| > 0
// post-conditions-end
{
// impl-start
res := [];
var current_string : string := "";
for i := 0 to |s|
// invariants-start
invariant forall j :: j >= 0 && j < |current_string| ==> current_string[j] == '(' || current_string[j] == ')'
invariant forall s1 :: s1 in res ==> (forall j :: j >= 0 && j < |s1| ==> s1[j] == '(' || s1[j] == ')') && |s1| > 0
// invariants-end
{
if (s[i] == ' ')
{
if (current_string != "") {
res := res + [current_string];
current_string := "";
}
}
else
{
current_string := current_string + [s[i]];
}
}
if (current_string != "") {
res := res + [current_string];
current_string := "";
}
// impl-end
}
method parse_nested_parens(paren_string: string) returns (res : seq<int>)
// pre-conditions-start
requires forall i :: i >= 0 && i < |paren_string| ==> paren_string[i] == '(' || paren_string[i] == ')' || paren_string[i] == ' '
// pre-conditions-end
// post-conditions-start
ensures forall x :: x in res ==> x >= 0
// post-conditions-end
{
// impl-start
var strings : seq<string> := split(paren_string);
res := [];
for i := 0 to |strings|
// invariants-start
invariant forall x :: x in res ==> x >= 0
// invariants-end
{
var cur : int := parse_paren_group(strings[i]);
res := res + [cur];
}
// impl-end
}