def test_convert_to_cnf(self): statement = Not(Iff(Symbol("a"), Symbol("c"))) statement = converter.convert_formula(statement) a_symbol = Symbol("a") c_symbol = Symbol("c") expected = And( And(Or(c_symbol, a_symbol), Or(Not(a_symbol), a_symbol)), And(Or(c_symbol, Not(c_symbol)), Or(Not(a_symbol), Not(c_symbol)))) self.assertEqual(expected, statement)
def test_print_cnf_list(self): cnf = list() a_symbol = Symbol("a") b_symbol = Symbol("b") not_a = Not(a_symbol) not_b = Not(b_symbol) cnf.append([a_symbol, b_symbol]) cnf.append([not_b, a_symbol]) cnf.append([not_a, not_b]) writer = StringIO() util.print_cnf_list(cnf, out=writer) cnf_list = "[[a, b], [~b, a], [~a, ~b]]\n" self.assertEqual(cnf_list, writer.getvalue())
def perform_annihilation(statement): change = False if isinstance(statement, GeneralizedOr): i = 0 while i < len(statement.args): statement.args[i], change_new = perform_annihilation( statement.args[i]) if isinstance(statement.args[i], Contradiction): del statement.args[i] i -= 1 i += 1 change = (change_new or change) if len(statement.args) == 0: return Contradiction(), True elif isinstance(statement, GeneralizedAnd): i = 0 while i < (len(statement.args) - 1): if isinstance(statement.args[i], Not): negate = statement.args[i].args[0] else: negate = Not(statement.args[i]) j = i + 1 while j < len(statement.args): if negate == statement.args[j]: return Contradiction(), True j += 1 i += 1 return statement, change
def __init__(self, formulas, goal): self.root = TreeNode() for formula in formulas: self.root.formulas.append(TreeFormula(formula)) self.root.formulas.append(TreeFormula(Not(goal))) self.count = 1 self.expand_tree()
def _adjacency_helper(symbols): return_list = [] """ [a, b, c] [[a, b, c], [a, b, ~c], [a, ~b, c], ...] """ for i in symbols: if len(return_list) == 0: return_list.append([i]) return_list.append([Not(i)]) else: temp = deepcopy(return_list) for j in range(len(return_list)): return_list[j].append(i) for j in range(len(temp)): return_list.append(temp[j] + [Not(i)]) return return_list
def add_goal(self, statement): """ :param statement: :return: """ statement = parser.parse(statement) self._add_statement(deepcopy(statement), self.goals) self._add_statement(Not(deepcopy(statement)), self._goals)
def add_formula(self, formula, count): if self.closed: return False self.formulas.append(formula) to_check = Not(formula.formula) if not isinstance( formula.formula, Not) else formula.formula.args[0] if self.has_formula(to_check): self.closed = True self.number = count return True return False
def negate_formula(formula): """ Negate the formula (or removing the Not if it's the outermost Operator) :param formula: formula :return: Negated formula """ if isinstance(formula, Not): return formula.args[0] elif isinstance(formula, Formula): return Not(formula) else: raise TypeError(str(formula) + " is not a valid formula")
def distribute_not(statement): """ Distribute not over and/or clauses (flipping them) :param statement: :return: """ if isinstance(statement, Symbol): return statement, False args = statement.args change = False if isinstance(statement, Not): if isinstance(args[0], And) or isinstance(args[0], Or) \ or isinstance(args[0], GeneralizedOr) or isinstance(args[0], GeneralizedAnd): new_type = GeneralizedOr if isinstance(args[0], Or) or isinstance(args[0], GeneralizedOr): new_type = GeneralizedAnd new_args = [] for arg in args[0].args: new_args.append(Not(arg)) statement = new_type(*new_args) change = True elif isinstance(args[0], Not): statement = args[0].args[0] change = True """ elif isinstance(args[0], Quantifier): new_type = Existential if isinstance(args[0], Existential): new_type = Universal statement = new_type(args[0].symbol, Not(args[0].args[0])) statement.args[0] = _distribute_not(statement.args[0]) """ else: for i in range(len(args)): args[i], change = distribute_not(args[i]) if change: break return statement, change
def convert_if(statement): """ Convert conditional (A -> B) into (~A or B) :param statement: :return: """ if isinstance(statement, Symbol) or isinstance(statement, Not): return statement, False change = False args = statement.args for i in range(len(args)): args[i], change = convert_if(args[i]) if change is True: break if change is False and isinstance(statement, If): statement = GeneralizedOr(Not(deepcopy(args[0])), deepcopy(args[1])) change = True return statement, change
def test_is_tautology(self): cnf = list() cnf.append(Symbol("a")) cnf.append(Not(Symbol("a"))) is_taut = util.is_tautology(cnf) self.assertTrue(is_taut)
def test_negate_not(self): negate = util.negate_formula(Not(Symbol("a"))) self.assertEqual(Symbol("a"), negate)
def test_non_equality_2(self): statement_1 = Not(Symbol("b")) statement_2 = Symbol("a") self.assertNotEqual(statement_1, statement_2)
def test_symbol_lt_operator_1(self): self.assertLess(Symbol('a'), Not(Symbol('a')))
def test_cnf_negation(self): statement = Not(Not(And(Symbol("a"), Symbol("b")))) statement = converter.convert_formula(statement) expected = And(Symbol("a"), Symbol("b")) self.assertEqual(expected, statement)
def test_operator_not_lt_symbol(self): self.assertFalse(Not(Symbol("a")) < Symbol("b"))
def test_parse_iff_2(self): statement = parser.parse("iff(not(A), not(B))") self.assertEqual(statement, Iff(Not(Symbol("A")), Not(Symbol("B"))))
def test_cnf_not_distribution_2(self): statement = Not( Or(And(Symbol("a"), Not(Symbol("b"))), Not(Symbol("c")))) statement = converter.convert_formula(statement) expected = And(Or(Not(Symbol("a")), Symbol("b")), Symbol("c")) self.assertEqual(expected, statement)
def test_operator_le_symbol(self): self.assertLessEqual(Not(Symbol('a')), Not(Symbol('b')))
def expand_formula(self, tree_formula, tree_node): tree_formula.number = self.count tree_formula.broken = True self.count += 1 formula = tree_formula.formula if isinstance(formula, Not): if isinstance(formula.args[0], Not): children_nodes = tree_node.get_children() for child_node in children_nodes: self.add_formula(child_node, formula.args[0].args[0]) elif isinstance(formula.args[0], And): left_nodes, right_nodes = tree_node.add_children() for left_node in left_nodes: self.add_formula(left_node, Not(formula.args[0].args[0])) for right_node in right_nodes: self.add_formula(right_node, Not(formula.args[0].args[1])) elif isinstance(formula.args[0], Or): children_nodes = tree_node.get_children() for child_node in children_nodes: for i in range(2): if self.add_formula(child_node, Not(formula.args[0].args[i])): break elif isinstance(formula.args[0], If): children_nodes = tree_node.get_children() for child_node in children_nodes: if self.add_formula(child_node, formula.args[0].args[0]): continue self.add_formula(child_node, Not(formula.args[0].args[1])) elif isinstance(formula.args[0], Iff): left_nodes, right_nodes = tree_node.add_children() for left_node in left_nodes: if self.add_formula(left_node, formula.args[0].args[0]): continue self.add_formula(left_node, Not(formula.args[0].args[1])) for right_node in right_nodes: if self.add_formula(right_node, Not(formula.args[0].args[0])): continue self.add_formula(right_node, formula.args[0].args[1]) elif isinstance(formula, And): children_nodes = tree_node.get_children() for child_node in children_nodes: for i in range(2): if self.add_formula(child_node, formula.args[i]): break elif isinstance(formula, Or): left_nodes, right_nodes = tree_node.add_children() for left_node in left_nodes: self.add_formula(left_node, formula.args[0]) for right_node in right_nodes: self.add_formula(right_node, formula.args[1]) elif isinstance(formula, If): left_nodes, right_nodes = tree_node.add_children() for left_node in left_nodes: self.add_formula(left_node, Not(formula.args[0])) for right_node in right_nodes: self.add_formula(right_node, formula.args[1]) elif isinstance(formula, Iff): left_nodes, right_nodes = tree_node.add_children() for left_node in left_nodes: for i in range(2): if self.add_formula(left_node, formula.args[i]): break for right_node in right_nodes: for i in range(2): if self.add_formula(right_node, Not(formula.args[i])): break
def test_operator_gt_symbol(self): self.assertGreater(Not(Symbol("a")), Symbol("b"))
def test_not(self): statement_a = Symbol('a') statement_not = Not(statement_a) self.assertEqual(statement_not.arity, 1) self.assertEqual(repr(statement_not), "not(a)") self.assertEqual(str(statement_not), "~a")
def test_operator_ge_symbol(self): self.assertGreaterEqual(Not(Symbol("a")), Not(Symbol("a")))
def test_cnf_converter_equiv(self): statement = Iff(Symbol("a"), Symbol("b")) statement = converter.convert_formula(statement) expected = And(Or(Not(Symbol("a")), Symbol("b")), Or(Not(Symbol("b")), Symbol("a"))) self.assertEqual(expected, statement)
def test_parse_not(self): statement = parser.parse("not(a)") self.assertEqual(statement, Not(Symbol("a")))