1

Basically, I have a graph coloring program where each node with an edge to another node has to be different colors. Here, is my code:

node(1..4).

edge(1,2).
edge(2,3).
edge(3,4).
edge(4,1).
edge(2,4).

color(1..3).

{ assign(N,C) : color(C) } = 1 :- node(N).

1 { assign(N,1) : color(1) } 1 :- node(N). %line in question

:- edge(N,M), assign(N,C), assign(M,C).

How would I tell the program to only assign color 1, once? The line labeled %line in question is the line giving me problems. Here is another solution I tried that didn't work:

node(1..4).

edge(1,2).
edge(2,3).
edge(3,4).
edge(4,1).
edge(2,4).

color(1..3).

{ assign(N,C) : color(C) } = 1 :- node(N).

:- edge(N,M), assign(N,C), assign(M,C).

vtx(Node, Color) :- node(Node), color(Color).

1 { vtx(N, 1) : color(1) } 1 :- node(N).

#show vtx/2.

If anyone could help me out it would be much appreciated.

2 Answers2

1

In this simple case of restricting a single color to be used once, you can write the a single constraint

:- assign(N, 1), assign(M, 1), node(N), node(M), N!=M.
vukk
  • 523
  • 2
  • 11
0

Actually, the line you marked as in question :

1 { assign(N,1) : color(1) } 1 :- node(N). %line in question

can be translated as

If N is a node, we will (and we must) assign color(1) to node(N) and only assign once, i.e. If node(i) is true, we will have exactly one node(i, 1).

Therefore, with this rule and your facts node(1..4), you will immediately get assign(1,1), assign(2,1), assign(3,1), assign(4,1). This is defninitely unsatisfiable under color problem (with the last constraint).

Back to your requirement:

How would I tell the program to only assign color 1, once?

The problem here is the constraint you set in the line: "color 1 is assigned only once" applies to each node(i), i=1,2,3,4 instead of all nodes.

To make it clearer, you might as well consider that this line would be instantiated as:

1 { assign(1,1) : color(1) } 1 :- node(1). 
1 { assign(2,1) : color(1) } 1 :- node(2). 
1 { assign(3,1) : color(1) } 1 :- node(3). 
1 { assign(4,1) : color(1) } 1 :- node(4).

With node(1..4) all true, we will have assign(1,1), assign(2,1), assign(3,1), assign(4,1).

What you want is assign(N, 1) appears once and only once in the answer, thus in your rule, this should be true with no premiere condition.

Therefore, change the problem line into:

{ assign(N,1): node(N), color(1) } = 1. %problem line changed

You will get the proper assignment:

clingo version 5.4.0
Reading from test.lp
Solving...
Answer: 1
assign(2,2) assign(1,3) assign(3,3) assign(4,1)
Answer: 2
assign(1,2) assign(2,3) assign(3,2) assign(4,1)
Answer: 3
assign(2,1) assign(1,3) assign(3,3) assign(4,2)
Answer: 4
assign(2,1) assign(1,2) assign(3,2) assign(4,3)
SATISFIABLE

Intuitively, this line means the assign(N, 1) should be in answer set under no condition, as long as N is a node. This will count all nodes instead of every single one.

BobHU
  • 402
  • 5
  • 18