Files
Provable-Programming-exercises/chap_3/e3_3.dfy
2026-03-10 13:05:37 +01:00

105 lines
1.8 KiB
Plaintext

method Study(n: nat, h: nat)
decreases n * 201 + h
{
if h != 0 {
// first, study for an hour, and then:
Study(n, h - 1);
} else if n == 0 {
// you just finished course 0 - woot woot, graduation time!
} else {
// find out how much studying is needed for the next course
var hours := RequiredStudyTime(n - 1);
// get started with course n-1:
Study(n - 1, hours);
}
}
method RequiredStudyTime(c: nat) returns (hours: nat)
ensures hours <= 200
method Outer(a: nat)
decreases a
{
if a != 0 {
var b := RequiredStudyTime(a - 1);
Inner(a, b);
}
}
method Inner(a: nat, b: nat)
requires 1 <= a
decreases a, b
{
if b == 0 {
Outer(a - 1);
} else {
Inner(a, b - 1);
}
}
method Outer'(a: nat)
decreases a, 0, 0
{
if a != 0 {
var b := RequiredStudyTime(a - 1);
Inner'(a - 1, b);
}
}
method Inner'(a: nat, b: nat)
decreases a, b, 1
{
if b == 0 {
Outer'(a);
} else {
Inner'(a, b - 1);
}
}
function F(n: nat): nat
decreases n, 1
{
if n == 0 then 1 else n - M(F(n - 1))
}
function M(n: nat): nat
decreases n, 0
{
if n == 0 then 0 else n - F(M(n - 1))
}
method StudyPlan(n: nat)
requires n <= 40
decreases 40 - n, 201
{
if n == 40 {
// done
} else {
var hours := RequiredStudyTime(n);
Learn(n, hours);
}
}
method Learn(n: nat, h: nat)
requires n < 40
decreases 40 - n, h
{
if h == 0 {
StudyPlan(n + 1);
} else {
Learn(n, h - 1);
}
}
function F'(x: nat, y: nat): int
decreases x % 2, if x % 2 == 0 then 1000 - x else x
{
if 1000 <= x then
x + y
else if x % 2 == 0 then
F'(x + 2, y + 1)
else if x < 6 then
F'(2 * y, y)
else
F'(x - 4, y + 3)
}