2

Assume I have a graph and want to find 2 different cliques withhin the graph. A clique is a subset of the graphs vertices where all of them are connected. Example Graph with 2 cliques (a,b,c) and (b,c,d) of cliquesize 3 :

edge(a,b). edge(a,c). edge(b,c). edge(d,c). edge(d,b).
vertex(X;Y) :- edge(X,Y).

enter image description here

Getting 2 cliques is rather easy:

#const cs=3. % cliquesize
cs{clique1(X) : vertex(X)}cs.
:- clique1(X), clique1(Y), X!=Y, not edge(X,Y), not edge(Y,X).
cs{clique2(X) : vertex(X)}cs.
:- clique2(X), clique2(Y), X!=Y, not edge(X,Y), not edge(Y,X).

#show clique1/1.
#show clique2/1.

gives:

Answer: 1
clique2(d) clique1(a) clique2(b) clique2(c) clique1(b) clique1(c)
Answer: 2
clique2(d) clique1(d) clique2(b) clique2(c) clique1(b) clique1(c)
Answer: 3
clique2(a) clique1(a) clique2(b) clique2(c) clique1(b) clique1(c)
Answer: 4
clique2(a) clique1(d) clique2(b) clique2(c) clique1(b) clique1(c)
SATISFIABLE

which can be interpretet as:

Answer 1: (a,b,c), (b,c,d)
Answer 2: (b,c,d), (b,c,d)
Answer 3: (a,b,c), (a,b,c)
Answer 4: (b,c,d), (a,b,c)

But how to test if both cliques are different? I tried

differ() :- clique1(X), clique2(Y), X!=Y.
:- not differ().

But this has no effect on the output. How do I test if two cliques differ?


Now I found this Solution:

differ() :- clique1(X), vertex(X), not clique2(X).
:- not differ().

It works but I don't like that it needs 2 lines. How do I put it in one constraint?

DuDa
  • 3,718
  • 4
  • 16
  • 36

1 Answers1

1

How do I put it in one constraint?

This is a bit tricky since you basically want an existential quantification: "There must be at least one vertex difference between cliques", so simply plugging the body of your rule deriving differ/0 doesn't work. (Since that would be a universal quantification over all vertices)

I think the following would fit your requirement of a one-line constraint:

:- #count{X : clique1(X), not clique2(X)} < 1.

However, dependíng on how big your input graphs are, I could imagine that this might cause performance issues.

I'm not sure about your exact requirements, but maybe you could take a slightly different approach:

  • Only look for one clique (basically comment out the clique2 part)
  • Configure the number of cliques you actually want via the number of answer sets you request from clingo.

In your scenario, that would then be ..$clingo -n 2 clique.asp, with the additional bonus that you only get one clique per answer set, and however many (different) cliques you want.

  • Of course, counting them! Now I feel stupid. Yes, performance is an issue and maybe I have to outsource this problem. – DuDa Nov 20 '20 at 15:30