Introduction
Your mission in life is simple: Prove people wrong on the internet!
To do this you usually carefully analyze their statements and point out the contradiction in them.
It's time to automate this, but as we are lazy, we want to prove people wrong with the least effort (read: shortest code) possible.
Specification
Input
Your input will be a formula in conjunctive normal form. For the format, you may use the below format or define your own, upon the needs of your language (you may not encode more in the format than the pure CNF though). The test-cases (here) are however provided in the below format (although it won't be too hard generating your own).
Your input will be a a list of a list of a list of variables (you may also read it as strings / require strings). The input is a formula in conjunctive normal form (CNF) written as a set of clauses, each being a list of two lists. The first list in the clause encodes the positive literals (variables), the second list encodes the negative (negated) literals (variables). Every variable in the clause is OR'ed together and all clauses are AND'ed together.
To make it clearer: [[[A,B],[C]],[[C,A],[B]],[[B],[A]]]
can be read as:
(A OR B OR (NOT C)) AND (C OR A OR (NOT B)) AND (B OR (NOT A))
Output
The output is boolean, e.g. either some truthy value or some falsy value.
What to do?
It's simple: Check if the formula given at hand is satisfiable, e.g. whether there exists some assignment of true and false to all variables such that the overall formula yields "true". Your output will be "true" if the formula is satiesfiable and "false" if it is not.
Fun-Fact: This is a NP-complete problem in the general case.
Note: Generating a truth-table and checking if any resulting entry is true, is allowed.
Corner Cases
If you get an empty 3rd-level list, then there's no such (positive / negative) variable in that clause - a valid input.
You can leave other corner cases undefined if you want to.
You may also return true upon an empty formula (1st level list) and false upon an empty clause (2nd level list).
Who wins?
This is code-golf so the shortest answer in bytes wins!
Standard rules apply of course.
Test-cases
[[[P],[Q,R]],[[Q,R],[P]],[[Q],[P,R]]] -> true
[[[],[P]],[[S],[]],[[R],[P]],[[U],[Q]],[[X],[R]],[[Q],[S]],[[],[P,U]],[[W],[Q,U]]] -> true
[[[],[P,Q]],[[Q,P],[]],[[P],[Q]],[[Q],[P]]] -> false
[[[P],[]],[[],[P,S]],[[P,T],[]],[[Q],[R]],[[],[R,S]],[[],[P,Q,R]],[[],[P]]] -> false
optional behavior (not mandatory, may be left undefined):
[] -> true (empty formula)
[[]] -> false (empty clause)
[[[],[]]] -> false (empty clause)
(A OR B OR (NOT C)) AND (C OR A OR (NOT B)) AND (B OR (NOT A))
? \$\endgroup\${{P,Q},{P,!Q},{!P,Q},{!P,!Q}}
(not in this order) which can be easily shown is a contradiction. For the 4): This is trivially a contradiction because it isP AND ... AND (NOT P)
which can obviously never be true for any value of P. \$\endgroup\$