Skip to content

Commit

Permalink
Markup file parts (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
WeetHet authored Aug 30, 2024
1 parent c588dbf commit 2a83537
Show file tree
Hide file tree
Showing 118 changed files with 1,537 additions and 519 deletions.
55 changes: 32 additions & 23 deletions 000-has_close_elements.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,41 @@ function abs1(x : int, threshold : int): bool
}

method has_close_elements(numbers: seq<int>, threshold: int) returns (flag : bool)
requires threshold > 0
ensures flag == (exists i: int, j: int :: i >= 0 && j >= 0 && i < |numbers| && j < |numbers| && i != j && !abs1(numbers[i] - numbers[j], threshold))
// pre-conditions-start
requires threshold > 0
// pre-conditions-end
// post-conditions-start
ensures flag == (exists i: int, j: int :: i >= 0 && j >= 0 && i < |numbers| && j < |numbers| && i != j && !abs1(numbers[i] - numbers[j], threshold))
// post-conditions-end
{
flag := false;
var i: int := 0;
while (i < |numbers|)
invariant 0 <= i && i <= |numbers|
invariant flag == (exists i1: int, j1: int :: i1 >= 0 && j1 >= 0 && i1 < i && j1 < |numbers| && i1 != j1 && !abs1(numbers[i1] - numbers[j1], threshold))
// impl-start
flag := false;
var i: int := 0;
while (i < |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 && !abs1(numbers[i1] - numbers[j1], threshold))
// invariants-end
{
var j: int := 0;
while (j < |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 && !abs1(numbers[i1] - numbers[j1], threshold))
// invariants-end
{
var j: int := 0;
while (j < |numbers|)
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 && !abs1(numbers[i1] - numbers[j1], threshold))
if (i != j)
{
var distance: int := abs(numbers[i] - numbers[j]);
if (distance < threshold)
{
if (i != j)
{
var distance: int := abs(numbers[i] - numbers[j]);
if (distance < threshold)
{
flag := true;
}

}
j := j + 1;
flag := true;
}
i := i + 1;
}
j := j + 1;
}
i := i + 1;
}
// impl-end
}
41 changes: 8 additions & 33 deletions 001-separate-paren-groups.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -46,56 +46,30 @@ function IsValidParentheses1(s: string, i: int, depth: int): bool
IsValidParentheses1(s, i + 1, depth)
}

// function Concat(res : seq<string>): string
// decreases |res|
// {
// if (|res| == 0) then
// ""
// else
// res[0] + Concat(res[1..])
// }

// function CalcBal(s : string, j : int, i : int): int
// requires forall i1 :: i1 >= 0 && i1 < |s| ==> s[i1] == '(' || s[i1] == ')'
// requires 0 <= i && i <= |s|
// requires 0 <= j && j <= i
// decreases i - j
// {
// if (j == i) then
// 0
// else if (s[j] == '(') then
// 1 + CalcBal(s, j + 1, i)
// else
// -1 + CalcBal(s, j + 1, i)
// }

method separate_paren_groups(paren_string: string) returns (res : seq<string>)
// pre-conditions-start
requires forall i :: i >= 0 && i < |paren_string| ==> paren_string[i] == '(' || paren_string[i] == ')'
requires forall i :: 0 <= i <= |paren_string| ==> IsValidParentheses(paren_string, i, 0)
requires IsValidParentheses2(paren_string, 0, 0)
// pre-conditions-end
// post-conditions-start
ensures |res| > 0 ==> forall i :: 0 <= i < |res| ==> IsValidParentheses1(res[i], 0, 0)
// ensures Concat(res) == paren_string
// post-conditions-end
{
// impl-start
res := [];
var current_string: string := "";
var current_depth: int := 0;

var i: int := 0;

while (i < |paren_string|)
// invariants-start
invariant 0 <= i && i <= |paren_string|
invariant 0 <= i && i < |paren_string| ==> paren_string[i] in {'(', ')'}
invariant |res| > 0 ==> (forall i1 :: 0 <= i1 < |res| ==> IsValidParentheses1(res[i1], 0, 0))
invariant IsValidParentheses(paren_string, i, 0)

// invariant current_depth >= 0
// invariant CalcBal(paren_string, 0, i) == current_depth
// invariant (current_depth == 0) == (current_string == "")
// invariant (current_depth == 0) ==> IsValidParentheses2(paren_string[0..i], 0, 0)
// invariant IsValidParentheses2(paren_string[0..i], 0, 0) ==> (current_depth == 0)
// invariant IsValidParentheses2(paren_string[0..i], 0, 0) ==> IsValidParentheses2(paren_string[i..], 0, 0)
// invariant IsValidParentheses2(paren_string, i, current_depth)
// invariant Concat(res) + current_string == paren_string[0..i]
// invariants-end
{
var c: char := paren_string[i];
if (c == '(')
Expand All @@ -116,4 +90,5 @@ method separate_paren_groups(paren_string: string) returns (res : seq<string>)
}
i := i + 1;
}
// impl-end
}
8 changes: 7 additions & 1 deletion 002-truncate.dfy
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@


function truncate(x : real) : (i : real)
// pre-conditions-start
requires x >= 0.0
// pre-conditions-end
// post-conditions-start
ensures (0.0 <= x - i < 1.0)
// post-conditions-end
{
// impl-start
x.Floor as real
}
// impl-end
}
15 changes: 11 additions & 4 deletions 003-below_zero.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,32 @@ lemma psum_property(s: seq<int>, i: int)
}

method below_zero(ops: seq<int>) returns (res : bool)
// post-conditions-start
ensures res ==> forall i : int :: 0 <= i <= |ops| ==> psum(ops[..i]) >= 0
ensures !res ==> exists i : int :: 0 <= i <= |ops| && psum(ops[..i]) < 0
ensures !res ==> exists i : int :: 0 <= i <= |ops| && psum(ops[..i]) < 0
// post-conditions-end
{

// impl-start
var balance : int := 0;
var i : int := 0;
while (i < |ops|)
while (i < |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
{
// assert-start
assert psum(ops[..(i + 1)]) == psum(ops[..i]) + ops[i] by {
psum_property(ops, i);
}
// assert-end
balance := balance + ops[i];
if (balance < 0) {
return false;
}
i := i + 1;
}
return true;
}
// impl-end
}
22 changes: 18 additions & 4 deletions 004-mean_absolute_derivation.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -24,52 +24,66 @@ function mean(s: seq<real>) : real
}

method mean_absolute_derivation(numbers: seq<real>) returns (derivation: real)
// pre-conditions-start
requires |numbers| > 0
// pre-conditions-end
// post-conditions-start
ensures var m := mean(numbers);
derivation == mean(seq(|numbers|, i requires 0 <= i < |numbers| => abs(numbers[i] - m)))
// post-conditions-end
{
// impl-start
var s: real := 0.0;
var i := 0;
while i < |numbers|
// invariants-start
invariant 0 <= i <= |numbers|
invariant s == sum(numbers[..i])
// invariants-end
{
s := s + numbers[i];
// assert-start
assert sum(numbers[..i + 1]) == sum(numbers[..i]) + numbers[i] by {
assert numbers[..i+1][..i] == numbers[..i];
sum_prop(numbers[..i + 1]);
}
// assert-end
i := i + 1;
}

var m := s / |numbers| as real;
assert numbers[..|numbers|] == numbers;
assert m == mean(numbers);
assert numbers[..|numbers|] == numbers; // assert-line
assert m == mean(numbers); // assert-line

var t: real := 0.0;
i := 0;

ghost var pref_seq := [];
while i < |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])
// invariants-end
{
ghost var pre_seq := pref_seq;
assert pre_seq[..|pre_seq|] == pre_seq[..i] == pre_seq;
assert pre_seq[..|pre_seq|] == pre_seq[..i] == pre_seq; // assert-line

pref_seq := pref_seq + [abs(numbers[i] - m)];

// assert-start
assert sum(pref_seq[..i + 1]) == sum(pref_seq[..i]) + pref_seq[i] by {
assert pref_seq[..i+1][..i] == pref_seq[..i];
sum_prop(pref_seq[..i + 1]);
}
// assert-end

t := t + abs(numbers[i] - m);
i := i + 1;
}

assert pref_seq[..|pref_seq|] == pref_seq;
assert pref_seq[..|pref_seq|] == pref_seq; // assert-line
derivation := t / |numbers| as real;
// impl-end
}
43 changes: 24 additions & 19 deletions 005-intersperse.dfy
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@

method intersperse(numbers: seq<int>, delimeter: int) returns (res: seq<int>)
ensures |numbers| != 0 ==> |numbers| * 2 - 1 == |res|
ensures |numbers| == 0 ==> |res| == 0
ensures forall i : int :: i >= 0 && i < |res| && i % 2 == 0 ==> res[i] == numbers[i / 2]
ensures forall i : int :: i >= 0 && i < |res| && i % 2 == 1 ==> res[i] == delimeter
// post-conditions-start
ensures |numbers| != 0 ==> |numbers| * 2 - 1 == |res|
ensures |numbers| == 0 ==> |res| == 0
ensures forall i : int :: i >= 0 && i < |res| && i % 2 == 0 ==> res[i] == numbers[i / 2]
ensures forall i : int :: i >= 0 && i < |res| && i % 2 == 1 ==> res[i] == delimeter
// post-conditions-end
{
res := [];
if (|numbers| != 0)
// impl-start
res := [];
if (|numbers| != 0)
{
var i : int := 0;
while (i + 1 < |numbers|)
// 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
// invariants-end
{
var i : int := 0;
while (i + 1 < |numbers|)
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
{
res := res + [numbers[i]];
res := res + [delimeter];
i := i + 1;
}
res := res + [numbers[i]];
res := res + [numbers[i]];
res := res + [delimeter];
i := i + 1;
}
res := res + [numbers[i]];
}
// impl-end
}
22 changes: 22 additions & 0 deletions 006-parse_nested_parens.dfy
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
method parse_paren_group(s : string) returns (max_depth : int)
// pre-conditions-start
requires forall i :: i >= 0 && i < |s| ==> s[i] == '(' || s[i] == ')'
// pre-conditions-end
// post-conditions-start
ensures max_depth >= 0
// post-conditions-end
{
// impl-start
var depth: int := 0;
max_depth := 0;
var i: int := 0;
Expand All @@ -19,19 +24,27 @@ method parse_paren_group(s : string) returns (max_depth : int)
}
i := i + 1;
}
// impl-end
}

method split(s : string) returns (res : seq<string>)
// pre-conditions-start
requires forall i :: i >= 0 && i < |s| ==> s[i] == '(' || s[i] == ')' || s[i] == ' '
// pre-conditions-end
// post-conditions-start
ensures forall s1 :: s1 in res ==> (forall i :: i >= 0 && i < |s1| ==> s1[i] == '(' || s1[i] == ')') && |s1| > 0
// post-conditions-end
{
// impl-start
res := [];
var current_string : string := "";
var i : int := 0;
while (i < |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
{
if (s[i] == ' ')
{
Expand All @@ -50,20 +63,29 @@ method split(s : string) returns (res : seq<string>)
res := res + [current_string];
current_string := "";
}
// impl-end
}

method parse_nested_parens(paren_string: string) returns (res : seq<int>)
// pre-conditions-start
requires forall i :: i >= 0 && i < |paren_string| ==> paren_string[i] == '(' || paren_string[i] == ')' || paren_string[i] == ' '
// pre-conditions-end
// post-conditions-start
ensures forall x :: x in res ==> x >= 0
// post-conditions-end
{
// impl-start
var strings : seq<string> := split(paren_string);
var i : int := 0;
res := [];
while (i < |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
}
Loading

0 comments on commit 2a83537

Please sign in to comment.