Skip to content

Commit

Permalink
60, 85, 133, 142, 151 - generalized sum method (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
gt22 authored Aug 12, 2024
1 parent 2de9a2e commit eb3202d
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 25 deletions.
40 changes: 40 additions & 0 deletions 060-sum_to_n.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
function sum(s: seq<int>) : int
{
if |s| == 0 then 0 else s[0] + sum(s[1..])
}

lemma sum_prop(s: seq<int>)
requires |s| > 0
ensures sum(s) == sum(s[..|s| - 1]) + s[ |s| - 1 ]
{
if (|s| > 1) {
assert (s[1..][..|s[1..]| - 1]) == s[1..|s| - 1];
}
}

function number_seq(n: int) : (r : seq<int>)
requires n >= 0
ensures |r| == n
{
seq(n, i => i + 1)
}

method sum_squares(n: int) returns (r : int)
requires n >= 1
ensures r == sum(number_seq(n))
{
r := 0;
var k := 0;
ghost var v := number_seq(n);
while(k < n)
invariant 0 <= k <= |v|
invariant r == sum(v[..k])
{
assert v[..k + 1][..k] == v[..k];
r := r + (k + 1);
k := k + 1;
assert sum(v[..k]) == r by { sum_prop(v[..k]); }
}
assert v[..k] == v;
return r;
}
45 changes: 45 additions & 0 deletions 085-add.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
function sumc(s: seq<int>, p: seq<bool>) : int
requires |s| == |p|
{
if |s| == 0 then 0 else (if p[0] then s[0] else 0) + sumc(s[1..], p[1..])
}

lemma sum_prop(s: seq<int>, p: seq<bool>)
requires |s| > 0
requires |s| == |p|
ensures sumc(s, p) == sumc(s[..|s| - 1], p[..|s| - 1]) + (if p[ |s| - 1 ] then s[ |s| - 1 ] else 0)
{
if (|s| > 1) {
assert (s[1..][..|s[1..]| - 1]) == s[1..|s| - 1];
assert (p[1..][..|s[1..]| - 1]) == p[1..|s| - 1];
}
}

function add_conditon(lst: seq<int>) : (p : seq<bool>)
ensures |lst| == |p|
{
seq(|lst|, i requires 0 <= i < |lst| => i % 2 == 1 && lst[i] % 2 == 0)
}

method add(v: seq<int>) returns (r : int)
ensures r == sumc(v, add_conditon(v))
{
r := 0;
var k := 0;
var p := add_conditon(v);
while(k < |v|)
invariant 0 <= k <= |v|
invariant r == sumc(v[..k], p[..k])
{
assert v[..k + 1][..k] == v[..k];
assert p[..k + 1][..k] == p[..k];
r := r + if p[k] then v[k] else 0;
k := k + 1;
assert sumc(v[..k], p[..k]) == r by {
sum_prop(v[..k], p[..k]);
}
}
assert v[..k] == v;
assert p[..k] == p;
return r;
}
43 changes: 43 additions & 0 deletions 133-sum_squares.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
function sum(s: seq<int>) : int
{
if |s| == 0 then 0 else s[0] + sum(s[1..])
}

lemma sum_prop(s: seq<int>)
requires |s| > 0
ensures sum(s) == sum(s[..|s| - 1]) + s[ |s| - 1 ]
{
if (|s| > 1) {
assert (s[1..][..|s[1..]| - 1]) == s[1..|s| - 1];
}
}

function ceil(f: real) : (c : int)
{
(f + 1.0).Floor
}

function square_seq(lst: seq<real>) : (sq : seq<int>)
ensures |sq| == |lst|
{
seq(|lst|, i requires 0 <= i < |lst| => ceil(lst[i]) * ceil(lst[i]))
}

method sum_squares(lst: seq<real>) returns (r : int)
ensures r == sum(square_seq(lst))
{
r := 0;
var k := 0;
var v := square_seq(lst);
while(k < |lst|)
invariant 0 <= k <= |lst|
invariant r == sum(v[..k])
{
assert v[..k + 1][..k] == v[..k];
r := r + v[k];
k := k + 1;
assert sum(v[..k]) == r by { sum_prop(v[..k]); }
}
assert v[..k] == v;
return r;
}
55 changes: 35 additions & 20 deletions 142-sum_squares.dfy
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
method sum_squares(a : seq<int>) returns (result : seq<int>)
ensures |result| == |a|
ensures forall i : int :: i >= 0 && i < |result| && i % 3 == 0 ==> result[i] == a[i] * a[i]
ensures forall i : int :: i >= 0 && i < |result| && i % 4 == 0 && i % 3 != 0 ==> result[i] == a[i] * a[i] * a[i]
function sum(s: seq<int>) : int
{
if |s| == 0 then 0 else s[0] + sum(s[1..])
}

lemma sum_prop(s: seq<int>)
requires |s| > 0
ensures sum(s) == sum(s[..|s| - 1]) + s[ |s| - 1 ]
{
result := [];
var i := 0;
while i < |a|
invariant i >= 0 && i <= |a|
invariant |result| == i
invariant forall j : int :: j >= 0 && j < |result| && j % 3 == 0 ==> result[j] == a[j] * a[j]
invariant forall j : int :: j >= 0 && j < |result| && j % 4 == 0 && j % 3 != 0 ==> result[j] == a[j] * a[j] * a[j]
{
if i % 3 == 0 {
result := result + [a[i] * a[i]];
} else if i % 4 == 0 && i % 3 != 0 {
result := result + [a[i] * a[i] * a[i]];
} else {
result := result + [a[i]];
if (|s| > 1) {
assert (s[1..][..|s[1..]| - 1]) == s[1..|s| - 1];
}
i := i + 1;
}
}

function square_seq(lst: seq<int>) : (sq : seq<int>)
ensures |sq| == |lst|
{
seq(|lst|, i requires 0 <= i < |lst| => if i % 3 == 0 then lst[i] * lst[i] else (if i % 4 == 0 then lst[i] * lst[i] * lst[i] else lst[i]))
}

method sum_squares(lst: seq<int>) returns (r : int)
ensures r == sum(square_seq(lst))
{
r := 0;
var k := 0;
var v := square_seq(lst);
while(k < |lst|)
invariant 0 <= k <= |lst|
invariant r == sum(v[..k])
{
assert v[..k + 1][..k] == v[..k];
r := r + v[k];
k := k + 1;
assert sum(v[..k]) == r by { sum_prop(v[..k]); }
}
assert v[..k] == v;
return r;
}
53 changes: 53 additions & 0 deletions 151-double_the_difference.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
function sumc(s: seq<int>, p: seq<bool>) : int
requires |s| == |p|
{
if |s| == 0 then 0 else (if p[0] then s[0] else 0) + sumc(s[1..], p[1..])
}

lemma sum_prop(s: seq<int>, p: seq<bool>)
requires |s| > 0
requires |s| == |p|
ensures sumc(s, p) == sumc(s[..|s| - 1], p[..|s| - 1]) + (if p[ |s| - 1 ] then s[ |s| - 1 ] else 0)
{
if (|s| > 1) {
assert (s[1..][..|s[1..]| - 1]) == s[1..|s| - 1];
assert (p[1..][..|s[1..]| - 1]) == p[1..|s| - 1];
}
}

function add_conditon(lst: seq<int>) : (p : seq<bool>)
ensures |lst| == |p|
{
seq(|lst|, i requires 0 <= i < |lst| => lst[i] >= 0 && lst[i] % 2 == 1)
}

function square_seq(lst: seq<int>) : (sq : seq<int>)
ensures |sq| == |lst|
ensures forall i :: 0 <= i < |lst| ==> sq[i] == lst[i] * lst[i]
{
seq(|lst|, i requires 0 <= i < |lst| => lst[i] * lst[i])
}

method double_the_difference(lst: seq<int>) returns (r : int)
ensures r == sumc(square_seq(lst), add_conditon(lst))
{
r := 0;
var k := 0;
var v := square_seq(lst);
var p := add_conditon(lst);
while(k < |lst|)
invariant 0 <= k <= |lst|
invariant r == sumc(v[..k], p[..k])
{
assert v[..k + 1][..k] == v[..k];
assert p[..k + 1][..k] == p[..k];
r := r + if p[k] then v[k] else 0;
k := k + 1;
assert sumc(v[..k], p[..k]) == r by {
sum_prop(v[..k], p[..k]);
}
}
assert v[..k] == v;
assert p[..k] == p;
return r;
}
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Current status:
- [ ] 57. monotonic
- [x] 58. common
- [x] 59. largest_prime_factor
- [ ] 60. sum_to_n
- [x] 60. sum_to_n
- [ ] 61. correct_bracketing
- [ ] 62. derivative
- [ ] 63. fibfib
Expand All @@ -87,7 +87,7 @@ Current status:
- [ ] 82. prime_length
- [ ] 83. starts_one_ends
- [ ] 84. solve
- [ ] 85. add
- [x] 85. add
- [ ] 86. anti_shuffle
- [ ] 87. get_row
- [ ] 88. sort_array
Expand Down Expand Up @@ -135,7 +135,7 @@ Current status:
- [x] 130. tri
- [ ] 131. digits
- [ ] 132. is_nested
- [ ] 133. sum_squares
- [x] 133. sum_squares
- [ ] 134. check_if_last_char_is_a_letter
- [ ] 135. can_arrange
- [ ] 136. largest_smallest_integers
Expand All @@ -144,7 +144,7 @@ Current status:
- [x] 139. special_factorial
- [ ] 140. fix_spaces
- [ ] 141. file_name_check
- [ ] 142. sum_squares
- [x] 142. sum_squares
- [ ] 143. words_in_sentence
- [ ] 144. simplify
- [ ] 145. order_by_points
Expand All @@ -153,7 +153,7 @@ Current status:
- [x] 148. bf
- [ ] 149. sorted_list_sum
- [x] 150. x_or_y
- [ ] 151. double_the_difference
- [x] 151. double_the_difference
- [x] 152. compare
- [x] 153. Strongest_Extension
- [x] 154. cycpattern_check
Expand Down

0 comments on commit eb3202d

Please sign in to comment.