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

Arithmetic term rewriter #263

Merged
merged 10 commits into from
Apr 21, 2021
Merged

Arithmetic term rewriter #263

merged 10 commits into from
Apr 21, 2021

Conversation

AntoniusW
Copy link
Collaborator

@AntoniusW AntoniusW commented Aug 6, 2020

Add ArithmeticTerm rewriting, allowing arithmetic expressions in ordinary literals and heads. Fixes #260 and checks another item from #89.

The rewriting works as follows:
for every rule, take every arithmetic expression E that occurs in an atom A that is not a ComparisonLiteral, replace E in A with a fresh variable V and add to the body of the rule a new ComparisonLiteral with contents V = E.

For example:
p(X+1) :- q(Y/2), r(f(X*2),Y), X-2 = Y*3, X = 0..9.
is rewritten to
p(_A1) :- q(_A2), r(f(_A3),Y), X-2 = Y*3, X = 0..9, _A1 = X+1, _A2 = Y/2, _A3 = X*2.
where _A1, _A2, and _A3 are new variables starting with _ to prevent name clashes with variables from the input program.

[Note that due to recursion, the literals in the actual rewritten rule are ordered differently, to be precise: p(_A1) :- _A1 = X+1, _A2 = Y/2, q(_A2), _A3 = X*2, r(f(_A3),Y), X-2 = Y*3, X = 0..9., but that should be rather irrelevant for the solver.]

- Obtain from ExternalAtom its input/output literals, and lower/upper
  bounds from IntervalTerm.
- Add ArithmeticTermsRewriting.
- In AlphaTest create mutable list of rules for Program.
@codecov
Copy link

codecov bot commented Aug 6, 2020

Codecov Report

Merging #263 (52e895a) into master (c45ceb8) will increase coverage by 0.26%.
The diff coverage is 84.40%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #263      +/-   ##
============================================
+ Coverage     77.42%   77.68%   +0.26%     
- Complexity     2312     2362      +50     
============================================
  Files           178      179       +1     
  Lines          7788     7897     +109     
  Branches       1354     1387      +33     
============================================
+ Hits           6030     6135     +105     
  Misses         1336     1336              
- Partials        422      426       +4     
Impacted Files Coverage Δ Complexity Δ
.../ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java 61.90% <ø> (ø) 20.00 <0.00> (ø)
...va/at/ac/tuwien/kr/alpha/grounder/Unification.java 75.86% <78.57%> (+7.68%) 20.00 <0.00> (+5.00)
...under/transformation/ArithmeticTermsRewriting.java 84.26% <84.26%> (ø) 34.00 <34.00> (?)
...c/tuwien/kr/alpha/common/terms/ArithmeticTerm.java 70.00% <100.00%> (+3.33%) 21.00 <3.00> (+5.00)
.../ac/tuwien/kr/alpha/common/terms/IntervalTerm.java 67.79% <100.00%> (+1.12%) 26.00 <2.00> (+2.00)
...transformation/NormalizeProgramTransformation.java 100.00% <100.00%> (ø) 3.00 <0.00> (ø)
.../ac/tuwien/kr/alpha/common/terms/FunctionTerm.java 75.75% <0.00%> (+3.03%) 25.00% <0.00%> (+1.00%)
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c45ceb8...52e895a. Read the comment docs.

# Conflicts:
#	src/main/java/at/ac/tuwien/kr/alpha/common/atoms/ExternalAtom.java
#	src/main/java/at/ac/tuwien/kr/alpha/grounder/NaiveGrounder.java
#	src/test/java/at/ac/tuwien/kr/alpha/api/AlphaTest.java
@AntoniusW AntoniusW marked this pull request as ready for review October 2, 2020 01:35
Copy link
Collaborator

@madmike200590 madmike200590 left a comment

Choose a reason for hiding this comment

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

This looks good! There are a couple of minor issues with regards to readability and test coverage which I noted in the respective detailed comments.
Since I know it's time-consuming, the following is purely a suggestion, but I think it would make sense to write a bit of documentation about how arithmetic term handling now works from an ASP programmer's point of view, i.e. "what can I do?", "which types of expressions are (or aren't) supported", "(high-level) what are my expressions rewritten to?". I think this could go into the pull request description. I'm planning to do the same thing for my currently open PR for aggregates - if we start documenting new features this way, we would have a starting point for things that can eventually be consolidated into a manual for Alpha.

@@ -110,6 +111,25 @@ private static boolean unifyTerms(Term left, Term right, Unifier currentSubstitu
}
return true;
}
if (leftSubs instanceof ArithmeticTerm && rightSubs instanceof ArithmeticTerm) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since Unification#unifyTerms is already pretty long and also recursive, would it make sense to split it up into a few methods? I was thinking something along the lines of unifyFunctionTerms, unifyArithmeticTerms, unifyWithVariableTerm, basically getting each of the ifs and accompanying recursive calls into their own method.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As we discussed, I do not think that splitting this up into multiple methods increases readability much.

final ArithmeticTerm leftArithmeticTerm = (ArithmeticTerm) leftSubs;
final ArithmeticTerm rightArithmeticTerm = (ArithmeticTerm) rightSubs;
if (!leftArithmeticTerm.getArithmeticOperator().equals(rightArithmeticTerm.getArithmeticOperator())) {
return false;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Codecov is complaining that this and the other return false;s in this method aren't covered by any tests. In general, I couldn't find any dedicated unit tests for Unification. I thínk it would make sense to create a new UnificationTest that specifically checks correct behavior of Unifications public methods (thereby covering the whole class).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Test cases added, I hope those statements are now better covered.

} else if (atomToRewrite instanceof ExternalAtom) {
// Rewrite output terms, as so-far only the input terms list has been rewritten.
List<Term> rewrittenOutputTerms = new ArrayList<>();
for (Term term : ((ExternalAtom) atomToRewrite).getOutput()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Codecov is complaining that the ExternalAtom part is not covered by any tests. Generally, I think it would make sense to have a dedicated ArithmeticTermsRewritingTest in addition to the existing (more "regession-test-like") ArithmeticTermsTest. The advantage of such a "real unit test" would be (in addition to codecov being able to measure coverage better) that a set of more fine-grained tests would also be an ideal starting point for debugging if ever any issues related to this code occurred.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ArithmeticTermsRewritingTest is now also included.

Copy link
Collaborator

@madmike200590 madmike200590 left a comment

Choose a reason for hiding this comment

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

Thanks for following up on this, looks good to me now!

@madmike200590 madmike200590 merged commit bde482b into master Apr 21, 2021
@madmike200590 madmike200590 deleted the arithmetic_term_rewriter branch April 21, 2021 13:21
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.

alpha UNSAT vs. clingo SAT
2 participants