def is_fru(tuples, node): mit = ckt.Const0Node() nsupp = node.support() isupp = set() seltuples = [] for (n, ci, ki) in tuples: if ci in nsupp and ki in nsupp: isupp.add(ci) isupp.add(ki) seltuples.append((ci, ki)) print(len(nsupp), len(isupp)) print(nsupp) print(isupp) assert isupp == nsupp print('# of pairs of inputs in support: ' % len(seltuples)) for (ci, ki) in seltuples: eq = (ci ^ ki) mit = mit | eq comp = ckt.NotGate(mit) miter = (node ^ comp) S = Solver() nmap = {} clauses = adapter.circuitToCNF(miter, nmap, lambda n: S.newVar()) for cl in clauses: S.addClause(*cl) r1 = S.solve(nmap[miter]) if r1 == False: return True r2 = S.solve(-nmap[miter]) if r2 == False: return True
def testSort(): S = Solver() xs = [S.newVar() for i in range(8)] (clauses, ws) = sortNetwork(TWO_COMP_EQ, xs, lambda: S.newVar()) for c in clauses: S.addClause(*c) tt = [] while S.solve(): row = [] ms = [] ns = [] bc = [] for vi in xs: mi = int(S.modelValue(vi)) ms.append(mi) bc.append(-vi if mi else vi) for vi in ws: mi = int(S.modelValue(vi)) ns.append(mi) S.addClause(*bc) row.append(ms) row.append(ns) tt.append(row) assert list(reversed(sorted(ms))) == ns tt.sort() for row in tt: print(row)
def is_unate(gate): s = Solver() supports = gate.support() #print supports def newVar(n): return s.newVar() for inp in supports: s.push() node_to_literal_0 = {} node_to_literal_1 = {} for sup in supports: if sup != inp: node_to_literal_0[sup] = newVar(0) node_to_literal_1[sup] = node_to_literal_0[sup] ckt1 = ckt.NotGate(gate) ckt_cnf_0 = adapter.circuitToCNF(gate, node_to_literal_0, newVar) ckt_cnf_1 = adapter.circuitToCNF(gate, node_to_literal_1, newVar) for clause in ckt_cnf_0 + ckt_cnf_1: s.addClause(*clause) # Check counter example for positive unateness r1 = s.solve(-node_to_literal_0[inp], node_to_literal_1[inp], node_to_literal_0[gate], -node_to_literal_1[gate]) if r1: # Check counter example for negative unateness r2 = s.solve(-node_to_literal_0[inp], node_to_literal_1[inp], -node_to_literal_0[gate], node_to_literal_1[gate]) if r2: return False s.pop() return True
def getUnateNodes(outputs): S = Solver() supports = set() gates = set() for o in outputs: supports = supports.union(o.support()) gates = gates.union(o.transitiveFaninCone()) # topo sort. ckt.computeLevels(gates) def newVar(n): return S.newVar() cnf = [] nmap1 = {} nmap2 = {} cnf += adapter.gateSetToCNF(gates, nmap1, newVar) cnf += adapter.gateSetToCNF(gates, nmap2, newVar) iMap = {} for inp in supports: i1 = ckt.InputNode(inp.name + "__1") i2 = ckt.InputNode(inp.name + "__2") iEq = ckt.XnorGate(i1, i2) nmap = {i1: nmap1[inp], i2: nmap2[inp]} cnf += adapter.circuitToCNF(iEq, nmap, newVar) iMap[inp] = (nmap[i1], nmap[i2], nmap[iEq]) for c in cnf: S.addClause(*c) unates = set() for gate in gates: if gate.is_input(): continue f0 = nmap1[gate] f1 = nmap2[gate] unate = True for i in supports: c1 = checkUnate(S, i, f0, f1, iMap, 0) c2 = checkUnate(S, i, f0, f1, iMap, 1) if not c1 and not c2: unate = False break if unate: unates.add(gate) return unates
def is_comparator(n): support = n.support() if len(support) != 2: return False support = list(support) support.sort(key=lambda n: n.is_keyinput()) if support[0].is_keyinput() or (not support[1].is_keyinput()): return False x0, x1 = support[0], support[1] miter = n ^ (x0 ^ x1) nmap = {} S = Solver() clauses = adapter.circuitToCNF(miter, nmap, lambda n: S.newVar()) for cl in clauses: S.addClause(*cl) r1 = S.solve(nmap[miter]) if r1 == False: return True r2 = S.solve(-nmap[miter]) if r2 == False: return True return False
def test(): xs = [ckt.InputNode('x%d' % i) for i in range(32)] ys = onecount(xs) eq4 = ckt.AndGate(~ys[0], ~ys[1], ys[2], ~ys[3]) print(len(eq4)) return S = Solver() nmap = {} clauses = circuitToCNF(eq4, nmap, lambda n: S.newVar()) for c in clauses: S.addClause(*c) tt = [] while S.solve(): blockingClause = [] row = [] for xi in itertools.chain(reversed(xs)): li = nmap[xi] vi = S.modelValue(li) row.append(vi) if vi: blockingClause.append(-li) else: blockingClause.append(li) num_ones = sum(row) li = nmap[eq4] vi = S.modelValue(li) row.append(vi) tt.append(row) S.addClause(*blockingClause) assert (num_ones == 4) == vi tt.sort() for row in tt: def listToString(l): return ''.join(str(int(i)) for i in l) p1 = listToString(row[:len(xs)]) p2 = listToString(row[len(xs):]) print('%s | %s ' % (p1, p2))
def is_cubestripper(gate, ps): # solver object s = Solver() # new variable. def newVar(n): return s.newVar() unates = [] for inp in ps: s.push() # create clauses. node_to_literal_0 = {} node_to_literal_1 = {} for sup in ps: if sup != inp: node_to_literal_0[sup] = newVar(0) node_to_literal_1[sup] = node_to_literal_0[sup] ckt1 = ckt.NotGate(gate) ckt_cnf_0 = adapter.circuitToCNF(gate, node_to_literal_0, newVar) ckt_cnf_1 = adapter.circuitToCNF(gate, node_to_literal_1, newVar) for clause in ckt_cnf_0 + ckt_cnf_1: s.addClause(*clause) # Check counter example for positive unateness r1 = s.solve(-node_to_literal_0[inp], node_to_literal_1[inp], node_to_literal_0[gate], -node_to_literal_1[gate]) if r1: # Check counter example for negative unateness r2 = s.solve(-node_to_literal_0[inp], node_to_literal_1[inp], -node_to_literal_0[gate], node_to_literal_1[gate]) if r2: return False, None else: unates.append(0) else: unates.append(1) s.pop() return True, unates
from solver import Solver import sys s = Solver() # Get KB filename from arguments filename = sys.argv[1] # Add each clause from the KB to the solver for line in open(filename, 'r'): s.addClause(line) # Run resolution s.solve()