def test_es_2(self): clauses = ['a || b', '!a || !b'] resolvents = [] expected = {cnf.c(clause) for clause in clauses + resolvents} result = resolution_closure([cnf.c(clause) for clause in clauses], early_stopping=True) assert result == expected
def _search_solver_helper(self, sent, symbols): m = sent.implicit_model() unassigned_symbols = sorted(symbols - m.keys()) # TODO: different orders if len(unassigned_symbols) == 0: if sent.check_model(m): return m else: return None else: next_symbol = unassigned_symbols[0] negative_unit_clause = Clause([Literal(next_symbol, polarity=False)]) closure = limited_unit_resolution_closure(negative_unit_clause, sent.clauses) if cnf.c('FALSE') not in closure: sat_if_false = self._search_solver_helper(Cnf(closure), symbols) if sat_if_false != None: # early termination if already satisfied return sat_if_false positive_unit_clause = Clause([Literal(next_symbol, polarity=True)]) closure = limited_unit_resolution_closure(positive_unit_clause, sent.clauses) if cnf.c('FALSE') not in closure: sat_if_true = self._search_solver_helper(Cnf(closure), symbols) return sat_if_true else: return None
def test_clause_remove(self): c1 = cnf.c('!a || b || e') c2 = c1.remove('a') assert c2 == cnf.c('b || e') c3 = c1.remove('b') assert c3 == cnf.c('!a || e') c4 = c1.remove('d') assert c4 == c1
def test_closure_4(self): clauses = ['a || b', '!a', '!b || !c', 'c || d', '!d || !e'] resolvents = [ '!b || !e', '!b || d', '!c', '!e', 'a || !c', 'a || !e', 'a || d', 'b', 'c || !e', 'd' ] expected = {cnf.c(clause) for clause in clauses + resolvents} result = resolution_closure([cnf.c(clause) for clause in clauses]) assert result == expected
def test_clause_hash(self): size = len( set([ cnf.c('d || !c'), cnf.c('!c || d'), cnf.c('b'), cnf.c('!c || d || !e'), cnf.c('d || !e || !c') ])) assert size == 3
def test_contents1(self): board = SudokuBoard([[0, 0, 0, 3], [0, 0, 0, 2], [3, 0, 0, 0], [4, 0, 0, 0]]) expected = { cnf.c('d3_1_4'), cnf.c('d2_2_4'), cnf.c('d3_3_1'), cnf.c('d4_4_1') } assert set(board.contents()) == expected
def test_limited_unit_resolution_closure1(self): clauses = [cnf.c('!b || d'), cnf.c('b'), cnf.c('d')] closure = limited_unit_resolution_closure(cnf.c('!d'), clauses) expected = { cnf.c('!b || d'), cnf.c('b'), cnf.c('!d'), cnf.c('d'), cnf.c('!b'), cnf.c('FALSE') } assert closure == expected
def test_unit_resolution(self): sent = cnf.sentence([ '!b || d', '!b || e', '!c || !e || !f', '!e || f', 'a || !b', 'b || !d || e', 'c || !e', 'd || !e', 'd || e' ]) resolved = unit_resolution(cnf.c('!a'), sent) expected = cnf.sentence([ '!a', '!b', '!b || d', '!b || e', '!c || !e || !f', '!d || e', '!e || f', 'a || !b', 'b || !d || e', 'c || !e', 'd || !e', 'd || e' ]) assert set(resolved.clauses) == set(expected.clauses) resolved = unit_resolution(cnf.c('!c'), resolved)
def test_unit_resolution_closure1(self): clauses = [cnf.c('!b || d'), cnf.c('b'), cnf.c('!d')] expected = { cnf.c('!b || d'), cnf.c('b'), cnf.c('!d'), cnf.c('d'), cnf.c('!b'), cnf.c('FALSE') } assert unit_resolution_closure(clauses) == expected
def test_es_6(self): clauses = [ 'a || b', '!a || b || e', 'a || !b', 'b || !e', 'd || !e', '!b || !c || !f', 'a || !e', '!b || f', '!b || c' ] start_time1 = time.perf_counter() result = resolution_closure([cnf.c(clause) for clause in clauses], early_stopping=True) end_time1 = time.perf_counter() assert result == {cnf.c('FALSE')} start_time2 = time.perf_counter() result = resolution_closure([cnf.c(clause) for clause in clauses], early_stopping=False) end_time2 = time.perf_counter() assert cnf.c('FALSE') in result print(f"\nWith early stopping: {end_time1 - start_time1:0.4f}s") print(f"W/o early stopping: {end_time2 - start_time2:0.4f}s")
def cnf(self): num_symbols = self.box_width * self.box_width clause_strs = [] for zone in self.zones(): for digit in irange(1, num_symbols): clause_strs += exactly_one_clauses(zone, digit) clause_strs += nonempty_clauses(self.box_width) clauses = [cnf.c(clause) for clause in clause_strs] return Cnf(list(set(clauses)))
def contents(self): clauses = [] for row in range(len(self.matrix)): for col in range(len(self.matrix[row])): digit = self.matrix[row][col] if digit != 0: clause = cnf.c(lit(digit, row + 1, col + 1)) clauses.append(clause) return clauses
def cnf(self): clauses = self.general_clauses() for row in range(len(self.matrix)): for col in range(len(self.matrix[row])): digit = self.matrix[row][col] if digit != 0: clause = cnf.c(lit(digit, row+1, col+1)) clauses.append(clause) return Cnf(clauses)
def test_queue2(self): queue = ClauseQueue() assert queue.push(cnf.c('!b || !c')) assert not queue.empty() assert queue.push(cnf.c('b')) assert queue.push(cnf.c('!b || c || d')) assert not queue.push(cnf.c('!b || !c')) assert queue.pop() == cnf.c('b') assert queue.pop() == cnf.c('!b || !c') assert not queue.empty() assert queue.pop() == cnf.c('!b || c || d') assert queue.pop() == None assert queue.empty()
def test_clause_bool(self): assert bool(cnf.c('a')) assert not bool(cnf.c('FALSE'))
def test_cnf(self): assert cnf.c('d || !c') == cnf.c('!c || d')
def test_resolve_symbol(self): resolvent = resolve_symbol(cnf.c('!b || !c'), cnf.c('b || d'), 'b') assert resolvent == cnf.c('d || !c') resolvent = resolve_symbol(cnf.c('!b || !c || e'), cnf.c('b || d'), 'b') assert resolvent == cnf.c('d || !c || e') resolvent = resolve_symbol(cnf.c('!b || !c'), cnf.c('b || d'), 'c') assert resolvent == None resolvent = resolve_symbol(cnf.c('!b || !c'), cnf.c('b || c || e || d'), 'b') assert resolvent == None resolvent = resolve_symbol(cnf.c('!b || !c'), cnf.c('b || !c || e || d'), 'b') assert resolvent == cnf.c('d || !c || e')
def test_clause_str(self): assert str(cnf.c('!c || d')) == '!c || d' assert str(cnf.c('FALSE')) == 'FALSE'
def test_clause_in(self): assert 'a' in cnf.c('!a || !c') assert 'b' not in cnf.c('!a || !c') assert 'c' in cnf.c('!a || !c')
def test_unit_resolution_closure3(self): clauses = [cnf.c('!b || d'), cnf.c('b || e')] assert unit_resolution_closure(clauses) == set(clauses)
def test_unit_resolution_closure2(self): clauses = [ cnf.c('!a'), cnf.c('!b || d'), cnf.c('!b || e'), cnf.c('!c || !e || !f'), cnf.c('!e || f'), cnf.c('a || !b'), cnf.c('b || !d || e'), cnf.c('c || !e'), cnf.c('d || !e'), cnf.c('d || e') ] expected = { cnf.c('!a'), cnf.c('!b || d'), cnf.c('!b || e'), cnf.c('!c || !e || !f'), cnf.c('!e || f'), cnf.c('a || !b'), cnf.c('b || !d || e'), cnf.c('c || !e'), cnf.c('d || !e'), cnf.c('d || e'), cnf.c('!b'), cnf.c('!d || e') } assert unit_resolution_closure(clauses) == expected
def test_closure_1(self): clauses = ['a || b', '!a || b'] resolvents = ['b'] expected = {cnf.c(clause) for clause in clauses + resolvents} result = resolution_closure([cnf.c(clause) for clause in clauses]) assert result == expected
def test_es_3(self): clauses = ['a || b', '!a || b', '!b'] result = resolution_closure([cnf.c(clause) for clause in clauses], early_stopping=True) assert result == {cnf.c('FALSE')}
def test_clause_getitem(self): c1 = cnf.c('!a || b || e') assert not c1['a'] assert c1['b']
def test_clause_lt(self): assert cnf.c('a || b || e') < cnf.c('b || c || e')
def test_clause_eq(self): assert cnf.c('!c || d') == cnf.c('!c || d') assert cnf.c('d || !c') == cnf.c('!c || d') assert cnf.c('!c || d') != cnf.c('!c || !d')
def test_resolve4(self): resolvents = resolve(cnf.c('!b || !c || e || !f'), cnf.c('b || d')) assert resolvents == [cnf.c('!c || d || e || !f')]
def test_es_5(self): clauses = ['a || b', '!a', '!b || !c', 'c || d', '!d || !e', 'e'] result = resolution_closure([cnf.c(clause) for clause in clauses], early_stopping=True) assert result == {cnf.c('FALSE')}
def test_clause_symbols(self): c1 = cnf.c('!a || b || e') assert c1.symbols() == {'a', 'b', 'e'}
def full_resolution(sent): return cnf.c('FALSE') not in resolution_closure(sent.clauses, early_stopping=True)