dimacs.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. """For reading in DIMACS file format
  2. www.cs.ubc.ca/~hoos/SATLIB/Benchmarks/SAT/satformat.ps
  3. """
  4. from sympy.core import Symbol
  5. from sympy.logic.boolalg import And, Or
  6. import re
  7. from pathlib import Path
  8. def load(s):
  9. """Loads a boolean expression from a string.
  10. Examples
  11. ========
  12. >>> from sympy.logic.utilities.dimacs import load
  13. >>> load('1')
  14. cnf_1
  15. >>> load('1 2')
  16. cnf_1 | cnf_2
  17. >>> load('1 \\n 2')
  18. cnf_1 & cnf_2
  19. >>> load('1 2 \\n 3')
  20. cnf_3 & (cnf_1 | cnf_2)
  21. """
  22. clauses = []
  23. lines = s.split('\n')
  24. pComment = re.compile(r'c.*')
  25. pStats = re.compile(r'p\s*cnf\s*(\d*)\s*(\d*)')
  26. while len(lines) > 0:
  27. line = lines.pop(0)
  28. # Only deal with lines that aren't comments
  29. if not pComment.match(line):
  30. m = pStats.match(line)
  31. if not m:
  32. nums = line.rstrip('\n').split(' ')
  33. list = []
  34. for lit in nums:
  35. if lit != '':
  36. if int(lit) == 0:
  37. continue
  38. num = abs(int(lit))
  39. sign = True
  40. if int(lit) < 0:
  41. sign = False
  42. if sign:
  43. list.append(Symbol("cnf_%s" % num))
  44. else:
  45. list.append(~Symbol("cnf_%s" % num))
  46. if len(list) > 0:
  47. clauses.append(Or(*list))
  48. return And(*clauses)
  49. def load_file(location):
  50. """Loads a boolean expression from a file."""
  51. s = Path(location).read_text()
  52. return load(s)