Stepwise Debugging of Answer-Set Programs

05/18/2017 ∙ by Johannes Oetsch, et al. ∙ TU Wien 0

We introduce a stepping methodology for answer-set programming (ASP) that allows for debugging answer-set programs and is based on the stepwise application of rules. Similar to debugging in imperative languages, where the behaviour of a program is observed during a step-by-step execution, stepping for ASP allows for observing the effects that rule applications have in the computation of an answer set. While the approach is inspired from debugging in imperative programming, it is conceptually different to stepping in other paradigms due to non-determinism and declarativity that are inherent to ASP. In particular, unlike statements in an imperative program that are executed following a strict control flow, there is no predetermined order in which to consider rules in ASP during a computation. In our approach, the user is free to decide which rule to consider active in the next step following his or her intuition. This way, one can focus on interesting parts of the debugging search space. Bugs are detected during stepping by revealing differences between the actual semantics of the program and the expectations of the user. As a solid formal basis for stepping, we develop a framework of computations for answer-set programs. For fully supporting different solver languages, we build our framework on an abstract ASP language that is sufficiently general to capture different solver languages. To this end, we make use of abstract constraints as an established abstraction for popular language constructs such as aggregates. Stepping has been implemented in SeaLion, an integrated development environment for ASP. We illustrate stepping using an example scenario and discuss the stepping plugin of SeaLion. Moreover, we elaborate on methodological aspects and the embedding of stepping in the ASP development process.

READ FULL TEXT VIEW PDF
POST COMMENT

Comments

There are no comments yet.

Authors

page 39

This week in AI

Get the week's most popular data science and artificial intelligence research sent straight to your inbox every Saturday.

1 Introduction

Answer-set programming (ASP) [Niemelä (1999), Marek and Truszczyński (1999)]

is a paradigm for declarative problem solving that is popular amongst researchers in artificial intelligence and knowledge representation. Yet it is rarely used by software engineers outside academia so far. Arguably, one obstacle preventing developers from using ASP is a lack of support tools for developing answer-set programs. One particular problem in the context of programming support is

debugging of answer-set programs. Due to the fully declarative semantics of ASP, it can be quite tedious to detect an error in an answer-set program. In recent years, debugging in ASP has received some attention [Brain and De Vos (2005), Syrjänen (2006), Brain et al. (2007), Pührer (2007), Gebser et al. (2008), Gebser et al. (2009), Pontelli et al. (2009), Oetsch et al. (2010), Oetsch et al. (2010), Oetsch et al. (2011), Oetsch et al. (2012b), Polleres et al. (2013), Frühstück et al. (2013), Shchekotykhin (2015)]. These previous works are important contributions towards ASP development support, however current approaches come with limitations to their practical applicability. First, existing techniques and tools only capture a basic ASP language fragment that does not include many language constructs that are available and frequently used in modern ASP solver languages, e.g.,, aggregates or choice rules are not covered by current debugging strategies (with the exception of the work by PFSF13, where cardinality constraints are dealt with by translation). Second, usability aspects are often not considered in current approaches, in particular, the programmer is required to either provide a lot of data to a debugging system or he or she is confronted with a huge amount of information from the system (tackling this problem in query-based debugging has been addressed by S15).

This paper introduces a stepping methodology for ASP, which is a novel technique for debugging answer-set programs that is general enough to deal with current ASP solver languages and is intuitive and easy to use. Our method is similar in spirit to the widespread and effective debugging strategy in imperative programming, where the idea is to gain insight into the behaviour of a program by executing statement by statement following the program’s control flow. In our approach, we allow for stepwise constructing interpretations by considering rules of an answer-set program at hand in a successive manner. This method guarantees that either an answer set will be reached, or some error will occur that provides hints why the semantics of the program differs from the user’s expectations. A major difference to the imperative setting is that, due to its declarativity, ASP lacks any control flow. Instead, we allow the user to follow his or her intuition on which rule instances to become active. This way, one can focus on interesting parts of the debugging search space from the beginning. For illustration, the following answer-set program has as its only answer set.

a :- not b.
b :- not a.
a :- b.

Let’s step through the program to obtain explanations why this is the case. In the beginning of a stepping session, no atom is considered to be true. Under this premise, the first two rules are active. The user decides which of these rules to apply. Choosing a rule to be applied in this manner is considered a step in our approach. In case the user chooses the first rule, the atom a is derived. Then, no further rule is active and one of the answer sets, {a} has been reached. If, on the other hand, the user chooses the second rule in the first step, atom b is derived and a is considered false. Then, the third rule becomes active. However, this rule would derive a that is already considered false when choosing the second rule. In this case, the user sees that no answer set can be reached based on the initial choice.

Besides single steps that allow the user to consider one rule instance at a time, we also lay the ground for so-called jumps. The intuition is that in a jump multiple rule instances and even multiple non-ground rules can be considered at once. Jumping significantly speeds up the stepping process which makes our technique a usable tool for debugging in practice. Consider the following encoding of an instance of the three-colouring problem in the Gringo language [Gebser et al. (2011)]:

1{color(X,red;green;blue)}1 :- node(X).

:- edge(X,Y), color(X,C), color(X,C).

node(X):-edge(X,Y).
node(Y):-edge(X,Y).
edge(1,2). edge(1,3). edge(1,4).
edge(2,4). edge(2,5). edge(2,6).
edge(3,4). edge(3,5). edge(3,6).
edge(4,5). edge(5,6).

The user expects the program to have answer sets but it does not. Following our approach, the reason for that can be found after two actions. First, trusting the “instance” part of the program, the user applies a jump on all rules of this part, and, intuitively, gets all atoms implied by these rules as an intermediate result. Second, the user applies an arbitrary instance of the rule

1{color(X,red;green;blue)}1 :- node(X).

that is active under the atoms derived during the jump. Suppose, the user chooses the instance

1 {color(1, red), color(1, green), color(1, blue)} 1 :- node(1).

and selects color(1, red) to be true. Then, the debugging system reveals that the instance

:- edge(1, 2), color(1, red), color(1, red).

of the “check” constraint becomes unexpectedly active. Now, the users sees that the second occurrence of color(X,C) in the constraint has to be replaced by color(Y,C). Generally, bugs can be detected whenever stepping reveals differences between the actual semantics of the program and the expectations of the user.

In order to establish a solid formal basis for our stepping technique, we developed a framework of computations for answer-set programs. For fully supporting current solver languages, we were faced with several challenges. For one, the languages of answer-set solvers differ from each other and from formal ASP languages in various ways. In order to develop a method that works for different solvers, we need an abstract ASP language that is sufficiently general to capture actual solver languages. To this end, we make use of abstract constraints (Marek and Remmel, 2004; Marek and Truszczyński, 2004) as an established abstraction for language constructs such as aggregates, weight constraints, and external atoms. We rely on a semantics for arbitrary abstract-constraint programs with disjunctions that we introduced for this purpose in previous work Oetsch et al. (2012a). In contrast to other semantics for this type of programs, it is compatible with the semantics of all the ASP solvers we want to support, namely, Clasp Gebser et al. (2012), DLV Leone et al. (2006), and DLVHEX Redl (2016). Note that our framework for computations for abstract-constraint programs differs from the one by Liu et al. (2010). We did not build on this existing notion for three reasons. First, it does not cover rules with disjunctive heads which we want to support. Second, steps in this framework correspond to the application of multiple rules. Since our method is rooted in the analogy to stepping in procedural languages, where an ASP rule corresponds to a statement in an imperative language, we focus on steps corresponding to application of a single rule. Finally, the semantics of non-convex literals differs from that of DLVHEX in the existing approach. A thorough discussion on the relation of the two notions of computations is given in Section 5.

Another basic problem deals with the grounding step in which variables are removed from answer-set programs before solving. In formal ASP languages, the grounding of a program consists of all rules resulting from substitutions of variables by ground terms. In contrast, actual grounding tools apply many different types of simplifications and pre-evaluations for creating a variable-free program. In order to close this gap between formal and practical ASP, Pührer developed abstractions of the grounding step together with an abstract notion of non-ground answer-set program as the base language for the stepping methodology in his PhD thesis (Pührer, 2014). Based on that, stepping can easily be applied to existing solver languages and it becomes robust to changes to these languages. As we focus on the methodological aspects of stepping in this article, we do not present these abstractions and implicitly use grounding as carried out by actual grounding tools.

The stepping technique has been implemented in SeaLion Oetsch et al. (2013), an integrated development environment for ASP. We discuss how SeaLion can be used for stepping answer-set programs written in the Gringo or the DLV language.111The framework introduced in this paper subsumes and significantly extends previous versions of the stepping technique for normal logic programs (Oetsch et al., 2010, 2011) and DL-programs (Oetsch et al., 2012b).

Outline

Next, we provide the formal background that is necessary for our approach. We recall the syntax of disjunctive abstract-constraint programs and the semantics on which we base our framework Oetsch et al. (2012a). Section 3 introduces a framework of computations that allows for breaking the semantics down to the level of individual rules. After defining states and computations, we show several properties of the framework, most importantly soundness and completeness in the sense that the result of a successful computation is an answer set and that every answer set can be constructed with a computation. Moreover, we study language fragments for which a simpler form of computation suffices. In Section 4, we present the stepping technique for debugging answer-set programs based on our computation framework. We explain steps and jumps as a means to progress in a computation using an example scenario. Moreover, we discuss methodological aspects of stepping on the application level (how stepping is used for debugging and program analysis) and the top level (how stepping is embedded in the ASP development process). We illustrate the approach with several use cases and describe the stepping interface of SeaLion. Related work is discussed in Section 5. We compare stepping to other debugging approaches for ASP and discuss the relation of our computation framework to that of Liu et al. (2010) and transition systems for ASP Lierler (2011); Lierler and Truszczyński (2016); Brochenin et al. (2014). We conclude the paper in Section 6.

In A we compile guidelines for stepping and give general recommendations for ASP development. Selected and short proofs are included in the main text and all remaining proofs are provided in B.

2 Background

As motivated in the introduction, we represent grounded answer-set programs by abstract-constraint programs (Marek and Remmel, 2004; Marek and Truszczyński, 2004; Oetsch et al., 2012a). Non-ground programs will be denoted by programs in the input language of Gringo. Thus, we implicitly assume that grounding translates (non-ground) Gringo rules to rules of abstract-constraint programs. For a detailed formal account of our framework in the non-ground setting we refer the interested reader to the dissertation of Pührer (2014).

We assume a fixed set of ground atoms.

Definition 1

An interpretation is a set of ground atoms. A ground atom is true under interpretation , symbolically , if , otherwise it is false under .

We will use the symbol to denote the complement of a relation denoted with the symbol in different contexts.

For better readability, we sometimes make use of the following notation when the reader may interpret the intersection of two sets and of ground atoms as a projection from to .

Definition 2

For two sets and of ground atoms, is the projection of to .

2.1 Syntax of Abstract-Constraint Programs

Rule heads and bodies of abstract-constraint programs are formed by so-called abstract-constraint atoms.

Definition 3 (Marek and Remmel, 2004; Marek and Truszczyński, 2004)

An abstract constraint, abstract-constraint atom, or C-atom, is a pair , where is a finite set called the domain of , denoted by , and is a collection of sets of ground atoms, called the satisfiers of , denoted by .

We can express atoms also as C-atoms. In particular, for a ground atom , we identify the C-atom with . We call such C-atoms elementary.

We will also make use of default negation in abstract-constraint programs. An abstract-constraint literal, or C-literal, is a C-atom or a default negated C-atom .

Unlike the original definition, we introduce abstract-constraint programs with disjunctive rule heads.

Definition 4

An abstract-constraint rule, or simply C-rule, is an expression of the form

(1)

where and any , for , is a C-atom.

Note that if all disjuncts share the same domain they can be expressed by a single C-atom (see Pührer, 2014) but in general disjunction adds expressivity.

We identify different parts of a C-rule and introduce some syntactic properties.

Definition 5

For a C-rule of form (1),

  • is the body of ,

  • is the positive body of ,

  • is the negative body of , and

  • is the head of .

If and , then is a C-fact. For C-facts, we usually omit the symbol “”. A C-rule of form (1) is normal if and positive if .

We define the domain of a default negated C-atom as . Then, the domain of a set of C-literals is given by

Finally, the domain of a C-rule is

Definition 6

An abstract-constraint program, or simply C-program, is a finite set of C-rules. A C-program is normal, respectively positive, if it contains only normal, respectively positive, C-rules. A C-program is elementary if it contains only elementary C-atoms.

2.2 Satisfaction Relation

Intuitively, a C-atom is a literal whose truth depends on the truth of all atoms in under a given interpretation. The satisfiers in explicitly list which combinations of true atoms in make the C-atom true.

Definition 7

An interpretation satisfies a C-atom , symbolically , if . Moreover, iff .

Important criteria for distinguishing classes of C-atoms are concerned with their semantic behaviour with respect to growing (or shrinking) interpretations. In this respect, we identify monotonicity properties in the following.

Definition 8

A C-literal is monotone if, for all interpretations and , if and , then also . is convex if, for all interpretations , , and , if , , and , then also . Moreover, a C-program is monotone (respectively, convex) if for all all C-literals are monotone (respectively, convex).

Next, the notion of satisfaction is extended to C-rules and C-programs in the obvious way.

Definition 9

An interpretation satisfies a set of C-literals, symbolically , if for all . For brevity, we will use the notation to denote that for some . Moreover, satisfies a C-rule , symbolically , if implies . A C-rule such that is called active under . As well, satisfies a set of C-rules, symbolically , if for every . If , we say that is a model of .

2.3 Viewing ASP Constructs as Abstract Constraints

We want to use abstract constraints as a uniform means to represent common constructs in ASP solver languages. As an example, we recall how weight constraints Simons et al. (2002) can be expressed as C-atoms. In a similar fashion, we can use them as abstractions of e.g., aggregates Faber et al. (2004, 2011) or external atoms Eiter et al. (2005). Note that the relation between abstract constraints and ASP constructs is well known and motivated abstract constraints in the first place (cf. Marek and Remmel, 2004; Marek and Truszczyński, 2004).

Definition 10 (Simons et al., 2002)

A weight constraint is an expression of form

(2)

where each is a ground atom and each weight is a real number, for . The lower bound and the upper bound are either a real number, , or .

For a weight constraint to be true, the sum of weights of those atoms , , that are true and the weights of the atoms , , that are false must lie within the lower and the upper bound. Thus, a weight constraint of form (2) corresponds to the C-atom , where the domain consists of the atoms appearing in the weight constraint and

2.4 Semantics and Characterisations based on External Support and Unfounded Sets

The semantics we use Oetsch et al. (2012a) extends the FLP-semantics (Faber et al. 2004; 2011) and coincides with the original notion of answer sets by Gelfond and Lifschitz (1991) on many important classes of logic programs, including elementary C-programs. Similar to the original definition of answer sets, Faber et al. make use of a program reduct depending on a candidate interpretation for determining whether satisfies a stability criterion and thus is considered an answer set. However, the reduct of Faber, Leone, and Pfeifer differs in spirit from that of Gelfond and Lifschitz as it does not reduce the program to another syntactic class (the Gelfond-Lifschitz reduct of an elementary C-program is always positive). Instead, the so-called FLP-reduct, defined next, keeps the individual rules intact and just ignores all rules that are not active under the candidate interpretation.

Definition 11

Let be an interpretation, and let be a C-program. The FLP-reduct of with respect to is given by .

The notion of answer sets for abstract-constraint programs defined next provides the semantic foundation for the computation model we use for debugging.

Definition 12 (Oetsch et al., 2012a)

Let be a C-program, and let be an interpretation. is an answer set of if and there is no such that , , and satisfy the following condition:

  • for every with , there is some with and .

The set of all answer sets of is denoted by .

The purpose of Condition () is to prevent minimisation within C-atoms: the requirement ensures that a satisfier can enforce to be true in an answer set even if the same C-atom has a satisfier . As a consequence answer sets need not be subset minimal (see Pührer, 2014 for details).

Our choice of semantics has high solver compatibility as its objective as we want to support Gringo, DLV, and DLVHEX. We need an FLP-style treatment of non-convex literals for being compatible with DLVHEX, disjunctions to support DLV and DLVHEX, and we must allow for weight constraints in rule heads for compatibility with Gringo. Note that Gringo/Clasp treats aggregates in the way suggested by Ferraris (2011). As a consequence, its semantics differs from our semantics in some cases, when recursion is used through negated c-atoms, as ours is an extension of the FLP semantics. For an in-depth comparison of FLP-semantics and Ferraris semantics we refer to work by Truszczyński (2010). An example where the semantics differ is given by the single rule Gringo program a :- not 0{a}0 that has only the empty set as answer set under our semantics, whereas Clasp also admits as an answer set. In practice, this difference only hardly influences the compatibility with Gringo, as aggregates are seldom used in this way. We examined all Gringo encodings send to the second ASP competition and could not find any such usage.

Our framework of computations for stepping is based on a characterisation of the semantics of Definition 12 in terms of external supports. Often, answer sets are computed following a two-step strategy: First, a model of the program is built, and second, it is checked whether this model obeys a foundedness condition ensuring that it is an answer set. Intuitively, every set of atoms in an answer set must be “supported” by some active rule that derives one of the atoms. Here, it is important that the reason for this rule to be active does not depend on the atom it derives. Such rules are referred to as external support (Lee, 2005). The extension of this notion to our setting is the following.

Definition 13 (Oetsch et al., 2012a)

Let be a C-rule, a set of atoms, and an interpretation. Then, is an external support for with respect to if

  • ,

  • ,

  • there is some with and , for some , and

  • for all with , holds.

Condition (i) ensures that is active. Condition (ii) prevents self-support by guaranteeing the support to be “external” of , i.e., is also be active without the atoms in . In case is a model, Items (iii) and (iv) jointly ensure that there is some C-atom in the head of that is satisfied by and derives some atom of .

We can express the absence of an external support in an interpretation by the concept of an unfounded set.

Definition 14 (Oetsch et al., 2012a)

Let be a C-program, a set of atoms, and an interpretation. Then, is unfounded in with respect to if there is no C-rule that is an external support for with respect to .

[Oetsch et al., 2012a] Let be a C-program and an interpretation. Then, is an answer set of iff is a model of and there is no set with that is unfounded in with respect to .

3 Computation Framework

In this section, we want to break the conceptual complexity of the semantics down to artefacts the programmer is familiar with: the rules the user has written or, more precisely, their ground instances. To this end, we introduce a framework of computations that captures the semantics described in the previous section. In this computation model, on top of which we will introduce stepping in Section 4, an interpretation is built up step-by-step by considering an increasing number of rule instances to be active. A computation in our framework is a sequence of states which are structures that keep information which rules and atoms have already been considered and what truth values were assigned to those atoms. Utilising the framework, only one rule and the atoms it contains have to be considered at once while building up an interpretation until an answer set is reached or a source for the unexpected behaviour becomes apparent.

In the next two subsections, we introduce states and computations. In Section 3.3, we define and show some properties of computations that we need later on when we describe stepping. Section 3.4 is concerned with the existence of a stable computation which is a simpler form of computation that suffices for many popular classes of answer-set programs. We discuss existing work related to our computation framework later in Section 5.

3.1 States

Our framework is based on sequences of states, reassembling computations, in which an increasing number of ground rules are considered that build up a monotonically growing interpretation. Besides that interpretation, states also capture literals which cannot become true in subsequent steps and sets that currently lack external support in the state’s interpretation.

Definition 15

A state structure is a tuple , where is a set of C-rules, is an interpretation, a set of atoms such that and are disjoint, and is a collection of sets of atoms. We call the domain of and define , , , and .

A state structure is a state if

  • and for every ,

  • for every , and

  • .

We call the empty state.

Intuitively, we use the first component of a state to collect C-rules that the user has considered to be active and satisfied. The interpretation collects atoms that have been considered true. Condition (i) ensures that and are compatible in the sense that every C-rule that is considered active and satisfied is active and satisfied with respect to . Dual to , the interpretation collects atoms that the user has considered to be false. We require that all atoms appearing in a C-rule in is either in or in which is expressed in Condition (ii). Finally, the set keeps track of unfounded subsets of , as stated in Condition (iii). Intuitively, as we will see later, when building a computation, the aim is to get rid of all unfounded sets (except for the empty set) in order to compute an answer set of a C-program. If a state does not contain such unfounded sets then we call it stable:

Definition 16

A state is stable if .

The intuition is that when a state is stable, no more C-rules need to be added to to provide missing external support for the atoms in the current interpretation . Note that a state is stable exactly when . For example, the empty state is a stable state.

Example 1

Consider the C-rules

and the state structures

and are stable states. is not a state as . is not a state as the sets and are unfounded in with respect to but and . is a state but not stable.

3.2 Computations

Next, we show how we can proceed forward in a computation, i.e., which states might follow a given state using a successor relation for state structures.

Definition 17

For a state and a state structure , is a successor of if there is a C-rule and sets such that

  • ,

  • , , and ,

  • ,

  • ,

  • and , and

  • iff , where , , and is not an external support for with respect to .

We denote by .

Condition (i) ensures that a successor state considers exactly one rule more to be active. Conditions (ii) and (iii) express that the interpretations and are extended by the so far unconsidered literals in and appearing in the new C-rule . Note that from being a state structure we get that and are distinct. A requirement for considering as next C-rule is that it is active under the current interpretation , expressed by Condition (iv). Moreover, must be satisfied and still be active under the succeeding interpretation, as required by Condition (v). The final condition ensures that the unfounded sets of the successor are extensions of the previously unfounded sets that are not externally supported by the new rule.

Here, it is interesting that only extended previous unfounded sets can be unfounded sets in the extended C-program and that is the only C-rule which could provide external support for them in with respect to the new interpretation as seen next.

Let be a state and a successor of , where . Moreover, let be a set of literals with . Then, the following statements are equivalent:

  • is unfounded in with respect to .

  • , where , , and is not an external support for with respect to .

The result shows that determining the unfounded sets in a computation after adding a further C-rule can be done locally, i.e., only supersets of previously unfounded sets can be unfounded sets, and if such a superset has some external support then it is externally supported by . The result also implies that the successor relation suffices to “step” from one state to another. Let be a state and a successor of . Then, is a state. We show that the Conditions (i), (ii), and (iii) of Definition 15 hold for . Consider some rule . In case , and hold because of Item (v) of Definition 17 and because of Item (iii) of the same definition. Moreover, in case , we have . As is a state, we have . Hence, since also . Note that because of Item (ii) of Definition 17. Therefore, as and , also and . From these two cases, we see that Conditions (i) and (ii) of Definition 15 hold for . Finally, Condition (iii) follows from Item (vi) of Definition 17 and Theorem 3.2.

Next, we define computations based on the notion of a state.

Definition 18

A computation is a sequence of states such that is a successor of , for all . We call rooted if is the empty state and stable if each is stable, for .

3.3 Properties

We next define when a computation has failed, gets stuck, is complete, or has succeeded. Intuitively, failure means that the computation reached a point where no answer set of the C-program can be reached. A computation is stuck when the last state activated rules deriving literals that are inconsistent with previously chosen active rules. It is considered complete when there are no more unconsidered active rules. Finally, a computation has succeeded if an answer set has been reached.

Definition 19

Let be a C-program and a computation such that . Then, is called a computation for . Moreover,

  • has failed for at step if there is no answer set of such that , , and ;

  • is complete for if for every rule , we have ;

  • is stuck in if it is not complete for but there is no successor of such that ;

  • succeeded for if it is complete and is stable.

Example 2

Let be the C-program consisting of the C-rules

that has as its single answer set, and consider the sequences

, , , , and are computations for . The sequence is not a computation, as is not a state. is not a computation, as the second state in is not a successor of the empty state. , , and are rooted. , , and are stable. and are complete and have succeeded for . is complete for but has failed for at Step because has no answer set. has failed for at Step . has failed for at Step and is stuck in .

The following result guarantees the soundness of our framework of computations. Let be a C-program and a computation that has succeeded for . Then, is an answer set of . As is complete for , we have . Conversely, we have because for each we have and . By stability of , we get that . The conjecture holds since then . The computation model is also complete in the following sense: Let be a state, a C-program with , and an answer set of with and . Then, there is a computation that has succeeded for such that and . As the empty state, , is trivially a state, we can make the completeness aspect of the previous result more apparent in the following corollary: Let be a C-program and . Then, there is a rooted computation that has succeeded for such that and . The claim follows immediately from Theorem 3.3 in case .

Note, that there are states that do not result from rooted computations, e.g., the state is not a successor of any other state. However, for stable states, we can guarantee the existence of rooted computations. Let be a stable state. Then, there is a rooted computation with . The result is a direct consequence of Corollary 3.3 and Definition 16.

The next theorem lays the ground for the jumping technique that we introduce in Section 4. It allows for extending a computation by considering multiple rules of a program at once and using ASP solving itself for creating this extension. Let be a C-program, a computation for , a set of C-rules with , and an answer set of with and . Then, there is a computation for , such that is stable, and . By Theorem 3.3, as , , and , there is a computation that has succeeded for such that and . Then, is stable and, as , we have . As , we have that is a computation for .

The following result illustrates that the direction one chooses for building up a certain interpretation, i.e., the order of the rules considered in a computation, is irrelevant in the sense that eventually the same state will be reached. Let be a C-program and and computations complete for such that . Then, iff and . The “if” direction is trivial. Let . Towards a contradiction, assume . Without loss of generality, we focus on the case that there is some such that . Then, it holds that , , and . Consequently, . By completeness of , we have which contradicts our assumption. Hence, we have .

By definition of a state, from and , it follows that . Towards a contradiction, assume . Without loss of generality we focus on the case that there is some such that . Consider the integer where such that but . Then, by definition of a successor, for , we have for some . As then and, as , we have , it must hold that by definition of a state structure. From we know that . Therefore, since , we get that , being a contradiction to our assumption. As then , , and since in every step in a computation exactly one rule is added it must hold that .

For rooted computations, the domain of each state is determined by the atoms in the C-rules it contains. Let be a rooted computation. Then, and , for all . The proof is by contradiction. Let be the smallest index with such that or . Note that as . As is a successor of , we have and , where , , and . As we have and , it holds that

where . For establishing the contradiction, it suffices to show that and . Consider some . Then, because , , and . Moreover, implies and therefore . Now, consider some . As , we have . Consider the case that . Then, also which is a contradiction to as is a state structure. Hence, . First, assume . This leads to a contradiction as then since . It follows that and therefore . One can show that analogously.

3.4 Stable Computations

In this section, we are concerned with the existence of stable computations, i.e., computations that do not involve unfounded sets. We single out an important class of C-programs for which one can solely rely on this type of computation and also give examples of C-programs that do not allow for succeeding stable computations.

Intuitively, the -hardness of the semantics (cf. Pührer, 2014), demands for unstable computations in the general case. This becomes obvious when considering that for a given C-program one could guess a candidate sequence for a stable computation in polynomial time. Then, a polynomial number of checks whether each state is a successor of the previous one in the sequence suffices to establish whether is a computation. Following Definition 17, these checks can be done in polynomial time when we are allowed to omit Condition (vi) for unfounded sets. Hence, answer-set existence for the class of C-programs for which every answer set can be built up with stable computations is in NP.

Naturally, it is interesting whether there are syntactic classes of C-programs for which we can rely on stable computations only. It turns out that many syntactically simple C-programs already require the use of unfounded sets.

Example 3

Consider C-program  consisting of the C-rules

We have that is the only answer set of and

is the only computation that succeeds for : starting at the empty state, only rule is active, thus it must be the new rule in the successor. When, deciding the truth values for the atoms in , requires to be positive, and must be true as well, as otherwise the computation is stuck due to violation of . The second state of