-
Notifications
You must be signed in to change notification settings - Fork 2
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
Remove or comment out unused code #47
Conversation
8b9aa4d
to
360c197
Compare
The `IOEquivalenceTest` file seems to be semi-thought and in draft status.
Also, fix a copy-paste error in a test (which now enables it).
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.
I started to look at this. Many changes look ok. For some I will have to think. Can we somehow split this into easy cases and ones that remain in the PR?
We can definitely do that, perhaps by cherry-picking the commits. But the problem is to agree what is easy (or not and why). To me, all changes are "obvious improvements". The only thing that I am unsure of is whether we can go ahead and remove more code instead of just commenting it out. |
I will go through the commits and mark easy ones as a first step |
|
||
if (useEqTest) { | ||
ce = this.eqTest.findCounterExample(hyp, null); | ||
ce = this.eqTest.findCounterExample(hyp, new ArrayList<>()); |
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.
This is not ok by the convention that inputs is the set of inputs to consider, this should be a subset of the input alphabet of the provided hypothesis (from LearnLib).
We use null (probably incorrectly) to say "no restrictions". If we change this, we should fix it properly and
a) either mark the parameter clearly as unused and pass null
b) pass the actual set of inputs in tests and use the parameter in implementations
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.
I've looked a bit more on this. Here are two things I've found:
- In the entire code base of ralib, we pass
null
for this argument. I think this shows that either this argument is not needed in practice (and LearnLib's interface has been over-engineered; perhaps its interface should only specify the 1-argument version of this method), or we do not use the functionality of this method properly. - If I am not mistaken, this particular call which is flagged in this comment refers to the definition of this function in IOEquivalenceTest.java. That argument is unused by the method; we may as well pass anything there...
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.
I think it is over-engineered in LearnLib. @mtf90: can you suggest something here?
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.
Just to pick up on @kostis' previous comment: both versions are problematic. The parameter is meant to determine which input symbols should be used for finding counterexamples. So null
would get flagged by any null-analysis and new ArrayList<>()
could (if implemented accordingly) at most return epsilon as a counterexample. The reason why this works in this case is (probably) because you only use the IOEquivalenceTest
and IORandomWalk
which ignore this parameter and use an internal field for the inputs.
As for the question whether this is over-engineered, I think it has its benefits. Passing the eligible input symbols as a parameter allows the equivalence oracle to not have to store the inputs. Especially for LearnLib features such as Resumable
or SupportsGrowingAlphabet
(which allow you to snapshot learning states and expand in different input-directions) this is quite useful because it reduces data dependencies. This is currently already a hassle with caches which do store the referenced alphabet and therefore need to be updated as well when new input symbols are introduced. By removing this parameter this management would also be necessary for equivalence oracles.
I can see your point that it adds somewhat of an overhead in the learning loop, but it also reduces overhead when implementing equivalence oracles. So for right now, I would suggest to keep the interface as is and try to simplify the equivalence oracles if possible.
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.
Please remove marked changes to equivalence tests for now. @mtf90 and @FredrikTaquist to comment on counterexample analyses / LearnLib design and optimised symbolic suffixes
@@ -328,7 +327,7 @@ public void run() { | |||
|
|||
DefaultQuery<PSymbolInstance, Boolean> ce2 = null; | |||
|
|||
ce2 = (findCounterexamples ? this.randomWalk.findCounterExample(hyp, null) : ce); | |||
ce2 = (findCounterexamples ? this.randomWalk.findCounterExample(hyp, new ArrayList<>()) : ce); |
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.
See related comment
|
||
if (useEqTest) { | ||
ce = this.eqTest.findCounterExample(hyp, null); | ||
ce = this.eqTest.findCounterExample(hyp, new ArrayList<>()); |
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.
I think it is over-engineered in LearnLib. @mtf90: can you suggest something here?
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.
Please do not merge this. If I remember correctly some of the one sides checks (e.g., only using sys1reg in getNext was done under the assumption that it is sufficient to use the values in registers of the SUT for finding counterexamples). I would like to discuss this first and we should then write a short documentation that this will not check equivalence between two automata in general!
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.
Similar comment as for RAEquiivalenceTest
. I'll wait until these two cases get resolved.
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.
I will refactor this in a separate PR
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.
Please do not merge this. If I remember correctly some of the one sides checks (e.g., only using sys1reg in getNext was done under the assumption that it is sufficient to use the values in registers of the SUT for finding counterexamples). I would like to discuss this first and we should then write a short documentation that this will not check equivalence between two automata in general!
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.
OK, this change can be separated and/or reverted However, note that the previous code was not using its sys2reg
argument in any interesting way: it was only passing it to a (trivial) method that was ignoring it and returned false
in all cases. The only thing that such code achieves is creating confusion for the reader...
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.
I will refactor this in a separate PR
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.
This should stay in the codebase but become a configuration option or a strategy object. @mtf90: how do we best align this with LearnLib?
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.
I can revert this change, but note that the call to linearBackWardsSearch
was commented out, so the code of that method was/is unused. How exactly do we know that the code does what is supposed to do (or will continue to do so after changes) if this code is not tested?
Perhaps a middle ground is to also comment out the method's code until it's decided to use this method (or have it as a configuration option or strategy, as you suggest). I will do that.
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.
Removed code was put back in a commented out block.
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.
Depending on which functionality you can provide, you may either use the "old" LocalSuffixFinder
or Malte's acex framework. See here for an example.
It is no surprise that there is a lot of unused/unnecessary code in the code base.
Such code was due to either attempts to fix things that did not lead anywhere or copy-pasting from another file without subsequent cleanups. Unused code is confusing and also adds (unnecessary) runtime overheads. It's better to remove or comment out this code, and I've used my best judgement to choose between these two options. Perhaps this PR can be improved in this respect (e.g. by removing some code that this first attempt just comments out).
While at it, the PR also fixes some small copy-paste errors (e.g. not checking a test, but repeating a prior test), removes some lines and does some cosmetic cleanups in methods and files which were touched.