-
-
Notifications
You must be signed in to change notification settings - Fork 185
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
Support cyclic redefinitions #825
base: master
Are you sure you want to change the base?
Conversation
e3607eb
to
df8a7f5
Compare
@Calvin-L Can you share any specific corner cases that you think might come up? While we all seem to agree that this feature could be beneficial, it's important to define its scope carefully. I'd rather tackle any possible problems beforehand, instead of wasting time only to find out that we should stay with what we already have (instantiation). |
One thing I had in mind is:
Should this (1) make |
In the meeting today I think some people mentioned that you can use configuration files to create recursive operators. Will this change that behavior? |
This particular example produces
I would recommend maintaining TLC's backward compatibility whenever feasible. Additionally, it's worth noting that recursive operators can be defined without explicitly declaring them as recursive: a57a3a7 |
While this now passes all the tests, I'm no longer convinced that it's worth the effort. The INSTANCE technique only adds a slight amount of syntactic overhead. ---- MODULE ModuleWithF ----
F == /\ A
/\ B
/\ C
====
---- MODULE Derived -----
EXTENDS ModuleWithF
MWF == INSTANCE ModuleWithF
RF == /\ MWF!F
/\ D
====
Config file:
CONSTANT F <- RF |
final OpApplNode oan = (OpApplNode) en; | ||
if (oan.getOperator() == o) { | ||
if (!s.isDefinedWith(oan)) { | ||
oan.resetOperator(s); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes in this PR look reasonable---although this specific line looks a little fishy to me because it modifies the semantic graph while the graph is being traversed. There is a good reason the Java standard collections forbid this kind of behavior, and those data structures are much simpler than this one.
If we do end up merging this, I would want to at least document what kinds of changes preVisit
and postVisit
are allowed to make.
This reverts commit 213165a. Signed-off-by: Markus Alexander Kuppe <github.com@lemmster.de>
A cyclic redefinition RF is a formula that is defined from another formula F while also re-defining F: ```tla F == /\ A /\ B /\ C RF == /\ F /\ D CONSTANT F <- RF ``` Supported: - Initial predicate - Next-state relation - 0-arity and higher-arity sub-actions provided the parameters are constant level - Invariants Impl notes: - Only action with constant-level (formal) parameters can be cyclicly redefined, because TLC does not create an Action instance for defs with non-constant-level parameters. More precisely, TLC does not recurse on action definitions with non-constant parameters in Tool#getActions. - Redefining a (cyclic) redefinition not tested - Labels and positional subexpression names smoke tested [Feature][TLC][Changelog] Signed-off-by: Markus Alexander Kuppe <github.com@lemmster.de>
A cyclic redefinition RF is a formula that is defined from another formula F while also re-defining F: ```tla F == /\ A /\ B /\ C RF == /\ F /\ D CONSTANT F <- RF ``` Supported: - Initial predicate - Next-state relation - 0-arity and higher-arity sub-actions provided the parameters are constant level - Invariants - Ordinary operators Impl notes: - Eagerly substituting the RF OpDefNode in all call-sites (OpApplNode) for F could be made the default -- it should avoid a one lookup per each evaluation [Feature][TLC][Changelog] Signed-off-by: Markus Alexander Kuppe <github.com@lemmster.de>
5e684fe
to
0b38631
Compare
@Calvin-L Agreed, |
A cyclic redefinition RF is a formula that is defined from another formula F while also re-defining F:
Supported: