Conversation
d89fbf6 to
b1f40d9
Compare
b1f40d9 to
b300ed9
Compare
|
The code fails with this input Here's the output: |
c0605cd to
78b01bc
Compare
|
For our limited form of axioms this might actually be just enough. One thing is missing before I can put this to our production: To be sure that we're running the correct version, I'd need to have the version information from opensmt. See issue #800 . |
46d12d9 to
8acd08a
Compare
2810c10 to
32f3743
Compare
|
Ok, I think generally PR is over Though, we definitely need some sort of error handling, LANonLinearException produces errors with different format under different complilers rn. Should it be a different issue though? |
00adce9 to
c34e1ba
Compare
7e441a2 to
adaea42
Compare
src/logics/ArithLogic.cc
Outdated
| assert(logic.isPlus(polyTerm) || logic.isTimesNonlin(polyTerm)); | ||
| for (PTRef factor : logic.getPterm(polyTerm)) { | ||
| auto [var, c] = logic.splitTermToVarAndConst(factor); | ||
| auto [var, c] = logic.splitPolyTerm(factor); |
There was a problem hiding this comment.
Nonlinear multiplication should be handled as a factor, not as a sum, no? I think this is not correct.
There was a problem hiding this comment.
In this case it is the same though.. Operations like
x1 * x2 * x3
and
x1 + x2 + x3
Are split in the same manner, elements of the arithmetic operation extracted one by one and analyzed separately
There was a problem hiding this comment.
Or maybe I don't fully understand what toPoly function does, but from what I get it splits operation into terms
There was a problem hiding this comment.
Can @blishko comment on this? I am not following up on the issue at the moment.
There was a problem hiding this comment.
I am also confused right now. How is the term like5 * x1 * x2 gonna be represented?
One nonlinear multiplication with three children, or like 5 * (x1*x2) so the top-level multiplication is linear and the second one is nonlinear?
| assert(logic.isNumVar(v) || (laVarMapper.isNegated(v) && logic.isNumVar(logic.mkNeg(v)))); | ||
| auto [v,c] = logic.splitPolyTerm(expr); | ||
| x = getLAVar_single(v); | ||
| assert(logic.isNumVar(v) || (laVarMapper.isNegated(v) && logic.isNumVar(logic.mkNeg(v)))); |
There was a problem hiding this comment.
Why has the assert moved? Just keep it in the original place, no?
There was a problem hiding this comment.
It was moved because getLAVar_single contains check for nonlin multiplication and will throw exception if it is detected. Otherwise assertion will fail because v is nonlin multiplication and is not in the scope of assertion...
I can either change assertion disjunction or add handling of the nonlin multiplication before the assertion, but those are both non-perfect solutions either... Tell me which one you prefer!
There was a problem hiding this comment.
I do not understand. Since expr must be either NumVar or TimesLin, how can splitPolyTerm(expr) yield TimesNonLin? I would expect that getLAVar_single never throws here. I do not even consider it necessary to add assert(not isTimesNonLin(v)) because I really do not see a rationale for how it could appear here unless I am missing something.
There was a problem hiding this comment.
Problem is that at this point expr can be potentially timesNonlin, since we don't have NonLinArith and send potentially Nonlin queries into the LASolver (we can truly understand if it is Lin or Nonlin only after simplifications).
splitPolyTerm is general call, that works both for linear and nonlinear terms...
There was a problem hiding this comment.
We are talking about an if block guarded by the condition if (logic.isNumVar(expr) || logic.isTimesLin(expr)), hence why I assume that it is impossible that expr is TimesNonlin.
There was a problem hiding this comment.
It is due to our representation of formulas
basically 2xy is (TimesLin 2 (TimesNonlin x y))
Therefore this check doesn't check that there is no nonlin multiplication in the formula
There was a problem hiding this comment.
OK. Then I would add an additional assert before getLAVar_single that considers nonlin as well, to 1) make it more under control and 2) to document that this is the expected behavior.
c974f2b to
469252e
Compare
0a88022 to
469252e
Compare
| @@ -91,9 +92,7 @@ void LASolver::isProperLeq(PTRef tr) | |||
| assert(logic.isLeq(tr)); | |||
| auto [cons, sum] = logic.leqToConstantAndTerm(tr); | |||
There was a problem hiding this comment.
| auto [cons, sum] = logic.leqToConstantAndTerm(tr); | |
| [[maybe_unused]] auto const [cons, sum] = logic.leqToConstantAndTerm(tr); |
There was a problem hiding this comment.
I would also change the name of the function to assertIsProperLeq with [[maybe_unused]] PTRef tr
There was a problem hiding this comment.
Should we address it in this PR? Because it already seems to be grown out of scope significantly, and refactoring [cons,sum] is not connected directly to the NonLin support...
| assert(!logic.isTimes(sum) || ((logic.isNumVar(logic.getPterm(sum)[0]) && logic.isOne(logic.mkNeg(logic.getPterm(sum)[1]))) || | ||
| (logic.isNumVar(logic.getPterm(sum)[1]) && logic.isOne(logic.mkNeg(logic.getPterm(sum)[0]))))); | ||
| assert(logic.isPlus(sum) or logic.isTimesLin(sum) or logic.isMonomial(sum)); | ||
| (void) cons; (void)sum; |
There was a problem hiding this comment.
| (void) cons; (void)sum; |
There was a problem hiding this comment.
Same question as above, I can do it in separate PR
src/tsolvers/lasolver/LASolver.cc
Outdated
|
|
||
| LVRef LASolver::getLAVar_single(PTRef expr_in) { | ||
|
|
||
| if (logic.isTimesNonlin(expr_in)) { throw NonLinException(logic.pp(expr_in)); } |
There was a problem hiding this comment.
Can we do a function for this? Like logic.checkIsNotNonlin. Then, for example, changing the error message would be necessary to update in just one place.
There was a problem hiding this comment.
Do you mean logic.checkIsNotNonlin would be the only function to throw NonLinException, right?
(Because otherwise it wouldn't bring much benefit...)
However, it would mean making it void, because if/else branch wouldn't make much sense and just calling it within a function to check if it will throw exception or not
I'm not sure how efficient this architectural change would be 🤔
| SymRef SymStore::newSymbImpl(char const * fname, SRef rsort, vec<SRef> const & args, SymbolConfig const & symConfig, | ||
| bool isInternal) { |
There was a problem hiding this comment.
After I studied a bit Symbol.h, I believe we should integrate an internal flag into SymbolConfig (e.g. similarly to isInterpreted) instead of this isInternal parameter. This would be compatible with the existing code, allowing to use it also with declareFun etc. Connected to this, I think we should remove SymConf and instead allow graceful construction of SymbolConfig, possibly also adding some getters. For example, I see that noScoping implies isInterpreted (I dunno why, though).
There was a problem hiding this comment.
That part of the code is very much historical, to put it nicely. noScoping would probably mean that the symbol is a reserved word. that could well be the reason why it's isInterpreted. I'm not convinced that the choices I made when introducing those fields were very informed. I encourage you to look at them with a critical eye.
There was a problem hiding this comment.
@Tomaqa do you think it should be done within the scope of this PR or separately?
Bc it will require slight amount of changes in SymbolConfig
469252e to
d025b20
Compare
d025b20 to
1c3a5b8
Compare
20f734b to
3eccfcd
Compare
aa4fd8e to
3394533
Compare
Allows to create nonlin functions
Removed all of the constraints for the creation of nonlin predicates inside of the functions.
Only the assertions are checked for nonlinearity