Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2011
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.48 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3.  
  4. log_indent = 0
  5.  
  6. def log(*s):
  7.   global log_indent
  8.   print "c " + (" " * log_indent) + " ".join(map(str, s))
  9.   log_indent += 2
  10.  
  11. def log_out():
  12.   global log_indent
  13.   log_indent -= 2
  14.  
  15.  
  16.  
  17. class Formula(object):
  18.   def __init__(self):
  19.     self.nvars = 2  # Variables 1 & 2 are used as placeholders. They are == 0.
  20.     self.clauses = []
  21.  
  22.   def allocate(self, n = 1):
  23.     curn = self.nvars
  24.     self.nvars += n
  25.     return curn
  26.  
  27.   def add_triplet(self, a, b, c, truth_table):
  28.     assert a < self.nvars
  29.     assert b < self.nvars
  30.     assert c < self.nvars    
  31.    
  32.     for av in xrange(2):
  33.       for bv in xrange(2):
  34.         for cv in xrange(2):
  35.           if (av, bv, cv) not in truth_table:
  36.             self.clauses.append((-(a+1) if av else a+1,
  37.                                  -(b+1) if bv else b+1,
  38.                                  -(c+1) if cv else c+1))
  39.  
  40.   def print_cnf(self):
  41.     print "p cnf %d %d" % (self.nvars, len(self.clauses))
  42.    
  43.     for a, b, c in self.clauses:
  44.       print a, b, c, 0
  45.  
  46.   def check(self, x):
  47.     for a, b, c in self.clauses:
  48.       v = False
  49.       if a < 0:
  50.         v = v or not x[-a - 1]
  51.       else:
  52.         v = v or x[a - 1]
  53.  
  54.       if b < 0:
  55.         v = v or not x[-b - 1]
  56.       else:
  57.         v = v or x[b - 1]
  58.      
  59.       if c < 0:
  60.         v = v or not x[-c - 1]
  61.       else:
  62.         v = v or x[c - 1]
  63.      
  64.       if not v:
  65.         print "Wrong clause:", a, b, c
  66.  
  67.  
  68.   def set_const1(self, a, v):
  69.     log("x" + str(a), "=", v)
  70.     self.add_triplet(a, 0, 1, [(v, 0, 0)])
  71.     log_out()
  72.  
  73.   def set_const2(self, a, b, va, vb):
  74.     log("x" + str(a), "x" + str(b), "=", va, vb)
  75.     self.add_triplet(a, b, 0, [(va, vb, 0)])
  76.     log_out()
  77.  
  78.   def set_const3(self, a, b, c, va, vb, vc):
  79.     log("x" + str(a), "x" + str(b), "x" + str(c), "=", va, vb, vc)
  80.     self.add_triplet(a, b, c, [(va, vb, vc)])
  81.     log_out()
  82.  
  83.   def set_long_constant(self, a, n, v):
  84.     log("x" + str(a) + "..x" + str(a + n - 1), "=", v)
  85.     for i in xrange(0, n - 2, 3):
  86.       b1 = v % 2
  87.       v //= 2
  88.       b2 = v % 2
  89.       v //= 2
  90.       b3 = v % 2
  91.       v //= 2
  92.       self.set_const3(a + i, a + i + 1, a + i + 2, b1, b2, b3)
  93.     if n % 3 == 1:
  94.       self.set_const1(a + n - 1, v)
  95.     elif n % 3 == 2:
  96.       self.set_const2(a + n - 2, a + n - 1, v % 2, v // 2)
  97.     log_out()
  98.  
  99.   def new_long_constant(self, n, v):
  100.     a = self.allocate(n)
  101.     self.set_long_constant(a, n, v)
  102.     return a
  103.  
  104.   def or2(self, a, b):
  105.     log("x%d | x%d" % (a, b))
  106.     self.add_triplet(a, b, 0, [(0, 1, 0), (1, 0, 0), (1, 1, 0)])
  107.     log_out()
  108.  
  109.   def or3(self, a, b, c):
  110.     log("x%d | x%d | x%d" % (a, b, c))
  111.     self.add_triplet(a, b, c, [(0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)])
  112.     log_out()
  113.  
  114.   def eq_or(self, a, b, c):
  115.     log("x%d = x%d | x%d" % (a, b, c))
  116.     self.add_triplet(a, b, c, [(0, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)])
  117.     log_out()
  118.  
  119.   def new_or(self, a, b):
  120.     x = self.allocate()
  121.     self.eq_or(x, a, b)
  122.     return x
  123.    
  124.   def or_mult(self, a, n):
  125.     if n == 1:
  126.       formula.set_const1(a, 1)
  127.     elif n == 2:
  128.       formula.or2(a, a + 1)
  129.     elif n == 3:
  130.       formula.or3(a, a + 1, a + 2)
  131.     else:
  132.       log(" | ".join("x%d" % i for i in range(a, a + n)))
  133.       c = self.new_or(a, a + 1)
  134.       for i in xrange(a + 2, a + n - 2):
  135.         c = self.new_or(c, i)
  136.       self.or3(c, a + n - 2, a + n - 1)
  137.       log_out()
  138.  
  139.   def eq_and(self, a, b, c):
  140.     log("x%d = x%d & x%d" % (a, b, c))
  141.     self.add_triplet(a, b, c, [(0, 0, 0), (0, 0, 1), (0, 1, 0), (1, 1, 1)])
  142.     log_out()
  143.  
  144.   def new_and(self, a, b):
  145.     x = self.allocate()
  146.     self.eq_and(x, a, b)
  147.     return x
  148.  
  149.   def eq_xor(self, a, b, c):
  150.     log("x%d = x%d xor x%d" % (a, b, c))
  151.     self.add_triplet(a, b, c, [(0, 0, 0), (1, 0, 1), (1, 1, 0), (0, 1, 1)])
  152.     log_out()
  153.  
  154.   def new_xor(self, a, b):
  155.     x = self.allocate()
  156.     self.eq_xor(x, a, b)
  157.     return x
  158.  
  159.   def eq(self, a, b):
  160.     log("x%d = x%d" % (a, b))
  161.     self.add_triplet(a, b, 0, [(0, 0, 0), (1, 1, 0)])
  162.     log_out()
  163.    
  164.  
  165. def greater_than_1(formula, a, n):
  166.   assert n > 1
  167.   log("x%d..x%d > 1" % (a, a + n - 1))
  168.   formula.or_mult(a + 1, n - 1)
  169.   log_out()
  170.  
  171.  
  172. def multiply1(formula, res, a, n, bit):
  173.   log("x%d..x%d = x%d..x%d * x%d" % (res, res + n - 1, a, a + n - 1, bit))
  174.   for i in range(n):
  175.     formula.eq_and(res + i, a + i, bit)
  176.   log_out()
  177.  
  178.  
  179. def new_multiply1(formula, a, n, bit):
  180.   res = formula.allocate(n)
  181.   multiply1(formula, res, a, n, bit)
  182.   return res
  183.  
  184.  
  185. def add(formula, res, a, b, n):
  186.   log("x%d..x%d = x%d..x%d + x%d..x%d" % (res, res + n, a, a + n - 1, b, b + n - 1))
  187.  
  188.   formula.eq_xor(res, a, b)
  189.   c = formula.new_and(a, b)
  190.  
  191.   for i in range(1, n):
  192.     # res[i] = c xor a[i] xor b[i]
  193.    
  194.     d = formula.new_xor(a + i, b + i)
  195.     formula.eq_xor(res + i, c, d)
  196.    
  197.     # c = c & (a[i] xor b[i]) || a[i] & b[i]
  198.    
  199.     e = formula.new_and(a + i, b + i)
  200.     f = formula.new_and(c, d)
  201.     c = formula.new_or(e, f)
  202.  
  203.   formula.eq(res + n, c)  
  204.  
  205.   log_out()
  206.  
  207.  
  208. def new_add(formula, a, b, n):
  209.   res = formula.allocate(n + 1)
  210.   add(formula, res, a, b, n)
  211.   return res
  212.  
  213.  
  214. def multiply(formula, res, y, z, n):
  215.   log("x%d..x%d = x%d..x%d * x%d..x%d" % (res, res + 2*n - 1, y, y + n - 1, z, z + n - 1))
  216.  
  217.   psum = formula.allocate(n + 1)
  218.   formula.set_const1(psum + n, 0)
  219.  
  220.   multiply1(formula, psum, y, n, z)
  221.  
  222.   formula.eq(res, psum)
  223.  
  224.   for i in range(1, n):
  225.     # psum = y * z[i] + (psum >> 1)
  226.     d = new_multiply1(formula, y, n, z + i)
  227.     psum = new_add(formula, d, psum + 1, n)
  228.    
  229.     formula.eq(res + i, psum)
  230.  
  231.   for i in range(1, n + 1):
  232.     formula.eq(res + n + i - 1, psum + i)
  233.  
  234.   log_out()  
  235.  
  236.  
  237. formula = Formula()
  238.  
  239. # bits
  240. n = 7
  241.  
  242. # x = y * z
  243. x = formula.new_long_constant(2*n, 239)
  244. y = formula.allocate(n)
  245. z = formula.allocate(n)
  246.  
  247. greater_than_1(formula, y, n)
  248. greater_than_1(formula, z, n)
  249.  
  250. multiply(formula, x, y, z, n)
  251.  
  252. formula.print_cnf()
  253.  
  254. # For n = 2, x = 6:
  255. #
  256. #formula.check([False, False,
  257. #               False, True, True, False,  # x = 6
  258. #               False, True,               # y = 2
  259. #               True, True,                # z = 3
  260. #               False, True, False,        # x10..x12 = y = 2
  261. #               False, True,               # x13..x14 = y = 2
  262. #               True, True, False,         # x15..x17 = x13..x14 + x11..x12
  263. #               False, True,               # x18 - x19
  264. #               False, False, False])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement