def is_monotonic(alpha, mgr, num_features, constraint_sdd): counterexample = [[None, None] for _ in xrange(num_features)] for i in xrange(num_features): beta1 = sdd.sdd_condition(i + 1, alpha, mgr) beta2 = sdd.sdd_condition(-(i + 1), alpha, mgr) beta3 = sdd.sdd_conjoin(beta1, beta2, mgr) # check if f|x does not entail f|!x gamma = sdd.sdd_conjoin( sdd.sdd_conjoin(sdd.sdd_negate(beta2, mgr), beta1, mgr), constraint_sdd, mgr) model = next(models.models(gamma, sdd.sdd_manager_vtree(mgr))) counterexample[i][0] = [v for _, v in model.items()] if counterexample[i][0]: counterexample[i][0][i] = 1 # check if f|!x does not entail f|x gamma = sdd.sdd_conjoin( sdd.sdd_conjoin(sdd.sdd_negate(beta1, mgr), beta2, mgr), constraint_sdd, mgr) model = next(models.models(gamma, sdd.sdd_manager_vtree(mgr))) counterexample[i][1] = [v for _, v in model.items()] if counterexample[i][1]: counterexample[i][1][i] = 0 for c in counterexample: if c[0] and c[1]: return False, counterexample return True, counterexample
def _primes_two(alpha, variables, cache1, cache2, pmgr, mgr): if len(variables) == 0: if sdd.sdd_node_is_false(alpha): return sdd.sdd_manager_false(pmgr) if sdd.sdd_node_is_true(alpha): return sdd.sdd_manager_true(pmgr) key = (len(variables), sdd.sdd_id(alpha)) if key in cache1: global cache_hits cache_hits += 1 if cache_hits % 1000 == 0: print "cache-hits-update:", cache_hits return cache1[key] var, remaining = variables[0], variables[1:] alpha0 = sdd.sdd_condition(-var, alpha, mgr) alpha1 = sdd.sdd_condition(var, alpha, mgr) primes0 = _primes_two(alpha0, remaining, cache1, cache2, pmgr, mgr) primes1 = _primes_two(alpha1, remaining, cache1, cache2, pmgr, mgr) qrimes0 = _keep_imp(primes0, alpha1, remaining, cache1, cache2, pmgr, mgr) qrimes1 = _keep_imp(primes1, alpha0, remaining, cache1, cache2, pmgr, mgr) gamma = sdd.sdd_disjoin(qrimes0, qrimes1, pmgr) gamma = sdd.sdd_conjoin(_sdd_unused(var, pmgr), gamma, pmgr) kappa = sdd.sdd_conjoin(primes0, sdd.sdd_negate(qrimes0, pmgr), pmgr) kappa = sdd.sdd_conjoin(kappa, _sdd_used_neg(var, pmgr), pmgr) gamma = sdd.sdd_disjoin(gamma, kappa, pmgr) kappa = sdd.sdd_conjoin(primes1, sdd.sdd_negate(qrimes1, pmgr), pmgr) kappa = sdd.sdd_conjoin(kappa, _sdd_used_pos(var, pmgr), pmgr) gamma = sdd.sdd_disjoin(gamma, kappa, pmgr) cache1[key] = gamma return gamma
def _primes_one_given_term(alpha, variables, inst, cache, cache_dummy, pmgr, mgr): if len(variables) == 0: if sdd.sdd_node_is_true(alpha): return sdd.sdd_manager_true(pmgr) if sdd.sdd_node_is_false(alpha): return sdd.sdd_manager_false(pmgr) #add cases for true/false key = (len(variables), sdd.sdd_id(alpha)) if key in cache: return cache[key] var, remaining = variables[0], variables[1:] val, remaining_val = inst[0], inst[1:] beta2 = sdd.sdd_forall(var, alpha, mgr) gamma2 = _primes_one_given_term(beta2, remaining, remaining_val, cache, cache_dummy, pmgr, mgr) gamma9 = gamma2 pvar = 3 * (var - 1) + 1 kappa2 = sdd.sdd_manager_literal(-pvar, pmgr) gamma2 = sdd.sdd_conjoin(gamma2, kappa2, pmgr) if val == 0: beta0 = sdd.sdd_condition(-var, alpha, mgr) gamma0 = _primes_one_given_term(beta0, remaining, remaining_val, cache, cache_dummy, pmgr, mgr) gamma0 = sdd.sdd_conjoin(gamma0, sdd.sdd_negate(gamma9, pmgr), pmgr) kappa0 = sdd.sdd_conjoin(sdd.sdd_manager_literal(-(pvar + 1), pmgr), sdd.sdd_manager_literal((pvar + 2), pmgr), pmgr) kappa0 = sdd.sdd_conjoin(kappa0, sdd.sdd_manager_literal(pvar, pmgr), pmgr) gamma0 = sdd.sdd_conjoin(gamma0, kappa0, pmgr) #gamma0 = sdd.sdd_conjoin(gamma0,sdd.sdd_negate(gamma9,pmgr),pmgr) if val == 1: beta1 = sdd.sdd_condition(var, alpha, mgr) gamma1 = _primes_one_given_term(beta1, remaining, remaining_val, cache, cache_dummy, pmgr, mgr) gamma1 = sdd.sdd_conjoin(gamma1, sdd.sdd_negate(gamma9, pmgr), pmgr) kappa1 = sdd.sdd_conjoin(sdd.sdd_manager_literal((pvar + 1), pmgr), sdd.sdd_manager_literal(-(pvar + 2), pmgr), pmgr) kappa1 = sdd.sdd_conjoin(kappa1, sdd.sdd_manager_literal(pvar, pmgr), pmgr) gamma1 = sdd.sdd_conjoin(gamma1, kappa1, pmgr) #gamma1 = sdd.sdd_conjoin(gamma1,sdd.sdd_negate(gamma9,pmgr),pmgr) if val == 0: gamma = sdd.sdd_disjoin(gamma0, gamma2, pmgr) if val == 1: gamma = sdd.sdd_disjoin(gamma1, gamma2, pmgr) #gamma = sdd.sdd_disjoin(sdd.sdd_disjoin(gamma0, gamma1, pmgr), gamma2, pmgr) #if len(variables) > 60: # print len(variables), sdd.sdd_manager_count(mgr) cache[key] = gamma return gamma
def condition_and_minimize(alpha, mgr, num_features, inst): for i in xrange(num_features): if not inst[i]: alpha = sdd.sdd_condition(-1 * (i + 1), alpha, mgr) # After conditioning, the literals can be T or F. # After we do global_minimize_cardinality that forces the conditioned # literals to be F. return sdd.sdd_global_minimize_cardinality(alpha, mgr)
def _primes_one(alpha, variables, cache, cache_dummy, pmgr, mgr): if len(variables) == 0: if sdd.sdd_node_is_true(alpha): return sdd.sdd_manager_true(pmgr) if sdd.sdd_node_is_false(alpha): return sdd.sdd_manager_false(pmgr) #add cases for true/false key = (len(variables), sdd.sdd_id(alpha)) if key in cache: global cache_hits cache_hits += 1 #if cache_hits % 1000 == 0: print "cache-hits-update:", cache_hits return cache[key] var, remaining = variables[0], variables[1:] beta2 = sdd.sdd_forall(var, alpha, mgr) gamma2 = _primes_one(beta2, remaining, cache, cache_dummy, pmgr, mgr) gamma9 = gamma2 pvar = 3 * (var - 1) + 1 kappa2 = sdd.sdd_manager_literal(-pvar, pmgr) gamma2 = sdd.sdd_conjoin(gamma2, kappa2, pmgr) beta0 = sdd.sdd_condition(-var, alpha, mgr) gamma0 = _primes_one(beta0, remaining, cache, cache_dummy, pmgr, mgr) gamma0 = sdd.sdd_conjoin(gamma0, sdd.sdd_negate(gamma9, pmgr), pmgr) kappa0 = sdd.sdd_conjoin(sdd.sdd_manager_literal(-(pvar + 1), pmgr), sdd.sdd_manager_literal((pvar + 2), pmgr), pmgr) kappa0 = sdd.sdd_conjoin(kappa0, sdd.sdd_manager_literal(pvar, pmgr), pmgr) gamma0 = sdd.sdd_conjoin(gamma0, kappa0, pmgr) #gamma0 = sdd.sdd_conjoin(gamma0,sdd.sdd_negate(gamma9,pmgr),pmgr) beta1 = sdd.sdd_condition(var, alpha, mgr) gamma1 = _primes_one(beta1, remaining, cache, cache_dummy, pmgr, mgr) gamma1 = sdd.sdd_conjoin(gamma1, sdd.sdd_negate(gamma9, pmgr), pmgr) kappa1 = sdd.sdd_conjoin(sdd.sdd_manager_literal((pvar + 1), pmgr), sdd.sdd_manager_literal(-(pvar + 2), pmgr), pmgr) kappa1 = sdd.sdd_conjoin(kappa1, sdd.sdd_manager_literal(pvar, pmgr), pmgr) gamma1 = sdd.sdd_conjoin(gamma1, kappa1, pmgr) #gamma1 = sdd.sdd_conjoin(gamma1,sdd.sdd_negate(gamma9,pmgr),pmgr) gamma = sdd.sdd_disjoin(gamma0, gamma1, pmgr) gamma = sdd.sdd_disjoin(gamma, gamma2, pmgr) cache[key] = gamma return gamma
def least_flips(alpha, mgr, inst): beta = alpha for (i, element) in enumerate(inst): literal = i + 1 if element == 0: literal *= -1 beta = sdd.sdd_condition(literal, beta, mgr) is_model = sdd.sdd_node_is_true(beta) leastFlipsDict = {} return least_flips_helper(is_model, inst, alpha, mgr, leastFlipsDict)
def is_monotone(alpha, manager): """ A function alpha is monotone iff f|~x |= f|x for all X. """ result = True var_count = sdd.sdd_manager_var_count(manager) sdd.sdd_ref(alpha, manager) for x in xrange(1, var_count + 1): f_x = sdd.sdd_condition(x, alpha, manager) sdd.sdd_ref(f_x, manager) f_nx = sdd.sdd_condition(-x, alpha, manager) sdd.sdd_ref(f_nx, manager) # f|~x |= f|x iff f|~x ^ f|x == f|~x f_both = sdd.sdd_conjoin(f_x, f_nx, manager) if f_both != f_x: result = False sdd.sdd_deref(f_x, manager), sdd.sdd_deref(f_nx, manager) if result is False: break sdd.sdd_deref(alpha, manager) return result
def _is_prime(prime, f, mgr): var_count = sdd.sdd_manager_var_count(mgr) term = prime_to_dict(prime, var_count) for var in term: alpha = f for varp in term: if varp == var: continue lit = varp if term[varp] == 1 else -varp alpha = sdd.sdd_condition(lit, alpha, mgr) if sdd.sdd_node_is_true(alpha): return False return True
def _keep_imp(beta, alpha, variables, cache1, cache2, pmgr, mgr): #if len(variables) == 0: if sdd.sdd_node_is_false(beta): return sdd.sdd_manager_false(pmgr) if sdd.sdd_node_is_false(alpha): return sdd.sdd_manager_false(pmgr) if sdd.sdd_node_is_true(alpha): return beta key = (len(variables), sdd.sdd_id(alpha), sdd.sdd_id(beta)) if key in cache2: global cache_hits cache_hits += 1 #if cache_hits % 1000 == 0: print "cache-hits-update:", cache_hits return cache2[key] var, remaining = variables[0], variables[1:] pvar = 3 * (var - 1) + 1 alpha0 = sdd.sdd_condition(-var, alpha, mgr) alpha1 = sdd.sdd_condition(var, alpha, mgr) beta0 = sdd.sdd_condition(pvar, beta, pmgr) beta0 = sdd.sdd_condition(-(pvar + 1), beta0, pmgr) #beta0 = sdd.sdd_condition( (pvar+2),beta0,pmgr) beta1 = sdd.sdd_condition(pvar, beta, pmgr) beta1 = sdd.sdd_condition((pvar + 1), beta1, pmgr) #beta1 = sdd.sdd_condition(-(pvar+2),beta1,pmgr) betad = sdd.sdd_condition(-pvar, beta, pmgr) P = _keep_imp(betad, alpha0, remaining, cache1, cache2, pmgr, mgr) Q = _keep_imp(betad, alpha1, remaining, cache1, cache2, pmgr, mgr) R0 = _keep_imp(beta0, alpha0, remaining, cache1, cache2, pmgr, mgr) R1 = _keep_imp(beta1, alpha1, remaining, cache1, cache2, pmgr, mgr) gamma = sdd.sdd_conjoin(P, Q, pmgr) gamma = sdd.sdd_conjoin(_sdd_unused(var, pmgr), gamma, pmgr) kappa = sdd.sdd_conjoin(_sdd_used_neg(var, pmgr), R0, pmgr) gamma = sdd.sdd_disjoin(gamma, kappa, pmgr) kappa = sdd.sdd_conjoin(_sdd_used_pos(var, pmgr), R1, pmgr) gamma = sdd.sdd_disjoin(gamma, kappa, pmgr) cache2[key] = gamma return gamma