I am trying to clear something up with subsets.
Say I have this setup:
A={x,y} B={a,b,c,{x,y}}
I understand that:
x is not a member of B.
A is a member of B
But now I am wondering:
Is A a proper subset of B?
If it's not, is it because A is considered an element in B and not a set? Would it only be a subset of B if B={a,b, c, {{x,y}}} (and in this case, would {x,y} not be a member of B)?
If it is a proper subset of B, then why?
Thank you!
A is not a proper subset of B because A contains members that B does not — x and y. A would be a proper subset if it were {{x, y}}.
Related
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
I'm attempting to find the amount of inversions within a list. Inversions would be defined as any pair a,b from a list, where ai is the index of a and bi is the index of b that satisfies a > b and ai < bi. Essentially a comes before b but yet is larger than b.
The first thing I did was write a predicate to find out what the index is.
indexOf(Index, Element, List) :-
nth1(Index, List, Element).
Then I wrote a predicate to determine if any set of two numbers is an inversion
isInversion(A, B, List) :-
A \= B, indexOf(AI, A, List), indexOf(BI, B, List), A > B, AI < BI.
At this point I have a lot of questions, especially as I'm very unfamiliar with logic programming languages. My first question is, indexOf won't actually give me the index will it? I'm confused how that would actually work as it seems like it'd essentially have to try every number, which I'm not explicitly telling it to do.
If somehow indexOf will automatically determine the index and store it in AI/BI like I'm expecting, then I believe my isInversion predicate will evaluate correctly, if I'm wrong please let me know.
My main concern is how to actually determine the amount of inversions. In something like python I would do
count = 0
for a in puzzle
for b in puzzle
if a is b continue
if isInversion(a, b, puzzle)
count = count + 1
That would give me my amount of inversions. But how can I do this in prolog? For loops don't seem very stylistic so I don't want to use that.
Something to note, I have searched for other questions. It's a little tough since I obviously don't know exactly what I'm trying to look for. However I just wanted to make it clear that I felt things such as Prolog do predicate for all pairs in List? didn't help me answer the question.
You should remove the constraint A\=B as it will fail with unbound variables.
Then use aggregate_all/3 to count all the inversions (you don't actually need the values A/B of the inversion):
isInversion(A, B, List):-
indexOf(AI, A, List),
indexOf(BI, B, List),
A > B,
AI < BI.
countInversions(List, N):-
aggregate_all(count, isInversion(_, _, List), N).
Sample run:
?- countInversions([4,3,2,1,9], N).
N = 6.
You may see which inversions exists using findall/3 on isInversion:
?- findall(A-B, isInversion(A,B,[4,3,2,1,9]), LInversions).
LInversions = [4-3, 4-2, 4-1, 3-2, 3-1, 2-1].
In situation, there are two positive numbers a,b,c,d and it is satisfied with a+b>c+d.(this is fact)
When we only know the values ab, cd (we don't know a,b,c,d respectively),
how can we prove this fact a+b>c+d?
for example, a=2,b=8,c=3,d=6 => a+b(10)>c+d(9).
but we only know ab(16), cd(18). how can we know the fact a+b>c+d?
thank you
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.
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