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) }