Technical Guide to Answer Set Programming

Here I will go over the main reasons for using ASP, syntax, and best practices. Feel free to check my github repo for working examples (if this is useful to you, consider dropping a star). All the specific syntax I use is from clingo.

What problem does an ASP solve?

ASP is, as the wiki page states, a good approach to solving NP-hard problems where we want to establish a search space and let a solver find a solution without having to design an algorithm (but keeping some explainability). In a more practical way, we write programs that are lists of rules; then we let a solver find solution/s that satisfy all rules.

What does it mean to satisfy all rules?

All rules are in the shape head :- body which roughly translates to the logic statement head <- body, which is a logical equivalence to head or not(body). To satisfy all rules is then equivalent to find a set of variables such that for each rule either the head is true, or the body is false .

If you come from Prolog this is extremely familiar; the advantage being that ASP can deal with circular dependency loops.

Syntax

Let’s go over practical, concise explanations on semantics:

head <- rule.
head is part of a solution if rule is part of a solution
head <-.
head is part of a solution (always)
<- rule.
rule cannot be part of the solution
{head }<- rule.
head is (or not) a part of a solution if rule is a part of a solution
head <- {rule1;rule2}.
head is a part of a solution if rule1 OR rule2 is a part of a solution
{head1;head2} <- rule.
head1 or head2 are a part of a solution if rule is a part of a solution. We can read the ; as an OR.
L{head1;head2;head3}U <- rule.
[L,U] heads are a part of a solution if rule is a part of a solution

Syntax extension with variables

L{var_head_1(A,B):var(B);var_head_2(A,C):var(C)}U <- var_body(A).
for every var_body(A) we guessi a total of [L,U] (summing var_head_1 and var_head_2) are a part of a solution. Each var_head_1(A,B) needs there to be a corresponding var(B)(and the same applies to (var_head_2(A,C) and var(C)). We can read the : as “such that”.

Debugging ASP problems

General methodology

It is just good practice to use the methodology officially recomended. The approach suggested is called generate (rules with {} on the head) and test (rules of the shape :-body). Generate refers to the fact that, in the simplest of cases {a}., the solver will clone every pre-existing solution that didn’t have a and add a to it (if a had not been referenced, duplicating the solutions).

I will add to this methodology that implications head :- body by themselves only extend the current solution by sometimes deducing some variables. If we had 3 solutions prior to an implication, we will keep the same solutions with some more variables on them.

Common pitfalls

I want to create the pairs of different numbers between 1 and 2. I have num(1).num(2).

I am getting too many incorrect solutions

Now I am getting an UNSAT

Let me create this relation that uses 6+ terms and expresses perfectly all the constraints of the problem

My program never finishes

Efficiency tricks

Generally speaking, the easiest way to increase efficiency is to generate less possible variables. Lets use an example from the github on robots.

A specific (but very common) example:

Robots doing some tasks in a map represented by edges edge(Node1,Node2). There is also a time T.

  1. Robots on a map can move to somewhere adjacent.
{at(R,N2,T+1)}=1:-at(R,N1,T)} ,time(T+1).% a robot will be exactly at one place at a time
:- at(R,N2,T+1),at(R,N1,T),edge(N1,N2) . % no teleporting
{at(R,N2,T): edge(N1,N2);at(R,N1,T)}=1 :- at(R,N1,T-1),time(T).% a robot will exactly be at one adjactent place at a time
  1. These robots have to do a series of tasks in a certain order.
can_be_done(J,O,T2):- %operation O of job J can be done at T2
	operation(J,O-1,_),%the previous operation exists
	done(J,O-1,T1),time(T2),T1<T2.% previos was finished before
done(J,O,T) :- done(J,O,T-1),time(T).
can_be_done(J,O,T2):- %operation O of job J can be done at T2
	operation(J,O-1,_),%the previous operation exists
	done(J,O-1,T2-1).% previos was finished before

Donation

Monero
49va5kaQ8qzQjfNpTjURwiFR9Zh1uQQsT5cbnnur2NUsfzCbU1QQ2tG3PhdeapEGFTLuGMcx46ss6grJTKKFfP8EC1ePk9M
Monero QR Code
Paypal
PayPal QR Code