This repo has a bunch of neat ideas, but does not have a proven working polynomial time solution to solve 3SAT.
It attempts to process an instance and keep implying new clauses until it either 1) derives a set of clauses which imply the instance is unsatisfiable or 2) run out of new clauses to imply.
As described below, v2_utils.process(instance, max_length) aims to return a bool indicating if the instance is satisfiable. When tested with max_length == 3, this returns false positives. If it can be shown that there exists a fixed value for max_length that is independent of the number of terminals, then P = NP.
- Navigate to the 
Scriptsdirectory 
cd Scripts
- Create a virtual environment
 
python3 -m venv .venv
- Install the requirements
 
pip install -r requirements.txt
A list of benchmark problems can be found here
Run readcnf.py to iterate through the files in /inputs or /UUF50.218.1000 (you have to unzip satisfiable instances into /inputs or unsatisfiable instances into /UUF50.218.1000 and call the function at the bottom of the file)
baseline_solver.py
write_blockages(instance)- writes a file, 
blockages.mdwith information about the given instance - Displays the following:
- instance size
 - instance clauses
 - blocked assignments (and how many times each one is blocked)
 - whether it's satisfiable
 
 
- writes a file, 
 is_satisfiable(instance)- simply returns a bool indicating whether the given instance is satisfiable
 - This is a baseline check done in exponential time
 
v2_utils.py
process(instance (as list of lists), max_length)- This is the only function you have to directly call
 - This processes an instance according to the ideas outlined below
 - It returns a bool indicating whether 
instanceis satisfiable- Note: currently throws out false positives if 
max_length == 3 
 - Note: currently throws out false positives if 
 
todict(instance (as list of lists))- Converts the given list of lists into an object similar to a Trie fine tuned to support sets
 - See Rope Example for an example and explanation
 
check_sat(instance (as Trie-esque data structure))- Keep adding implied clauses to the instance until you either a. derive contradicting 1-terminal clauses or b. can't imply any new clauses
 - Return a bool indicating whether 
instanceis satisfiable- Note: currently throws out false positives if 
max_length == 3 
 - Note: currently throws out false positives if 
 - Read the section Important Ideas below
 
main.py
- Has a few demo functions, showcasing 
write_blockages()andprocess() 
This section has a quick overview of the ideas used in this repo. If you want a highly detailed explanation, read the paper in Documents.
- An instance of 3SAT can be blocked (from being the satisfying assignment) by a clause
 - Clauses in the instance can imply new clauses in the following ways:
- Implication: if two clauses contain the same term which is positive in one clause and negated in the other, then they imply a new clause which contains all the remaining terms in either clause (excluding the opposite form terms)
- ex, 
[-1, 2, 3]and[1, 4, 5]imply[2, 3, 4, 5] 
 - ex, 
 - Reduction: if two clauses in an implication are identical except for the opposite form term, the implied clause's length will be one less than the input clauses
- ex, 
[-1, 2, 3]and[1, 2, 3]imply[2, 3] 
 - ex, 
 - Expansion: given a clause and a term not in that clause, you can append that term to the clause without blocking any additional assignments
- ex 
[1, 2, 3]implies[1, 2, 3, 4] 
 - ex 
 
 - Implication: if two clauses contain the same term which is positive in one clause and negated in the other, then they imply a new clause which contains all the remaining terms in either clause (excluding the opposite form terms)
 - Using the different types of implications, we can keep adding clauses to the instance without changing whether it's satisfiable
 - If we derive two clauses which contain a single term each and that term is positive in one clause and negated in the other, the instance is unsatisfiable. Call these contradicting 1-terminal clauses.
- In other words, 
[a], [-a]is in the instance for someain the set of terminals 
 - In other words, 
 - Ideally, we'd find a way to continually process all the clauses until we either 1) derive the contradicting 1-terminal clauses or 2) know that there is no way to derive these clauses (as such, the instance would be satisfiable)
 
Run pytest to run tests