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.