-
Notifications
You must be signed in to change notification settings - Fork 9
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
Rule Set Classification #610
base: main
Are you sure you want to change the base?
Conversation
… efficient) refactoring
@@ -54,6 +54,8 @@ bytecount = "0.6.8" | |||
colored = "2" | |||
|
|||
[dev-dependencies] | |||
assert_cmd = "2.0" |
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 don't see why we would need assert_cmd
.
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.
It will be removed. I overlooked it somehow.
@@ -32,6 +32,8 @@ pub mod execution; | |||
pub mod rule_model; | |||
pub mod util; | |||
|
|||
pub mod static_checks; |
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.
At some point, we should rename this as static_check
is a bit too generic. Maybe something like ruleset_classification
could work but I'm not quite sold on that either.
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.
Right now, this module is implemented on data types of the rule_model
module. Maybe rule_model_classification
would be a good name? Also since it is based on the rule_model
module, wouldn't it be better to make it a submodule of rule_model
?
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 I would keep it separate. Maybe even have it in its own crate. These static analysis are useful but not required for anything happening in the Nemo Core so I rather see it as something that we put "on top". But this should be discussed in a bigger group. Some of the checks could potentially be used to influence the reasoning strategies...
@@ -147,6 +147,24 @@ impl Rule { | |||
result | |||
} | |||
|
|||
pub fn positive_variables_as_vec(&self) -> Vec<&Variable> { |
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.
Would it make sense to return an iterator instead of a vector here?
Probably the above method returning a HashSet could then also be implemented based on the method returning the iterator.
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.
Yes, it would make sense. I used it to get the join variables of a rule. Since same elements in a set is not possible, the other method was not sufficient. Maybe this can be added to the IterableVariables
-Trait?
@@ -5,7 +5,7 @@ use std::hash::Hash; | |||
pub(crate) type ExternalReference = usize; | |||
|
|||
/// Origin of a program component | |||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] | |||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)] |
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.
Is it really required that this is Ord
and PartialOrd
? I think the structs having Origin
as one of their field have a custom implementation of Ord
and PartialOrd
anyway that does not involve comparing the origin at all.
fn weak_acyclicity_graph(&'a self) -> WeakAcyclicityGraph<'a>; | ||
} | ||
|
||
impl<'a> AcyclicityGraphConstructor<'a> for RuleSet { |
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.
If only implemented on a RuleSet, the name of the trait is misleading. Also, why have the trait at all if its implementation is just calling JointAcyclicityGraph::build_graph
? We could replace calls of the method joint_acyclicity_graph
simply by directly calling JointAcyclicityGraph::build_graph
.
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 made this because build_graph
method of JointAcyclicityGraph
and WeakAcyclicityGraph
looked pretty much the same. I hoped to refactor that into actually just one method but I couldn't do it myself. The idea was to give an input (in form of an enum) to decide whether the JointAcyclicityGraph
or WeakAcyclicityGraph
should be build.
Ok(program) => program, | ||
Err((_program, report)) => { | ||
report.eprint()?; | ||
return Err(Box::new(Error::new(ErrorKind::Other, "error1"))); |
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 ok to now have error handling here and to just expect
Ok
from the Result
s since we run these checks on predefined rule sets, which should always succeed parsing.
(Same below.)
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.
Will be done.
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.
Don't add MacOS specific stuff to git!
(Feel free to add .DS_Store
to the root .gitignore
.)
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.
Sorry, I somehow forgot to add it.
Will be done.
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.
Remove mac stuff
nemo/src/static_checks/positions.rs
Outdated
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 there is a lot to be reworked here.
For example, in general positions are independent of specific acyclicity checks so the code should be independent too, that is generic in places where MarkingType
and AttackingType
are currently hardcoded.
As for the acyclicity_graphs
I do not really like the approach of introducing various traits on type aliases.
I think I need to play around with this a little bit to see what makes sense 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.
I've done the playing around in acyclicity_graphs.rs
. I think we can make similar adjustments here.
nemo/src/static_checks/rule_set.rs
Outdated
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'll also play around here with possible refactorings.
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 done the playing around in acyclicity_graphs.rs
. I think we can make similar adjustments 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.
As you wrote in some comment above some things are unnecessary complicated. I agree on that. Some things can be written more easily and shouldn't need as much code as it does right now.
To be honest, I do not like every refactoring you have done in the last commit. For example, the new implementation of the new
function of both graphs is written much shorter than before which is good. But I think it cannot be read as easy as before since both functions are quite big now.
Is there a way where we can find a compromise on that one?
General comment: It would be good to think about the API and UI for running these checks. I have created an issue #611 for this purpose. |
…rn as we discussed. This reverts commit b1b64f9.
…s and use the Builder-Pattern. Also I reduced the number of traits significantly.
… of the construction of the special positions
…ed methods significantly. Reimplementing some methods for Variable as methods for RuleAndVariable
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.
Looks nice overall. I left some specific comments again :)
special_edge_cycles | ||
} | ||
|
||
fn edge_is_special(&self, node: &Position<'a>, next_node: &Position<'a>) -> bool { |
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 there is kind of a convention to have methods returning bool
named as is_...
or at least have them start with a verb (is
, contains
, ...). That is, I would go for is_edge_special
here. (This reminds me of ruby's convention, where this method would probably be called edge_special?
.)
.any(|cycle| self.cycle_contains_special_edge(cycle)) | ||
} | ||
|
||
fn cycle_contains_special_edge(&self, cycle: &Cycle<Position<'a>>) -> bool { |
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 to the comment below, I think contains_special_edge_in_cycle
would be a better name.
} | ||
|
||
/// Returns the common marking of a RuleSet. | ||
pub fn build_and_check_marking(&self) -> Option<Positions> { |
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 would be good if the method names (at least for the public methods) would somehow indicate what this marking is for. I assume it's for the sticky check? Maybe also it would be worthwhile to rename occurrences of "Marking" to "StickyMarking" but I'm less sure about that...
} | ||
} | ||
|
||
trait AffectedPositionsBuilderPrivate<'a> { |
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 capabilities described by this trait are not really a builder pattern.
Maybe I would call this trait AffectedPositionInference
because both RuleSets
and Rule
are "capable" of infering affected positions (possibly based on already given positions).
} | ||
} | ||
|
||
trait AttackedPositionsBuilderPrivate<'a> { |
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.
Same as above and the same also applies below.
Also keep in mind in general that traits do not describe entities but capabilities. (This a bit different from interface in object oriented languages I would say.)
pub struct RuleAndVariablePair<'a>(pub [RuleAndVariable<'a>; 2]); | ||
|
||
// NOTE: KEEP? | ||
/// This Trait provides methods to get all (HashSet<Position> / Positions) of some type. |
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.
To get rid of the Doc errors, I think you can put the code snippets in backticks (`).
For Example:
/// This Trait provides methods to get all (`HashSet<Position>` / `Positions`) of some type.
|
||
// NOTE: KEEP? | ||
/// This Trait provides methods to get all (HashSet<Position> / Positions) of some type. | ||
pub trait AllPositivePositions<'a> { |
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 because a method is implemented on two different structures does not mean that there needs to be a trait for this.
For this trait and also others in this file I would say that the functionality is too specific to justify generalizing this into a trait.
If you want to keep the trait, it needs to describe a proper capability.
Also PositivePosition
should be renamed to something like PositiveLiteralPosition
because it is not clear what it means for a Position
to be positive.
This PR will add membership checks for various syntactic (and some semantic) classes of rule sets. The implementation is done by @xR0xEr.
(This will still take some time and I am mainly creating this Draft PR now to have a place for review and discussion.)