Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Atom constructor reuses wrong object from store #160

Closed
maweki opened this issue Feb 29, 2024 · 2 comments
Closed

Atom constructor reuses wrong object from store #160

maweki opened this issue Feb 29, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@maweki
Copy link

maweki commented Feb 29, 2024

The Atom-constructor incorrectly matches existing objects if they are tuples

import pysat
print(pysat.VERSION)
from pysat.formula import Atom

boxes = {}
width = 3
height = 4
for x in range(width):
  for y in range(height):
      boxes[(x,y)] = Atom(object=(x,y))
      print(repr(boxes[(x,y)]))
print("==========")
for b in enumerate(boxes.items()):
  print(b)

The result is

(1, 8, 'dev', 3)
Atom(('0', '0'))
Atom(('0', '1'))
Atom(('0', '2'))
Atom(('0', '3'))
Atom(('1', '0'))
Atom(('1', '1'))
Atom(('1', '2'))
Atom(('1', '3'))
Atom(('2', '0'))
Atom(('2', '1'))
Atom(('2', '2'))
Atom(('2', '3'))
==========
(0, ((0, 0), Atom(('0', '0'))))
(1, ((0, 1), Atom(('1', '0'))))
(2, ((0, 2), Atom(('2', '0'))))
(3, ((0, 3), Atom(('0', '3'))))
(4, ((1, 0), Atom(('1', '0'))))
(5, ((1, 1), Atom(('1', '1'))))
(6, ((1, 2), Atom(('2', '1'))))
(7, ((1, 3), Atom(('1', '3'))))
(8, ((2, 0), Atom(('2', '0'))))
(9, ((2, 1), Atom(('2', '1'))))
(10, ((2, 2), Atom(('2', '2'))))
(11, ((2, 3), Atom(('2', '3'))))

The Atoms are constructed correctly. But when we print out the whole dictionary, we can see that for entry 1,2, and 6 the Atom's internal object has been replaced with the later created Atom with the "mirrored" tuple. And if we check boxes[(0,1)] is boxes[(1,0)] then we get True which is not what we originally expressed.

The same happens with a tuple of strings, or a list of ints, but not with a string (object=str(x)+str(y)).

I guess the minimal test case would be

a = Atom((3,4))
b = Atom((4,3))
print(a is b) # should return False, does return True
a = Atom(('3','4'))
b = Atom(('4','3'))
print(a is b) # should return False, does return True
a = Atom([3,4])
b = Atom([4,3])
print(a is b) # should return False, does return True
@alexeyignatiev
Copy link
Collaborator

Hm, interesting. It must have to do with the duplicate checking, which probably somehow fails to distinguish differently sorted tuples. I more-or-less understand where it comes from (flattening and then sorting in _get_key()). I will need to think how this could be fixed.

@alexeyignatiev
Copy link
Collaborator

This should be fixed in 1.8.dev7. Closing the issue. Feel free to reopen if it persists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants