Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code cleanup and performance improvements for communication, allow/block and rename #1800

Open
wants to merge 54 commits into
base: master
Choose a base branch
from

Conversation

jkeiren
Copy link
Collaborator

@jkeiren jkeiren commented Jan 14, 2025

This pull request has the following main changes:

  • Extract calculation of the following operators over summands from linearise.cpp into separate files:
    • communication
    • allow/block
    • rename
  • Add tests for the code that is extracted
  • Minor code cleanup for allow/block and rename
  • Major rework of communication:
    • I added more documentation, relating it to Muck van Weerdenburg's note.
    • Cleaned up by using more modern C++
    • Major performance improvement, but using the trick explained below.

Major performance improvement

When calculating the communication operator over a complex multiaction, for every combination of matching communication expressions, a new summand is generated. The reason for this are the open terms that can appear as parameters to the multiactions: the decision whether a communication actually succeeds depends on the valuation of the variables. Therefore, when calculating the operators, we do not yet know which of the communications will end up being successful, and we take this into account. If n communication expressions match, this gives rise to 2^n multiactions.

In practice, however, many of the multiactions that are generated will later be filtered out because they are not allowed, or they contain an action that is blocked. The optimization that is implemented is as follows:
Calculate the set of actions that appears in a multiaction in the allow set, and only add multiactions to the result in which all actions appear in this set of actions. This may still generate multiactions that are later removed by the allow, but it already avoids a significant amount of work.

For concrete examples of mCRL2 models generated from Cordis models, this reduces the time for mcrl22lps --no-alpha from 1550s to 11s; for some summands, the number of multiactions generated is reduced from 10^6 to just 1.

TODO

  • Clean up the code in linearise_communication.h, and revert the use of some of the iterators in the interfaces, since they reduce readability.

jkeiren added 30 commits January 2, 2025 15:38
This seems a remnant of ancient history, when rest was stored as a pointer.

To eliminate, we use the invariant rest[i].empty() == rest_is_null[i].
while (a != b = c) { S } is rather ugly and hard to understand. Replace this with the equivalent:
b = c;
while (a != b) { S ; b = c }
The previous refactoring showed that the body of the loop was executed at most once, and can be replaced by a simple if-then-else
if match_failed[i] == true, tmp[i] is never read anymore.
After refactoring, this code can be shared between can_communicate and might_communicate.
Due to the use of temporary date, can_communicate and might_communicate are tightly couple to comm_entry. This changeset makes this explicit, by pushing the functions into the comm_entry class as methods. This also nicely encapsulates the date contained in comm_entry.
rest[i].empty() iff rest_is_null[i] is not an invariant (we only know rest_is_null[i] implies rest[i].empty())
- Make lhs, rhs in comm_entry constant; this was already the case, but the intent is now also clear in the code.
- Use references instead of copies in some places where appropriate.
r_is_null is true iff r.empty()
First step in refactoring this code.
Using iterators should avoid a lot of copying and (re)allocation.
Ignore IDE files for Jetbrains
This now allows removing occursinterm in favour of search_free_variable.
jkeiren added 18 commits January 6, 2025 13:36
Preparation for using std::multiset.
- One vector was copied in combining tuple lists.
  By using move semantics, we avoid creation and destruction of aterms
- Multisets so far do not seem to prove an advantage, so we avoid their use.
Also fix bug that was caught by this test.
In case there were many matches of communication expressions in a single summand, first all possible combinations of matches were explored, and the corresponding condition and summand generated. So, for a single summand that matches n communication expressions, 2^n possible multiactions are generated. In practice, however, many of these multiactions contain actions that are either blocked, or that are not part of any multiaction in an allow set.

I added two test cases that were very slow without this change, but that take hardly any time now. These cases are adapted from the mCRL2 translation of a Cordis model, for which without the modification mcrl22lps --no-alph takes 1550s, and with the modification it terminates in 11s.
@jkeiren jkeiren requested a review from mlaveaux January 14, 2025 19:11
@jkeiren jkeiren marked this pull request as draft January 14, 2025 19:11
@jkeiren jkeiren marked this pull request as ready for review January 15, 2025 10:42
@jkeiren jkeiren added the enhancement Something can be improved label Jan 15, 2025
This significantly cleans up the parameter lists of the methods used.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Something can be improved
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant