On 04Aug2014 04:51, varun...@gmail.com <varun...@gmail.com> wrote:
I have some trouble understanding the davis putnam algorithm for
satisfiability. I understood most of the code but I don't know where exactly
backtracking is happening here. Your assistance would be very helpful to me.
At a glance, in the bottom part of the sat(cnf) function.
The top part of the function performs some simple operations and possibly
returns.
The bottom part, executed if the earlier code does not return, copies cnf to
deep_copy, removes list2 from deep_copy and -list2 from cnf, and runs the sat()
function on each.
To my mind, that constitutes a backtrack: back up, and try a different way (on
the modified cnf and deep_copy).
Cheers,
Cameron Simpson <c...@zip.com.au>
import sys
import math
import copy
final_list = []
def sat(cnf):
while( len(cnf) > 1 ):
in_item = single_clause(cnf) #in_item: the first single_clause
in cnf
if in_item != None:
del_sat(cnf, in_item)
else:
break
for i in cnf:
if len(i) == 0:
cnf.remove(i)
return
if len(cnf) == 1:
final_list.extend( [cnf[0][0]] ) # like a watchlist
for i in range(0, len(final_list)):
if final_list[i] > 0:
print "Not equivalent!"
sys.exit(0)
return final_list
deep_copy = copy.deepcopy(cnf)
list2 = cnf[0][0]
del_sat(deep_copy,list2) # recursion to delete and then find another
way and the proceed or delete more like a tree
sat(deep_copy)
del_sat(cnf,-list2)
sat(cnf)
return
def parseXml(file_1, file_2):
global cnf
readfile_1 = open(file_1, "r")
readfile_2 = open(file_2, "r")
sum_a = int(readfile_1.readline())
sum_b = int(readfile_2.readline())
inputs_1 = readfile_1.readline().split()
inputs_1.sort()
inputs_2 = readfile_2.readline().split()
inputs_2.sort()
outputs_1 = readfile_1.readline().split()
outputs_1.sort()
outputs_2 = readfile_2.readline().split()
outputs_2.sort()
inputmap_1 = {}
inputmap_2 = {}
outputmap_1 = []
outputmap_2 = []
while True:
line = readfile_1.readline().strip()
if not line:
break
net,item = line.split()
inputmap_1[item] = int(net)
while True:
line = readfile_2.readline().strip()
if not line:
break
net,item = line.split()
inputmap_2[item] = int(net)
#print inputmap_2
for line in readfile_1.readlines():
inp1 = line.split()
gate = inp1.pop(0)
mapping = map(int, inp1)
outputmap_1.extend([(gate, mapping)])
print 'outputmap_1'
print outputmap_1
for line in readfile_2.readlines():
inp2 = line.split()
gate = inp2.pop(0)
mapping = map(int, inp2)
outputmap_2.extend([(gate, mapping)])
return inputs_1, inputs_2, outputs_1, outputs_2, inputmap_1, inputmap_2,
outputmap_1, outputmap_2
def single_clause(cnf):
for i in cnf:
if len(i) == 1:
return i[0]
return None
def del_sat(cnf,in_item):
cnf2 = cnf[:]
for k in cnf2:
if k.count(in_item):
cnf.remove(k)
for i in cnf:
if i.count( -in_item):
i.remove(-in_item)
def cnf_out(miter):
miter_len = len(miter)
cnf = []
while (miter_len > 0):
x = miter.pop(0)
if ( x[0] == "and" ):
cnf.extend( [[x[1][0], -x[1][2]]] )
cnf.extend( [[x[1][1], -x[1][2]]] )
cnf.extend( [[-x[1][0], -x[1][1], x[1][2]]] )
elif ( x[0] == "or" ):
cnf.extend( [[x[1][0], x[1][1], -x[1][2]]] )
cnf.extend( [[-x[1][0], x[1][2]]] )
cnf.extend( [[-x[1][1], x[1][2]]] )
elif ( x[0] == "xor" ):
cnf.extend( [[x[1][0], x[1][1], -x[1][2]]] )
cnf.extend( [[-x[1][0], -x[1][1], -x[1][2]]] )
cnf.extend( [[-x[1][0], x[1][1], x[1][2]]] )
cnf.extend( [[x[1][0], -x[1][1], x[1][2]]] )
else:
cnf.extend( [[x[1][0], x[1][1]]] )
cnf.extend( [[-x[1][0], -x[1][1]]] )
miter_len = miter_len - 1
return cnf
inputs_1, inputs_2, outputs_1, outputs_2, inputmap_1, inputmap_2, outputmap_1,
outputmap_2 = parseXml(sys.argv[1], sys.argv[2])
incoming1=[]
incoming2=[]
outgoing1=[]
outgoing2=[]
for i in inputs_1:
incoming1.extend([inputmap_1[i]])
for j in inputs_2:
incoming2.extend([inputmap_2[j]])
for k in outputs_1:
outgoing1.extend([inputmap_1[k]])
for l in outputs_2:
outgoing2.extend([inputmap_2[l]])
gate_num = 0
for output in outputmap_1:
for j in output[1]:
if gate_num < j:
gate_num = j # gate_num: first line of netlist file. Total number of
nets always need max no..
map2 = outputmap_2
num = len( map2 ) #No. of gates in netlist 2
for i in range(1, num + 1):
j = len( map2[i-1][1] ) # Total No. of inputs and outputs of a gate
for k in range(0, j):
if map2[i-1][1][k] not in incoming2:
total = 0
for l in incoming2:
if map2[i-1][1][k] > l:
total = total + 1 # Total no. of nets minus total no. of
input nets like an offset
map2[i-1][1][k] = map2[i-1][1][k] + gate_num - total
else:
x = incoming2.index( map2[i-1][1][k] )
map2[i-1][1][k] = incoming1[x]
miter = outputmap_1
miter.extend(map2) #Combine gate lists of the two netlists to 'miter'
out_len = len(outgoing1) #No. of outputs from each netlist (netlist1's out_len
should be equal to netlist2's)
for i in range(out_len):
total = 0
for j in incoming2: # e.g: incoming2 = [1,2]
if outgoing2[i] > j: # e.g outgoing2 = [10]
total = total + 1 # should be the size of incoming2
outgoing2[i] = outgoing2[i] + gate_num - total
xor_gate = [( 'xor', [outgoing1[i], outgoing2[i], 9000+i] )]
miter.extend(xor_gate)
if out_len > 1:
or_gate_1 = [( 'or', [9000, 9000+1, 9000 + out_len] )]
miter.extend(or_gate_1)
for i in range(out_len - 2):
or_gate=[( 'or', [9000 + out_len + i, 9000 +i + 2, 9000 + i + out_len +
1] )]
miter.extend(or_gate) # 9000 just a random no. for the no. of nets used
in order to prevent overlap of two nos.
built_cnf = cnf_out(miter)
count = 0
built_len = len(built_cnf)
for i in range(0, built_len):
built_leni = len(built_cnf[i])
for j in range(0, built_leni):
if abs( built_cnf[i][j] ) > count: #count is the total number of nets in
the miter circuit
count = abs( built_cnf[i][j])
value = sat(built_cnf)
print value
print "Equivalent!"
--
https://mail.python.org/mailman/listinfo/python-list
--
https://mail.python.org/mailman/listinfo/python-list