From a50f3abf812ee8ae327a0028b88444e0e7e11377 Mon Sep 17 00:00:00 2001 From: Komi Golov Date: Wed, 2 Oct 2024 15:49:02 +0200 Subject: [PATCH] Minor fixes, implementation of 018-how_many_times (#52) 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. --- 000-has_close_elements.dfy | 11 ++---- 001-separate-paren-groups.dfy | 6 +--- 003-below_zero.dfy | 5 +-- 004-mean_absolute_derivation.dfy | 10 ++---- 005-intersperse.dfy | 7 ++-- 006-parse_nested_parens.dfy | 13 ++----- 007-filter_by_substring.dfy | 9 ++--- 008-sum_product.dfy | 6 +--- 009-rolling_max.dfy | 5 +-- 010-is_palindrome.dfy | 5 +-- 011-string_xor.dfy | 42 +++++++++++----------- 012-longest.dfy | 36 ++++++++----------- 018-how_many_times.dfy | 26 ++++++++++++++ 020-find_closest_elements.dfy | 60 ++++++++++++++------------------ 021-rescale_to_unit.dfy | 17 +++------ 026-remove_duplicates.dfy | 10 ++---- 029-filter_by_prefix.dfy | 5 +-- 030-get-positive.dfy | 5 +-- 031-is-prime.dfy | 6 ++-- 033-sort_third.dfy | 14 ++------ 20 files changed, 117 insertions(+), 181 deletions(-) create mode 100644 018-how_many_times.dfy diff --git a/000-has_close_elements.dfy b/000-has_close_elements.dfy index 5e2f9f8..3d8eba7 100644 --- a/000-has_close_elements.dfy +++ b/000-has_close_elements.dfy @@ -16,18 +16,13 @@ method has_close_elements(numbers: seq, 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 { @@ -39,9 +34,7 @@ method has_close_elements(numbers: seq, threshold: real) returns (flag : b flag := true; } } - j := j + 1; } - i := i + 1; } // impl-end } diff --git a/001-separate-paren-groups.dfy b/001-separate-paren-groups.dfy index b4dc20d..ba406af 100644 --- a/001-separate-paren-groups.dfy +++ b/001-separate-paren-groups.dfy @@ -106,11 +106,8 @@ method separate_paren_groups(paren_string: string) returns (res : seq) 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 @@ -149,7 +146,6 @@ method separate_paren_groups(paren_string: string) returns (res : seq) current_string := ""; } } - i := i + 1; } // impl-end } diff --git a/003-below_zero.dfy b/003-below_zero.dfy index 67e5106..a8eb177 100644 --- a/003-below_zero.dfy +++ b/003-below_zero.dfy @@ -24,10 +24,8 @@ method below_zero(ops: seq) 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 @@ -41,7 +39,6 @@ method below_zero(ops: seq) returns (res : bool) if (balance < 0) { return false; } - i := i + 1; } return true; // impl-end diff --git a/004-mean_absolute_derivation.dfy b/004-mean_absolute_derivation.dfy index 6e0f4e1..87bf1e8 100644 --- a/004-mean_absolute_derivation.dfy +++ b/004-mean_absolute_derivation.dfy @@ -34,10 +34,8 @@ method mean_absolute_derivation(numbers: seq) 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 { @@ -48,7 +46,6 @@ method mean_absolute_derivation(numbers: seq) returns (derivation: real) sum_prop(numbers[..i + 1]); } // assert-end - i := i + 1; } var m := s / |numbers| as real; @@ -56,12 +53,10 @@ method mean_absolute_derivation(numbers: seq) returns (derivation: real) 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]) @@ -80,7 +75,6 @@ method mean_absolute_derivation(numbers: seq) returns (derivation: real) // assert-end t := t + abs(numbers[i] - m); - i := i + 1; } assert pref_seq[..|pref_seq|] == pref_seq; // assert-line diff --git a/005-intersperse.dfy b/005-intersperse.dfy index 10c7c48..a6c9622 100644 --- a/005-intersperse.dfy +++ b/005-intersperse.dfy @@ -10,10 +10,8 @@ method intersperse(numbers: seq, delimeter: int) returns (res: seq) 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 @@ -21,9 +19,8 @@ method intersperse(numbers: seq, delimeter: int) returns (res: seq) { res := res + [numbers[i]]; res := res + [delimeter]; - i := i + 1; } - res := res + [numbers[i]]; + res := res + [numbers[|numbers|-1]]; } // impl-end } diff --git a/006-parse_nested_parens.dfy b/006-parse_nested_parens.dfy index e01f4b9..bc0dfb0 100644 --- a/006-parse_nested_parens.dfy +++ b/006-parse_nested_parens.dfy @@ -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 == '(') { @@ -22,7 +21,6 @@ method parse_paren_group(s : string) returns (max_depth : int) else { depth := depth - 1; } - i := i + 1; } // impl-end } @@ -38,10 +36,8 @@ method split(s : string) returns (res : seq) // 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 @@ -57,7 +53,6 @@ method split(s : string) returns (res : seq) { current_string := current_string + [s[i]]; } - i := i + 1; } if (current_string != "") { res := res + [current_string]; @@ -76,16 +71,14 @@ method parse_nested_parens(paren_string: string) returns (res : seq) { // impl-start var strings : seq := 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 } diff --git a/007-filter_by_substring.dfy b/007-filter_by_substring.dfy index f6e69ea..752890b 100644 --- a/007-filter_by_substring.dfy +++ b/007-filter_by_substring.dfy @@ -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 @@ -30,10 +28,8 @@ method filter_by_substring(strings: seq, 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 @@ -43,7 +39,6 @@ method filter_by_substring(strings: seq, substring: string) returns (res { res := res + [strings[i]]; } - i := i + 1; } // impl-end } diff --git a/008-sum_product.dfy b/008-sum_product.dfy index c4e3f9b..9d74fef 100644 --- a/008-sum_product.dfy +++ b/008-sum_product.dfy @@ -32,9 +32,7 @@ method sum_product(numbers: seq) 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]) { @@ -53,8 +51,6 @@ method sum_product(numbers: seq) returns (s : int, p : int) } // assert-end p := p * numbers[i]; - - i := i + 1; } return s, p; diff --git a/009-rolling_max.dfy b/009-rolling_max.dfy index 62b5bf3..bab7f6f 100644 --- a/009-rolling_max.dfy +++ b/009-rolling_max.dfy @@ -20,10 +20,8 @@ method rolling_max(numbers: seq) returns (result : seq) var running_max: Option := 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)) @@ -45,7 +43,6 @@ method rolling_max(numbers: seq) returns (result : seq) match running_max { case Some(n1) => result := result + [n1]; } - i := i + 1; } // impl-end } diff --git a/010-is_palindrome.dfy b/010-is_palindrome.dfy index e859143..99641d6 100644 --- a/010-is_palindrome.dfy +++ b/010-is_palindrome.dfy @@ -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 } diff --git a/011-string_xor.dfy b/011-string_xor.dfy index e167a8f..83c9872 100644 --- a/011-string_xor.dfy +++ b/011-string_xor.dfy @@ -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 } diff --git a/012-longest.dfy b/012-longest.dfy index c500ce3..073de15 100644 --- a/012-longest.dfy +++ b/012-longest.dfy @@ -11,33 +11,25 @@ function getVal(mx : Option) : string method longest(strings: seq) returns (result : Option) // 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 diff --git a/018-how_many_times.dfy b/018-how_many_times.dfy new file mode 100644 index 0000000..351ced4 --- /dev/null +++ b/018-how_many_times.dfy @@ -0,0 +1,26 @@ +method how_many_times(s: string, substr: string) returns (times: int) + // post-condition-start + ensures times == |set i {:trigger} | 0 <= i <= |s| - |substr| && s[i..i+|substr|] == substr| + // post-condition-end +{ + // impl-start + times := 0; + if (|substr| > |s|) { + return; + } + ghost var starts: set := {}; + for i := 0 to |s| - |substr| + 1 + // invariants-start + invariant forall j :: j in starts ==> j < i + invariant |starts| == times + invariant starts == set j {:trigger} | 0 <= j < i && s[j..j+|substr|] == substr + // invariants-end + { + if s[i..i+|substr|] == substr { + times := times + 1; + starts := starts + {i}; + } + } + assert starts == set i {:trigger} | 0 <= i <= |s| - |substr| && s[i..i+|substr|] == substr; // assert-line + // impl-end +} diff --git a/020-find_closest_elements.dfy b/020-find_closest_elements.dfy index d79f236..1eed4dc 100644 --- a/020-find_closest_elements.dfy +++ b/020-find_closest_elements.dfy @@ -1,9 +1,9 @@ function dist(a: real, b: real) : (d : real) ensures d >= 0.0 ensures (d == 0.0) <==> a == b - { - if a < b then b - a else a - b - } +{ + if a < b then b - a else a - b +} // distinct elements @@ -20,42 +20,36 @@ method find_closest_elements(s: seq) returns (l : real, h : real) ensures forall a, b : int :: des(s, a, b) ==> dist(l, h) <= dist(s[a], s[b]) ensures l <= h // post-conditions-end +{ + // impl-start + l := s[0]; + h := s[1]; + var d : real := dist(l, h); + for i := 0 to |s| + // invariants-start + invariant d == dist(l, h) + invariant exists a, b :: des(s, a, b) && l == s[a] && h == s[b] + invariant forall a, b :: a < i && des(s, a, b) ==> d <= dist(s[a], s[b]) + // invariants-end { - // impl-start - l := s[0]; - h := s[1]; - var d : real := dist(l, h); - var i : int := 0; - while (i < |s|) + for j := i + 1 to |s| // invariants-start - invariant 0 <= i <= |s| invariant d == dist(l, h) invariant exists a, b :: des(s, a, b) && l == s[a] && h == s[b] - invariant forall a, b :: a < i && des(s, a, b) ==> d <= dist(s[a], s[b]) + invariant forall a, b :: (a < i || (a == i && b < j)) && des(s, a, b) ==> d <= dist(s[a], s[b]) // invariants-end { - var j : int := i + 1; - while (j < |s|) - // invariants-start - invariant 0 <= j <= |s| - invariant d == dist(l, h) - invariant exists a, b :: des(s, a, b) && l == s[a] && h == s[b] - invariant forall a, b :: (a < i || (a == i && b < j)) && des(s, a, b) ==> d <= dist(s[a], s[b]) - // invariants-end - { - if dist(s[i], s[j]) <= d { - l := s[i]; - h := s[j]; - d := dist(l, h); - } - j := j + 1; + if dist(s[i], s[j]) <= d { + l := s[i]; + h := s[j]; + d := dist(l, h); } - i := i + 1; } - if (l <= h) { - return l, h; - } else { - return h, l; - } - // impl-end } + if (l <= h) { + return l, h; + } else { + return h, l; + } + // impl-end +} diff --git a/021-rescale_to_unit.dfy b/021-rescale_to_unit.dfy index 76c0435..c0b1b31 100644 --- a/021-rescale_to_unit.dfy +++ b/021-rescale_to_unit.dfy @@ -1,6 +1,5 @@ -function affine(x: real, shift: real, scale: real) : (y : real) +function affine(x: real, shift: real, scale: real) : real requires scale > 0.0 - ensures y == (x + shift) / scale { (x + shift) / scale } @@ -45,10 +44,8 @@ method rescale_to_unit(s: seq) returns (r : seq) // impl-start var mni : int := if s[0] < s[1] then 0 else 1; var mxi : int := if s[0] < s[1] then 1 else 0; - var i : int := 2; - while (i < |s|) + for i := 2 to |s| // invariants-start - invariant 0 <= i <= |s| invariant 0 <= mni < |s| invariant 0 <= mxi < |s| invariant forall j : int :: (0 <= j < i) ==> s[mni] <= s[j] <= s[mxi] @@ -61,30 +58,25 @@ method rescale_to_unit(s: seq) returns (r : seq) if (s[i] > s[mxi]) { mxi := i; } - i := i + 1; } var shift := -s[mni]; var scale := s[mxi] - s[mni]; assert scale > 0.0; // assert-line r := []; - var j := 0; - while (j < |s|) + for j := 0 to |s| // invariants-start - invariant 0 <= j <= |s| invariant |r| == j invariant forall k : int :: 0 <= k < j ==> 0.0 <= r[k] <= 1.0 invariant affine_seq(s[..j], r, shift, scale) // invariants-end { - var rj : real := s[j] + shift; - rj := rj / scale; + var rj : real := affine(s[j], shift, scale); // assert-start assert rj <= 1.0 by { div_unit(s[j] + shift, scale); } // assert-end r := r + [rj]; - j := j + 1; } assert s[..|s|] == s; // assert-line // assert-start @@ -97,6 +89,5 @@ method rescale_to_unit(s: seq) returns (r : seq) affine_unit(s[mxi], shift, scale); } // assert-end - return r; // impl-end } diff --git a/026-remove_duplicates.dfy b/026-remove_duplicates.dfy index 46887ba..79365a8 100644 --- a/026-remove_duplicates.dfy +++ b/026-remove_duplicates.dfy @@ -9,10 +9,8 @@ method remove_duplicates(a: seq) returns (result: seq) { // impl-start var res: seq := []; - var i := 0; - while i < |a| + for i := 0 to |a| // invariants-start - invariant 0 <= i <= |a| invariant forall j :: 0 <= j < |res| ==> count_rec(a, res[j]) == 1 invariant forall j :: 0 <= j < i ==> (a[j] in res <==> count_rec(a, a[j]) == 1) invariant forall j :: 0 <= j < |res| ==> res[j] in a[..i] @@ -22,7 +20,6 @@ method remove_duplicates(a: seq) returns (result: seq) if cnt == 1 { res := res + [a[i]]; } - i := i + 1; } result := res; // impl-end @@ -51,10 +48,8 @@ method count(a: seq, x: int) returns (cnt: int) // impl-start cnt := 0; ghost var positions: set := {}; - var i := 0; - while i < |a| + for i := 0 to |a| // invariants-start - invariant 0 <= i <= |a| invariant cnt == |positions| invariant positions == set k | 0 <= k < i && a[k] == x invariant cnt == count_rec(a[..i], x) @@ -70,7 +65,6 @@ method count(a: seq, x: int) returns (cnt: int) count_prop(a[..i + 1], x); } // assert-end - i := i + 1; } assert a == a[..|a|]; // assert-line // impl-end diff --git a/029-filter_by_prefix.dfy b/029-filter_by_prefix.dfy index 0821323..b36098c 100644 --- a/029-filter_by_prefix.dfy +++ b/029-filter_by_prefix.dfy @@ -5,17 +5,14 @@ method filter_by_prefix(xs: seq, p: string) returns (filtered: seq starts_with(filtered[j], p) // invariants-end { if starts_with(xs[i], p) { filtered := filtered + [xs[i]]; } - i := i + 1; } // impl-end } diff --git a/030-get-positive.dfy b/030-get-positive.dfy index 3b9bb63..21f7789 100644 --- a/030-get-positive.dfy +++ b/030-get-positive.dfy @@ -8,10 +8,8 @@ method get_positive(l : seq) returns (result : seq) { // impl-start result := []; - var i : int := 0; - while i < |l| + for i := 0 to |l| // invariants-start - invariant i >= 0 && i <= |l| invariant |result| <= i invariant forall i1 : int :: i1 >= 0 && i1 < |result| ==> result[i1] > 0 invariant i > 0 ==> (l[i - 1] > 0 ==> exists i2 :: i2 >= 0 && i2 < |result| && result[i2] == l[i - 1]) @@ -29,7 +27,6 @@ method get_positive(l : seq) returns (result : seq) assert forall i1 :: i1 >= 0 && i1 < |res_prev| ==> res_prev[i1] == result[i1]; // assert-line assert forall i1 :: i1 >= 0 && i1 < i ==> (l[i1] > 0 ==> exists i2 :: i2 >= 0 && i2 < |res_prev| && res_prev[i2] == l[i1]); // assert-line } - i := i + 1; } // impl-end } diff --git a/031-is-prime.dfy b/031-is-prime.dfy index 16bba25..a467824 100644 --- a/031-is-prime.dfy +++ b/031-is-prime.dfy @@ -8,19 +8,17 @@ method is_prime(k: int) returns (result: bool) // post-conditions-end { // impl-start - var i := 2; result := true; - while i < k + for i := 2 to k // invariants-start - invariant 2 <= i <= k invariant !result ==> exists j :: 2 <= j < i && k % j == 0 invariant result ==> forall j :: 2 <= j < i ==> k % j != 0 // invariants-end { if k % i == 0 { result := false; + return; } - i := i + 1; } // impl-end } diff --git a/033-sort_third.dfy b/033-sort_third.dfy index 154aa3a..4727415 100644 --- a/033-sort_third.dfy +++ b/033-sort_third.dfy @@ -12,16 +12,13 @@ method sort_third(a: seq) returns (sorted_even: seq) { // impl-start var p := []; - var i := 0; - while i < |a| + for i := 0 to |a| // invariants-start - invariant 0 <= i <= |a| invariant |p| == i invariant forall j :: 0 <= j < i ==> p[j] == (j % 3 == 0) // invariants-end { p := p + [i % 3 == 0]; - i := i + 1; } sorted_even := SortSeqPred(a, p); @@ -41,10 +38,8 @@ method SortSeqPred(s: seq, p: seq) returns (sorted: seq) { // impl-start sorted := s; - var i := 0; - while i < |sorted| + for i := 0 to |sorted| // invariants-start - invariant 0 <= i <= |sorted| invariant |sorted| == |s| invariant forall j, k :: 0 <= j < k < i && p[j] && p[k] ==> sorted[j] <= sorted[k] invariant multiset(s) == multiset(sorted) @@ -55,8 +50,7 @@ method SortSeqPred(s: seq, p: seq) returns (sorted: seq) { if p[i] { var minIndex := i; - var j := i + 1; - while j < |sorted| + for j := i + 1 to |sorted| // invariants-start invariant i <= minIndex < j <= |sorted| invariant p[minIndex] @@ -66,14 +60,12 @@ method SortSeqPred(s: seq, p: seq) returns (sorted: seq) if p[j] && sorted[j] < sorted[minIndex] { minIndex := j; } - j := j + 1; } if minIndex != i { var temp := sorted[i]; sorted := sorted[i := sorted[minIndex]][minIndex := temp]; } } - i := i + 1; } // impl-end }