-
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.
- Loading branch information
Showing
9 changed files
with
246 additions
and
17 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,34 @@ | ||
function tri(n: nat): nat | ||
decreases if n % 2 == 0 then 0 else n | ||
{ | ||
if n == 1 then 3 | ||
else if n % 2 == 0 then 1 + n / 2 | ||
else tri(n - 1) + tri(n - 2) + tri(n + 1) | ||
} | ||
|
||
method Tribonacci(n: nat) returns (result: seq<nat>) | ||
ensures |result| == n + 1 | ||
ensures forall i :: 0 <= i <= n ==> result[i] == tri(i) | ||
{ | ||
if n == 0 { | ||
result := [1]; | ||
} else { | ||
result := [1, 3]; | ||
var i := 2; | ||
while i <= n | ||
invariant 0 <= i <= n + 1 | ||
invariant |result| == i | ||
invariant forall j :: 0 <= j < i ==> result[j] == tri(j) | ||
{ | ||
if i % 2 == 0 { | ||
result := result + [1 + i / 2]; | ||
} else { | ||
assert result[i - 2] == tri(i - 2); | ||
assert result[i - 1] == tri(i - 1); | ||
assert (i + 3) / 2 == tri(i + 1); | ||
result := result + [result[i - 2] + result[i - 1] + (i + 3) / 2]; | ||
} | ||
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,31 @@ | ||
function factorial(n: nat): nat | ||
decreases n | ||
{ | ||
if n == 0 then 1 else n * factorial(n - 1) | ||
} | ||
|
||
function special_factorial_rec(n: nat): nat | ||
decreases n | ||
{ | ||
if n == 0 then 1 else factorial(n) * special_factorial_rec(n - 1) | ||
} | ||
|
||
method special_factorial(n: nat) returns (result: nat) | ||
requires n > 0 | ||
ensures result == special_factorial_rec(n) | ||
{ | ||
result := 1; | ||
var fact := 1; | ||
|
||
var i := 0; | ||
while i < n | ||
invariant 0 <= i <= n | ||
invariant result == special_factorial_rec(i) | ||
invariant fact == factorial(i) | ||
decreases n - i + 1 | ||
{ | ||
i := i + 1; | ||
fact := fact * i; | ||
result := result * fact; | ||
} | ||
} |
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 @@ | ||
datatype Planet = Mercury | Venus | Earth | Mars | Jupiter | Saturn | Uranus | Neptune | ||
datatype Option<T> = Some(value: T) | None | ||
|
||
function PlanetFromString(name: string): Option<Planet> | ||
ensures PlanetFromString(name).Some? ==> 0 <= PlanetIndex(PlanetFromString(name).value) <= 7 | ||
{ | ||
match name | ||
case "Mercury" => Some(Mercury) | ||
case "Venus" => Some(Venus) | ||
case "Earth" => Some(Earth) | ||
case "Mars" => Some(Mars) | ||
case "Jupiter" => Some(Jupiter) | ||
case "Saturn" => Some(Saturn) | ||
case "Uranus" => Some(Uranus) | ||
case "Neptune" => Some(Neptune) | ||
case _ => None | ||
} | ||
|
||
function PlanetIndex(p: Planet): int | ||
{ | ||
match p | ||
case Mercury => 0 | ||
case Venus => 1 | ||
case Earth => 2 | ||
case Mars => 3 | ||
case Jupiter => 4 | ||
case Saturn => 5 | ||
case Uranus => 6 | ||
case Neptune => 7 | ||
} | ||
|
||
function GetPlanetsBetween(planet1: string, planet2: string): seq<string> | ||
ensures |GetPlanetsBetween(planet1, planet2)| <= 6 | ||
{ | ||
var p1 := PlanetFromString(planet1); | ||
var p2 := PlanetFromString(planet2); | ||
if p1.None? || p2.None? then | ||
[] | ||
else | ||
var i1 := PlanetIndex(p1.value); | ||
var i2 := PlanetIndex(p2.value); | ||
if i1 < i2 then | ||
GetPlanetsBetweenIndices(i1 + 1, i2 - 1) | ||
else if i1 > i2 then | ||
GetPlanetsBetweenIndices(i2 + 1, i1 - 1) | ||
else | ||
[] | ||
} | ||
|
||
function GetPlanetsBetweenIndices(start: int, end: int): seq<string> | ||
requires 0 <= start <= 7 && 0 <= end <= 7 | ||
ensures |GetPlanetsBetweenIndices(start, end)| <= (if start <= end then end - start + 1 else 0) | ||
decreases if start <= end then end - start + 1 else 0 | ||
{ | ||
if start > end then | ||
[] | ||
else | ||
match start | ||
case 0 => ["Mercury"] + GetPlanetsBetweenIndices(1, end) | ||
case 1 => ["Venus"] + GetPlanetsBetweenIndices(2, end) | ||
case 2 => ["Earth"] + GetPlanetsBetweenIndices(3, end) | ||
case 3 => ["Mars"] + GetPlanetsBetweenIndices(4, end) | ||
case 4 => ["Jupiter"] + GetPlanetsBetweenIndices(5, end) | ||
case 5 => ["Saturn"] + GetPlanetsBetweenIndices(6, end) | ||
case 6 => ["Uranus"] + GetPlanetsBetweenIndices(7, end) | ||
case 7 => ["Neptune"] | ||
} |
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,16 @@ | ||
predicate IsPrime(n: nat) | ||
{ | ||
n > 1 && | ||
forall k :: 2 <= k < n ==> n % k != 0 | ||
} | ||
|
||
method x_or_y(n: nat, x: int, y: int) returns (result: int) | ||
ensures IsPrime(n) ==> result == x | ||
ensures !IsPrime(n) ==> result == y | ||
{ | ||
if IsPrime(n) { | ||
return x; | ||
} else { | ||
return y; | ||
} | ||
} |
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 |
---|---|---|
@@ -1,27 +1,22 @@ | ||
method Compare(scores: array<int>, guesses: array<int>) returns (result: array<int>) | ||
requires scores.Length == guesses.Length | ||
ensures result.Length == scores.Length | ||
ensures forall i :: 0 <= i < result.Length ==> | ||
result[i] == if scores[i] == guesses[i] then 0 else abs(scores[i] - guesses[i]) | ||
ensures forall i :: 0 <= i < result.Length ==> result[i] == abs(scores[i] - guesses[i]) | ||
{ | ||
result := new int[scores.Length]; | ||
var i := 0; | ||
while i < scores.Length | ||
invariant 0 <= i <= scores.Length | ||
invariant result.Length == scores.Length | ||
invariant forall k :: 0 <= k < i ==> | ||
result[k] == if scores[k] == guesses[k] then 0 else abs(scores[k] - guesses[k]) | ||
invariant forall k :: 0 <= k < i ==> result[k] == abs(scores[k] - guesses[k]) | ||
{ | ||
if scores[i] == guesses[i] { | ||
result[i] := 0; | ||
} else { | ||
result[i] := abs(scores[i] - guesses[i]); | ||
} | ||
result[i] := abs(scores[i] - guesses[i]); | ||
i := i + 1; | ||
} | ||
} | ||
|
||
function abs(x: int): int | ||
ensures 0 <= abs(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,59 @@ | ||
class Extension { | ||
var name: string | ||
var strength: int | ||
|
||
constructor(n: string) | ||
ensures name == n | ||
ensures strength == CalculateStrength(n) | ||
{ | ||
name := n; | ||
strength := CalculateStrength(n); | ||
} | ||
|
||
static function CalculateStrength(s: string): int | ||
{ | ||
CountUpperCase(s) - CountLowerCase(s) | ||
} | ||
|
||
static function CountUpperCase(s: string): int | ||
{ | ||
if |s| == 0 then 0 | ||
else (if 'A' <= s[0] <= 'Z' then 1 else 0) + CountUpperCase(s[1..]) | ||
} | ||
|
||
static function CountLowerCase(s: string): int | ||
{ | ||
if |s| == 0 then 0 | ||
else (if 'a' <= s[0] <= 'z' then 1 else 0) + CountLowerCase(s[1..]) | ||
} | ||
} | ||
|
||
method Strongest_Extension(className: string, extensions: seq<string>) returns (result: string) | ||
requires |extensions| > 0 | ||
ensures |result| > |className| | ||
ensures result[..|className|] == className | ||
ensures result[|className|] == '.' | ||
ensures var extName := result[|className| + 1..]; | ||
extName in extensions | ||
ensures var extName := result[|className| + 1..]; | ||
forall i :: 0 <= i < |extensions| ==> Extension.CalculateStrength(extName) >= Extension.CalculateStrength(extensions[i]) | ||
{ | ||
var strongestExt := new Extension(extensions[0]); | ||
ghost var strongestIndex := 0; | ||
|
||
for i := 1 to |extensions| | ||
invariant 0 <= strongestIndex < |extensions| | ||
invariant strongestExt.name == extensions[strongestIndex] | ||
invariant strongestExt.strength == Extension.CalculateStrength(extensions[strongestIndex]) | ||
invariant forall j :: 0 <= j < i ==> strongestExt.strength >= Extension.CalculateStrength(extensions[j]) | ||
invariant forall j :: 0 <= j < i ==> Extension.CalculateStrength(extensions[strongestIndex]) >= Extension.CalculateStrength(extensions[j]) | ||
{ | ||
var currentExt := new Extension(extensions[i]); | ||
if currentExt.strength > strongestExt.strength { | ||
strongestExt := currentExt; | ||
strongestIndex := i; | ||
} | ||
} | ||
|
||
result := className + "." + strongestExt.name; | ||
} |
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,27 @@ | ||
predicate IsSubstring(s: string, sub: string) | ||
{ | ||
|s| >= |sub| && exists i {:trigger s[i..i+|sub|]} :: 0 <= i <= |s| - |sub| && s[i..i+|sub|] == sub | ||
} | ||
|
||
function RotateString(s: string, n: nat): string | ||
requires 0 <= n <= |s| | ||
{ | ||
s[n..] + s[..n] | ||
} | ||
|
||
method CycpatternCheck(word: string, pattern: string) returns (result: bool) | ||
ensures result ==> exists i :: 0 <= i <= |pattern| && IsSubstring(word, RotateString(pattern, i)) | ||
ensures !result ==> forall i :: 0 <= i <= |pattern| ==> !IsSubstring(word, RotateString(pattern, i)) | ||
{ | ||
var i := 0; | ||
while i <= |pattern| | ||
invariant 0 <= i <= |pattern| + 1 | ||
invariant forall j :: 0 <= j < i ==> !IsSubstring(word, RotateString(pattern, j)) | ||
{ | ||
if IsSubstring(word, RotateString(pattern, i)) { | ||
return true; | ||
} | ||
i := i + 1; | ||
} | ||
return false; | ||
} |
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