-
Notifications
You must be signed in to change notification settings - Fork 33
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
ADT reasoning on distinct literals is incomplete #1014
Comments
Is this true? I get On the more general point of "should we propagate the clause earlier than model generation" — the only mechanism we have to do that currently is the case split mechanism (splitting on |
You're right. It does return |
In the current architecture (where case splits use their own little backtracking algorithm), probably. With #901 not sure but could be worth trying. In any case we could also always enable model generation. There is not much to loose — it would only impact problems that we currently return |
I agree, we can activate model generation by default, at least in presence of theory for which model generation extends their support as record and ADT theories. Not sure it's worth doing it for LIA but it shouldn't impact the performance. |
In fact the incompleteness has no relation with the ADT theory. If you run (set-logic ALL)
(declare-datatype Data (
(cons1 (d1 Int))
(cons2)
))
(declare-const x Data)
(declare-const y Data)
(declare-const z Data)
(assert ((_ is cons1) x))
(assert ((_ is cons1) y))
(assert ((_ is cons1) z))
(assert (and (<= 0 (d1 x)) (<= (d1 x) 1)))
(assert (and (<= 0 (d1 y)) (<= (d1 y) 1)))
(assert (and (<= 0 (d1 z)) (<= (d1 z) 1)))
(assert (distinct x y z))
(check-sat) We got (set-logic QF_DT)
(declare-datatype Data (
(cons1 (d1 Bool))
(cons2)
))
(declare-const x Data)
(declare-const y Data)
(declare-const z Data)
(assert ((_ is cons1) x))
(assert ((_ is cons1) y))
(assert ((_ is cons1) z))
(assert (distinct x y z))
(check-sat) and the option We don't get the best answer because we don't call It's a bit sad that the |
Ah yes of course nobody is doing case splits for the boolean theory. Hm. Not sure what the proper fix is but at least we understand the issue now :) |
We may add a special function in |
We need to do case-splits for booleans in a way that doesn't negatively impact the existing solver, that's the tricky part (in particular doing case-splits for just any boolean term doesn't sound like a good idea as it would degenerate into every problems being solved by the pure backtracking case-split mechanism instead of the actual SAT solver). Now that I think about it, this will probably be easier to tackle once #901 is complete. |
Closing in favor of #1156 now that we have identified the underlying cause. |
The current implementation of the ADT theory is incomplete. By incomplete I mean the reasoning isn't capable to notice inconsistency of some ground problems involving only ADT and boolean symbols. I notice this flaw while documenting the module
Adt_rel
, see #1013.For instance, Alt-Ergo answers
Unknown
on this input file:The expected answer is
unsat
. If we remove the second constructorcons2
, Alt-Ergo will promote the ADTData
to a record and we got the correct answer.This issue comes from the fact the
assume
function inAdt_rel
ignores silently disequations when the involved constructors have payloads. Let's imagine we have two constructor applications:x = cons1 u
andy = cons2 v
and we assume thatx <> y
. Then we have to propagateu <> v
to CC(X).But if we have payloads with at least two fields? If
x = cons1 u1 u2
andy = cons1 v1 v2
and we assumex <> y
, then we have to propagateu1 <> v1 \/ u2 <> v2
. In this case we have to propagate a clause but AE relations can only propagate literals!The current code of
assume
does nothing if one of the involved constructor has a payload. We can do better if the payload has only one field but if we want to treat the general case, we have to work more.This issue resembles a lot to the issue with the distinct literal. When I tried to propagate this literal in CC(X), I couldn't do it because its negation isn't literal but a clause.
A possible solution would be to change our definition of facts. Currently a fact is just an annotated literal but we could consider annotated clauses instead.
Another one would be to use a kind of union-find structure in
Adt_rel
to keep in mind all these constraints until we can produce a literal.The text was updated successfully, but these errors were encountered: