-
Notifications
You must be signed in to change notification settings - Fork 0
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
Constraint propagation solver and new hole types (4 PRs) #25
Merged
Merged
Changes from 25 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
a53cc81
Add is_subdomain
Whebon 6ee3176
Replace `_pattern_match_with_hole`, `_pattern_match`, `_rulenode_matc…
Whebon 350794e
Add Solver stub
Whebon e25314a
Scaffolding of the `Solver`
Whebon 01d3154
Add support for bychildtypes
Whebon cc600cc
Add DataStructures for the PriorityQueue class
Whebon 3189b01
Reorganize code over multiple files
Whebon d6c3f27
Test basic functionality of the Solver
Whebon fb51e07
Add `VarNode` and refactor `MatchNode` -> `RuleNode`
Whebon ab769c7
Add `fill_hole!` for the `FixedShapedIterator`
Whebon 7036d55
Add path-based tree manipulations and the Forbidden constraint
Whebon 8fbdef7
add `is_feasible` and `get_node_path`
Whebon a8c932e
Add `SolverStatistics` to track the number of propagations
Whebon 6e0af03
Add path based propagation triggers (on_tree_manipulation is a `Dict`)
Whebon fe5c18c
Move `max_depth` and `max_size` to the Solver
Whebon b263f7a
Add post method to differentiate between rescheduling and posting new…
Whebon 70d24de
Remove legacy code
Whebon d56f674
Add `make_less_than_or_equal!` and test cases
Whebon 7ab0ee6
Commit to `is_feasible` checks over try-catch blocks
Whebon 6d367e4
Add tests for `Forbidden` and `Ordered` GrammarConstraints
Whebon 1f278a8
Add new implementation of `LocalOrdered`
Whebon 2239275
Add jump starts for the solver, and fix tiebreakers in `make_less_tha…
Whebon bb5c0d1
Add tests for Forbidden and Ordered constraints
Whebon 4838177
Add the jump start to `Solver` constructor
Whebon 8e3120d
Ensure newly added holes are simplified (FSH of domain size 1 should …
Whebon 1690499
Tabs to spaces, Grammar to AbstractGrammar; minor changes to docs and…
THinnerichs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,13 +4,15 @@ authors = ["Jaap de Jong <[email protected]>"] | |
version = "0.1.0" | ||
|
||
[deps] | ||
HerbGrammar = "4ef9e186-2fe5-4b24-8de7-9f7291f24af7" | ||
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" | ||
HerbCore = "2b23ba43-8213-43cb-b5ea-38c12b45bd45" | ||
HerbGrammar = "4ef9e186-2fe5-4b24-8de7-9f7291f24af7" | ||
MLStyle = "d8e11817-5142-5d16-987a-aa16d5891078" | ||
|
||
[compat] | ||
julia = "1.8" | ||
HerbCore = "0.1.0" | ||
HerbGrammar = "0.1.0" | ||
julia = "1.8" | ||
|
||
[extras] | ||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
""" | ||
Forbidden <: GrammarConstraint | ||
|
||
This [`GrammarConstraint`] forbids any subtree that matches the pattern given by `tree` to be generated. | ||
A pattern is a tree of [`AbstractRuleNode`](@ref)s. | ||
Such a node can either be a [`RuleNode`](@ref), which contains a rule index corresponding to the | ||
rule index in the [`Grammar`](@ref) and the appropriate number of children, similar to [`RuleNode`](@ref)s. | ||
It can also contain a [`VarNode`](@ref), which contains a single identifier symbol. | ||
A [`VarNode`](@ref) can match any subtree, but if there are multiple instances of the same | ||
variable in the pattern, the matched subtrees must be identical. | ||
Any rule in the domain that makes the match attempt successful is removed. | ||
|
||
For example, consider the tree `1(a, 2(b, 3(c, 4))))`: | ||
|
||
- `Forbidden(RuleNode(3, [RuleNode(5), RuleNode(4)]))` forbids `c` to be filled with `5`. | ||
- `Forbidden(RuleNode(3, [VarNode(:v), RuleNode(4)]))` forbids `c` to be filled, since a [`VarNode`] can | ||
match any rule, thus making the match attempt successful for the entire domain of `c`. | ||
Therefore, this tree invalid. | ||
- `Forbidden(RuleNode(3, [VarNode(:v), VarNode(:v)]))` forbids `c` to be filled with `4`, since that would | ||
make both assignments to `v` equal, which causes a successful match. | ||
|
||
!!! warning | ||
The [`Forbidden`](@ref) constraint makes use of [`LocalConstraint`](@ref)s to make sure that constraints | ||
are also enforced in the future when the context of a [`Hole`](@ref) changes. | ||
Therefore, [`Forbidden`](@ref) can only be used in implementations that keep track of the | ||
[`LocalConstraint`](@ref)s and propagate them at the right moments. | ||
""" | ||
struct Forbidden <: GrammarConstraint | ||
tree::AbstractRuleNode | ||
end | ||
|
||
function on_new_node(solver::Solver, c::Forbidden, path::Vector{Int}) | ||
#minor optimization: prevent the first hardfail (https://github.com/orgs/Herb-AI/projects/6/views/1?pane=issue&itemId=55570518) | ||
if c.tree isa RuleNode | ||
@match get_node_at_location(solver, path) begin | ||
hole::Hole => if !hole.domain[c.tree.ind] return end | ||
node::RuleNode => if node.ind != c.tree.ind return end | ||
end | ||
end | ||
post!(solver, LocalForbidden(path, c.tree)) | ||
end | ||
|
||
""" | ||
check_tree(c::Forbidden, g::Grammar, tree::RuleNode)::Bool | ||
|
||
Checks if the given [`AbstractRuleNode`](@ref) tree abides the [`Forbidden`](@ref) constraint. | ||
""" | ||
function check_tree(c::Forbidden, tree::AbstractRuleNode)::Bool | ||
@match pattern_match(tree, c.tree) begin | ||
::PatternMatchHardFail => () | ||
::PatternMatchSoftFail => () | ||
::PatternMatchSuccess => return false | ||
::PatternMatchSuccessWhenHoleAssignedTo => () | ||
end | ||
return all(check_tree(c, child) for child ∈ tree.children) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
""" | ||
Ordered <: GrammarConstraint | ||
|
||
A [`GrammarConstraint`](@ref) that enforces a specific order in [`MatchVar`](@ref) | ||
assignments in the pattern defined by `tree`. | ||
Nodes in the pattern can either be a [`RuleNode`](@ref), which contains a rule index corresponding to the | ||
rule index in the [`Grammar`](@ref) and the appropriate number of children. | ||
It can also contain a [`VarNode`](@ref), which contains a single identifier symbol. | ||
A [`VarNode`](@ref) can match any subtree, but if there are multiple instances of the same | ||
variable in the pattern, the matched subtrees must be identical. | ||
|
||
The `order` defines an order between the variable assignments. | ||
For example, if the order is `[x, y]`, the constraint will require | ||
the assignment to `x` to be less than or equal to the assignment to `y`. | ||
The order is recursively defined by [`RuleNode`](@ref) indices. | ||
For more information, see [`Base.isless(rn₁::AbstractRuleNode, rn₂::AbstractRuleNode)`](@ref). | ||
|
||
For example, consider the tree `1(a, 2(b, 3(c, 4))))`: | ||
|
||
- `Ordered(RuleNode(3, [VarNode(:v), VarNode(:w)]), [:v, :w])` removes every rule | ||
with an index of 5 or greater from the domain of `c`, since that would make the index of the | ||
assignment to `v` greater than the index of the assignment to `w`, violating the order. | ||
- `Ordered(RuleNode(3, [VarNode(:v), VarNode(:w)]), [:w, :v])` removes every rule | ||
with an index of 4 or less from the domain of `c`, since that would make the index of the | ||
assignment to `v` less than the index of the assignment to `w`, violating the order. | ||
|
||
!!! warning | ||
The [`Ordered`](@ref) constraint makes use of [`LocalConstraint`](@ref)s to make sure that constraints | ||
are also enforced in the future when the context of a [`Hole`](@ref) changes. | ||
Therefore, [`Ordered`](@ref) can only be used in implementations that keep track of the | ||
[`LocalConstraint`](@ref)s and propagate them at the right moments. | ||
""" | ||
struct Ordered <: GrammarConstraint | ||
tree::AbstractRuleNode | ||
order::Vector{Symbol} | ||
end | ||
|
||
function on_new_node(solver::Solver, c::Ordered, path::Vector{Int}) | ||
#minor optimization: prevent the first hardfail (https://github.com/orgs/Herb-AI/projects/6/views/1?pane=issue&itemId=55570518) | ||
if c.tree isa RuleNode | ||
@match get_node_at_location(solver, path) begin | ||
hole::Hole => if !hole.domain[c.tree.ind] return end | ||
node::RuleNode => if node.ind != c.tree.ind return end | ||
end | ||
end | ||
post!(solver, LocalOrdered(path, c.tree, c.order)) | ||
end | ||
|
||
""" | ||
check_tree(c::Ordered, g::Grammar, tree::RuleNode)::Bool | ||
|
||
Checks if the given [`AbstractRuleNode`](@ref) tree abides the [`Ordered`](@ref) constraint. | ||
""" | ||
function check_tree(c::Ordered, tree::AbstractRuleNode)::Bool | ||
vars = Dict{Symbol, AbstractRuleNode}() | ||
if pattern_match(tree, c.tree, vars) isa PatternMatchSuccess | ||
# Check variable ordering | ||
for (var₁, var₂) ∈ zip(c.order[1:end-1], c.order[2:end]) | ||
if vars[var₁] > vars[var₂] | ||
return false | ||
end | ||
end | ||
end | ||
return all(check_tree(c, child) for child ∈ tree.children) | ||
end | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 is not clear from the naming what Forbidden actually is. Maybe rename to
ForbiddenConstraint
?