Example #1
0
    def test_check_of_true_in_or(self):
        """
		Tests simplifying a formula that has true in or
		"""
        p = bf.Or(
            [
                bf.Var("a"),
                bf.Var("b"),
                bf.Fls(),
                bf.And([bf.Var("b"), bf.Var("a")]),
                bf.Or([bf.Var("b"), bf.Var("a")]),
                bf.Tru(),
            ]
        )
        result = bf.Tru()
        self.assertEqual(result, au.simplify(p), "Invalid simplification, expected same as result.")

        p = bf.Or(
            [
                bf.Var("a"),
                bf.Var("b"),
                bf.And([bf.Var("b"), bf.Var("a")]),
                bf.Or([bf.Var("b"), bf.Var("a"), bf.Tru(), bf.Fls()]),
                bf.Tru(),
            ]
        )
        result = bf.Tru()
        self.assertEqual(result, au.simplify(p), "Invalid simplification, expected same as result.")
Example #2
0
def SAT_solver_brute_force(CNF_formula, dictionary):
	"""
	Solves SAT problem by trying all the possibilities for variables in formula.
	"""
	if isinstance(CNF_formula, bf.Tru):
		#Formula is Tru / satisfiable - return dictionary with given values of variables
		return dictionary
	elif isinstance(CNF_formula, bf.Fls):
		# Formula is Fls -/ not satisfiable -  return None
		return None

	else:
		# Take first variable and set its value to True
		variables = au.extract_variables(CNF_formula)
		dictionary[variables[0]] = bf.Tru()
		simplified_formula = CNF_formula.replace(dictionary)
		simplified_formula = au.simplify(simplified_formula)
		result = SAT_solver_brute_force(simplified_formula, dictionary)

		if result is not None:
			# Return dictionary if formula is satisfiable
			return result
		else:
			# Set same variable to False and try to solve again again
			dictionary[variables[0]] = bf.Fls()
			# replace and simplify formula
			simplified_formula = au.simplify(CNF_formula.replace(dictionary) )
			return SAT_solver_brute_force(simplified_formula, dictionary)
Example #3
0
    def test_not_and(self):
        """
		Tests simplifying a formula that changes an And to a Or.
		"""
        p = bf.Not(bf.And([bf.Tru(), bf.Tru(), bf.Tru(), bf.Not(bf.Tru()), bf.Not(bf.Var("a"))]))
        self.assertEqual(bf.Tru(), au.simplify(p), "Invalid simplification, expected Tru.")

        p = bf.Not(bf.And([bf.Tru(), bf.Tru(), bf.Tru(), bf.Not(bf.Fls()), bf.Not(bf.Var("a"))]))
        self.assertEqual(bf.Var("a"), au.simplify(p), "Invalid simplification, expected Var 'a'.")
Example #4
0
    def test_not_or(self):
        """
		Tests simplifying a formula that changes an Or to a And.
		"""
        p = bf.Not(bf.Or([bf.Tru(), bf.Tru(), bf.Tru(), bf.Not(bf.Tru()), bf.Not(bf.Var("a"))]))
        self.assertEqual(bf.Fls(), au.simplify(p), "Invalid simplification, expected Fls.")

        p = bf.Not(bf.Or([bf.Fls(), bf.Fls(), bf.Fls(), bf.Not(bf.Tru()), bf.Not(bf.Var("a"))]))
        self.assertEqual(bf.Var("a"), au.simplify(p), "Invalid simplification, expected Var 'a'.")
Example #5
0
def DPLL(formula):
	"""
	Implementation of DPLL - argument is formula in CNF form. Returns False if formula is not in SAT or values of variables otherwise.
	"""
	CNF_formula = au.simplify(au.cnf_nnf(formula))

	values = {}
	while True:
		if isinstance(CNF_formula, bf.Tru) or isinstance(CNF_formula, bf.Fls) or isinstance(CNF_formula, bf.Var) or isinstance(CNF_formula, bf.Not):
		# Formula is only True, False, Var or negated Var - no more pure vars / literals, we finished
			break

		temp_value = {}
        #Always check only for first clause in formula - sequence is F, T, Var, Not, And
		clause = CNF_formula.formulas[0]
		if isinstance(clause, bf.Var):
			#It is only literal - Var
			values[clause.name] = bf.Tru()
			temp_value[clause.name] = bf.Tru()
		elif isinstance(clause, bf.Not):
			# It is only literal - negated Var
			values[clause.formula.name] = bf.Fls()
			temp_value[clause.formula.name] = bf.Fls()

		if temp_value:
			#We found literal - replace formula with its value, simplify, put in cnf and look for literal again
			replaced_formula = CNF_formula.replace(temp_value)
			formula_simplified = au.simplify(replaced_formula)
			CNF_formula = au.cnf_nnf(formula_simplified)
		else:
			#finish, no more literals
			break

	#Check for pure variables
	pure_var_values = au.pure_variables(CNF_formula)
	replaced_formula = CNF_formula.replace(pure_var_values)
	formula_simplified = au.simplify(replaced_formula)
	CNF_formula = au.cnf_nnf(formula_simplified)

	#Solve the rest of formula by brute force
	values_brute_force = SAT_solver_brute_force(CNF_formula, {})
	if values_brute_force is not None:
		# satisfiable problem
		return dict(values.items() + pure_var_values.items() + values_brute_force.items())
	else:
		# unsatisfiable problem
		return False
Example #6
0
    def test_using_absorptions(self):
        """
		Tests simplifying a formula that uses absorptions.
		"""
        p1 = bf.And([bf.Var("a"), bf.And([bf.Var("b"), bf.Var("a")]), bf.Or([bf.Var("c"), bf.Var("b")])])
        p2 = bf.Or([bf.Var("a"), bf.And([bf.Var("b"), bf.Var("a")]), bf.Or([bf.Var("c"), bf.Var("b")])])
        p = bf.And([p2, bf.Not(bf.And([bf.Tru(), bf.Tru(), bf.Tru(), bf.Not(bf.Tru()), bf.Not(bf.Var("a")), p1]))])
        result = bf.Or([bf.Var("a"), bf.Var("b"), bf.Var("c"), bf.And([bf.Var("a"), bf.Var("b")])])
        self.assertEqual(
            result, au.simplify(p, use_absorptions=True), "Invalid simplification, expected same as result."
        )
Example #7
0
# Or
or1 = bf.Or([x1, x2, x3, x4])
or2 = bf.Or([x1, bf.Or([x1, x2, x3, x4]), x4, x3, x2])      # this is equivalent to bf.Or([x1, x1, x2, x3, x4, x4, x3, x2])
or3 = bf.Or([])                                             # bf.Or([]) is equivalent to bf.Fls()

# Examples of using the nnf method
print "NNF EXAMPLES:"
print au.nnf(bf.Not(bf.Not(bf.Var("b"))))
print au.nnf(bf.Or([bf.And([bf.Var("a"), bf.Var("b")]), bf.Var("c")]))
print au.nnf(bf.Not(bf.Or([bf.Var("a"), bf.Var("b")])))
print au.nnf(bf.And([bf.Var("a"), bf.And([bf.Var("b"), bf.Var("a")]), bf.Or([bf.Var("c"), bf.Var("b")])]))
print "-----------------------------------------------------------------------------------------------------------------\n"

# Examples of using the cnf method
print "CNF EXAMPLES:"
print au.cnf_nnf(bf.Or([bf.Var("b"), bf.Var("c")]))
print au.cnf_nnf(bf.And([bf.Not(bf.Var("a")), bf.Or([bf.Var("b"), bf.Var("c")])]))
print au.cnf_nnf(bf.And([bf.Var("a"), bf.Or([bf.Var("b"), bf.And([bf.Var("c"), bf.Var("d")])])]))
print au.cnf_nnf(bf.Not(bf.Or([bf.Var("a"), bf.Var("b"), bf.Not(bf.Fls())])))
print "-----------------------------------------------------------------------------------------------------------------\n"

# Examples of using the simplify method
print "SIMPLIFY EXAMPLES:"
print au.simplify(bf.Not(bf.Or([bf.Var("b"), bf.Var("c")])))
print au.simplify(bf.And([bf.Not(bf.Var("a")), bf.Or([bf.Var("b"), bf.Var("c")])]))
print au.simplify(bf.And([bf.Var("a"), bf.Or([bf.Var("b"), bf.Tru(), bf.And([bf.Fls(), bf.Var("c"), bf.Var("d")])])]))
print au.simplify(bf.Not(bf.Or([bf.Var("a"), bf.Var("b"), bf.Not(bf.Fls())])))
print "-----------------------------------------------------------------------------------------------------------------\n"

Example #8
0
    def test_false_in_and(self):
        """
		Tests simplifying a formula that contains Fls in And. Result must be Fls'.
		"""
        p = bf.And([bf.Tru(), bf.Tru(), bf.Tru(), bf.Not(bf.Tru()), bf.Var("a")])
        self.assertEqual(bf.Fls(), au.simplify(p), "Invalid simplification, expected Tru.")
Example #9
0
    def test_remove_true_from_and(self):
        """
		Tests simplifying a formula that contains Tru in And. Result must be Var 'a'.
		"""
        p = bf.And([bf.Tru(), bf.Tru(), bf.Tru(), bf.Not(bf.Fls()), bf.Var("a")])
        self.assertEqual(bf.Var("a"), au.simplify(p), "Invalid simplification, expected Var 'a'.")
Example #10
0
    def test_true_in_or(self):
        """
		Tests simplifying a formula that contains Tru in Or. Result must be True.
		"""
        p = bf.Or([bf.Fls(), bf.Tru(), bf.Fls(), bf.Not(bf.Tru()), bf.Var("a")])
        self.assertEqual(bf.Tru(), au.simplify(p), "Invalid simplification, expected Tru.")
Example #11
0
    def test_false(self):
        """
		Tests simplifying a formula that is already simplified. Result must be Fls.
		"""
        p = bf.Fls()
        self.assertEqual(bf.Fls(), au.simplify(p), "Invalid simplification, expected Fls.")
Example #12
0
    def test_true(self):
        """
		Tests simplifying a formula that is already simplified. Result must be Tru.
		"""
        p = bf.Tru()
        self.assertEqual(bf.Tru(), au.simplify(p), "Invalid simplification, expected Tru.")