What's the approach to solving this kind of logic problem? - algorithm

What would be the approach to a kind of problem that sounds like this:
A says B lies
B says C lies
D says B lies
C says B lies
E says A and D lie
How many lie and how many tell the truth?
I am not looking for the answer to the problem above, but the approach to this kind of problem. Thanks a lot.

A -> !B
B -> !C
D -> !B
C -> !B
E -> !A & !D
Reminder:
X -> Y <=> !X | Y
Transform the 5 equations into logical propositions, and you will find answers.

To solve equations of the form
X1 = NOT X 3
X5 = NOT X 2
etc
Form a graph with nodes as Xi and connecting Xi and X j iff the equation Xi = NOT X j appears.
Now try to 2-colour the graph using Breadth First Search.

Assuming you're looking to solve this with a program... it's actually pretty easy to brute force, if you've got a reasonably small input set. For example, in this case you've basically got 5 Boolean variables - whether each person is a truth-teller or not.
Encode the statements as tests, and then run through every possible combination to see which ones are valid.
This is obviously a "dumb" solution and will fail for large input sets, but it's likely to be rather easier to code than a full "reasoning" engine. Often I find that you can get away with doing a lot less work by taking into account what size of problem you're actually going to encounter :)

Use a logic programming language such as Prolog. They are specifically designed to solve such problems.
Other alternatives include functional-logic languages and model checkers.

Related

Is there an algorithm that can find steps to solve a set of equations

To start, I am not quite sure how to explain the problem and as a result have no clue how to search about it. It is as follows:
I have a large number of equations. The equations can be solved for any given variable, given the other unknowns, or can be solved simultaneously to solve for multiple unknowns. For example, given a and b, equations f(x, y) = a and g(x, y) = b, one can simultaneously solve to get x and y.
I need an algorithm that takes the known values and the equations and return the order in which solving them would result in the desired value.
Example equations:
f(a, b) = 0
f(b, c) = 0
Find c given a -> use eq1 to find b given a, then use eq2 to find c given b
Example 2:
f(x, y, a) = 0
f(x, y, b) = 0
Find x given a, b -> solve for x and y simultaneously using eq1 and eq2
I have attempted a simpler form of the problem using a graph, where the nodes are variables and edges are equations that connect them. However, this does not account for equations with more than 1 unknown and does not consider simultaneous solving.
There are a number of steps:
Match equations and variables as a standard bipartite matching; with edges between equations and variables (and if the maximum matching isn't perfect you have problems) https://cs.stackexchange.com/questions/50410/perfect-matching-in-a-graph-and-complete-matching-in-bipartite-graph
Find minimal set of equations to solve simultaneously using strongly connected components
https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
Those sets can then be solved in various ways; tearing is a common technique to reduce the size of the system even further; see e.g.,
https://people.inf.ethz.ch/~fcellier/Lect/MMPS/Refs/tearing.pdf

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.

Flattening quantification over relations

I have a Relation f defined as f: A -> B × C. I would like to write a firsr-order formula to constrain this relation to be a bijective function from A to B × C?
To be more precise, I would like the first order counter part of the following formula (actually conjunction of the three):
∀a: A, ∃! bc : B × C, f(a)=bc -- f is function
∀a1,a2: A, f(a1)=f(a2) → a1=a2 -- f is injective
∀(b, c) : B × C, ∃ a : A, f(a)=bc -- f is surjective
As you see the above formulae are in Higher Order Logic as I quantified over the relations. What is the first-order logic equivalent of these formulae if it is ever possible?
PS:
This is more general (math) question, rather than being more specific to any theorem prover, but for getting help from these communities --as I think there are mature understanding of mathematics in these communities-- I put the theorem provers tag on this question.
(Update: Someone's unhappy with my answer, and SO gets me fired up in general, so I say what I want here, and will probably delete it later, I suppose.
I understand that SO is not a place for debates and soapboxes. On the other hand, the OP, qartal, whom I assume is the unhappy one, wants to apply the answer from math.stackexchange.com, where ZFC sets dominates, to a question here which is tagged, at this moment, with isabelle and logic.
First, notation is important, and sloppy notation can result in a question that's ambiguous to the point of being meaningless.
Second, having a B.S. in math, I have full appreciation for the logic of ZFC sets, so I have full appreciation for math.stackexchange.com.
I make the argument here that the answer given on math.stackexchange.com, linked to below, is wrong in the context of Isabelle/HOL. (First hmmm, me making claims under ill-defined circumstances can be annoying to people.)
If I'm wrong, and someone teaches me something, the situation here will be redeemed.
The answerer says this:
First of all in logic B x C is just another set.
There's not just one logic. My immediate reaction when I see the symbol x is to think of a type, not a set. Consider this, which kind of looks like your f: A -> BxC:
definition foo :: "nat => int × real" where "foo x = (x,x)"
I guess I should be prolific in going back and forth between sets and types, and reading minds, but I did learn something by entering this term:
term "B × C" (* shows it's of type "('a × 'b) set" *)
Feeling paranoid, I did this to see if had fallen into a major gotcha:
term "f : A -> B × C"
It gives a syntax error. Here I am, getting all pedantic, and our discussion is ill-defined because the notation is ill-defined.
The crux: the formula in the other answer is not first-order in this context
(Another hmmm, after writing what I say below, I'm full circle. Saying things about stuff when the context of the stuff is ill-defined.)
Context is everything. The context of the other site is generally ZFC sets. Here, it's HOL. That answerer says to assume these for his formula, wich I give below:
Ax is true iff x∈A
Bx is true iff x∈B×C
Rxy is true iff f(x)=y
Syntax. No one has defined it here, but the tag here is isabelle, so I take it to mean that I can substitute the left-hand side of the iff for the right-hand side.
Also, the expression x ∈ A is what would be in the formula in a typical set theory textbook, not Rxy. Therefore, for the answerer's formula to have meaning, I can rightfully insert f(x) = y into it.
This then is why I did a lot of hedging in my first answer. The variable f cannot be in the formula. If it's in the formula, then it's a free variable which is implicitly quantified. Here's the formula in Isar syntax:
term "∀x. (Ax --> (∃y. By ∧ Rxy ∧ (∀z. (Bz ∧ Rxz) --> y = z)))"
Here it is with the substitutions:
∀x. (x∈A --> (∃y. y∈B×C ∧ f(x)=y ∧ (∀z. (z∈B×C ∧ f(x)=z) --> y = z)))
In HOL, f(x) = f x, and so f is implicitly, universally quantified. If this is the case, then it's not first-order.
Really, I should dig deep to recall what I was taught, that f(x)=y means:
(x,f(x)) = (x,y) which means we have to have (x,y)∈(A, B×C)
which finally gets me:
∀x. (x∈A -->
(∃y. y∈B×C ∧ (x,y)∈(A,B×C) ∧ (∀z. (z∈B×C ∧ (x,z)∈(A,B×C)) --> y = z)))
Finally, I guess it turns out that in the context of math.stackexchange.com, it's 100% on.
Am I the only one who feels compulsive about questioning what this means in the context of Isabelle/HOL? I don't accept that everything here is defined well enough to show that it's first order.
Really, qartal, your notation should be specific to a particular logic.
First answer
With Isabelle, I answer the question based on my interpretation of your
f: A -> B x C, which I take as a ZFC set, in particular a subset of the
Cartesian product A x (B x C)
You're sort of mixing notation from the two logics, that of ZFC
sets and that of HOL. Consequently, I might be off on what I think you're
asking.
You don't define your relation, so I keep things simple.
I define a simple ZFC function, and prove the first
part of your first condition, that f is a function. The second part would be
proving uniqueness. It can be seen that f satisfies that, so once a
formula for uniqueness is stated correctly, auto might easily prove it.
Please notice that the
theorem is a first-order formula. The characters ! and ? are ASCII
equivalents for \<forall> and \<exists>.
(Clarifications must abound when
working with HOL. It's first-order logic if the variables are atomic. In this
case, the type of variables are numeral. The basic concept is there. That
I'm wrong in some detail is highly likely.)
definition "A = {1,2}"
definition "B = A"
definition "C = A"
definition "f = {(1,(1,1)), (2,(1,1))}"
theorem
"!a. a \<in> A --> (? z. z \<in> (B × C) & (a,z) \<in> f)"
by(auto simp add: A_def B_def C_def f_def)
(To completely give you an example of what you asked for, I would have to redefine my function so its bijective. Little examples can take a ton of work.)
That's the basic idea, and the rest of proving that f is a function will
follow that basic pattern.
If there's a problem, it's that your f is a ZFC set function/relation, and
the logical infrastructure of Isabelle/HOL is set up for functions as a type.
Functions as ordered pairs, ZFC style, can be formalized in Isabelle/HOL, but
it hasn't been done in a reasonably complete way.
Generalizing it all is where the work would be. For a particular relation, as
I defined above, I can limit myself to first-order formulas, if I ignore that
the foundation, Isabelle/HOL, is, of course, higher-order logic.

Algorithm for 2-Satisfiability problem

Can anyone explain the algorithm for 2-satisfiability problem or provide me the links for the same? I could not find good links to understand it.
If you have n variables and m clauses:
Create a graph with 2n vertices: intuitively, each vertex resembles a true or not true literal for each variable. For each clause (a v b), where a and b are literals, create an edge from !a to b and from !b to a. These edges mean that if a is not true, then b must be true and vica-versa.
Once this digraph is created, go through the graph and see if there is a cycle that contains both a and !a for some variable a. If there is, then the 2SAT is not satisfiable (because a implies !a and vica-versa). Otherwise, it is satisfiable, and this can even give you a satisfying assumption (pick some literal a so that a doesn't imply !a, force all implications from there, repeat). You can do this part with any of your standard graph algorithms, ala Breadth-First Search , Floyd-Warshall, or any algorithm like these, depending on how sensitive you are to the time complexity of your algorithm.
You can solve it with greedy approach.
Or using Graph theory, here is link which explains the solution using graph theory.
http://www.cs.tau.ac.il/~safra/Complexity/2SAT.ppt
Here is the Wikipedia page on the subject, which describes a polynomial time algorithm. (The brute force algorithm of just trying all the different truth assignments is exponential time.) Maybe a bit of further explanation will help.
The expression "if P then Q" is only false when P is true and Q is false. So the expression has the same truth table values as "Q or not P". It is also equivalent to its contrapositive, "if not Q then not P", and that in turn is equivalent to "not P or Q" (the same as the other one).
So the algorithm involves replacing every expression of the form "A or B", with the two expressions, "if not A then B" and "if not B then A". (Putting it another way, A and B can't both be false.)
Next, construct a graph representing these implications. Create nodes for each "A" and "not A", and add links for each of the implications obtained above.
The last step is to make sure that none of the variables is equivalent to its own negation. That is, for each variable A (or not A), follow the links to discover all the nodes that can be reached from it, taking care to detect loops.
If one of the variables, A, can reach "not A", and "not A" can also reach A, then the original expression is not satisfiable. (It is a paradox.) If none of the variables do this, then it is satisfiable.
(It's okay if A implies "not A", but not the other way around. That just means that A must be negated to satisfy the expression.)
2 satisfiabilty:
if x & !x is strongly connected
then from !x we can reach to x
from x we can reach to !x
so in our operation,
in case of x,
we have 2 options only,
1.taking x (x) that leads to !x
2.rejecting x (!x) that leads to x
and both the choices are leading to the paradox of taking and rejecting a choice at the same time
so the satisfiability is impossible :D

Ocaml implementation advice for an algorithm on sets

I am having problems for converting following algo in ocaml To implement this algorithm i used Set.Make(String) functor actualy in and out are 2 functions Can any one give me percise code help in ocaml for following
This is actually Algo for Live Variables[PDF] ..Help would be appreciated greatly
for all n, in[n] = out[n] = Ø
w = { set of all nodes }
repeat until w empty
n = w.pop( )
out[n] = ∪ n’ ∈ succ [n] in[n’]
in[n] = use[n] ∪ (out[n] — def [n])
if change to in[n],
for all predecessors m of n, w.push(m)
end
for all n, in[n] = out[n] = Ø
w = { set of all nodes }
repeat until w empty
n = w.pop( )
out[n] = ∪ n’ ∈ succ [n] in[n’]
in[n] = use[n] ∪ (out[n] — def [n])
if change to in[n],
for all predecessors m of n, w.push(m)
end
It's hard for me to tell what is exactly going on here. I think there is some alignment issues with your text --repeat until w empty should be repeating the next 5lines, right? And how are in and out functions, they look like arrays to me? Aside from those deficiencies I'll tackle some general rules I have followed.
I've had to translate a number of numerical methods in C and Fortran algorithms to functional languages and I have some suggestions for you.
0) Define the datatypes being used. This will really help you with the next step (spoiler: looking for functional constructs). Once you know the datatypes you can more accurately define the functional constructs you will eventually apply.
1) Look for functional constructs. fold, recursion, and maps, and when to use them. For example, the for all predecessors m is a fold (unsure if that it would fold over a tree or list, but none-the-less, a fold). While loops are a good place for recursion --but don't worry about making it a tail call, you can modify the parameters later to adhere to those requirements. Don't worry about being 100% pure. Remove enough impure constructs (references or arrays) to get a feel for the algorithm in a functional way.
2) Write any part of the algorithm that you can. Leaving functions blank, add dummy values, and just implement what you know --then you can ask SO better, more informed questions.
3) Re-write it. There is a good chance you missed some functional constructs or used an array or reference where you now realize you can use a list or set or by passing an accumulator. You may have defined a list, but later you realize you cannot randomly access it (well, it would be pretty detrimental to), or it needs to be traversed forward and back (a good place for a zipper). Either way, when you finally get it you'll know, and you should have a huge ear-to-ear grin on your face.

Resources