Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor fixes, implementation of 018-how_many_times #52

Merged
merged 7 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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