Example #1
0
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
Example #2
0
def least_flips_helper(is_model, inst, alpha, mgr, leastFlipsDict):
    sid = sdd.sdd_id(alpha)

    if sid in leastFlipsDict.keys():
        return leastFlipsDict[sid]

    flip_inst = inst[:]

    if sdd.sdd_node_is_true(alpha):
        return (my_inf, flip_inst) if is_model else (0, flip_inst)
    elif sdd.sdd_node_is_false(alpha):
        return (0, flip_inst) if is_model else (my_inf, flip_inst)

    if sdd.sdd_node_is_literal(alpha):
        level = abs(sdd.sdd_node_literal(alpha)) - 1
        if (inst[level] == 1) == (sdd.sdd_node_literal(alpha) > 0):
            if is_model:
                flip_inst[level] = 1 - inst[level]
                return (1, flip_inst)
            else:
                return (0, flip_inst)
        else:
            if is_model:
                return (0, flip_inst)
            else:
                flip_inst[level] = 1 - inst[level]
                return (1, flip_inst)

    node_elements = sdd.sdd_node_elements(alpha)
    m = sdd.sdd_node_size(alpha)
    assert m == 2

    prime1 = sdd.sddNodeArray_getitem(node_elements, 0)
    sub1 = sdd.sddNodeArray_getitem(node_elements, 1)
    prime0 = sdd.sddNodeArray_getitem(node_elements, 2)
    sub0 = sdd.sddNodeArray_getitem(node_elements, 3)

    if sdd.sdd_node_literal(prime1) < 0:
        prime1, prime0 = prime0, prime1
        sub1, sub0 = sub0, sub1

    level = abs(sdd.sdd_node_literal(prime1)) - 1

    result1, flip_inst1 = least_flips_helper(is_model, inst, sub1, mgr,
                                             leastFlipsDict)
    result0, flip_inst0 = least_flips_helper(is_model, inst, sub0, mgr,
                                             leastFlipsDict)

    if (result1 + (int)(inst[level] != 1)) < (result0 +
                                              (int)(inst[level] != 0)):
        result, flip_inst = result1 + (int)(inst[level] != 1), flip_inst1[:]
        if inst[level] == 0:
            flip_inst[level] = 1
    else:
        result, flip_inst = result0 + (int)(inst[level] != 0), flip_inst0[:]
        if inst[level] == 1:
            flip_inst[level] = 0

    leastFlipsDict[sid] = (result, flip_inst)
    return (result, flip_inst)
Example #3
0
def enumerate_primes(primes, pmgr, var_count):
    pvtree = sdd.sdd_manager_vtree(pmgr)
    while not sdd.sdd_node_is_false(primes):
        mincard = sdd.sdd_global_minimize_cardinality(primes, pmgr)
        for model in models.models(mincard, pvtree):
            term = prime_to_dict(model, var_count)
            yield term
        primes = sdd.sdd_conjoin(primes, sdd.sdd_negate(mincard, pmgr), pmgr)
Example #4
0
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
Example #5
0
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)
Example #6
0
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)
Example #7
0
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
Example #8
0
def node_value(node, values, model):
    if sdd.sdd_node_is_true(node):
        return True
    elif sdd.sdd_node_is_false(node):
        return False
    elif sdd.sdd_node_is_literal(node):
        lit = sdd.sdd_node_literal(node)
        var = lit if lit > 0 else -lit
        lit = 1 if lit > 0 else 0
        return model[var] == lit
    else:
        sdd_id = sdd.sdd_id(node)
        return values[sdd_id]
Example #9
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
Example #10
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
Example #11
0
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
Example #12
0
 def is_false(self, node):
     return sdd.sdd_node_is_false(node)
Example #13
0
def _encode_grid_aux(source,sink,nodes,graph,manager,
                     base=None,cache=None,verbose=False):
    nodes = sorted(nodes)
    key = (source,tuple(nodes))

    if cache and key in cache:
        return cache[key]

    if True: # INITIALIZATION FOR (S,T) PATHS
        if sink not in nodes: # unreachable
            return sdd.sdd_manager_false(manager)

        if len(nodes) == 1: # must be sink
            return sdd.sdd_manager_true(manager)

        if not g.reachable(source,sink,nodes):
            alpha = sdd.sdd_manager_false(manager)
            cache[key] = alpha
            return alpha

        if source == sink:
            # turn off all other edges
            alpha = sdd.sdd_manager_true(manager)
            sdd.sdd_ref(alpha,manager)

            my_nodes = list(nodes)
            my_nodes.remove(source)
            for node in my_nodes: # for all unused nodes
                edges = graph.incident_edges(node,nodes=nodes)
                sdd_vars = [ graph.edge_to_index[edge] + 1 for edge in edges ]
                all_false = all_false_term(sdd_vars,manager)
                alpha,tmp = sdd.sdd_conjoin(alpha,all_false,manager),alpha
                sdd.sdd_ref(alpha,manager); sdd.sdd_deref(tmp,manager)

            cache[key] = alpha
            return alpha

        alpha = sdd.sdd_manager_false(manager)
        sdd.sdd_ref(alpha,manager)

    else: # INITIALIZATION FOR ALL PATHS STARTING FROM S

        # empty graph, source should equal sink
        if len(nodes) == 1:
            return sdd.sdd_manager_true(manager)

        # initial case: no more paths
        alpha = sdd.sdd_manager_true(manager)
        sdd.sdd_ref(alpha,manager)

        my_nodes = list(nodes)
        my_nodes.remove(source)
        for node in my_nodes: # for all unused nodes
            edges = graph.incident_edges(node,nodes=nodes)
            sdd_vars = [ graph.edge_to_index[edge] + 1 for edge in edges ]
            all_false = all_false_term(sdd_vars,manager)
            alpha,tmp = sdd.sdd_conjoin(alpha,all_false,manager),alpha
            sdd.sdd_ref(alpha,manager); sdd.sdd_deref(tmp,manager)

    # after this, try to extend the paths
    # first, find incident edges
    edges = graph.incident_edges(source,nodes=nodes)
    sdd_vars = [ graph.edge_to_index[edge] + 1 for edge in edges ]
    all_false = all_false_term(sdd_vars,manager)
    sdd.sdd_ref(all_false,manager)

    # for each incident edge
    my_nodes = list(nodes)
    my_nodes.remove(source)
    for edge,sdd_var in zip(edges,sdd_vars):

        # recurse
        neighbor = Graph.neighbor(source,edge)
        gamma = _encode_grid_aux(neighbor,sink,my_nodes,graph,manager,
                                 base=base,cache=cache,verbose=verbose)
        if sdd.sdd_node_is_false(gamma): continue

        # exactly one edge on
        sdd_lit = sdd.sdd_manager_literal(sdd_var,manager)
        beta = sdd.sdd_exists(sdd_var,all_false,manager)
        beta = sdd.sdd_conjoin(beta,sdd_lit,manager)
        beta = sdd.sdd_conjoin(beta,gamma,manager)

        # accumulate
        alpha,tmp = sdd.sdd_disjoin(alpha,beta,manager),alpha
        sdd.sdd_ref(alpha,manager); sdd.sdd_deref(tmp,manager)
        
    sdd.sdd_deref(all_false,manager)
    cache[key] = alpha

    return alpha
Example #14
0
 def is_false(self, node):
     assert node is not None
     return sdd.sdd_node_is_false(node)