Skip to content

FunctionConstraints are not respected by solution when added as a series of pairwise constraints between variables. #102

@dcanelhas

Description

@dcanelhas

Hi, it seems the solution returned by this simple example violates the added constraints.
I may have implemented it wrong or missed something about how constraints are handled (conjunction vs disjunction?) but it appears that the constraints provided pairwise, aren't chained together properly to enforce a globally consistent solution. I apologise if this is as designed, but I couldn't find any hints in the documentation that this behaviour is to be expected.

Python version: 3.9.7
OS: Windows 10
python-constraint2 release: 2.4.0 (installed through pip)

from constraint import Problem
problem = Problem()
domain = ['a', 'b']

grid_size = 4
num_tiles = grid_size**2
tile_indices = range(num_tiles)
problem.addVariables(tile_indices, domain)

# enforces inequality between horizontal neighbours
for row in range(grid_size):
    for col in range(grid_size-1):
        idx = row*grid_size + col
        idx_right = row*grid_size + col+1
        problem.addConstraint(lambda r, c:  c != r, [idx_right, idx])

# enforces inequality between vertical neighbours
for row in range(grid_size-1):
    for col in range(grid_size):
        idx = row*grid_size + col
        idx_down = (row+1)*grid_size + col
        problem.addConstraint(lambda d, c:  c != d, [idx_down, idx])

solution = problem.getSolution()

# print solution
if solution:
    for row in range(grid_size):
        for col in range(grid_size):
            idx = row*grid_size + col
            if col == grid_size-1: 
                print(f"{list(solution.values())[idx]}")
            else:
                # don't print newline unless at edge
                print(f"{list(solution.values())[idx]}", end='')
                
[ds, cs,cvs] = problem._getArgs()
print(ds)
print(cs)
print(cvs)

I would expect the solution to be some form of 4x4 checker-board pattern of 'a' and 'b' but instead I get

baab
abab
baba
baab

which obviously has a's and b's appearing next to each other in both rows and columns.

printing the constraints out shows that there is a constraint defined between 12 and 8 (which should be the two b's at the start of the last and second-to-last rows)

12: [(<constraint.constraints.FunctionConstraint object at 0x000001AB812E0B50>, [13, 12]), (<constraint.constraints.FunctionConstraint object at 0x000001AB812E0F70>, [12, 8])]

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions