3SAT solved in polynomial time? - complexity-theory

I have seen few errors in the cnf files for both satisfiable and unsatisfiable clauses files SATLIB Benchmark Problems
To be more specific I have found out that the 1st file of the zip folder here:
20 variables, 91 clauses - 1000 instances, all satisfiable
contains a file with the title of "uf20-01", the equation of which is unsatisfiable clearly as the 7th clause at the 15th line and the 87th clause at line number 4 are both exact inverse of each other!((5 19 17) and (-5 -19 -17))
Thus an AND operation having them at any point of time would result in equation to be unsatisfiable.
I have come to a conclusion that if two clauses are exact inverse of each other then and only then the equation is unsatisfiable, else the equation is satisfiable.. I have attempted another UNSAT file of the above link with trial and error and though the MINISAT browser version also says the same file to be unsatisified I have found out a solution for the same in 1's and 0's for every variable.
The algorithm above was posted to a journal by me but got rejected.
My question is :
Can somebody give me an example of an unsatisfiable 3SAT equation that contains only 3 variables(or maybe a bit more..) without having any clause being an exact inverse of the other?
If I can get such a clause then the algorithm is wrong(but still it proves many SAT benchmark problems to be UNSAT) and it would not prove that many UNSAT problems in the 1st link are indeed SAT.
This is teasing my mind and hope you all can understand it, as if the algorithm above is right, then I have proved P=NP! It can start a revolution also..
BTW: I have sent email to SATLIB contact person also but still no reply after 2 days concerning the 2nd link file.

In the 3-Sat in CNF all clauses are OR-clauses and they are combined by AND. So the two lines you cite define the following two clauses
x5 or x17 or x19
(not x5) or (not x17) or (not x19)
which can both be satisfied, for example, by setting x5 to true, x17 to false, and x19 arbitrary.

There are many:
(x1 or x2 or x3) and (not x1 or x2) and not x2 and not x3
In general you will need to introduce more variables to show this. But it intuitively even does not seem true that the inversion of all the variables of any clause is not needed for UNSAT to occur. As another answer points out, even in the most basic case, it is still SAT when this occurs. Perhaps the benchmark test set tends to have this but it does not generalize.

Related

Solve specific combination in propositional logic rule set (SAT Solver)

In the car industry you have thousand of different variants of components available to choose from when you buy a car. Not every component is combinable, so for each car there exist a lot of rules that are expressed in propositional logic. In my case each car has between 2000 and 4000 rules.
They look like this:
A → B ∨ C ∨ D
C → ¬F
F ∧ G → D
...
where "∧" = "and" / "∨" = "or" / "¬" = "not" / "→" = "implication".
With the tool "limboole" (http://fmv.jku.at/limboole/) I am able to to convert the propositional logic expressions into conjunctive normal form (CNF). This is needed in case I have to use a SAT solver.
Now, I would like to check the buildability feasibility for specific components within the rule set. For example, for each of the following expressions or combinations, I would like to check if the are feasible within the rule set.
(A) ∧ (B)
(A) ∧ (C ∨ F)
(B ∨ G)
...
My question is how to solve this problem. I asked a similar questions before (Tool to solve propositional logic / boolean expressions (SAT Solver?)), but with a different focus and now I am stuck again. Or I just do not understand it.
One option is to calculate all solutions with an ALLSAT approach of the rule set. Then I could check if each combination is part of any solution. If yes, I can derive that this specific combination is feasible.
Another option would be, that I add the combination to the rule set and then run a normal SAT solver. But I would have to do it for each expression I want to check.
What do you think is the most elegant or rather easiest way to solve this problem?
The best method which is known to me is to use "incremental solving under assumptions" technique. It was motivated by the same problem you have: multiple SAT instances (CNF formulae) which have some common subformulae.
Formally, you have some core Boolean formula C in CNF. And you have a set of assumptions {A_i}, i=1..n, where A_i is a Boolean formula in CNF also.
On the step 0 you provide to the solver your core formula C. It tries to solve it, says a result to you and save its state (lets call this state as core-state). If formula C is satisfiable, on the step i you provide assumption A_i to the solver and it continues its execution from the core-state. Actually, it tries to solve a formula C ∧ A_i but not from the beginning.
You can find a bunch of papers related to this topic easily, where much information is located. Also, you can check you favorite SAT-solver for the support of this technique.

Modulo function and variable domain

Here is a simple CLPFD relation:
1 #= 81 mod X.
This returns:
X in inf.. -1\/1..sup,
81 mod X#=1.
Unless my math is completely incorrect, shouldn't the domain of X be -80.. -1\/1..80?
First things first:
Is there a mistake in the constraint solver?
No(t necessarily), because all admissible solutions are still contained in the domain that is deduced, and no wrong solutions are reported. The domain that you deduced is a proper subset of what the solver reports.
Does the constraint solver propagate as well as it could in this case?
No, obviously not, as your stronger bounds already show. In fact, the admissible domain is even smaller than what you deduced: X in 2..80 would also be valid, because X can definitely not be negative, and it also cannot be equal to 1.
Exercise: Is X in 2..80 the smallest (with respect to set inclusion) domain that can be deduced in this case? Why (not)? And in what, if any, sense is it minimal?
So, what is going on here?
The explanation is rather easy: Implementing (mod)/2, (rem)/2, (div)/2 and—to somewhat lesser extent—even (*)/2 in such a way that they propagate as much as possible in all cases is brutally difficult to get right, and was clearly not done in this case.
Do we have to live with this shortcoming?
No, because we can improve the constraint solver to handle such cases too! That is, we can add logic so that it propagates more strongly! Doing this elegantly and correctly is an unsolved problem in general, and subject of active research. See for example Finite Domain Constraint Solver Learning, the references included therein, and several other papers. Of course, the dream would be to somehow derive the propagation directly from the specification of these operations, which is at least decades away. Until then, such issues are found and improved rather ad hoc.
Disclaimer: I don't know what I am talking about, I just wanted to see for myself what happens, and thought it might be useful to share.
With SWI-Prolog and library(clpfd):
?- use_module(library(clpfd)).
true.
?- 1 #= 81 rem X.
X in inf.. -1\/1..sup,
81 rem X#=1.
?- 1 #= 81 mod X.
X in inf.. -1\/1..sup,
81 mod X#=1.
?- 1 #= 81 - X * (81 // X ).
X in -80.. -1\/1..80,
X*_G1053#=80,
81//X#=_G1053,
_G1053 in -80.. -1\/1..80.
Strange, isn't the expression in the last example supposed to be how modulo division is defined?
If you take Gnu-Prolog (mod is not directly supported):
| ?- 1 #= 81 rem X.
X = _#4(2..80)
yes
| ?- 1 #= 81 - X * (81 // X).
no
Hmm. What if you just reorder the expression:
| ?- 1 #= 81 - (81 // X) * X.
X = _#4(2..80)
yes
Conclusion: yes, it seems that writing a good CLP(FD) library is indeed not easy. One could even be left with the impression that these libraries exhibit emergent behaviors that the authors are not always fully aware of.

How does the SAT solver produce the model(assignment[s])?

Here is a very simple cnf instance as (x1 or x2 or x3)&(x1 or x2)&(x2 or x3)and the formula is definitely satisfiable, the solution is x1 = x2 = x3 = 1, that is enough. So,my question is how the solver produce the assignment using DPLL or other procedure? Thanks.
Well, basically, for the case of CDCL
(CDCL SAT solvers implement DPLL, but can learn new clauses and backtrack non-chronologically. Clause learning with conflict analysis does not affect soundness or completeness. Conflict analysis identifies new clauses using the resolution operation. Therefore each learnt clause can be inferred from the original clauses and other learnt clauses by a sequence of resolution steps. If cN is the new learnt clause, then ϕ is satisfiable if and only if ϕ ∪ {cN} is also satisfiable. Moreover, the modified backtracking step also does not affect soundness or completeness, since backtracking information is obtained from each new learnt clause.).(Source : Wikipedia)
it's working as follow :
At first pick a branching variable, x1. A yellow circle means an arbitrary decision.
Now apply unit propagation, which yields that x4 must be 1 (i.e. True). A gray circle means a forced variable assignment during unit propagation. The resulting graph is called implication graph.
Arbitrarily pick another branching variable, x3.
Apply unit propagation and find the new implication graph.
Here the variable x8 and x12 are forced to be 0 and 1, respectively.
Pick another branching variable, x2.
Find implication graph.
Pick another branching variable, x7.
Find implication graph.
Found a conflict!
Find the cut that lead to this conflict. From the cut, find a conflicting condition.
Take the negation of this condition and make it a clause.
Add the conflict clause to the problem.
Non-chronological back jump to appropriate decision level.
Back jump and set variable values accordingly.
(Answer completely from Wikipedia: Conflict-Driven_Clause_Learning#Example)
Here is a list (not complete for sure) of solvers who use the CDCL algorithm, you should check them out :
MiniSAT.
Zchaff SAT.
Z3.
ManySAT.

Shortest-path in a grid using prolog

Sorry by the first ask, I'm new at the hood... I did a cleaning on the code. The problem is:
I have a square grid with paths and obstacles. I want to find the shortest path from a point to another. This is part of an artificial intelligence. When the path is too large, I can not see the whole list of points on the bash, but in the game, the character who travels this path, it does not at shortest path. So, my question is, how I can change this code to solve the shortest path. Thank you so much!
mov(X1,Y1,X2,Y2):-
pos(X1,Y1), X2 is X1 , Y2 is Y1+1 ,pos(X2,Y2).
mov(X1,Y1,X2,Y2):-
pos(X1,Y1), X2 is X1 , Y2 is Y1-1 ,pos(X2,Y2).
mov(X1,Y1,X2,Y2):-
pos(X1,Y1), X2 is X1+1 , Y2 is Y1 , pos(X2,Y2).
mov(X1,Y1,X2,Y2):-
pos(X1,Y1), X2 is X1 -1 , Y2 is Y1 , pos(X2,Y2).
path(X1,Y1,X2,Y2,Path) :-
travel(pos(X1,Y1),pos(X2,Y2),[pos(X1,Y1)],Q),
reverse(Q,Path).
travel(pos(X1,Y1),pos(X2,Y2),P,[pos(X2,Y2)|P]) :-
mov(X1,Y1,X2,Y2).
travel(pos(X1,Y1),pos(X2,Y2),Visited,Path) :-
mov(X1,Y1,X,Y),
pos(X,Y) \== pos(X2,Y2),
\+member(pos(X,Y),Visited),
travel(pos(X,Y),pos(X2,Y2),[pos(X,Y)|Visited],Path).
First some Prolog advice.
member/2 is a built-in, you should not have to define it.
ISO negation is \+, not not/1.
For performance, memberchk/2 beats member/2.
I see a lot of foo(X,Y) :- X == Y, ... in your code. It's much better if you just say foo(X,X) and save yourself the trouble of making explicit tests like this, unless you're going to do a conditional expression to avoid a choice point or something.
Lots of cuts in this code. Cuts and bugs tend to be great friends because the cut can undermine reasonable-looking code by preventing it from being executed.
If I had to solve this problem, I would want to separate the shortest-path logic from the grid traversal logic. You'll never be able to debug this, and even if you do, what you'll have is a one of those unreadable blocks of code that cannot be modified. It's clear that you have an explosion of terms because you're embedding the traversal logic in the path finding logic. Break them out into two separate steps and you will probably find that you get smaller pieces you can meaningfully test and debug. This is a good way of life with programming, regardless of the language: what would you do if you needed to change the grid structure or make the pathfinding more intelligent or complex? Keeping pieces granular always helps for managing change.
As for S.O. etiquette, this isn't great: you should talk about what doesn't work and what you've tried and you want to supply a minimum, complete, verifiable example. I suspect in producing such a thing you'd probably solve the problem yourself.

Generating lists of satisfying values for a set of constraints

Given a set of constraints, I would like to efficiently generate the set of values.
Suppose I have a few constraints on my Thungus[1]:
goodThungus(X) :-
X > 100,
X < 1000.
sin(X) = 0.
Now, I can check a Thungus by asking:
goodThungus(500).
I would like to generate all good Thungi. I'm not sure how to do that; I'm really not sure about how to do it efficiently.
Note: this of course has to be a computable generation.
[1] Arbitrary object selected for this example.
What you are asking for can't be done in the full general case: imagine doing f(X) = 0 where f is a function for which the roots cannot be analytically determined, for example. Or suppose f(X) is the function "does the program X halt?". No computer is going to solve that for you.
Your options are basically to either:
Limit the set of constraints to things that you can reason about. e.g. inequalities are good because you can identify ranges, then do intersections and unions on ranges efficiently etc.
Limit the set of values to a small enough number that you can test them individually against each of the constraints
UPDATE: For the kind of constraints stated in the question (ranges of real values and real-valued functions that can be analytically solved and have a finite number of solutions within any range) I would suggest the following approach:
Write a generating function that can iteratively return solutions for you function within a given range... this will need to be done analytically e.g. exploiting the fact that sin(X)=0 implies X=n*pi where n is any integer.
Do interval arithmetic and bounding on your range constraints to work out the range(s) that need to be scanned (in the example you would want the range 100 < X < 1000)
Apply your generating function to each of the target ranges in order to create all of the possible solutions.
I'll preface my suggestion by stating that I'm no expert in using numerical constraint logic programming systems, but here goes...
On the surface, I'd think that solving this kind of problem in PROLOG would be best suited to a numerical constraint logic programming system, perhaps such as CLP(R) (for reals) in SWI-PROLOG; unfortunately, the specific problem you've asked for is seeking to solve for a set of constraints including a non-linear constraint, which seems to be not well or widely supported amongst PROLOG implementations; instead, they seem to deal mainly with linear constraints and often have limited support for non-linear constraints such as X = sin(Y), for example.
Take SWI-PROLOG's CLP(R) library, and the following example program:
:- use_module(library(clpr)).
report_xsq_zeros :-
findall(X, {0 = (X * X) - 10}, Results),
write_ln(Results).
report_sin_zeros :-
findall(X, {0 = sin(X)}, Results),
write_ln(Results).
Now, executing report_xsq_zeros gives us:
?- report_xsq_zeros.
[3.16228, -3.16228]
true.
Here, the system correctly computed the zeros of the quadratic x^2 - 10, which are indeed approximately 3.16228 and -3.16228, where the range of X was unbounded. However, when we execute report_sin_zeros, we get:
?- report_sin_zeros.
[0.0]
true.
We see that the system only computed a single zero of the function sin(X), even though the range of X was indeed also unbounded. Perhaps this is because it is recognized that there are an infinite number of solutions here (though I'm only guessing...). If we were to program what you've asked for:
report_sin_zeros :-
findall(X, {X > 100, X < 1000, 0 = sin(X)}, Results),
write_ln(Results).
We get no results, as the underlying system only computed a single zero for sin(X) as shown earlier (i.e., binding X to 0.0 which lies outside the stated range):
?- report_sin_zeros.
[]
true.
I conclude that I've either not demonstrated proper usage of SWI-PL CLP(R) (I suggest you look into it yourself), or it won't solve your specific (non-linear) problem. Other CLP(R) implementations may behave differently to SWI-PROLOG CLP(R), but I don't have them installed so I can't check, but you could try SICSTUS CLP(R) or others; the syntax looks similar.
He is searching any X in [100..1000] for that sin(x) = 0. But this is a pure mathematical problem, and not meant for relational logical deduction / backtracking. simple Prolog is not suited for this?

Resources