def parse_bdd(filename): var_count,node_count = pre_parse_bdd(filename) print " zdd var count:", var_count print " zdd node count:", node_count manager = start_manager(var_count,range(1,var_count+1)) root = sdd.sdd_manager_vtree(manager) nodes = [None] * (node_count+1) index,id2index = 1,{} f = open(filename) for line in f.readlines(): if line.startswith("."): break line = line.strip().split() nid = int(line[0]) dvar = int(line[1]) lo,hi = line[2],line[3] hi_lit = sdd.sdd_manager_literal( dvar,manager) lo_lit = sdd.sdd_manager_literal(-dvar,manager) if lo == 'T': lo_sdd,lo_vtree = sdd.sdd_manager_true(manager),None elif lo == 'B': lo_sdd,lo_vtree = sdd.sdd_manager_false(manager),None else: lo_id = int(lo) lo_sdd,lo_vtree = nodes[id2index[lo_id]] if hi == 'T': hi_sdd,hi_vtree = sdd.sdd_manager_true(manager),None elif hi == 'B': hi_sdd,hi_vtree = sdd.sdd_manager_false(manager),None else: hi_id = int(hi) hi_sdd,hi_vtree = nodes[id2index[hi_id]] #v1,v2 = sdd.sdd_vtree_of(hi_lit),sdd.sdd_vtree_of(hi_sdd) #vt = sdd.sdd_vtree_lca(v1,v2,root) vt = sdd.sdd_manager_vtree_of_var(dvar,manager) vt = sdd.sdd_vtree_parent(vt) vt = sdd.sdd_vtree_right(vt) if dvar < var_count: hi_sdd = zero_normalize_sdd(hi_sdd,hi_vtree,vt,manager) lo_sdd = zero_normalize_sdd(lo_sdd,lo_vtree,vt,manager) vt = sdd.sdd_vtree_parent(vt) hi_sdd = sdd.sdd_conjoin(hi_lit,hi_sdd,manager) lo_sdd = sdd.sdd_conjoin(lo_lit,lo_sdd,manager) alpha = sdd.sdd_disjoin(hi_sdd,lo_sdd,manager) nodes[index] = (alpha,vt) id2index[nid] = index index += 1 f.close() return manager,nodes[-1][0]
def zero_normalize_sdd(alpha,alpha_vtree,vtree,manager): if sdd.sdd_node_is_false(alpha): return alpha #if vtree == sdd.sdd_vtree_of(alpha): if vtree == alpha_vtree: return alpha if sdd.sdd_vtree_is_leaf(vtree): var = sdd.sdd_vtree_var(vtree) nlit = sdd.sdd_manager_literal(-var,manager) return nlit left,right = sdd.sdd_vtree_left(vtree),sdd.sdd_vtree_right(vtree) beta_left = zero_normalize_sdd(alpha,alpha_vtree,left,manager) beta_right = zero_normalize_sdd(alpha,alpha_vtree,right,manager) beta = sdd.sdd_conjoin(beta_left,beta_right,manager) return beta
def models(node, vtree): """A generator for the models of an SDD.""" if sdd.sdd_vtree_is_leaf(vtree): var = sdd.sdd_vtree_var(vtree) if node is True or sdd.sdd_node_is_true(node): yield {var: 0} yield {var: 1} elif sdd.sdd_node_is_false(node): yield {} elif sdd.sdd_node_is_literal(node): lit = sdd.sdd_node_literal(node) sign = 0 if lit < 0 else 1 yield {var: sign} else: left_vtree = sdd.sdd_vtree_left(vtree) right_vtree = sdd.sdd_vtree_right(vtree) if node is True or sdd.sdd_node_is_true(node): # sdd is true for left_model in models(True, left_vtree): for right_model in models(True, right_vtree): yield _join_models(left_model, right_model) elif sdd.sdd_node_is_false(node): # sdd is false yield {} elif sdd.sdd_vtree_of(node) == vtree: # enumerate prime/sub pairs #elements = sdd.sdd_node_elements(node) elements = elements_as_list(node) for prime, sub in _pairs(elements): if sdd.sdd_node_is_false(sub): continue for left_model in models(prime, left_vtree): for right_model in models(sub, right_vtree): yield _join_models(left_model, right_model) else: # gap in vtree if sdd.sdd_vtree_is_sub(sdd.sdd_vtree_of(node), left_vtree): for left_model in models(node, left_vtree): for right_model in models(True, right_vtree): yield _join_models(left_model, right_model) else: for left_model in models(True, left_vtree): for right_model in models(node, right_vtree): yield _join_models(left_model, right_model)
def models(node, vtree): """A generator for the models of an SDD.""" if sdd.sdd_vtree_is_leaf(vtree): var = sdd.sdd_vtree_var(vtree) if node is True or sdd.sdd_node_is_true(node): yield {var: 0} yield {var: 1} elif sdd.sdd_node_is_false(node): yield {} elif sdd.sdd_node_is_literal(node): lit = sdd.sdd_node_literal(node) sign = 0 if lit < 0 else 1 yield {var: sign} else: left_vtree = sdd.sdd_vtree_left(vtree) right_vtree = sdd.sdd_vtree_right(vtree) if node is True or sdd.sdd_node_is_true(node): # sdd is true for left_model in models(True, left_vtree): for right_model in models(True, right_vtree): yield _join_models(left_model, right_model) elif sdd.sdd_node_is_false(node): # sdd is false yield {} elif sdd.sdd_vtree_of(node) == vtree: # enumerate prime/sub pairs elements = sdd.sdd_node_elements(node) for prime, sub in _pairs(elements): if sdd.sdd_node_is_false(sub): continue for left_model in models(prime, left_vtree): for right_model in models(sub, right_vtree): yield _join_models(left_model, right_model) else: # gap in vtree if sdd.sdd_vtree_is_sub(sdd.sdd_vtree_of(node), left_vtree): for left_model in models(node, left_vtree): for right_model in models(True, right_vtree): yield _join_models(left_model, right_model) else: for left_model in models(True, left_vtree): for right_model in models(node, right_vtree): yield _join_models(left_model, right_model)
def parse_bdd(filename,var_count=None): if var_count is None: var_count,node_count = pre_parse_bdd(filename) else: max_count,node_count = pre_parse_bdd(filename) #print " zdd var count:", var_count #print " zdd node count:", node_count manager = start_manager(var_count,range(1,var_count+1)) root = sdd.sdd_manager_vtree(manager) nodes = [None] * (node_count+1) index,id2index = 1,{} f = open(filename) for line in f.readlines(): if line.startswith("."): break line = line.strip().split() nid = int(line[0]) dvar = int(line[1]) lo,hi = line[2],line[3] hi_lit = sdd.sdd_manager_literal( dvar,manager) lo_lit = sdd.sdd_manager_literal(-dvar,manager) if lo == 'T': lo_sdd,lo_vtree = sdd.sdd_manager_true(manager),None elif lo == 'B': lo_sdd,lo_vtree = sdd.sdd_manager_false(manager),None else: lo_id = int(lo) lo_sdd,lo_vtree = nodes[id2index[lo_id]] if hi == 'T': hi_sdd,hi_vtree = sdd.sdd_manager_true(manager),None elif hi == 'B': hi_sdd,hi_vtree = sdd.sdd_manager_false(manager),None else: hi_id = int(hi) hi_sdd,hi_vtree = nodes[id2index[hi_id]] #v1,v2 = sdd.sdd_vtree_of(hi_lit),sdd.sdd_vtree_of(hi_sdd) #vt = sdd.sdd_vtree_lca(v1,v2,root) vt = sdd.sdd_manager_vtree_of_var(dvar,manager) vt = sdd.sdd_vtree_parent(vt) vt = sdd.sdd_vtree_right(vt) if dvar < var_count: hi_sdd = zero_normalize_sdd(hi_sdd,hi_vtree,vt,manager) lo_sdd = zero_normalize_sdd(lo_sdd,lo_vtree,vt,manager) vt = sdd.sdd_vtree_parent(vt) hi_sdd = sdd.sdd_conjoin(hi_lit,hi_sdd,manager) lo_sdd = sdd.sdd_conjoin(lo_lit,lo_sdd,manager) alpha = sdd.sdd_disjoin(hi_sdd,lo_sdd,manager) nodes[index] = (alpha,vt) id2index[nid] = index index += 1 f.close() last_sdd,last_vtree = nodes[-1] vt = sdd.sdd_manager_vtree(manager) if vt != last_vtree: last_sdd = zero_normalize_sdd(last_sdd,last_vtree,vt,manager) return manager,last_sdd