ex3.a.smv 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. MODULE passenger(on_boat)
  2. VAR
  3. crossed : boolean;
  4. ASSIGN
  5. init(crossed) := FALSE;
  6. next(crossed) := on_boat ? !crossed : crossed;
  7. MODULE main
  8. VAR
  9. -- selected passenger encodes which of the passengers will be crossed next
  10. -- selection happens as the boat returns, we could see this as the ferryman deciding what to do next while rowing back
  11. selected_passenger : {w, g, c, none};
  12. -- boat crossed encodes the boat is currently at the origin (not crossed) or at the destination (crossed)
  13. boat_crossed : boolean;
  14. -- these three passengers each have their own internal crossed variable (with the same meaning)
  15. -- they internally check whether they are on the boat and if so, their crossing value toggles
  16. wolf : passenger(selected_passenger = w);
  17. goat : passenger(selected_passenger = g);
  18. cabbage : passenger(selected_passenger = c);
  19. ASSIGN
  20. init(boat_crossed) := FALSE;
  21. -- the boat always toggles its crossing, representing the back and forth control flow of the boat
  22. next(boat_crossed) := !boat_crossed;
  23. -- this statement essentially encodes a set of follow-up states
  24. -- the only passengers which can be selected for crossing are those who have the same crossing value as the next boat crossing value
  25. -- in essence, due to this statement, the boat cannot take a passenger from the origin to the destination while at the desination or vice-versa
  26. next(selected_passenger) := {
  27. next(boat_crossed) = wolf.crossed ? w : selected_passenger,
  28. next(boat_crossed) = goat.crossed ? g : selected_passenger,
  29. next(boat_crossed) = cabbage.crossed ? c : selected_passenger,
  30. selected_passenger, none
  31. };
  32. DEFINE
  33. -- this is a simple definition for the goat being eaten by the wolf, looking at the crossed values of the boat, the wolf and the goat
  34. wolf_eats_goat := wolf.crossed = goat.crossed &
  35. wolf.crossed != boat_crossed;
  36. -- same but for the cabbage being eaten by the goat
  37. goat_eats_cabbage := goat.crossed = cabbage.crossed &
  38. goat.crossed != boat_crossed;
  39. -- this is a simple definition for all passengers being crossed, which is really the end state of our puzzle
  40. all_crossed := wolf.crossed &
  41. goat.crossed &
  42. cabbage.crossed;
  43. -- this spec is explained in detail in the trace provided in `ex3.a.out`
  44. LTLSPEC !(
  45. G (!wolf_eats_goat & !goat_eats_cabbage) &
  46. F all_crossed
  47. )