-
Notifications
You must be signed in to change notification settings - Fork 22
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
Fix/type hierarchy #73
Conversation
Codecov Report
❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more. @@ Coverage Diff @@
## main #73 +/- ##
==========================================
+ Coverage 88.30% 89.40% +1.09%
==========================================
Files 20 22 +2
Lines 1052 1170 +118
Branches 164 191 +27
==========================================
+ Hits 929 1046 +117
+ Misses 95 94 -1
- Partials 28 30 +2
Flags with carried forward coverage won't be shown. Click here to find out more.
|
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.
Some fairly minor things / questions for ya.
pddl/custom_types.py
Outdated
} | ||
if isinstance(names.values(), list) | ||
else {name(type_def): [] for type_def in names} | ||
) |
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 block's a little inscrutable for me. Can you rewrite with some commentary as to what's going on here? Both the indexing of [0]
and isinstance(names.values(), list)
look a little sus ;).
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.
When parsing (:types ...
, the type structure has the following types Dict[Token, Set]. Now, every type can have a single parent, so the [0]
is to extract that element. (Note here we do not allow (either ...
.
When parsing (:predicates ...
, each parameter may have >1 types with either
, so a list as dict value is needed here.
Finally, the []
is to allow domains with types without hierarchy.
def _print_types_with_parents(types: Dict): | ||
result = "" | ||
for t in sorted(types.keys()): | ||
result += f"{t} - {types[t]}" if types[t] else f"{t}" |
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 this be capturing the ancestors? If it's just the direct types, wouldn't it need to be space-separated? Maybe what's unclear here is the form of the types
dict -- if it's mapping a type to it's direct parent (no either
allowed), then maybe indicate that in a docstring or comment (the variable types
can be ambiguous).
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.
Good point. I will make the form of the types
dict more clear in the docstring.
pddl/parser/domain.py
Outdated
@@ -86,9 +86,11 @@ def requirements(self, args): | |||
|
|||
def types(self, args): | |||
"""Parse the 'types' rule.""" | |||
if not bool({Requirements.TYPING} & self._extended_requirements): | |||
if any(args[2].values()) and not 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.
args[2].values()
??
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.
While following the BNF, I noticed that the :typing
requirement is needed only when a hierarchy is defined, i.e., when the type_sep (-
) is used. This is actually a tiny detail, we can get rid of it or I may try to make it more readable.
pddl/parser/domain.py
Outdated
args[type_sep_index + 1][1:] | ||
if type(args[type_sep_index + 1]) is list | ||
else args[type_sep_index + 1] | ||
) |
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.
Some magic indexing happening ;). May be necessary, but a comment for our future selves would help.
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.
Aye :) Since the method captures both types with an ancestor (for the (types ...
definition) and types of variables (here either
is allowed), this snippet assigns either the whole list of ancestors or the single ancestor depending on what has been parsed.
@@ -41,7 +41,7 @@ def __init__( | |||
self, | |||
name: namelike, | |||
requirements: Optional[Collection["Requirements"]] = None, | |||
types: Optional[Dict[namelike, Collection[namelike]]] = None, | |||
types: Optional[Dict[namelike, Optional[namelike]]] = None, |
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.
idea: we could have a higher-level data structure instead of raw dictionaries, that would make easier to ask queries, e.g. all the parents of a given type, and guarantee other invariants, e.g. absence of cycles in the inheritance 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.
The only check performed now is whether there are cycles in the type def hierarchy.
048f28d
to
43fdbfc
Compare
as stated in #73 (comment), this piece of code could be made a bit more readable. This commit tries to make it more readable by giving a name to each condition of parsing failure due to missing type requirement.
This is appropriate to guarantee canonicity of the string representation.
According to the discussion in #70, only variables will have disjunctive type specifications. Constants have only one type. Moreover, types can only have one supertype, i.e. no multiple inheritance.
This commit fixes issue #76 and makes the parsing of typed lists of names separated from the typed lists of variables. Regarding the separation, since in the discussion in #70 and in a3af26d has been decided that "typed lists of names" should not have more than one parent (where 'parent' means a supertype for types, and a 'type' for constants), the parsing of typed list of names can be made separated from the parsing of other typed lists, e.g. the one of variables. This should simplify the code and make it more readable. Regarding issue #76, this commit adds two types of duplicates checks: 1) a check over simple typed lists, that simply checks whether there are two occurrences of the same item (which in PDDL terms means either duplicated types or duplicated constants); 2) a check over (complex) typed lists (i.e. with typed hierarchy), where we check whether multiple occurrences of names occurred (e.g. "constant_1 - type_1 constant_1 - type_2"). Tests for both checks have been added. Moreover, the 'storage' domain "IPC5 Domain: Storage Propositional" (path: tests/fixtures/pddl_files/storage/domain.pddl) had a duplication issue since the type of area was specified twice.
|
||
(define (domain Storage-Propositional) | ||
(:requirements :typing) | ||
(:types hoist surface place - object |
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.
Commit 22643a2 changed this line:
- :types hoist surface place area - object
+ (:types hoist surface place - object
Is that a right change?
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.
Reason: area
already stated below under a type (surface
) that is narrower than object
.
Also add some changes to utility functions, preparatory for future changes.
As discussed in #70, and in particular in comment #70 (comment) and #70 (comment), it has been decided to not allow multiple types excepts for action parameters and variables. This commit fixes the previous code regarding constants according to the above decision, namely, that constants should have at most one type specification. This change had some implication across the codebase. E.g.: - the initializer method of Constant should have a single optional type, rather than an optional collection of types - the utility function 'constants' is changed accordingly with the initializer - the problem parser is changed by making it to use DomainTransformer.typed_list_name, rather than DomainTransformer.typed_list_variables, to parse objects.
Since in previous commits we splitted parsing of names from parsing of variables, we can make more stricter assumptions on the input of the method. This allowed to simplify the code to a large extent. This introduced some code duplication with the typed_list_names method; but the author's opinion is that it is a good-enough solution for the state of the codebase, where things can be refactored and changed rapidly. Moreover, note that, differently from the typed_list_names, typed_list_variables has to handle multiple types of variables, like the 'either' construct.
740f3d8
to
fea7daf
Compare
…k_types_dictionary function
…es (partially fix #77)
fa06450
to
691390e
Compare
4cf18a3
to
f015fb4
Compare
In my opinion, the PR is in a good state. The code regarding consistency checks and parsing, if possible, can be improved in the future; in this PR, we can focus on the functional part. Also, the PR is solving different issues related to typing, which is good, but at some point, we should stop and postpone other changes for another PR. |
551f195
to
5cd8ab2
Compare
Thank you! I agree; we can proceed to merge this PR and iterate later on to improve. @haz ? |
Looking now... |
Looking pretty awesome to me! Not sure I'm a fan of the |
Fixes
Fix typing parsing. Changed structure from list to dict. This PR addresses issue #70. As mentioned in #70, we only allow the
either
keyword in the parameters spec.This PR also fixes #76, #77 and #78.
Types of changes
What types of changes does your code introduce?
Put an
x
in the boxes that applyChecklist
Put an
x
in the boxes that apply.