The verification tool chain works like this:
java -jar xcd.jar fileName.xcdThis command produces a folder "src-gen" which includes a set of ProMeLa files representing the entire ProMeLa model of that XCD specification.
cd src-gen spin -a configuration.pml
gcc -O2 -DMEMLIM=7024 -o pan pan.c
./pan
java -jar xcd.jar fileName.xcd \ && (cd src-gen ; spin -a configuration.pml \ && gcc -O2 -DMEMLIM=7024 -o pan pan.c \ && ./pan)Note the use of "&&" where the previous command may fail.
You can access the XCD case studies here (https://www.staff.city.ac.uk/c.kloukinas/Xcd/case_studies.html).
A simple "diff -bw output_file_before output_file_now" would be sufficient (-bw means ignore whitespaces - useful for the change below).
"...\\ ..." -> "...\\..."
String label_component = "COMPONENT_"; String label_connector = "CONNECTOR_"; String label_part = "PART_"; String label_role = "ROLE_"; String label_var = "VAR_"; ...
Check that when you do a "grep COMPONENT" on the source files the only results are these global labels (same for the other values too).
Check that the output produced is still the same.
String label_component = "CT_"; String label_connector = "CR_"; String label_part = "PT_"; String label_role = "RL_"; String label_var = "VR_"; ...
This pattern is further described in section 4.4.6 (p. 123), detailing how "user-defined buffers" are used by a component to receive messages from other components - see also Listing 4.9 on p. 126 (and Listings 4.10-12).
Essentially it's this: When component A sends a request/message to component B, B takes it out of the message channel queue and pushes it into a local buffer.
Then B pops some message from its local buffer to see if it satisfies the predicates that would make it safe to treat this message/responding to this request. When it finds one, it removes it from the local buffer and treats it. This is described in detail in section 4.4.7.2 (p. 125).
We had to use this convoluted pattern because Spin does not allow us to read a message from a message channel queue only when that message satisfies some condition/predicate, so we had to do it manually:
:: channel ? message // try to receive next message, if any. -> push_to_buffer(message) ; // called "push" in the pattern :: pop_from_buffer(message, conditions_A) -> if :: satisfies(message, conditions_B) -> treat(message); :: else -> assert(false); // raise an error fi :: pop_from_buffer(message, conditions_C) -> assert(false); // raise an error
Since then, another student has extended Spin so that we can now do such a "selective" message reception directly, without the use of an intermediate buffer:
:: channel ?? message : conditions_A && conditions_B -> treat(message); :: channel ?? message : conditions_A && (! conditions_B) -> assert(false); // raise an error :: channel ?? message : conditions_C /* NOTE: ?? receives the first message that matches the conditions - not necessarily the first message in the channel queue. */ -> assert(false); // raise an error
What we want now is to change the code in the Xcd translator so that it uses this second pattern, so as to take advantage of the extended Spin's functionality.
We expect a significant reduction in the number of states/transitions/memory but we cannot know how much we'll gain without doing these experiments.