How to write it in skolem form?(Prolog) - prolog

Translate the following formula into a horn formula in Skolem form:
∀w¬∀x∃z(H(w)∧(¬G(x,x)∨¬H(z)))
it's translated from german to english, how to write it in horn form and then in skolem form, i didn't find anything on internet...plz help me

I will always use the satisfiability preserving version of skolemization, i.e. the one where those are replaced which would become existential quantifiers when moved to the head of the formula.
To make life a bit simpler, let's push the negations to the atoms. We can also see that w doesn't occur in ¬G(x,x)∨¬H(z) and that x,z don't occur in H(w), allowing us to distribute the quantifiers a bit inside.
Then we obtain the formula ∀w¬H(w) ∨ ∃x∀z (G(x,x)∧ H(z)) .
If we want to refute the formula:
We skolemize ∃x and delete ∀w, ∀z and obtain:
¬H(w) ∨ (G(c,c)∧ H(z))
after CNF transformation, we have:
(¬H(w) ∨ G(c,c)) ∧ (¬H(w) ∨ H(z))
both clauses have exactly one positive literal, so they are horn clauses. Translated to Prolog syntax we get:
g(c,c) :- h(W).
h(Z) :- h(W).
If we want to prove the formula:
We have to negate before we skolemize, leading to:
∃w H(w) ∧ ∀x∃z (¬G(x,x) ∨ ¬H(z))
after skolemizing ∃w and ∃z, deleting ∀x and CNF transformation, we obtain:
H(c) ∧ (¬G(x,x) ∨ ¬H(f(x)))
That could be interpreted as a fact h(c) and a query ?- g(X,X), h(f(X)).
To be honest, both variants don't make much sense - the first does not terminate for any input and in the second version, the query will fail because g/2 is not defined.

does this page help?
6.3 Convert first-order logic expressions to normal form

A horn clause consists of various goals that all have to be satisfied in order for the whole clause to be true.
∀w¬∀x∃z(H(w)∧(¬G(x,x)∨¬H(z)))
First you want to translate the whole statement to human language for clarity. ¬ means NOT, ∧ means AND and ∨ means OR. The () are used to group goals.
∀w¬∀x∃z
For all w, all NOT x, at least 1 Z. If a w is true, x must be false and there must be at least 1 z.
H(w)
Is w a H? There must be a fact that says H(w) is true in your knowledge base.
¬G(x,x)
Is there a fact G(x,x)? If yes, return false.
¬H(z)
Is there a fact H(z)? If yes, return false.
z(H(w)∧(¬G(x,x)∨¬H(z)))
What this says that z is only true if H(w) is true AND either G(x,x) OR H(z) is false.
In Prolog you'd write this as
factCheck(W,X,Z) :- h(W), not(g(X,X);not(checkZ(Z)).
where Z is a list with at least 1 entry in it. If ANY element in list Z is true, fail.
%is the list empty?
checkZ([])
%is h true for the first element of the list?
checkZ([Head|Tail]) :- h(Head), !.
%remove the first element of the list
checkZ([Head|Tail]) :- checkZ(Tail).

Related

Set Intersection predicate Prolog using not

I am trying to build a simple predicate which get as inputs two lists and the results is a third one consisting of the intersection of the first two.
I have decided to do using logical statement. I am pretty sure my logic is correct but my predicate is not working. Any ideas?:
element(X,[H|T]) :-
X=H
;
element(X,T).
intersection(L1,L2,R) :-
not((
element(A,L1),
not(element(A,L2))
)),
not((
element(A,L1),
not(element(A,R))
)).
Please do not post alternative methods I am wondering why this one returns FALSE every time.
Your definition is correct too general. It admits e.g. that [] is the intersection of any two lists which is too general. I.e. it incorrectly succeeds for intersection([],[a],[a]). It lacks a third "for all" idiom stating that all elements that are in both lists will be in the resulting list.
But otherwise your definition is fine. For the ground case. What is a bit unusual is that the intersection is the first and not the last argument. Quite irritating to me are the variable names. I believe that R means "result", thus the intersection. And L1 and L2 are the two sets to build the intersection.
It is a bit too general, though - like many Prolog predicates - think of append([], non_list, non_list). Apart from lists, your definition admits also terms that are neither lists nor partial lists:
?- intersection(non_list1,[1,2|non_list2],[3,4|non_list3]).
To make it really useful safe, use it like so:
?- when(ground(intersection(I, A, B)), intersection(I, A, B)).
or so:
?- ( ground(intersection(I, A, B))
-> intersection(I, A, B)
; throw(error(instantiation_error, intersection(I, A, B)))
).
Or, using iwhen/2:
?- iwhen(ground(intersection(I, A, B)), intersection(I, A, B) ).
As a minor remark, rather write (\+)/1 in place of not/1.
The problem is that not/1 merely negates the outcome of your element/2. It doesn't cause element/2 to backtrack to find other instantiations for which the enclosing not/1 will be true.
Consider the following program.
a(1).
a(2).
b(1).
b(2).
b(3).
And the following queries:
b(X), not(a(X)).
not(a(X)), b(X).
The first one yields X = 3 while the second one yields false. That is because the first query first instantiates X with 1, then with 2, then with 3, until finally not(a(X)) succeeds.
The second query first instantiates X with 1, a(1) succeeds, so not(a(1)) fails. There is no backtracking done!
The lack of backtracking due to negation as pointed out by #SQB is actually not the only problem with your code. If you play around a little with ground queries you find that non-lists and the empty list as pointed out by #false are also not the only issue. Consider the following queries:
?- intersection([2,3],[1,2,3],[2,3,4]).
yes
?- intersection([2],[1,2,3],[2,3,4]).
yes
?- intersection([3],[1,2,3],[2,3,4]).
yes
?- intersection([],[1,2,3],[2,3,4]).
yes
The first is what usually is understood as intersection. The other three are all sublists of the intersection including the trivial sublist []. This is due to the way the predicate describes what an intersection is: In an intersection is not the case that an element is in the first but not the second list AND that said element is in the first but not the third list. This description clearly fits the three above queries hence they succeed. Fooling around a little more with this description in mind there are some other noteworthy ground queries that succeed:
?- intersection([2,2,3],[1,2,3],[2,3,4]).
yes
The question whether the presence of duplicates in the solution is acceptable or not is in fact quite a matter of debate. The lists [2,2,3] and [2,3] although different represent the same set {2,3}. There is this recent answer to a question on Prolog union that is elaborating on such aspects of answers. And of course the sublists of the intersection mentioned above can also contain duplicates or multiples:
?- intersection([2,2,2],[1,2,3],[2,3,4]).
yes
But why is this? For the empty list this is quite easy to see. The query
?- element(A,[]).
no
fails hence the conjunction element(A,L1), not(element(A,L2)) also fails for L1=[]. Therefore the negation wrapped around it succeeds. The same is true for the second negation, consequently [] can be derived as intersection. To see why [2] and [3] succeed as intersection it is helpful to write your predicate as logic formula with the universal quantifiers written down explicitly:
∀L1∀L2∀R∀A (intersection(L1,L2,R) ← ¬ (element(A,L1) ∧ ¬ element(A,L2)) ∧ ¬ (element(A,L1) ∧ ¬ element(A,R)))
If you consult a textbook on logic or one on logic programming that also shows Prolog code as logic formulas you'll find that the universal quantifiers for variables that do not occur in the head of the rule can be moved into the body as existential quantifiers. In this case for A:
∀L1∀L2∀R (intersection(L1,L2,R) ← ∃A ( ¬ (element(A,L1) ∧ ¬ element(A,L2)) ∧ ¬ (element(A,L1) ∧ ¬ element(A,R))))
So for all arguments L1,L2,R there is some A that satisfies the goals. Which explains the derivation of the sublists of the intersection and the multiple occurrences of elements.
However, it is much more annoying that the query
?- intersection(L1,[1,2,3],[2,3,4]).
loops instead of producing solutions. If you consider that L1 is not instantiated and look at the results for the following query
?- element(A,L1).
L1 = [A|_A] ? ;
L1 = [_A,A|_B] ? ;
L1 = [_A,_B,A|_C] ? ;
...
it becomes clear that the query
?- element(A,L1),not(element(A,[1,2,3])).
has to loop due to the infinitely many lists L1, that contain A, described by the first goal. Hence the corresponding conjunction in your predicate has to loop as well. Additionally to producing results it would also be nice if such a predicate mirrored the relational nature of Prolog and worked the other way around too (2nd or 3rd arguments variable). Let's compare your code with such a solution. (For the sake of comparison the following predicate describes sublists of the intersection just as your code does, for a different definition see further below.)
To reflect its declarative nature lets call it list_list_intersection/3:
list_list_intersection(_,_,[]).
list_list_intersection(L1,L2,[A|As]) :-
list_element_removed(L1,A,L1noA),
list_element_removed(L2,A,L2noA),
list_list_intersection(L1noA,L2noA,As).
list_element_removed([X|Xs],X,Xs).
list_element_removed([X|Xs],Y,[X|Ys]) :-
dif(X,Y),
list_element_removed(Xs,Y,Ys).
Like your predicate this version is also using the elements of the intersection to describe the relation. Hence it's producing the same sublists (including []):
?- list_list_intersection([1,2,3],[2,3,4],I).
I = [] ? ;
I = [2] ? ;
I = [2,3] ? ;
I = [3] ? ;
I = [3,2] ? ;
no
but without looping. However, multiple occurrences are not produced anymore as already matched elements are removed by list_element_removed/3. But multiple occurrences in both of the first lists are matched correctly:
?- list_list_intersection([1,2,2,3],[2,2,3,4],[2,2,3]).
yes
This predicate also works in the other directions:
?- list_list_intersection([1,2,3],L,[2,3]).
L = [2,3|_A] ? ;
L = [2,_A,3|_B],
dif(_A,3) ? ;
L = [2,_A,_B,3|_C],
dif(_A,3),
dif(_B,3) ? ;
...
?- list_list_intersection(L,[2,3,4],[2,3]).
L = [2,3|_A] ? ;
L = [2,_A,3|_B],
dif(_A,3) ? ;
L = [2,_A,_B,3|_C],
dif(_A,3),
dif(_B,3) ? ;
...
So this version corresponds to your code without the duplicates. Note how the element A of the intersection explicitly appears in the head of the rule where all elements of the intersection are walked through recursively. Which I believe is what you tried to achieve by utilizing the implicit universal quantifiers in front of Prolog rules.
To come back to a point in the beginning of my answer, this is not what is commonly understood as the intersection. Among all the results list_list_intersection/3 describes for the arguments [1,2,3] and [2,3,4] only [2,3] is the intersection. Here another issue with your code comes to light: If you use the elements of the intersection to describe the relation, how do you make sure you cover all intersecting elements? After all, all elements of [2] occur in [1,2,3] and [2,3,4]. An obvious idea would be to walk through the elements of one of the other lists and describe those occurring in both as also being in the intersection. Here is a variant using if_/3 and memberd_t/3:
list_list_intersection([],_L2,[]).
list_list_intersection([X|Xs],L2,I) :-
if_(memberd_t(X,L2),
(I=[X|Is],list_element_removed(L2,X,L2noX)),
(I=Is,L2noX=L2)),
list_list_intersection(Xs,L2noX,Is).
Note that it is also possible to walk through the arguments of the second list instead of the first one. The predicate memberd_t/3 is a reified variant of your predicate element/2 and list_element_removed/3 is again used in the description to avoid duplicates in the solution. Now the solution is unique
?- list_list_intersection([1,2,3],[2,3,4],L).
L = [2,3] ? ;
no
and the "problem queries" from above fail as expected:
?- list_list_intersection([1,2,3],[2,3,4],[]).
no
?- list_list_intersection([1,2,3],[2,3,4],[2]).
no
?- list_list_intersection([1,2,3],[2,3,4],[3]).
no
?- list_list_intersection([1,2,3],[2,3,4],[2,2,3]).
no
?- list_list_intersection([1,2,3],[2,3,4],[2,2,2]).
no
And of course you can also use the predicate in the other directions:
?- list_list_intersection([1,2,3],L,[2,3]).
L = [2,3] ? ;
L = [3,2] ? ;
L = [2,3,_A],
dif(_A,1) ? ;
...
?- list_list_intersection(L,[2,3,4],[2,3]).
L = [2,3] ? ;
L = [2,3,_A],
dif(4,_A) ? ;
...

What does the bitwise negation operator(\) do in prolog?

I have to implement some functions, one of which is f= ~p/\~q.
I have the following :
p(a). p(b).
q(a). q(b). q(c).
I found the function as:
f(X):-p(\X);q(\X).
When I verify it ( f(X). , f(a). , f(b). , f(c). ) it always returns false.
Shouldn't it return true for c since c is not of type p?
Thank you!
(\)/1 is an evaluable functor for bitwise complement. If you use it directly in an argument, it is only an uninterpreted functor. Evaluation is only performed with (is)/2, (>)/2 and other comparison operators.
In all current Prolog implementations you get:
?- X is \ 1.
X = -2.
Fine print: An ISO conforming system is free to define the value for \. That is, it is free, whether it uses 2's complement or another representation. However, there are only systems that use 2's complement.
Your implementation of that formula seems flawed.
You are required about f : (not p) and (not q)
A restricted negation is available in Prolog, using operator (\+)/1, and conjunction (X and Y) is expressed by comma i.e. (,)/2.
Semicolon i.e. (;)/2 means or, as for instance in the following test, that shows your initial assumption about f(c) is also wrong.
?- forall(member(X,[a,b,c,d]),(f(X)->writeln(y);writeln(n))).
n
n
n
y
(of course, after f/1 has been translated correctly)

prolog and translating propositional logic

My ultimate goal is to load a set of propositional formulas in to Prolog from a file in order to deduce some facts. Suppose I have the propositional formula:
p implies not(q).
In Prolog this would be:
not(q) :- p
Prolog does not seem to like the not operator in the head of the rule. I get the following error:
'$record_clause'/2: No permission to redefine built-in predicate `not/1'
Use :- redefine_system_predicate(+Head) if redefinition is intended
I know two ways to rewrite the general formula for p implies q. First, use the fact that the contrapositive is logically equivalent.
p implies q iff not(q) implies not(p)
Second, use the fact that p implies q is logically equivalent to not(p) or q (the truth tables are the same).
The first method leads me to my current problem. The second method is then just a conjunction or disjunction. You cannot write only conjunctions and disjunctions in Prolog as they are not facts or rules.
What is the best way around my problem so that I can express p implies not(q)?
Is it possible to write all propositional formulas in Prolog?
EDIT: Now I wish to connect my results with other propositional formulae. Suppose I have the following rule:
something :- formula(P, Q).
How does this connect? If I enter formula(false, true) (which evaluates to true) into the interpreter, this does not automatically make something true. Which is what I want.
p => ~q === ~p \/ ~q === ~( p /\ q )
So we can try to model this with a Prolog program,
formula(P,Q) :- P, Q, !, fail.
formula(_,_).
Or you can use the built-in \+ i.e. "not", to define it as formula(P,Q) :- \+( (P, Q) ).
This just checks the compliance of the passed values to the formula. If we combine this with domain generation first, we can "deduce" i.e. generate the compliant values:
13 ?- member(Q,[true, false]), formula(true, Q). %// true => ~Q, what is Q?
Q = false.
14 ?- member(Q,[true, false]), formula(false, Q). %// false => ~Q, what is Q?
Q = true ;
Q = false.
You are using the wrong tool. Try Answer Set Programming.

How does a Resolution algorithm work for propositional logic?

I haven't been able to understand what the resolution rule is in propositional logic. Does resolution simply state some rules by which a sentence can be expanded and written in another form?
Following is a simple resolution algorithm for propositional logic. The function returns the set of all possible clauses obtained by resolving it's 2 input. I can't understand the working of the algorithm, could someone explain it to me?
function PL-RESOLUTION(KB,α) returns true or false
inputs: KB, the knowledge base, a sentence α in propositional logic, the query, a
sentence in propositional logic
clauses <--- the set of clauses in the CNF representation of KB ∧ ¬α
new <--- {}
loop do
for each Ci, Cj in clauses do
resolvents <----- PL-RESOLVE(Ci, Cj)
if resolvents contains the empty clause then return true
new <--- new ∪ resolvents
if new ⊆ clauses then return false
clauses <---- clauses ∪ new
It's a whole topic of discussion but I'll try to explain you one simple example.
Input of your algorithm is KB - set of rules to perform resolution. It easy to understand that as set of facts like:
Apple is red
If smth is red Then this smth is sweet
We introduce two predicates R(x) - (x is red) and S(x) - (x is sweet). Than we can written our facts in formal language:
R('apple')
R(X) -> S(X)
We can substitute 2nd fact as ¬R v S to be eligible for resolution rule.
Caluclating resolvents step in your programs delete two opposite facts:
Examples: 1) a & ¬a -> empty. 2) a('b') & ¬a(x) v s(x) -> S('b')
Note that in second example variable x substituted with actual value 'b'.
The goal of our program to determine if sentence apple is sweet is true. We write this sentence also in formal language as S('apple') and ask it in inverted state. Then formal definition of problem is:
CLAUSE1 = R('apple')
CLAUSE2 = ¬R(X) v S(X)
Goal? = ¬S('apple')
Algorithm works as follows:
Take clause c1 and c2
calculate resolvents for c1 and c2 gives new clause c3 = S('apple')
calculate resolvents for c3 and goal gives us empty set.
That means our sentence is true. If you can't get empty set with such resolutions that means sentence is false (but for most cases in practical applications it's a lack of KB facts).
Consider clauses X and Y, with X = {a, x1, x2, ..., xm} and Y = {~a, y1, y2, ..., yn}, where a is a variable, ~a is its negation, and the xi and yi are literals (i.e., possibly-negated variables).
The interpretation of X is the proposition (a \/ x1 \/ x2 \/ ... \/ xm) -- that is, at least one of a or one of the xi must be true, assuming X is true. Likewise for Y.
We assume that X and Y are true.
We also know that (a \/ ~a) is always true, regardless of the value of a.
If ~a is true, then a is false, so ~a /\ X => {x1, x2, ..., xm}.
If a is true, then ~a is false. In this case a /\ Y => {y1, y2, ..., yn}.
We know, therefore, that {x1, x2, ..., xm, y1, y2, ..., yn} must be true, assuming X and Y are true. Observe that the new clause does not refer to variable a.
This kind of deduction is known as resolution.
How does this work in a resolution based theorem prover? Simple: we use proof by contradiction. That is, we start by turning our "facts" into clauses and add the clauses corresponding to the negation of our "goal". Then, if we can eventually resolve to the empty clause, {}, we will have reached a contradiction since the empty clause is equivalent to falsity. Because the facts are given, this means that our negated goal must be wrong, hence the (unnegated) goal must be true.
resolution is a procedure used in proving that argument which are expressible in predicate logic are correct
resolution lead to refute theorem proving technique for sentences in propositional logic.
resolution provides proof by refutation. i.e. to show that it is valid,resolution attempts to show that the negation of the statement produces a contradiction with a known statement
algorithm:
1). convert all the propositions of axioms to clause form
2). negate propositions & convert result to clause form
3)resolve them
4)if the resolvent is the empty clause, then contradiction has been found

How to input the following data in prolog?

not(A()) and not(D()) and not(B()) and not(A()).
What's the right way?
The concept of logical negation is already included in Prolog in means of failure. If your implementation doesn't supply it (it can happens) you can think not as
not(P) :- call(P), !, fail.
or
not(P) :- (call(P) -> fail ; true)
Then look at the formula, it can be simplified to have not applied just to single predicates:
~(A & ~D) & ~B & ~A = (~A | D) & ~B & ~A = ~A & ~B
It's just a De Morgan law and a consideration about the fact that D isn't useful to satisfability of the predicate.
then you can combine them:
final_predicate :- not(B), not(A).
EDIT: remember , is AND and ; is OR.
If simply trying to evaluate a propositional logic statement using PROLOG, you could try the following. Start with an encoding of the values of your 'propositions' a, b and d, such as:
a :- true. % this means that a is true.
b :- fail. % this means that b is false
...etc. For example, assuming your statements were:
a :- fail.
b :- fail.
d :- fail.
Then, executing your statement:
?- not(a), not(b), not(d), not(a).
true.
n.b.: The 'propositions' encoded here are 'simulated' - they're actually zero arity first-order predicates as far as PROLOG is concerned.
ps. a :- true. can be simplified to a..
pps. If I'm way off the mark and you're after a way of symbolically manipulating the statement into some other form, such as a normalization, then you need to write what is called a meta-interpreter in PROLOG. Refer to Clocksin and Mellish's Programming in Prolog, Appendix B, 'Clausal Form Program Listings', which might help you.

Resources