potassco / clasp

⚙️ A conflict-driven nogood learning answer set solver

Home Page:https://potassco.org/clasp/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Spurious answer sets when theory atoms are used.

rkaminsk opened this issue · comments

The aspif program

asp 1 0 0
1 1 1 1 0 0
1 1 1 2 0 0
1 0 0 0 1 2
1 0 1 3 0 2 2 -1
1 0 0 0 2 1 -2
9 1 0 1 c
9 5 3 0 0
4 1 a 1 1
4 1 b 1 2
0

equivalent to

{a}.
{b}.
:- b.
&c{} :- b, not a.
:- a, not b.

should just have one answer set but somehow two are reported:

clasp version 3.3.4
Reading from test.aspif
Solving...
Answer: 1

Answer: 2

SATISFIABLE

Models       : 2
Calls        : 1
Time         : 0.000s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
CPU Time     : 0.000s

(Also happens with the latest development version.)

Hi,

this is an interesting edge case for which we actually never fully specified an expected behaviour. First, in 2016, we agreed that theory atoms that occur in a head of a rule are treated as regular atoms wrt simplifications. Hence, your program should only have one answer set.

However, since the beginning of clasp, we allowed for rule simplifications during parsing. This started with simple simplifications like TAUT or CONTRA but meanwhile also includes truth value propagation (from facts or integrity constraints). Since b is already known to be false when &c{} :- b, not a. is processed, the rule is simplified to &c{} :- ⊥. and dropped.
The program that reaches clasp no longer contains a rule with &c{} in the head. Hence, it gets special treatment resulting in the two answer sets (one with and one without &c{}).

Interestingly enough, once you reorder the rules so that the integrity constraint :- b. comes after the &c{} :- b, not a., we are back at one answer set - ah, order dependency just what you'd expect from a declarative system 😅

I see your point. But I also think we have to do something about it because working around this issue puts a lot of load on the developer of a theory.

If you think it is to complicated to address this in clasp, we can also do this in gringo. If I had to fix it now, I would simply add release external statements for head occurrences of theory atoms. But then I also think that the complete handling of, whether a theory atom is external, should be done in gringo. Having both gringo and clasp add external statements sounds like a mess.

The program that reaches clasp no longer contains a rule with &c{} in the head. Hence, it gets special treatment resulting in the two answer sets (one with and one without &c{}).

So the correct semantics should be that the rule &c{} :- b, not a. is removed from the program,
leaving no trace that &c{} ever existed ?

@rkaminsk
I agree. It's not too complicated to add some code to clasp so that theory atoms are handled wrt to the unmodified input program. Of course, this will always require some extra processing/memory because the set of theory atoms is only known after parsing. Furthermore, it is then still the job of the grounder to actually output rules whose body is obviously false (e.g. &c{} :- a, not a. ).

Btw: Are there any new/problematic cases regarding clasp --pre? With the afore-mentioned changes, your program would be simplified to

asp 1 0 0
0

which has one answer set and no theory. Is that ok?

@MaxOstrowski
But what do you do for program in which &c{} occurrs the head of some r1 and the body of some r2 and only r1 is dropped during simplification. In that case, clasp would again do the wrong thing.

@rkaminsk
I agree. It's not too complicated to add some code to clasp so that theory atoms are handled wrt to the unmodified input program. Of course, this will always require some extra processing/memory because the set of theory atoms is only known after parsing. Furthermore, it is then still the job of the grounder to actually output rules whose body is obviously false (e.g. &c{} :- a, not a. ).

Yes, this is the job of the grounder. In hindsight, I am regretting a bit not having done this with external statements by the grounder. We have made the aspif semantics more complicated than necessary.

Btw: Are there any new/problematic cases regarding clasp --pre? With the afore-mentioned changes, your program would be simplified to

asp 1 0 0
0

which has one answer set and no theory. Is that ok?

That's exactly what I would expect.

Thanks, I'll include the fix tomorrow and let Max try if it works for his problem.

But what do you do for program in which &c{} occurrs the head of some r1 and the body of some r2 and only r1 is dropped during simplification. In that case, clasp would again do the wrong thing.

I think the behavior of clasp (with the fix) is okay in this case. If I were to come up with a theory, I would most likely not allow mixed occurrences of (the same) theory atoms in heads and bodies anyway. And I would discourage others from doing so. Even in clingcon, head occurrences of theory atoms are just syntactic sugar, they are shifted to the body anyway. With clingo's support for ASTs, this shifting can easily be done on the non-ground level.