Skip to content

Commit

Permalink
055, 057, 062, 063, 064, 066 (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
WeetHet authored Aug 14, 2024
1 parent 46d66ff commit 9e7521d
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 6 deletions.
35 changes: 35 additions & 0 deletions 055-fib.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
function fib(n: nat): nat
decreases n
{
if n == 0 then 0
else if n == 1 then 1
else fib(n - 1) + fib(n - 2)
}

method ComputeFib(n: nat) returns (result: nat)
ensures result == fib(n)
{
if n == 0 {
return 0;
}

if n == 1 {
return 1;
}

var a, b := 0, 1;
var i := 2;

while i <= n
invariant 2 <= i <= n + 1
invariant a == fib(i - 2)
invariant b == fib(i - 1)
{
var temp := a + b;
a := b;
b := temp;
i := i + 1;
}

return b;
}
28 changes: 28 additions & 0 deletions 057-monotonic.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
method monotonic(xs: seq<int>) returns (result: bool)
requires |xs| > 0
ensures result <==> (forall i, j :: 0 <= i < j < |xs| ==> xs[i] < xs[j]) || (forall i, j :: 0 <= i < j < |xs| ==> xs[i] > xs[j])
{
if |xs| == 1 {
return true;
}

var increasing := true;
var decreasing := true;
var i := 1;

while i < |xs|
invariant 1 <= i <= |xs|
invariant increasing <==> (forall j, k :: 0 <= j < k < i ==> xs[j] < xs[k])
invariant decreasing <==> (forall j, k :: 0 <= j < k < i ==> xs[j] > xs[k])
{
if xs[i - 1] >= xs[i] {
increasing := false;
}
if xs[i - 1] <= xs[i] {
decreasing := false;
}
i := i + 1;
}

result := increasing || decreasing;
}
16 changes: 16 additions & 0 deletions 062-derivative.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
method derivative(xs: seq<int>) returns (result: seq<int>)
requires |xs| > 0
ensures |result| == |xs| - 1
ensures forall i :: 0 <= i < |result| ==> result[i] == xs[i+1] * (i+1)
{
result := [];
var i := 1;
while i < |xs|
invariant 1 <= i <= |xs|
invariant |result| == i - 1
invariant forall j :: 0 <= j < |result| ==> result[j] == xs[j+1] * (j+1)
{
result := result + [xs[i] * i];
i := i + 1;
}
}
37 changes: 37 additions & 0 deletions 063-fibfib.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function fibfib(n: nat): nat
decreases n
{
if n == 0 || n == 1 then 0
else if n == 2 then 1
else fibfib(n - 1) + fibfib(n - 2) + fibfib(n - 3)
}

method ComputeFibFib(n: nat) returns (result: nat)
ensures result == fibfib(n)
{
if n == 0 || n == 1 {
return 0;
}

if n == 2 {
return 1;
}

var a, b, c := 0, 0, 1;
var i := 3;

while i <= n
invariant 3 <= i <= n + 1
invariant a == fibfib(i-3)
invariant b == fibfib(i-2)
invariant c == fibfib(i-1)
{
var temp := c + b + a;
a := b;
b := c;
c := temp;
i := i + 1;
}

return c;
}
28 changes: 28 additions & 0 deletions 064-vowel_count.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
method vowel_count(s: string) returns (count: int)
ensures count >= 0
ensures count == |(set i | 0 <= i < |s| && is_vowel(s[i]))| + if |s| > 0 && s[|s| - 1] == 'y' then 1 else 0
{
ghost var found := {};
count := 0;
var i := 0;
while i < |s|
invariant 0 <= i <= |s|
invariant count == |found|
invariant forall j :: 0 <= j < i && is_vowel(s[j]) ==> j in found
invariant forall x :: x in found ==> x < i
invariant found == (set j | 0 <= j < i && is_vowel(s[j]))
{
if is_vowel(s[i]) {
found := found + {i};
count := count + 1;
}
i := i + 1;
}
count := count + if |s| > 0 && s[|s| - 1] == 'y' then 1 else 0;
}

function is_vowel(c: char): bool
ensures is_vowel(c) <==> c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U'
{
c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U'
}
44 changes: 44 additions & 0 deletions 066-digitSum.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
function upper_sum_rec(s: string): int
ensures upper_sum_rec(s) >= 0
{
if |s| == 0 then
0
else
var remaining := upper_sum_rec(s[1..]);
to_int(s[0]) + remaining
}

lemma upper_sum_rec_prop(s: string)
requires |s| > 0
ensures upper_sum_rec(s) == upper_sum_rec(s[..|s|-1]) + to_int(s[|s|-1])
{
if (|s| > 1) {
assert (s[1..][..|s[1..]| - 1]) == s[1..|s| - 1];
}
}

function to_int(c: char): int
ensures 'A' <= c <= 'Z' ==> to_int(c) == c as int
ensures c < 'A' || c > 'Z' ==> to_int(c) == 0
{
if 'A' <= c <= 'Z' then c as int else 0
}

method upper_sum(s: string) returns (res: int)
ensures res == upper_sum_rec(s)
{
res := 0;
var i := 0;
while (i < |s|)
invariant 0 <= i <= |s|
invariant res == upper_sum_rec(s[..i])
{
res := res + to_int(s[i]);
assert upper_sum_rec(s[..i + 1]) == upper_sum_rec(s[..i]) + to_int(s[i]) by {
assert s[..i+1][..i] == s[..i];
upper_sum_rec_prop(s[..i + 1]);
}
i := i + 1;
}
assert s == s[..|s|];
}
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,18 @@ Current status:
- [x] 52. below_threshold
- [x] 53. add
- [x] 54. same_chars
- [ ] 55. fib
- [x] 55. fib
- [ ] 56. correct_bracketing
- [ ] 57. monotonic
- [x] 57. monotonic
- [x] 58. common
- [x] 59. largest_prime_factor
- [x] 60. sum_to_n
- [ ] 61. correct_bracketing
- [ ] 62. derivative
- [ ] 63. fibfib
- [ ] 64. vowels_count
- [x] 62. derivative
- [x] 63. fibfib
- [x] 64. vowels_count
- [ ] 65. circular_shift
- [ ] 66. digitSum
- [x] 66. digitSum
- [ ] 67. fruit_distribution
- [x] 68. pluck
- [x] 69. search
Expand Down

0 comments on commit 9e7521d

Please sign in to comment.