Skip to content

Commit

Permalink
Minor fixes, implementation of 018-how_many_times (#52)
Browse files Browse the repository at this point in the history
Minor fixes to 011-string_xor, 012-longest, 020-find-closest_elements,
021-rescale_to_unit.

Stylistic change of rewriting `while` to `for` when the latter would be
more idiomatic.
  • Loading branch information
jesyspa authored Oct 2, 2024
1 parent 9223614 commit a50f3ab
Show file tree
Hide file tree
Showing 20 changed files with 117 additions and 181 deletions.
11 changes: 2 additions & 9 deletions 000-has_close_elements.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,13 @@ method has_close_elements(numbers: seq<real>, threshold: real) returns (flag : b
{
// impl-start
flag := false;
var i: int := 0;
while (i < |numbers|)
for i := 0 to |numbers|
// invariants-start
invariant 0 <= i && i <= |numbers|
invariant flag == (exists i1: int, j1: int :: i1 >= 0 && j1 >= 0 && i1 < i && j1 < |numbers| && i1 != j1 && abs(numbers[i1] - numbers[j1]) < threshold)
// invariants-end
{
var j: int := 0;
while (j < |numbers|)
for j := 0 to |numbers|
// invariants-start
invariant 0 <= i && i < |numbers|
invariant 0 <= j && j <= |numbers|
invariant flag == (exists i1: int, j1: int :: i1 >= 0 && j1 >= 0 && ((i1 < i && j1 < |numbers|) || (i1 == i && j1 < j)) && i1 != j1 && abs(numbers[i1] - numbers[j1]) < threshold)
// invariants-end
{
Expand All @@ -39,9 +34,7 @@ method has_close_elements(numbers: seq<real>, threshold: real) returns (flag : b
flag := true;
}
}
j := j + 1;
}
i := i + 1;
}
// impl-end
}
6 changes: 1 addition & 5 deletions 001-separate-paren-groups.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,8 @@ method separate_paren_groups(paren_string: string) returns (res : seq<string>)
var current_string: string := "";
var current_depth: int := 0;

var i: int := 0;

while (i < |paren_string|)
for i := 0 to |paren_string|
// invariants-start
invariant 0 <= i <= |paren_string|
invariant forall k :: 0 <= k < |res| ==> ParenthesesDepth(res[k], 0, |res[k]|) == 0
invariant forall k :: 0 <= k < |res| ==> InnerDepthsPositive(res[k])
invariant ParenthesesDepth(paren_string, 0, |paren_string|) == 0
Expand Down Expand Up @@ -149,7 +146,6 @@ method separate_paren_groups(paren_string: string) returns (res : seq<string>)
current_string := "";
}
}
i := i + 1;
}
// impl-end
}
5 changes: 1 addition & 4 deletions 003-below_zero.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ method below_zero(ops: seq<int>) returns (res : bool)
{
// impl-start
var balance : int := 0;
var i : int := 0;
while (i < |ops|)
for i := 0 to |ops|
// invariants-start
invariant 0 <= i <= |ops|
invariant balance == psum(ops[..i])
invariant forall j : int :: 0 <= j <= i ==> psum(ops[..j]) >= 0
// invariants-end
Expand All @@ -41,7 +39,6 @@ method below_zero(ops: seq<int>) returns (res : bool)
if (balance < 0) {
return false;
}
i := i + 1;
}
return true;
// impl-end
Expand Down
10 changes: 2 additions & 8 deletions 004-mean_absolute_derivation.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@ method mean_absolute_derivation(numbers: seq<real>) returns (derivation: real)
{
// impl-start
var s: real := 0.0;
var i := 0;
while i < |numbers|
for i := 0 to |numbers|
// invariants-start
invariant 0 <= i <= |numbers|
invariant s == sum(numbers[..i])
// invariants-end
{
Expand All @@ -48,20 +46,17 @@ method mean_absolute_derivation(numbers: seq<real>) returns (derivation: real)
sum_prop(numbers[..i + 1]);
}
// assert-end
i := i + 1;
}

var m := s / |numbers| as real;
assert numbers[..|numbers|] == numbers; // assert-line
assert m == mean(numbers); // assert-line

var t: real := 0.0;
i := 0;

ghost var pref_seq := [];
while i < |numbers|
for i := 0 to |numbers|
// invariants-start
invariant 0 <= i <= |numbers|
invariant |pref_seq| == i
invariant pref_seq == seq(i, j requires 0 <= j < i => abs(numbers[j] - m))
invariant t == sum(pref_seq[..i])
Expand All @@ -80,7 +75,6 @@ method mean_absolute_derivation(numbers: seq<real>) returns (derivation: real)
// assert-end

t := t + abs(numbers[i] - m);
i := i + 1;
}

assert pref_seq[..|pref_seq|] == pref_seq; // assert-line
Expand Down
7 changes: 2 additions & 5 deletions 005-intersperse.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,17 @@ method intersperse(numbers: seq<int>, delimeter: int) returns (res: seq<int>)
res := [];
if (|numbers| != 0)
{
var i : int := 0;
while (i + 1 < |numbers|)
for i := 0 to |numbers| - 1
// invariants-start
invariant 0 <= i && i < |numbers|
invariant |res| == 2 * i
invariant forall i1 : int :: i1 >= 0 && i1 < |res| && i1 % 2 == 0 ==> res[i1] == numbers[i1 / 2]
invariant forall i1 : int :: i1 >= 0 && i1 < |res| && i1 % 2 == 1 ==> res[i1] == delimeter
// invariants-end
{
res := res + [numbers[i]];
res := res + [delimeter];
i := i + 1;
}
res := res + [numbers[i]];
res := res + [numbers[|numbers|-1]];
}
// impl-end
}
13 changes: 3 additions & 10 deletions 006-parse_nested_parens.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ method parse_paren_group(s : string) returns (max_depth : int)
// impl-start
var depth: int := 0;
max_depth := 0;
var i: int := 0;
while (i < |s|)
for i := 0 to |s|
{
var c: char := s[i];
if (c == '(') {
Expand All @@ -22,7 +21,6 @@ method parse_paren_group(s : string) returns (max_depth : int)
else {
depth := depth - 1;
}
i := i + 1;
}
// impl-end
}
Expand All @@ -38,10 +36,8 @@ method split(s : string) returns (res : seq<string>)
// impl-start
res := [];
var current_string : string := "";
var i : int := 0;
while (i < |s|)
for i := 0 to |s|
// invariants-start
invariant i >= 0 && i <= |s|
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
Expand All @@ -57,7 +53,6 @@ method split(s : string) returns (res : seq<string>)
{
current_string := current_string + [s[i]];
}
i := i + 1;
}
if (current_string != "") {
res := res + [current_string];
Expand All @@ -76,16 +71,14 @@ method parse_nested_parens(paren_string: string) returns (res : seq<int>)
{
// impl-start
var strings : seq<string> := split(paren_string);
var i : int := 0;
res := [];
while (i < |strings|)
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];
i := i + 1;
}
// impl-end
}
9 changes: 2 additions & 7 deletions 007-filter_by_substring.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@ method checkSubstring(s: string, sub: string) returns (result: bool)
}
else if (|s| >= |sub|)
{
var i: int := 0;
while (i <= |s| - |sub|)
for i := 0 to |s| - |sub|
{
if (s[i..i + |sub|] == sub)
{
result := true;
}
i := i + 1;
}
}
// impl-end
Expand All @@ -30,10 +28,8 @@ method filter_by_substring(strings: seq<string>, substring: string) returns (res
{
// impl-start
res := [];
var i : int := 0;
while (i < |strings|)
for i := 0 to |strings|
// invariants-start
invariant 0 <= i && i <= |strings|
invariant |res| <= i
invariant (forall s :: s in res ==> s in strings)
// invariants-end
Expand All @@ -43,7 +39,6 @@ method filter_by_substring(strings: seq<string>, substring: string) returns (res
{
res := res + [strings[i]];
}
i := i + 1;
}
// impl-end
}
6 changes: 1 addition & 5 deletions 008-sum_product.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ method sum_product(numbers: seq<int>) returns (s : int, p : int)
assert numbers[..|numbers|] == numbers; // assert-line
s := 0;
p := 1;
var i := 0;
while (i < |numbers|)
invariant 0 <= i <= |numbers|
for i := 0 to |numbers|
invariant s == sum(numbers[..i])
invariant p == prod(numbers[..i])
{
Expand All @@ -53,8 +51,6 @@ method sum_product(numbers: seq<int>) returns (s : int, p : int)
}
// assert-end
p := p * numbers[i];

i := i + 1;
}

return s, p;
Expand Down
5 changes: 1 addition & 4 deletions 009-rolling_max.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ method rolling_max(numbers: seq<int>) returns (result : seq<int>)
var running_max: Option<int> := None;
result := [];

var i : int := 0;
while (i < |numbers|)
for i := 0 to |numbers|
// invariants-start
invariant i >= 0 && i <= |numbers|
invariant |result| == i
invariant forall i1 : int :: i1 >= 0 && i1 < i ==> numbers[i1] <= result[i1]
invariant old(running_max) == None || (exists i : int :: old(running_max) == Some(i) && getVal(old(running_max)) <= getVal(running_max))
Expand All @@ -45,7 +43,6 @@ method rolling_max(numbers: seq<int>) returns (result : seq<int>)
match running_max {
case Some(n1) => result := result + [n1];
}
i := i + 1;
}
// impl-end
}
5 changes: 1 addition & 4 deletions 010-is_palindrome.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,13 @@ method reverse(str: string) returns (rev: string)
{
// impl-start
rev := "";
var i := 0;
while (i < |str|)
for i := 0 to |str|
// invariants-start
invariant i >= 0 && i <= |str|
invariant |rev| == i
invariant forall k :: 0 <= k < i ==> rev[k] == str[|str| - 1 - k]
// invariants-end
{
rev := rev + [str[|str| - i - 1]];
i := i + 1;
}
// impl-end
}
42 changes: 21 additions & 21 deletions 011-string_xor.dfy
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
method xor(a : char, b : char) returns (result : char)
// post-conditions-start
ensures result == (if a == b then '0' else '1')
// post-conditions-end
predicate represents_byte(a: char)
{
// impl-start
if (a == b) {
result := '0';
} else {
result := '1';
}
// impl-end
a in "01"
}

function char_xor(a: char, b: char): char
requires represents_byte(a)
requires represents_byte(b)
{
if (a == b) then
'0'
else
'1'
}

method string_xor(a: string, b: string) returns (result: string)
// pre-conditions-start
requires |a| == |b|
requires forall i :: 0 <= i < |a| ==> (a[i] == '0' || a[i] == '1')
requires forall i :: 0 <= i < |b| ==> (b[i] == '0' || b[i] == '1')
requires forall i :: 0 <= i < |a| ==> represents_byte(a[i])
requires forall i :: 0 <= i < |b| ==> represents_byte(b[i])
// pre-conditions-end
// post-conditions-start
ensures |result| == |a|
ensures forall i :: 0 <= i < |result| ==> (result[i] == '0' || result[i] == '1')
ensures forall i :: 0 <= i < |result| ==> result[i] == (if a[i] == b[i] then '0' else '1')
ensures forall i :: 0 <= i < |result| ==> represents_byte(result[i])
ensures forall i :: 0 <= i < |result| ==> result[i] == char_xor(a[i], b[i])
// post-conditions-end
{
// impl-start
result := "";
var i : int := 0;
while (i < |a|)
for i := 0 to |a|
// invariants-start
invariant i >= 0 && i <= |a|
invariant |result| == i
invariant forall j :: 0 <= j < i ==> result[j] == (if a[j] == b[j] then '0' else '1')
invariant forall i :: 0 <= i < |a| ==> represents_byte(a[i])
invariant forall i :: 0 <= i < |b| ==> represents_byte(b[i])
invariant forall j :: 0 <= j < i ==> result[j] == char_xor(a[j], b[j])
// invariants-end
{
var bitResult := if a[i] == b[i] then '0' else '1';
var bitResult := char_xor(a[i], b[i]);
result := result + [bitResult];
i := i + 1;
}
// impl-end
}
36 changes: 14 additions & 22 deletions 012-longest.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,25 @@ function getVal(mx : Option<string>) : string
method longest(strings: seq<string>) returns (result : Option<string>)
// post-conditions-start
ensures result == None <==> |strings| == 0
ensures result != None ==> (forall s :: s in strings ==> |getVal(result)| >= |s|)
ensures result != None ==> (exists s :: s in strings && |s| == |getVal(result)|)
ensures result != None ==> (exists i :: 0 <= i < |strings| && strings[i] == getVal(result) && forall j :: 0 <= j < i ==> |strings[j]| < |getVal(result)|)
ensures result != None ==> forall s :: s in strings ==> |getVal(result)| >= |s|
ensures result != None ==> getVal(result) in strings
// post-conditions-end
{
// impl-start
result := None;
if (|strings| != 0)
var mx : int := -1;
for i := 0 to |strings|
// invariants-start
invariant i == 0 <==> mx == -1
invariant forall s :: s in strings[0..i] ==> mx >= |s|
invariant result == None <==> mx == -1
invariant result != None ==> mx == |getVal(result)|
invariant result != None ==> getVal(result) in strings
// invariants-end
{
var i : int := 0;
var mx : int := -1;
while (i < |strings|)
// invariants-start
invariant i >= 0 && i <= |strings|
invariant (mx == -1) == (result == None)
invariant i == 0 ==> mx == -1
invariant i > 0 ==> (forall s :: s in strings[0..i] ==> mx >= |s|)
invariant i > 0 ==> (exists s :: s in strings && mx == |s|)
invariant i > 0 ==> mx == |getVal(result)|
invariant result != None ==> (exists i :: 0 <= i < |strings| && strings[i] == getVal(result) && forall j :: 0 <= j < i ==> |strings[j]| < |getVal(result)|)
// invariants-end
{
if (|strings[i]| > mx) {
mx := |strings[i]|;
result := Some(strings[i]);
}
i := i + 1;
if (|strings[i]| > mx) {
mx := |strings[i]|;
result := Some(strings[i]);
}
}
// impl-end
Expand Down
Loading

0 comments on commit a50f3ab

Please sign in to comment.