123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- MODULE main
- VAR
- pc: { L0, L1, L2, L3, L4 };
- year: unsigned word [11];
- days: unsigned word [14];
- DEFINE
- is_leap_year := (toint(year) mod 4 = 0 & toint(year) mod 100 != 0) |
- (toint(year) mod 400 = 0);
- days_in_year := is_leap_year ? 0ud14_366 : 0ud14_365;
- ASSIGN
- init(pc) := L0;
- next(pc) :=
- case
- pc = L0 : L1;
- pc = L1 & days > days_in_year : L2;
- pc = L1 : L4;
- pc = L2 : L3;
- pc = L3 : L1;
- -- self-loop at final location L4, to obtain infinite paths
- pc = L4 : L4;
- esac;
- next(year) :=
- case
- pc = L0 : 0ud11_1980;
- -- we compacted the program to just one addition branch on year
- pc = L3 : year + 0ud11_1;
- TRUE: year;
- esac;
- next(days) :=
- case
- -- we compacted the program to just one subtraction branch on days
- pc = L2 : days - days_in_year;
- TRUE : days;
- esac;
- -- for completeness, here is the program we are modeling in this version
- -- it is the legendary readable and compact solution provided by Stefan Ciobaca
- -- in our case we don't need any inlined functions :)
- -- L0: year = ORIGIN_YEAR;
- -- L1: while (days > DaysInYear(year)) {
- -- L2: days -= DaysInYear(year);
- -- L3: year++;
- -- }
- -- L4: exit;
- -- our specification remains the same as in subtask (b), only this time our exit PC is L4
- SPEC AG (pc = L1 -> AF (pc = L4))
- -- out of curiosity we also verify include the optimized property
- --SPEC AF (pc = L4)
- -- it gives the same output!
|