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

Allowing nested @optional` tags #120

Merged
merged 53 commits into from Sep 4, 2018
Merged

Allowing nested @optional` tags #120

merged 53 commits into from Sep 4, 2018

Conversation

amartyashankha
Copy link
Collaborator

Most of the action happens in OptionalTraversalTrie (in utils.py).
The most recent test is not passing. This is the one with a 250 line output. I'll put it in a separate file later.

@@ -219,3 +220,104 @@ def construct_where_filter_predicate(simple_optional_root_info):
# A CompoundMatchQuery is a representation of several MatchQuery objects containing
# - match_queries: a list MatchQuery objects
CompoundMatchQuery = namedtuple('CompoundMatchQuery', ('match_queries'))


class OptionalTraversalTrie(dict):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss this in person, and figure out whether and how it might relate to the QueryMetadataTable work that has been happening in parallel.

@@ -347,6 +349,26 @@ def __ne__(self, other):
"""Check another object for non-equality against this one."""
return not self.__eq__(other)

def __lt__(self, other):
"""Check another object for non-equality against this one."""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy-pasta docstring

@@ -347,6 +349,26 @@ def __ne__(self, other):
"""Check another object for non-equality against this one."""
return not self.__eq__(other)

def __lt__(self, other):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other could realistically be a FoldScopeLocation, we'll have to handle that case.

Also, FoldScopeLocation objects have to be comparable as well, which introduces some code duplication concerns. How about this:

  • Implement __eq__ and __lt__ on BaseLocation by specifying the rules for which heterogeneous types compare to each other. For equality, they aren't equal, and for __lt__ they can compare in lexicographic order of the type's name.
  • Set @total_ordering on BaseLocation.
  • If the two objects being compared are the same type, dispatch to a special private comparator method that is marked as an @abstractmethod in BaseLocation. In Location, this method specifies the logic for comparing Location objects to each other, and in FoldScopeLocation it specifies that object's comparison logic.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a separate PR? I don't think we need it for nested optionals.

if self.visit_counter != other.visit_counter:
return self.visit_counter < other.visit_counter

if self.field is None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem right. If other.field is also None, the objects are equal, which means that __lt__ must return False. With this implementation, x < x returns True if x is a Location at a vertex field.

This means you need to add more tests.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I just explicitly test that Location s objects are compared correctly?

# Simple optionals are ignored.
# There should be no complex optionals after a simple optional.
encountered_simple_optional = True

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove blank line at the end of block


# Recursively find all rooted subtrees of each of the children of the current node.
location_to_list_of_subtrees = {
location: [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not just location: list(self.get_all_rooted_subtrees_as_lists(location))? I don't think you need the nested comprehension.

@obi1kenobi
Copy link
Contributor

obi1kenobi commented Aug 30, 2018 via email

def __eq__(self, other):
"""Return True if the other object is smaller than self in the total ordering."""
if isinstance(self, Location) and isinstance(other, Location):
return self == other
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can leave __eq__ as an abstractmethod. Otherwise, I think that this line will cause infinite recursion.

raise NotImplementedError()

def __eq__(self, other):
"""Return True if the other object is smaller than self in the total ordering."""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy-pasta

@@ -237,6 +237,45 @@ def get_location_name(self):
"""Return a tuple of a unique name of the location, and the current field name (or None)."""
raise NotImplementedError()

@abstractmethod
def _compare(self, other):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about _check_if_object_of_same_type_is_smaller or something similarly more descriptive than _compare? Currently, it doesn't communicate that the other object is required to be of the same type as self.

if len(self.fold_path) != len(other.fold_path):
return len(self.fold_path) < len(other.fold_path)

for self_edge_tuple, other_edge_tuple in zip(self.fold_path, other.fold_path):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does if self.fold_path != other.fold_path: return self.fold_path < other.fold_path not work? If I remember correctly, it's a tuple-of-tuples, which should sort correctly.

@obi1kenobi
Copy link
Contributor

Also Github seems to think there are conflicts and that this can't be merged right now.

@coveralls
Copy link

coveralls commented Aug 31, 2018

Coverage Status

Coverage increased (+0.3%) to 95.282% when pulling 65f6822 on nested_optionals into 719341e on master.

@@ -38,6 +38,8 @@ def compare_ir_blocks(test_case, expected_blocks, received_blocks):
for i in six.moves.xrange(len(expected_blocks)):
expected = expected_blocks[i]
received = received_blocks[i]
if expected != received:
__import__('pdb').set_trace()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should probably remove this before we merge into master.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woops, fixed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is, actually -- the if expected != received: line is still there and it's causing a syntax error.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad. Hopefully actually fixed now.

Amartya Shankha Biswas added 2 commits September 1, 2018 13:31
@obi1kenobi obi1kenobi merged commit 1609a4f into master Sep 4, 2018
@obi1kenobi obi1kenobi deleted the nested_optionals branch September 4, 2018 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants