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)