Exemplo n.º 1
0
 def compute_reduced_core(self, i, j, val):
     """We compute the unsat core then remove any unnecessary terms."""
     if not (0 <= i <= 8 and 0 <= j <= 8 and 1 <= val <= 9):
         raise Exception(f'Index error: {i} {j} {val}')
     context = Context()
     self.assert_puzzle(context)
     self.assert_not_value(context, i, j, val)
     self.assert_trivial_rules(context)
     smt_stat = context.check_context_with_assumptions(
         None, self.duplicate_rules)
     # a valid puzzle should have a unique solution, so this should not happen, if it does we bail
     if smt_stat != Status.UNSAT:
         print(f'Error: {i} {j} {val} - not UNSAT: {Status.name(smt_stat)}')
         model = Model.from_context(context, 1)
         answer = self.puzzle_from_model(model)
         print(
             'Counter example (i.e. origonal puzzle does not have a unique solution):'
         )
         answer.pprint()
         model.dispose()
         context.dispose()
         return None
     core = context.get_unsat_core()
     filtered = core.copy()
     for term in core:
         filtered.remove(term)
         smt_stat = context.check_context_with_assumptions(None, filtered)
         if smt_stat != Status.UNSAT:
             filtered.append(term)
     context.dispose()
     print(
         f'Core: {i} {j} {val}   {len(filtered)} / {len(self.duplicate_rules)}'
     )
     return (i, j, val, filtered)
def pluck(puzzle, cardinality):

    # prepare our solver and context
    solver = Solver(puzzle)
    context = Context()
    solver.assert_rules(context)

    # start with a set of all 81 cells, and tries to remove one (randomly) at a time
    # but not before checking that the cell can still be deduced from the remaining cells.
    cells = set(range(81))
    cells_remaining = cells.copy()

    while len(cells) > cardinality and len(cells_remaining) != 0:
        cell = random.choice(list(cells_remaining))
        cells_remaining.discard(cell)
        row, column = cell // 9, cell % 9
        val = puzzle.get_cell(row, column)
        assert val is not None
        if solver.erasable(context, row, column, val):
            puzzle.erase_cell(row, column)
            cells.discard(cell)

    context.dispose()

    return (puzzle, len(cells))
Exemplo n.º 3
0
 def compute_core(self, i, j, val):
     """We compute the unsat core of the duplicate_rules when asserting self.var(i, j) != val w.r.t the puzzle (val is assumed to be the unique solution)."""
     if not (0 <= i <= 8 and 0 <= j <= 8 and 1 <= val <= 9):
         raise Exception(f'Index error: {i} {j} {val}')
     context = Context()
     self.assert_puzzle(context)
     self.assert_not_value(context, i, j, val)
     self.assert_trivial_rules(context)
     smt_stat = context.check_context_with_assumptions(
         None, self.duplicate_rules)
     # a valid puzzle should have a unique solution, so this should not happen, if it does we bail
     if smt_stat != Status.UNSAT:
         print(f'Error: {i} {j} {val} - not UNSAT: {Status.name(smt_stat)}')
         model = Model.from_context(context, 1)
         answer = self.puzzle_from_model(model)
         print(
             'Counter example (i.e. origonal puzzle does not have a unique solution):'
         )
         answer.pprint()
         model.dispose()
         context.dispose()
         return None
     core = context.get_unsat_core()
     context.dispose()
     print(
         f'Core: {i} {j} {val}   {len(core)} / {len(self.duplicate_rules)}')
     return (i, j, val, core)
Exemplo n.º 4
0
 def __init__(self, diagram, protocol, verbose):
     self.diagram = diagram
     self.protocol = protocol
     self.verbose = verbose
     self.maxTimeStamp = diagram.max_timestamp
     print('Maximum time = {0}'.format(self.maxTimeStamp))
     self.context = Context()
     # assert that (b i) = b_i and (pt x y) = pt_x_y
     yassert_formulas(self, YicesSignature.toYicesTerms())
Exemplo n.º 5
0
 def setUp(self):
     # this is required for some strange reason.
     # seems like yices/__init__.py does not get evaluated
     Yices.init()
     self.cfg = Config()
     self.ctx = Context(self.cfg)
     self.param = Parameters()
     self.param.default_params_for_context(self.ctx)
     global bool_t, int_t, real_t
     bool_t = Types.bool_type()
     int_t = Types.int_type()
     real_t = Types.real_type()
Exemplo n.º 6
0
 def solve(self):
     context = Context()
     self.assert_rules(context)
     self.assert_puzzle(context)
     smt_stat = context.check_context(None)
     answer = None
     if smt_stat == Status.SAT:
         model = Model.from_context(context, 1)
         answer = self.puzzle_from_model(model)
         model.dispose()
     context.dispose()
     return answer
Exemplo n.º 7
0
 def filter_core(self, core):
     i, j, val, terms = core
     context = Context()
     self.assert_puzzle(context)
     self.assert_not_value(context, i, j, val)
     self.assert_trivial_rules(context)
     filtered = terms.copy()
     for term in terms:
         filtered.remove(term)
         smt_stat = context.check_context_with_assumptions(None, filtered)
         if smt_stat != Status.UNSAT:
             filtered.append(term)
     context.dispose()
     return (i, j, val, filtered)
    def delgado(self, delegate):

        if not Delegates.has_delegate(delegate):
            notify(f'delgado skipping missing delegate {delegate}\n')
            return

        formulas = make_formulas()

        bound = len(formulas) + 1

        for i in range(1, bound):
            config = Config()
            config.default_config_for_logic("QF_BV")
            context = Context(config)
            terms = truncate(formulas, i)
            context.assert_formulas(terms)
            status = context.check_context()
            notify(f'delgado status = {Status.name(status)} for i = {i}\n')
            self.assertEqual(status, Status.SAT if i < 3 else Status.UNSAT)
            config.dispose()
            context.dispose()


        for i in range(1, bound):
            model = []
            terms = truncate(formulas, i)
            status = Delegates.check_formulas(terms, "QF_BV", delegate, model)
            notify(f'delagdo({delegate}) status = {Status.name(status)} for i = {i}\n')
            self.assertEqual(status, Status.SAT if i < 3 else Status.UNSAT)
            if status is Status.SAT:
                notify(f'delagdo({delegate}) model = {model[0].to_string(80, 100, 0)} for i = {i}\n')
            else:
                self.assertEqual(len(model), 0)


        for i in range(1, bound):
            model = []
            term = conjoin(formulas, i)
            status = Delegates.check_formula(term, "QF_BV", delegate, model)
            notify(f'delagdo({delegate}) status = {Status.name(status)} for i = {i}\n')
            self.assertEqual(status, Status.SAT if i < 3 else Status.UNSAT)
            if status is Status.SAT:
                notify(f'delagdo({delegate}) model = {model[0].to_string(80, 100, 0)} for i = {i}\n')
            else:
                self.assertEqual(len(model), 0)
 def test_timeout(self):
     cfg = Config()
     cfg.default_config_for_logic('QF_NIA')
     ctx = Context(cfg)
     int_t = Types.int_type()
     [x, y, z] = [
         Terms.new_uninterpreted_term(int_t, id) for id in ['x', 'y', 'z']
     ]
     # x, y, z > 0
     for var in [x, y, z]:
         ctx.assert_formula(Terms.arith_gt0_atom(var))
     # x^3 + y^3 = z3
     [x3, y3, z3] = [Terms.product([var, var, var]) for var in [x, y, z]]
     lhs = Terms.sum([x3, y3])
     eq = Terms.arith_eq_atom(lhs, z3)
     ctx.assert_formula(eq)
     status = ctx.check_context(timeout=1)
     self.assertEqual(status, Status.INTERRUPTED)
     ctx.dispose()
     cfg.dispose()
 def test_context(self):
     cfg = Config()
     ctx = Context(cfg)
     stat = ctx.status()
     ret = ctx.push()
     ret = ctx.pop()
     ctx.reset_context()
     ret = ctx.enable_option("arith-elim")
     ret = ctx.disable_option("arith-elim")
     stat = ctx.status()
     self.assertEqual(stat, 0)
     ctx.reset_context()
     bool_t = Types.bool_type()
     bvar1 = Terms.new_variable(bool_t)
     with assertRaisesRegex(self, YicesException,
                            'assertion contains a free variable'):
         ctx.assert_formula(bvar1)
     bv_t = Types.bv_type(3)
     bvvar1 = Terms.new_uninterpreted_term(bv_t, 'x')
     bvvar2 = Terms.new_uninterpreted_term(bv_t, 'y')
     bvvar3 = Terms.new_uninterpreted_term(bv_t, 'z')
     fmla1 = Terms.parse_term('(= x (bv-add y z))')
     fmla2 = Terms.parse_term('(bv-gt y 0b000)')
     fmla3 = Terms.parse_term('(bv-gt z 0b000)')
     ctx.assert_formula(fmla1)
     ctx.assert_formulas([fmla1, fmla2, fmla3])
     smt_stat = ctx.check_context(None)
     self.assertEqual(smt_stat, Status.SAT)
     ctx.assert_blocking_clause()
     ctx.stop_search()
     param = Parameters()
     param.default_params_for_context(ctx)
     param.set_param("dyn-ack", "true")
     with assertRaisesRegex(self, YicesException, 'invalid parameter'):
         param.set_param("foo", "bar")
     with assertRaisesRegex(self, YicesException,
                            'value not valid for parameter'):
         param.set_param("dyn-ack", "bar")
     param.dispose()
     ctx.dispose()
    def test_dimacs(self):

        formulas = make_formulas()

        bound = len(formulas) + 1

        simplified = [None] * bound

        # first round, don't simplify the CNF
        for i in range(1, bound):
            simplify = False
            filename = f'/tmp/basic{1}.cnf'
            terms = truncate(formulas, i)

            file_ok, status = Dimacs.export_formulas(terms, filename, simplify)

            notify(
                f'Round 1: {file_ok}, {Status.name(status)} = export@{i}({terms}, {filename}, {simplify})\n'
            )

            if file_ok:
                self.assertEqual(os.path.exists(filename), True)
            else:
                self.assertEqual(status in [Status.SAT, Status.UNSAT], True)

            term = Terms.yand(terms)
            file_ok_c, status_c = Dimacs.export_formula(
                term, filename, simplify)

            notify(
                f'Round 1: {file_ok_c}, {Status.name(status_c)} = export@{i}({term}, {filename}, {simplify})\n'
            )

        # second round, simplify the CNF
        for i in range(1, bound):
            simplify = True
            filename = f'/tmp/simplify{i}.cnf'
            terms = truncate(formulas, i)

            file_ok, status = Dimacs.export_formulas(terms, filename, simplify)

            # save the status for later
            simplified[i] = status

            notify(
                f'Round 2: {file_ok}, {Status.name(status)} = export@{i}({terms}, {filename}, {simplify})\n'
            )

            if file_ok:
                self.assertEqual(os.path.exists(filename), True)
            else:
                self.assertEqual(status in [Status.SAT, Status.UNSAT], True)

            term = Terms.yand(terms)
            file_ok_c, status_c = Dimacs.export_formula(
                term, filename, simplify)

            notify(
                f'Round 2: {file_ok_c}, {Status.name(status_c)} = export@{i}({term}, {filename}, {simplify})\n'
            )

            self.assertEqual(status_c, simplified[i])

        # third round check the results
        for i in range(1, bound):
            config = Config()
            config.default_config_for_logic("QF_BV")
            context = Context(config)
            terms = truncate(formulas, i)
            context.assert_formulas(terms)
            status = context.check_context()
            notify(f'Round 3: status = {Status.name(status)} for i = {i}\n')
            self.assertEqual(status, simplified[i])
            config.dispose()
            context.dispose()
Exemplo n.º 12
0
def V(vi, vj):
    return X[vi][vj]


#make the constants that we will need
C = {}
for i in range(1, 10):
    C[i] = Terms.integer(i)

one = C[1]
nine = C[9]

config = Config()
config.default_config_for_logic("QF_LIA")

context = Context(config)


# x is between 1 and 9
def between_1_and_9(x):
    return Terms.yand(
        [Terms.arith_leq_atom(one, x),
         Terms.arith_leq_atom(x, nine)])


for i in range(9):
    for j in range(9):
        context.assert_formula(between_1_and_9(V(i, j)))

# All elements in a row must be distinct
for i in range(9):