-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
049, 073, 081, 089, 108, 114, 128 (#34)
- Loading branch information
Showing
9 changed files
with
275 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
function modp_rec(n: int, p: int): int | ||
requires p > 0 | ||
requires n >= 0 | ||
{ | ||
if n == 0 then 1 % p else (modp_rec(n - 1, p) * 2) % p | ||
} | ||
|
||
method modp(n: int, p: int) returns (r: int) | ||
requires p > 0 | ||
requires n >= 0 | ||
ensures r == modp_rec(n, p) | ||
{ | ||
r := 1 % p; | ||
var i := 0; | ||
while i < n | ||
invariant 0 <= i <= n | ||
invariant r == modp_rec(i, p) | ||
{ | ||
r := (r * 2) % p; | ||
i := i + 1; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
method smallest_change(s: seq<int>) returns (c: int) | ||
ensures c == |set i {:trigger s[i]} | 0 <= i < |s| / 2 && s[i] != s[|s| - 1 - i]| | ||
{ | ||
ghost var pos := {}; | ||
c := 0; | ||
|
||
var i := 0; | ||
while i < |s| / 2 | ||
invariant 0 <= i <= |s| / 2 | ||
invariant pos == set j {:trigger s[j]} | 0 <= j < i && s[j] != s[|s| - 1 - j] | ||
invariant c == |pos| | ||
{ | ||
if s[i] != s[|s| - 1 - i] { | ||
pos := pos + {i}; | ||
c := c + 1; | ||
} | ||
i := i + 1; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
method numerical_letter_grade(grades: seq<real>) returns (letters: seq<string>) | ||
requires forall i :: 0 <= i < |grades| ==> 0.0 <= grades[i] <= 4.0 | ||
ensures |letters| == |grades| | ||
ensures forall i :: 0 <= i < |grades| && grades[i] == 4.0 ==> letters[i] == "A+" | ||
ensures forall i :: 0 <= i < |grades| && grades[i] < 4.0 && grades[i] > 3.7 ==> letters[i] == "A" | ||
ensures forall i :: 0 <= i < |grades| && grades[i] <= 3.7 && grades[i] > 3.3 ==> letters[i] == "A-" | ||
ensures forall i :: 0 <= i < |grades| && grades[i] <= 3.3 && grades[i] > 3.0 ==> letters[i] == "B+" | ||
ensures forall i :: 0 <= i < |grades| && grades[i] <= 3.0 && grades[i] > 2.7 ==> letters[i] == "B" | ||
ensures forall i :: 0 <= i < |grades| && grades[i] <= 2.7 && grades[i] > 2.3 ==> letters[i] == "B-" | ||
ensures forall i :: 0 <= i < |grades| && grades[i] <= 2.3 && grades[i] > 2.0 ==> letters[i] == "C+" | ||
ensures forall i :: 0 <= i < |grades| && grades[i] <= 2.0 && grades[i] > 1.7 ==> letters[i] == "C" | ||
ensures forall i :: 0 <= i < |grades| && grades[i] <= 1.7 && grades[i] > 1.3 ==> letters[i] == "C-" | ||
ensures forall i :: 0 <= i < |grades| && grades[i] <= 1.3 && grades[i] > 1.0 ==> letters[i] == "D+" | ||
ensures forall i :: 0 <= i < |grades| && grades[i] <= 1.0 && grades[i] > 0.7 ==> letters[i] == "D" | ||
ensures forall i :: 0 <= i < |grades| && grades[i] <= 0.7 && grades[i] > 0.0 ==> letters[i] == "D-" | ||
ensures forall i :: 0 <= i < |grades| && grades[i] == 0.0 ==> letters[i] == "E" | ||
{ | ||
letters := []; | ||
var i := 0; | ||
while i < |grades| | ||
invariant 0 <= i <= |grades| | ||
invariant |letters| == i | ||
invariant forall j :: 0 <= j < i && grades[j] == 4.0 ==> letters[j] == "A+" | ||
invariant forall j :: 0 <= j < i && grades[j] < 4.0 && grades[j] > 3.7 ==> letters[j] == "A" | ||
invariant forall j :: 0 <= j < i && grades[j] <= 3.7 && grades[j] > 3.3 ==> letters[j] == "A-" | ||
invariant forall j :: 0 <= j < i && grades[j] <= 3.3 && grades[j] > 3.0 ==> letters[j] == "B+" | ||
invariant forall j :: 0 <= j < i && grades[j] <= 3.0 && grades[j] > 2.7 ==> letters[j] == "B" | ||
invariant forall j :: 0 <= j < i && grades[j] <= 2.7 && grades[j] > 2.3 ==> letters[j] == "B-" | ||
invariant forall j :: 0 <= j < i && grades[j] <= 2.3 && grades[j] > 2.0 ==> letters[j] == "C+" | ||
invariant forall j :: 0 <= j < i && grades[j] <= 2.0 && grades[j] > 1.7 ==> letters[j] == "C" | ||
invariant forall j :: 0 <= j < i && grades[j] <= 1.7 && grades[j] > 1.3 ==> letters[j] == "C-" | ||
invariant forall j :: 0 <= j < i && grades[j] <= 1.3 && grades[j] > 1.0 ==> letters[j] == "D+" | ||
invariant forall j :: 0 <= j < i && grades[j] <= 1.0 && grades[j] > 0.7 ==> letters[j] == "D" | ||
invariant forall j :: 0 <= j < i && grades[j] <= 0.7 && grades[j] > 0.0 ==> letters[j] == "D-" | ||
invariant forall j :: 0 <= j < i && grades[j] == 0.0 ==> letters[j] == "E" | ||
{ | ||
if grades[i] == 4.0 { | ||
letters := letters + ["A+"]; | ||
} else if grades[i] > 3.7 { | ||
letters := letters + ["A"]; | ||
} else if grades[i] > 3.3 { | ||
letters := letters + ["A-"]; | ||
} else if grades[i] > 3.0 { | ||
letters := letters + ["B+"]; | ||
} else if grades[i] > 2.7 { | ||
letters := letters + ["B"]; | ||
} else if grades[i] > 2.3 { | ||
letters := letters + ["B-"]; | ||
} else if grades[i] > 2.0 { | ||
letters := letters + ["C+"]; | ||
} else if grades[i] > 1.7 { | ||
letters := letters + ["C"]; | ||
} else if grades[i] > 1.3 { | ||
letters := letters + ["C-"]; | ||
} else if grades[i] > 1.0 { | ||
letters := letters + ["D+"]; | ||
} else if grades[i] > 0.7 { | ||
letters := letters + ["D"]; | ||
} else if grades[i] > 0.0 { | ||
letters := letters + ["D-"]; | ||
} else { | ||
letters := letters + ["E"]; | ||
} | ||
|
||
i := i + 1; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
function rot_sym(c: char): char | ||
requires 'a' <= c <= 'z' | ||
ensures 'a' <= rot_sym(c) <= 'z' | ||
{ | ||
var alph := c as int - 'a' as int; | ||
((alph + 2 * 2) % 26 + 'a' as int) as char | ||
} | ||
|
||
method encrypt(s: string) returns (r: string) | ||
requires forall i :: 0 <= i < |s| ==> 'a' <= s[i] <= 'z' | ||
ensures |r| == |s| | ||
ensures forall i :: 0 <= i < |s| ==> r[i] == rot_sym(s[i]) | ||
{ | ||
r := ""; | ||
var i := 0; | ||
while i < |s| | ||
invariant 0 <= i <= |s| | ||
invariant |r| == i | ||
invariant forall j :: 0 <= j < i ==> r[j] == rot_sym(s[j]) | ||
{ | ||
r := r + [rot_sym(s[i])]; | ||
i := i + 1; | ||
} | ||
} | ||
|
||
method Main() { | ||
var s := "asdfghjkl"; | ||
var r := encrypt(s); | ||
assert r == "ewhjklnop"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
method count_nums(s: seq<int>) returns (cnt: nat) | ||
ensures cnt == |set i | 0 <= i < |s| && digits_sum(s[i]) > 0| | ||
{ | ||
ghost var found := {}; | ||
|
||
cnt := 0; | ||
var i := 0; | ||
while i < |s| | ||
invariant 0 <= i <= |s| | ||
invariant found == set j | 0 <= j < i && digits_sum(s[j]) > 0 | ||
invariant cnt == |found| | ||
{ | ||
if digits_sum(s[i]) > 0 { | ||
found := found + {i}; | ||
cnt := cnt + 1; | ||
} | ||
i := i + 1; | ||
} | ||
} | ||
|
||
function digits_sum(x: int): int | ||
decreases abs(x) | ||
{ | ||
if abs(x) < 10 then x else x % 10 + digits_sum(x / 10) | ||
} | ||
|
||
function abs(x: int): int | ||
ensures abs(x) >= 0 | ||
ensures abs(x) == x || abs(x) == -x | ||
{ | ||
if x >= 0 then x else -x | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
function Sum(a: seq<int>, s: int, t: int): int | ||
requires 0 <= s <= t <= |a| | ||
{ | ||
if s == t then 0 else Sum(a, s, t-1) + a[t-1] | ||
} | ||
|
||
method minSubArraySum(a: seq<int>) returns (s: int) | ||
ensures forall p,q :: 0 <= p <= q <= |a| ==> Sum(a, p, q) >= s | ||
ensures exists k, m :: 0 <= k <= m <= |a| && s == Sum(a, k, m) | ||
{ | ||
var k, m := 0, 0; | ||
s := 0; | ||
var n := 0; | ||
var c, t := 0, 0; | ||
while n < |a| | ||
invariant 0 <= c <= n <= |a| && t == Sum(a, c, n) | ||
invariant forall b :: 0 <= b <= n ==> Sum(a, b, n) >= Sum(a, c, n) | ||
invariant 0 <= k <= m <= n && s == Sum(a, k, m) | ||
invariant forall p,q :: 0 <= p <= q <= n ==> Sum(a, p, q) >= Sum(a, k, m) | ||
{ | ||
t, n := t + a[n], n + 1; | ||
if t > 0 { | ||
c, t := n, 0; | ||
} else if s > t { | ||
k, m, s := c, n, t; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
function abs(x: int): int | ||
ensures abs(x) >= 0 | ||
ensures abs(x) == x || abs(x) == -x | ||
ensures x >= 0 ==> abs(x) == x | ||
ensures x < 0 ==> abs(x) == -x | ||
{ | ||
if x >= 0 then x else -x | ||
} | ||
|
||
function sum_abs(s: seq<int>) : int | ||
ensures sum_abs(s) >= 0 | ||
{ | ||
if |s| == 0 then 0 else abs(s[0]) + sum_abs(s[1..]) | ||
} | ||
|
||
lemma sum_prop(s: seq<int>) | ||
requires |s| > 0 | ||
ensures sum_abs(s) == sum_abs(s[..|s| - 1]) + abs(s[|s| - 1]) | ||
{ | ||
if (|s| > 1) { | ||
assert (s[1..][..|s[1..]| - 1]) == s[1..|s| - 1]; | ||
} | ||
} | ||
|
||
method prod_signs(numbers: seq<int>) returns (s: int) | ||
ensures abs(s) == sum_abs(numbers) | ||
ensures |set i | 0 <= i < |numbers| && numbers[i] < 0| % 2 == 1 ==> s <= 0 | ||
ensures |set i | 0 <= i < |numbers| && numbers[i] < 0| % 2 == 0 ==> s >= 0 | ||
{ | ||
s := 0; | ||
var i := 0; | ||
while (i < |numbers|) | ||
invariant 0 <= i <= |numbers| | ||
invariant s == sum_abs(numbers[..i]) | ||
{ | ||
s := s + abs(numbers[i]); | ||
assert sum_abs(numbers[..i + 1]) == sum_abs(numbers[..i]) + abs(numbers[i]) by { | ||
assert numbers[..i+1][..i] == numbers[..i]; | ||
sum_prop(numbers[..i + 1]); | ||
} | ||
i := i + 1; | ||
} | ||
|
||
assert numbers == numbers[..|numbers|]; | ||
|
||
i := 0; | ||
ghost var negatives := {}; | ||
var cnt := 0; | ||
while (i < |numbers|) | ||
invariant 0 <= i <= |numbers| | ||
invariant cnt == |negatives| | ||
invariant negatives == set j | 0 <= j < i && numbers[j] < 0 | ||
{ | ||
if (numbers[i] < 0) { | ||
negatives := negatives + {i}; | ||
cnt := cnt + 1; | ||
} | ||
i := i + 1; | ||
} | ||
assert negatives == set i | 0 <= i < |numbers| && numbers[i] < 0; | ||
|
||
if (cnt % 2 == 1) { | ||
s := -s; | ||
} | ||
} | ||
|
||
method Main() { | ||
var nums := [1, 2, 2, -4]; | ||
var s := prod_signs(nums); | ||
print s; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters