Esempio n. 1
0
    def _init(self, formula):
        """
            SAT oracle initialization. The method creates a new SAT oracle and
            feeds it with the formula's hard clauses. Afterwards, all soft
            clauses of the formula are augmented with selector literals and
            also added to the solver. The list of all introduced selectors is
            stored in variable ``self.sels``.

            :param formula: input MaxSAT formula
            :type formula: :class:`WCNF`
        """

        self.oracle = Solver(name=self.solver,
                             bootstrap_with=formula.hard,
                             incr=True,
                             use_timer=True)

        for i, cl in enumerate(formula.soft):
            # TODO: if clause is unit, use its literal as selector
            # (ITotalizer must be extended to support PB constraints first)
            selv = self.vpool._next()
            cl.append(selv)
            self.oracle.add_clause(cl)
            self.sels.append(selv)
        self.is_weighted = any(w > 1 for w in formula.wght)

        if self.verbose > 1:
            print('c formula: {0} vars, {1} hard, {2} soft'.format(
                formula.nv, len(formula.hard), len(formula.soft)))
Esempio n. 2
0
    def __init__(self, formula, use_cld=False, solver_name='m22', use_timer=False):
        """
            Constructor.
        """

        # bootstrapping the solver with hard clauses
        self.oracle = Solver(name=solver_name, bootstrap_with=formula.hard,
                use_timer=use_timer)

        self.topv = formula.nv  # top variable id
        self.soft = formula.soft
        self.sels = []
        self.ucld = use_cld

        # mappings between internal and external variables
        VariableMap = collections.namedtuple('VariableMap', ['e2i', 'i2e'])
        self.vmap = VariableMap(e2i={}, i2e={})

        # at this point internal and external variables are the same
        for v in range(1, formula.nv + 1):
            self.vmap.e2i[v] = v
            self.vmap.i2e[v] = v

        for cl in self.soft:
            sel = cl[0]
            if len(cl) > 1 or cl[0] < 0:
                self.topv += 1
                sel = self.topv

                self.oracle.add_clause(cl + [-sel])

            self.sels.append(sel)
Esempio n. 3
0
def test_cnfplus():
    # testing cnf1:
    for name in solvers:
        if name != 'minicard':
            try:
                with Solver(name=name, bootstrap_with=cnf1) as s:
                    s.solve()
                assert False, 'we should not get here'
            except NotImplementedError:
                pass
        else:
            with Solver(name=name, bootstrap_with=cnf1) as s:
                for i, model in enumerate(s.enum_models(), 1):
                    pass
            assert i == 5, 'there should be 5 models'

    for name in solvers:
        if name != 'minicard':
            try:
                with Solver(name=name) as s:
                    s.append_formula(cnf1)
                    s.solve()
                assert False, 'we should not get here'
            except NotImplementedError:
                pass
        else:
            with Solver(name=name) as s:
                s.append_formula(cnf1)
                for i, model in enumerate(s.enum_models(), 1):
                    pass
            assert i == 5, 'there should be 5 models'
Esempio n. 4
0
File: lbx.py Progetto: sschnug/pysat
    def __init__(self, formula, use_cld=False, solver_name='m22', use_timer=False):
        """
            Constructor.
        """

        # bootstrapping the solver with hard clauses
        self.oracle = Solver(name=solver_name, bootstrap_with=formula.hard, use_timer=use_timer)

        self.topv = formula.nv  # top variable id
        self.soft = formula.soft
        self.sels = []
        self.ucld = use_cld
        self.vmap_dir = {}
        self.vmap_opp = {}

        for cl in self.soft:
            sel = cl[0]
            if len(cl) > 1 or cl[0] < 0:
                self.topv += 1
                sel = self.topv

                self.oracle.add_clause(cl + [-sel])

            self.sels.append(sel)
            self.vmap_dir[sel] = len(self.sels)
            self.vmap_opp[len(self.sels)] = sel
Esempio n. 5
0
    def __init__(self, formula, solver='m22', verbosity=1):
        """
            Constructor.
        """

        topv, self.verbose = formula.nv, verbosity

        # clause selectors and a mapping from selectors to clause ids
        self.sels, self.vmap = [], {}

        # constructing the oracle
        self.oracle = Solver(name=solver,
                             bootstrap_with=formula.hard,
                             use_timer=True)

        if isinstance(formula, WCNFPlus) and formula.atms:
            assert solver in SolverNames.minicard, \
                    'Only Minicard supports native cardinality constraints. Make sure you use the right type of formula.'

            for atm in formula.atms:
                self.oracle.add_atmost(*atm)

        # relaxing soft clauses and adding them to the oracle
        for i, cl in enumerate(formula.soft):
            topv += 1

            self.sels.append(topv)
            self.vmap[topv] = i

            self.oracle.add_clause(cl + [-topv])
Esempio n. 6
0
def solve_problem(input):
    
    sat_solver = Solver(name='g4')
    db = constructor_of_db(input["observations"])
    db_ops = constructor_of_ops(input["observations"])
    initial_clause(db, db_ops, input, sat_solver)
    if input["police"] + input["medics"] == 0:
        operations(db, db_ops, input, sat_solver)
    else:
        teams_operations(db, db_ops, input, sat_solver)
        quarantine(db_ops, input, sat_solver)
        immune(db_ops, input, sat_solver)
    queries = input["queries"]
    ans_dic = {}
    for query in queries:
        literal = extract_literal(query,db)
        ans = sat_solver.solve(assumptions = [literal])
        
        if ans:
            other_literal_list = extract_other_literals(query,db)
            ans_list = []
            for other_literal in other_literal_list:
                ans_list.append(sat_solver.solve(assumptions = [other_literal]))
            if sum(ans_list) >= 1:
                ans = '?'
            else: ans = 'T'
        else: 
            ans = 'F'
        ans_dic["{}".format(query)] = "{}".format(ans)
    
    for key, value in ans_dic.items():
        print("{}".format(key),":","'{}'".format(value))
Esempio n. 7
0
 def _one_node_maps_to_alo_state_classic(self,
                                         solver: Solver,
                                         size: int,
                                         new_node_from: int = 0) -> None:
     for i in range(new_node_from, self._apta.size):
         solver.add_clause(
             tuple(self._vars.var('x', i, j) for j in range(size)))
Esempio n. 8
0
    def init(self, with_soft=True):
        """
            The method for the SAT oracle initialization. Since the oracle is
            is used non-incrementally, it is reinitialized at every iteration
            of the MaxSAT algorithm (see :func:`reinit`). An input parameter
            ``with_soft`` (``False`` by default) regulates whether or not the
            formula's soft clauses are copied to the oracle.

            :param with_soft: copy formula's soft clauses to the oracle or not
            :type with_soft: bool
        """

        self.oracle = Solver(name=self.solver, bootstrap_with=self.hard, use_timer=True)

        if self.atm1:  # this check is needed at the beggining (before iteration 1)
            assert self.oracle.supports_atmost(), \
                    '{0} does not support native cardinality constraints. Make sure you use the right type of formula.'.format(solver_name)

            # self.atm1 is not empty only in case of minicard
            for am in self.atm1:
                self.oracle.add_atmost(*am)

        if with_soft:
            for cl, cpy in zip(self.soft, self.scpy):
                if cpy:
                    self.oracle.add_clause(cl)
Esempio n. 9
0
    def __init__(self,
                 formula,
                 use_cld=False,
                 solver_name='m22',
                 use_timer=False):
        """
            Constructor.
        """

        # bootstrapping the solver with hard clauses
        self.oracle = Solver(name=solver_name,
                             bootstrap_with=formula.hard,
                             use_timer=use_timer)

        self.topv = formula.nv  # top variable id
        self.soft = []
        self.ucld = use_cld
        self.vmap_dir = {}
        self.vmap_opp = {}

        for cl in formula.soft:
            new_cl = cl[:]
            if len(cl) > 1 or cl[0] < 0:
                self.topv += 1
                sel = self.topv

                new_cl.append(-sel)  # creating a new selector
                self.oracle.add_clause(new_cl)
            else:
                sel = cl[0]

            self.soft.append([sel])
            self.vmap_dir[sel] = len(self.soft)
            self.vmap_opp[len(self.soft)] = sel
 def __init__(self, dimacs_file, csv_file, verbose=False):
     self.__dimacs = DimacsFile(dimacs_file)
     self.__csv = CSVFile(csv_file)
     self.__cnf = CNF(from_file=dimacs_file)
     self.__formula = Solver(bootstrap_with=self.__cnf.clauses)
     assert self.__formula.solve() is True, "initial formula is UNSAT"
     self.__config_d = None
     self.__verbose = verbose
Esempio n. 11
0
 def _state_has_at_least_one_parent(self,
                                    solver: Solver,
                                    size: int,
                                    old_size: int = 0) -> None:
     for child in range(max(1, old_size), size):
         solver.add_clause(
             tuple(
                 self._vars.var('p', child, parent)
                 for parent in range(child)))
Esempio n. 12
0
    def __init__(self,
                 formula,
                 solver='g3',
                 adapt=False,
                 exhaust=False,
                 minz=False,
                 trim=False,
                 verbose=0):
        """
            Constructor.
        """

        # verbosity level
        self.verbose = verbose

        # constructing a local copy of the formula
        self.formula = WCNFPlus()
        self.formula.hard = formula.hard[:]
        self.formula.wght = formula.wght[:]
        self.formula.topw = formula.topw
        self.formula.nv = formula.nv

        # top variable identifier
        self.topv = formula.nv

        # processing soft clauses
        self._process_soft(formula)
        self.formula.nv = self.topv

        # creating an unweighted copy
        unweighted = self.formula.copy()
        unweighted.wght = [1 for w in unweighted.wght]

        # enumerating disjoint MCSes (including unit-size MCSes)
        to_hit, self.units = self._disjoint(unweighted, solver, adapt, exhaust,
                                            minz, trim)

        if self.verbose > 2:
            print('c mcses: {0} unit, {1} disj'.format(
                len(self.units),
                len(to_hit) + len(self.units)))

        # hitting set enumerator
        self.hitman = Hitman(bootstrap_with=to_hit,
                             weights=self.weights,
                             solver=solver,
                             htype='sorted',
                             mxs_adapt=adapt,
                             mxs_exhaust=exhaust,
                             mxs_minz=minz,
                             mxs_trim=trim)

        # SAT oracle bootstrapped with the hard clauses; note that
        # clauses of the unit-size MCSes are enforced to be enabled
        self.oracle = Solver(name=solver,
                             bootstrap_with=unweighted.hard +
                             [[mcs] for mcs in self.units])
Esempio n. 13
0
 def _one_node_maps_to_at_most_one_state(self,
                                         solver: Solver,
                                         size: int,
                                         new_node_from: int = 0,
                                         old_size: int = 0) -> None:
     for v in range(new_node_from, self._apta.size):
         for i in range(old_size, size):
             for j in range(0, i):
                 solver.add_clause((-self._vars.var('x', v, i),
                                    -self._vars.var('x', v, j)))
Esempio n. 14
0
 def _state_has_at_most_one_parent(self,
                                   solver: Solver,
                                   size: int,
                                   old_size: int = 0) -> None:
     for child in range(old_size, size):
         for parent in range(child):
             for other_parent in range(parent):
                 solver.add_clause(
                     (-self._vars.var('p', child, parent),
                      -self._vars.var('p', child, other_parent)))
Esempio n. 15
0
 def _order_parents_using_np_variables(self,
                                       solver: Solver,
                                       size: int,
                                       old_size: int = 0) -> None:
     for child in range(max(1, old_size - 1), size - 1):
         for parent in range(child):
             solver.append_formula(
                 _implication_to_clauses(
                     self._vars.var('p', child, parent),
                     self._vars.var('np', child + 1, parent - 1)))
Esempio n. 16
0
 def _preserve_parent_order_on_children(self,
                                        solver: Solver,
                                        size: int,
                                        old_size: int = 0) -> None:
     for child in range(max(2, old_size - 1), size - 1):
         for parent in range(1, child):
             for pre_parent in range(parent):
                 solver.append_formula(
                     _implication_to_clauses(
                         self._vars.var('p', child, parent),
                         -self._vars.var('p', child + 1, pre_parent)))
Esempio n. 17
0
 def _inconsistency_graph_constraints(self,
                                      solver: Solver,
                                      size: int,
                                      new_node_from: int = 0,
                                      old_size: int = 0) -> None:
     for node1 in range(self._ig.size):
         for node2 in self._ig.edges[node1]:
             if node1 >= new_node_from or node2 >= new_node_from:
                 for s in range(old_size, size):
                     solver.add_clause((-self._vars.var('x', node1, s),
                                        -self._vars.var('x', node2, s)))
Esempio n. 18
0
 def _one_node_maps_to_alo_state_switch(self,
                                        solver: Solver,
                                        size: int,
                                        new_node_from: int = 0,
                                        old_size: int = 0) -> None:
     for i in range(new_node_from, self._apta.size):
         solver.add_clause(
             tuple(self._vars.var('x', i, j) for j in range(size)) +
             (self._vars.var('sw_x', size, i), ))
     if old_size > 0:
         for v in range(self._apta.size):
             solver.add_clause((self._vars.var('sw_x', old_size, v), ))
Esempio n. 19
0
 def _define_t_variables(self,
                         solver: Solver,
                         size: int,
                         old_size: int = 0) -> None:
     for to in range(old_size, size):
         for from_ in range(to):
             solver.append_formula(
                 _iff_disjunction_to_clauses(
                     self._vars.var('t', from_, to),
                     tuple(
                         self._vars.var('y', from_, l_id, to)
                         for l_id in range(self._alphabet_size))))
Esempio n. 20
0
 def _define_p_variables(self,
                         solver: Solver,
                         size: int,
                         old_size: int = 0) -> None:
     for child in range(old_size, size):
         for parent in range(child):
             solver.append_formula(
                 _iff_conjunction_to_clauses(
                     self._vars.var('p', child, parent),
                     tuple(-self._vars.var('t', prev, child)
                           for prev in range(parent)) +
                     (self._vars.var('t', parent, child), )))
Esempio n. 21
0
    def search(self, lower_bound: int, upper_bound: int) -> Optional[DFA]:
        self._solver = Solver(self._solver_name)
        log_info('Solver has been started.')
        for size in range(lower_bound, upper_bound + 1):
            if self._assumptions_mode == 'none' and size > lower_bound:
                self._solver = Solver(self._solver_name)
                log_info('Solver has been restarted.')
            log_br()
            log_info('Trying to build a DFA with {0} states.'.format(size))

            STATISTICS.start_formula_timer()
            if self._assumptions_mode != 'none' and size > lower_bound:
                self._clause_generator.generate_with_new_size(
                    self._solver, size - 1, size)
            else:
                self._clause_generator.generate(self._solver, size)
            STATISTICS.stop_formula_timer()
            assumptions = self._clause_generator.build_assumptions(
                size, self._solver)
            while True:
                dfa = self._try_to_synthesize_dfa(size, assumptions)
                if dfa:
                    counter_examples = self._examples_provider.get_counter_examples(
                        dfa)
                    if counter_examples:
                        log_info(
                            'An inconsistent DFA with {0} states is found.'.
                            format(size))
                        log_info('Added {0} counterexamples.'.format(
                            len(counter_examples)))

                        STATISTICS.start_apta_building_timer()
                        (new_nodes_from, changed_statuses
                         ) = self._apta.add_examples(counter_examples)
                        STATISTICS.stop_apta_building_timer()

                        STATISTICS.start_ig_building_timer()
                        self._ig.update(new_nodes_from)
                        STATISTICS.stop_ig_building_timer()

                        STATISTICS.start_formula_timer()
                        self._clause_generator.generate_with_new_counterexamples(
                            self._solver, size, new_nodes_from,
                            changed_statuses)
                        STATISTICS.stop_formula_timer()
                        continue
                break
            if not dfa:
                log_info('Not found a DFA with {0} states.'.format(size))
            else:
                log_success('The DFA with {0} states is found!'.format(size))
                return dfa
        return None
Esempio n. 22
0
    def __init__(self,
                 formula,
                 use_cld=False,
                 solver_name='m22',
                 use_timer=False):
        """
            Constructor.
        """

        # bootstrapping the solver with hard clauses
        self.oracle = Solver(name=solver_name,
                             bootstrap_with=formula.hard,
                             use_timer=use_timer)
        self.solver = solver_name

        # adding native cardinality constraints (if any) as hard clauses
        # this can be done only if the Minicard solver is in use
        if isinstance(formula, WCNFPlus) and formula.atms:
            assert solver_name in SolverNames.minicard or \
                    solver_name in SolverNames.gluecard3 or \
                    solver_name in SolverNames.gluecard4, \
                    '{0} does not support native cardinality constraints'.format(solver_name)

            for atm in formula.atms:
                self.oracle.add_atmost(*atm)

        self.topv = formula.nv  # top variable id
        self.sels = []
        self.ucld = use_cld
        self.smap = {}

        # mappings between internal and external variables
        VariableMap = collections.namedtuple('VariableMap', ['e2i', 'i2e'])
        self.vmap = VariableMap(e2i={}, i2e={})

        # at this point internal and external variables are the same
        for v in range(1, formula.nv + 1):
            self.vmap.e2i[v] = v
            self.vmap.i2e[v] = v

        for cl in formula.soft:
            new_cl = cl[:]
            if len(cl) > 1 or cl[0] < 0:
                self.topv += 1
                sel = self.topv

                new_cl.append(-sel)  # creating a new selector
                self.oracle.add_clause(new_cl)
            else:
                sel = cl[0]

            self.sels.append(sel)
            self.smap[sel] = len(self.sels)
Esempio n. 23
0
 def _define_m_variables(self,
                         solver: Solver,
                         size: int,
                         old_size: int = 0) -> None:
     for child in range(old_size, size):
         for parent in range(child):
             for l_num in range(self._alphabet_size):
                 solver.append_formula(
                     _iff_conjunction_to_clauses(
                         self._vars.var('m', parent, l_num, child),
                         tuple(-self._vars.var('y', parent, l_less, child)
                               for l_less in range(l_num)) +
                         (self._vars.var('y', parent, l_num, child), )))
Esempio n. 24
0
 def _define_np_variables(self,
                          solver: Solver,
                          size: int,
                          old_size: int = 0) -> None:
     for child in range(max(old_size, 2), size):
         solver.append_formula(
             _iff_to_clauses(self._vars.var('np', child, 0),
                             -self._vars.var('p', child, 0)))
         for parent in range(1, child):
             solver.append_formula(
                 _iff_conjunction_to_clauses(
                     self._vars.var('np', child, parent),
                     (self._vars.var('np', child, parent - 1),
                      -self._vars.var('p', child, parent))))
Esempio n. 25
0
def test_cnf():
    # testing cnf2
    for name in solvers:
        with Solver(name=name, bootstrap_with=cnf2) as s:
            for i, model in enumerate(s.enum_models(), 1):
                pass
        assert i == 5, 'there should be 5 models'

    for name in solvers:
        with Solver(name=name) as s:
            s.append_formula(cnf2)
            for i, model in enumerate(s.enum_models(), 1):
                pass
        assert i == 5, 'there should be 5 models'
Esempio n. 26
0
 def _define_p_variables_using_nt(self,
                                  solver: Solver,
                                  size: int,
                                  old_size: int = 0) -> None:
     for child in range(max(1, old_size), size):
         solver.append_formula(
             _iff_to_clauses(self._vars.var('p', child, 0),
                             self._vars.var('t', 0, child)))
         for parent in range(1, child):
             solver.append_formula(
                 _iff_conjunction_to_clauses(
                     self._vars.var('p', child, parent),
                     (self._vars.var('t', parent, child),
                      self._vars.var('nt', parent - 1, child))))
Esempio n. 27
0
 def _order_children_using_zm(self,
                              solver: Solver,
                              size: int,
                              old_size: int = 0) -> None:
     for child in range(max(0, old_size - 1), size - 1):
         for parent in range(child):
             for l_num in range(1, self._alphabet_size):
                 solver.append_formula(
                     _conjunction_implies_to_clauses(
                         (self._vars.var('p', child, parent),
                          self._vars.var('p', child + 1, parent),
                          self._vars.var('m', parent, l_num, child)),
                         self._vars.var('zm', parent, l_num - 1,
                                        child + 1)))
Esempio n. 28
0
 def _dfa_is_deterministic(self,
                           solver: Solver,
                           size: int,
                           old_size: int = 0) -> None:
     for l_id in range(self._alphabet_size):
         for i in range(old_size):
             for j in range(old_size, size):
                 for k in range(j):
                     solver.add_clause((-self._vars.var('y', i, l_id, j),
                                        -self._vars.var('y', i, l_id, k)))
         for i in range(old_size, size):
             for j in range(size):
                 for k in range(j):
                     solver.add_clause((-self._vars.var('y', i, l_id, j),
                                        -self._vars.var('y', i, l_id, k)))
def vdWtest():
    fmla = vdW(3, 3, 20)
    fmla.to_fp(sys.stdout)
    for N in range(1, 50):
        print(N)
        with Solver(name="cdl", bootstrap_with=vdW(3, 3, N)) as S:
            print(S.solve())
Esempio n. 30
0
def GreedyCoreMetric(fmla, y_true, y_pred):
    """
  Args:
  y_true: a bitmask
  y_pred: probability distribution
  """
    UNSAT_FLAG = False
    sorted_indices = np.argsort(y_pred, kind="mergesort")
    print(sorted_indices)
    with Solver(name="cdl") as S:
        count = 0
        indices = []
        for i in range(len(sorted_indices)):
            next_index = sorted_indices[-(i + 1)]
            indices.append(next_index)
            next_clause = fmla.clauses[next_index]
            S.add_clause(next_clause)
            count += 1
            if not S.solve():
                UNSAT_FLAG = True
                break
    assert UNSAT_FLAG
    gen_core_length = len(indices)
    labelled_core_length = int(
        tf.reduce_sum(tf.cast(y_true, tf.int32), axis=-1))
    return indices, gen_core_length, labelled_core_length, float(
        gen_core_length / labelled_core_length)