Lurch Input Models
Lurch models begin with an optional C-code section, which is
followed by two percent signs (%%) and then a list of finite-state
machines; individual machines are separated by one or more blank
lines. Each finite-state machine is a list of state declarations
and / or transitions. Transitions may refer to the C-code section.
For example, the model below represents a simple producer-consumer
system:
To avoid conflicts with the C-code part of the model, Lurch global variables and function names begin with an underscore; main() also can not be used in the model. There are a few special functions called by Lurch at different times during its execution, all of which begin with an underscore:
enum { P, C } turn = P;
%%
pr_wait; (turn == P); -; produce;
produce; -; {turn = C;}; pr_wait;
cs_wait; (turn == C); -; consume;
consume; -; {turn = P;}; cs_wait;
The model begins with C; an enumerated type is used to declare the
variable turn, which has two values: P and C.
After the marker %% two finite-state machines are defined.
The first machine, which represents a producer process, has two transitions
(one on each line). The first says: when in the state pr_wait,
if (turn == P) evaulates to true, it is possible to go to state
produce. The dash in column three indicates that this transition
has no output side effect. The second transitions says: from state
produce it is possible to go directly to state
pr_wait, and if the transition occurs {turn = C;}
is executed as a side effect.
Also, the first state listed in a machine is assumed by Lurch to be the
initial state of the machine (pr_wait for the producer,
cs_wait for the consumer).
To avoid conflicts with the C-code part of the model, Lurch global variables and function names begin with an underscore; main() also can not be used in the model. There are a few special functions called by Lurch at different times during its execution, all of which begin with an underscore:
| void _before_all(void) | Called before Lurch's first attempt to find a path. |
| void _before(void) | Called before each of Lurch's attempts to find a path; can be used to set C variables to their initial values. |
| void _before_each(void) | Called before each step along a path. |
| void _score(void) | Called at the end of each time tick; can be used to modify a score value according to what Lurch reaches during that time tick. |
| void _after_each(void) | Called after each step along a path. |
| void _after(void) | Called after each attempt to find a path. |
| void _after_all(void) | Called after Lurch has finished looking for paths, or when the user hits CTRL-C to quit early. |
| void _hash(unsigned int *h) | Called each time Lurch calculates a hash value for a global state; can be used to include C variable values in the calculation, so that two otherwise identical states with different C variable values are treated as different states (*h comes in as the value of the global state hash; it can be modified by this function). |
| void _print(char *c) | Called each time a global state is output to a counter example trace file; can be used to include C variable information in the trace file. The constant _MAX_PRINT can be set to accommodate whatever length string is needed for this information. |
| void _tr_incr(_Tran *tr) | Called after each transition processed by Lurch; can be used to track information about how many times particular transitions are executed by Lurch. |