Is nonexistence queriable in Datalog? - datalog

Suppose I've defined a few values for a function:
+(value[1] == "cats")
+(value[2] == "mice")
Is it possible to define a function like the following?
(undefined[X] == False) <= (value[X] == Y)
(undefined[X] == True) <= (value[X] does not exist)
My guess is that it can't, for two reasons:
(1) Queries are guaranteed to terminate in Datalog, and you could query for undefined[X] == True.
(2) According to Wikipedia, one of the ways Datalog differs from Prolog is that Datalog "requires that every variable appearing in a negative literal in the body of a clause also appears in some positive literal in the body of the clause".
But I'm not sure, because the terms involved ("terminate", "literal", "negative") have so many uses. (For instance: Does negative literal mean f[X] == not Y or does it mean not (f[X] == Y)? Does termination mean that it can evaluate a single expression like undefined[3] == True, or does it mean it would have found all X for which undefined[X] == True?)

Here another definition of "safe".
A safety condition says that every variable in the body of a rule must occur in at least one positive (i.e., not negated)
atom.
Source: Datalog and Recursive Query Processing
And an atom (or goal) is a predicate symbol (function) along with a list of terms as arguments. (Note that “term” and “atom” are used differently here than they are in Prolog.)
The safety problem is to decide whether the result of a given Datalog program can be guaranteed to be finite even when some source relations are infinite.
For example, the following rule is not safe because the Y variable appears only in a negative atom (i.e. not predicate2(Z,Y)).
rule(X,Y) :- predicate1(X,Z), not predicate2(Z,Y) .
To meet the condition of safety the Y variable should appear in a positive predicate too:
rule(X,Y) :- predicate1(X,Z), not predicate2(Z,Y), predicate3(Y) .

Related

`nth0/3` behaviour when N is unbound

If I type in SWI Prolog a "nth0" query, the result is:
?- nth0(N,X,a).
N = 0,
X = [a|_G282] ;
N = 1,
X = [_G281, a|_G285] ;
N = 2,
X = [_G281, _G284, a|_G288] ;
... etc
however, the SWI manual says:
Errors
type_error(integer, Index) if Index is not an integer or unbound.
so, if my understanding of this text is correct (?), it seems that an error should be triggered instead of the previous results.
In addition, I wonder which one of the behaviours is the correct one taken into account the ISO standard.
(I known stack-overflow doesn't allows questions for references, so, I will not ask for a link to standard, but I hope do not break the rules if I ask: is ISO standard publicly available? if not, there are any equivalent RFC? ).
If I read this correctly, it says, for
nth0(?Index, ?List, ?Elem)
"... if Index is not an integer or unbound."
In the example, Index is unbound:
?- nth0(N, L, E).
N = 0,
L = [E|_G1103] ;
N = 1,
L = [_G1102, E|_G1106] ;
N = 2,
L = [_G1102, _G1105, E|_G1109] .
So could you be misreading the manual?
Just to make sure: the manual should be understood as "... if Index is not( or( an integer, unbound ) )". What it does when Index is unbound is that it starts enumerating valid lists where Index can be 0 or larger.
The predicate nth0/3 is not part of ISO Prolog, so there is no explicit reference. However, the way how and when errors are reported is defined in the standard. In particular, type errors are never reported due to an argument being not sufficiently instantiated. The concrete formulation in the SWI manual is a bit unfortunate. It should rather read for nth0(N, Xs, E):
N is neither a variable nor an integer
— type_error(integer, N).
Would now there be a restriction on N being instantiated (it's not in this case, but let's assume it), then there would be an error condition:
N is a variable
— instantiation_error.
The predicate nth0/3 used to be part of the DECsystem 10 library listut (also written ListUt) since 1983. Originally, the definition was only intended to be used with N being an integer. However, errors, as we have them now, did not yet exist and the system simply (and incorrectly) failed with an uninstantiated variable.
It was later adopted (and corrected) by Quintus Prolog in about 1984.
Now, we have an elaborate error classification that is able to capture the fine semantic differences between the various error situations.
More how predicates are defined in the standard.

swi-prolog truth assignment?

So I have this exercise that I'm stuck on:
A formula is:
tru
fls
variable(V) iff V is an atom.
or(Flist) iff every element in the list is a formula
there are implies, and, neg too. the form looks similar.
We can represent a truth assignment (an assignment of values to variables) by a Prolog list of the form [Var1/Value1, Var2/Value2,...VarN/ValueN]. Write a predicate sub(?F,?Asst,?G) which succeeds iff G is a formula which is a result of substituting the variables of F with corresponding values from the assignment Asst. (You can assume that the truth assignment A is at least partially instantiated).
E.g.
sub(variable(x), [x/tru], tru).
true
sub(or([variable(a),variable(b)]), [a/tru,b/fls], G).
G = or(tru,fls)
true
I've tried
sub(variable(x),[x/value],G):-
G = variable(value).
But it just returns false.
Edit: Sorry I didn't make the question clear, Can someone explain to me if there's a way to assign values associated with variables in a list to another variable? I think it has something to do with unification.
Variables are placeholders.
Beware of case sensitivity: Prolog variable names start with an uppercase character or underscore, atoms with a lowercase character.
Your code snippet of sub/3 assumes that the list of
key-value pairs has exactly a length of one ([x/value]).
By using member/2 the lists can have arbitrary length.
When handling n-ary logical connectives like and / or, you probably want a short-circuit implementation that returns as soon as possible. Like so:
sub(tru,_,tru).
sub(fls,_,fls).
sub(variable(X),Assoc,Value) :-
member(X/Value,Assoc).
sub(or([]),_,fls).
sub(or([X|Xs]),Assoc,V) :-
sub(X,Assoc,T),
( T = tru, V = tru % short-circuit logical-or
; T = fls, sub(or(Xs),Assoc,V)
).

how to assign one list to a variable in prolog?

I want to append([],C,C) where C is a list containing some elements . Is it possible? I will append some list in C containing elements append (Found,C,C) if other condition is true.
And also i want to store final value in C to a variable D . How can I do that?
I want to append([],C,C) where C is a list containing some elements. Is it possible?
append([],C,C) is always true. An empty list combined with anything is that anything. Look what Prolog says when you attempt it:
?- append([],C,C).
true.
This true without any bindings tells you that Prolog established the proof but no new bindings were created as a result. This code would have the same result:
meaningless(_, _, _).
?- meaningless(everybody, X, Squant).
true.
This suggests your desire is misplaced. append([], C, C) does not do what you think it does.
I will append some list in C containing elements append (Found,C,C) if other condition is true. And also i want to store final value in C to a variable D. How can I do that?
Thinking in terms of "storing" and other operations implying mutable state is a sure sign that you are not understanding Prolog. In Prolog, you establish bindings (or assert facts into the dynamic store, which is a tar pit for beginners). Something similar could be achieved in a Prolog fashion by doing something like this:
frob(cat, List, Result) :- append([cat], List, Result).
frob(dog, List, List).
This predicate frob/3 has two in-parameters: an atom and a list. If the atom is cat then it will append [cat] to the beginning of the list. The threading you see going between the arguments in the head of the clause and their use in the body of the clause is how Prolog manages state. Basically, all state in Prolog is either in the call stack or in the dynamic store.
To give an example in Python, consider these two ways of implementing factorial:
def fac(n):
result = 1
while n > 1:
result = result * n
n = n - 1
This version has a variable, result, which is a kind of state. We mutate the state repeatedly in a loop to achieve the calculation. While the factorial function may be defined as fac(n) = n * fac(n-1), this implementation does not have fac(n-1) hiding in the code anywhere explicitly.
A recursive method would be:
def fac(n):
if n < 1:
return 1
else:
return n * fac(n-1)
There's no explicit state here, so how does the calculation work? The state is implicit, it's being carried on the stack. Procedural programmers tend to raise a skeptical eyebrow at recursion, but in Prolog, there is no such thing as an assignable so the first method cannot be used.
Back to frob/3, the condition is implicit on the first argument. The behavior is different in the body because in the first body, the third argument will be bound to the third argument of the append/3 call, which will unify with the list of the atom cat appended to the second argument List. In the second body, nothing special will happen and the third argument will be bound to the same value as the second argument. So if you were to call frob(Animal, List, Result), Result will be bound with cat at the front or not based on what Animal is.
Do not get mixed up and think that Prolog is just treating the last argument as a return value! If that were true, this would certainly not work like so:
?- frob(X, Y, [whale]).
X = dog,
Y = [whale].
What appears to have happened here is that Prolog could tell that because the list did not start with cat it was able to infer that X was dog. Good Prolog programmers aspire to maintain that illusion in their APIs, but all that really happened here is that Prolog entered the first rule, which expanded to append([cat], X, [whale]) and then unification failed because Prolog could not come up with an X which, having had [cat] prepended to it, would generate [whale]. As a result, it went to the second rule, which unifies X with dog and the second two arguments with each other. Hence Y = [whale].
I hope this helps!

About Prolog syntax

Sometimes I see terms like:
X = a:b
or
X = a-b
I can do requests like
X = Y:Z
and the compiler unifies Y with a and Z with b, as expected.
Now my answer:
Which characters (or sequence of characters) am I allowed to use to combine two Prolog atoms?!
Maybe you can give me some links with further informations about this issue.
Thanks for your help and kind regards from Germany
Which characters (or sequence of characters) am I allowed to use to combine two Prolog atoms?!
What you are asking here for, is the entire operator syntax definition of Prolog. To get the very full answer to this, please refer to the tag iso-prolog for full information how to obtain the Prolog standard ISO/IEC 13211-1.
But as a short answer to start with:
Prolog syntax consists of
functional notation, like +(a,b), plus
a dynamically redefinable operator syntax, plus
some extra.
It seems you want to know which "characters" can be used as operators.
The short answer is that you can use all atoms Op that succeed for current_op(Pri,Fix,Op). So you can ask dynamically, which operators are present:
?- current_op(Pri, Fix, Op).
Pri = 1, Fix = fx, Op = ($)
; Pri = 1150, Fix = fx, Op = (module_transparent)
; Pri = 700, Fix = xfx, Op = (=#=)
; Pri = 700, Fix = xfx, Op = (#>=)
; Pri = 700, Fix = xfx, Op = (>=)
; ... .
All those operators can be used in the specified manner, as pre-, in-, or postfix with the indicated priorities. Some of these operators are specific to SWI, and some are defined by the standard. Above, only #>= and >= are standard operators.
Most of the operators consist of the graphic characters #$&*+-./:<=>?#^~ only or of letters, digits and underscores starting with a lower case letter. There are two solo characters !; and then there are ,| which are even more special. Operator names that are different to above need quoting - you rarely will encounter them.
To see how operators nest, use write_canonical(Term).
The long answer is that you are also able to define such operators yourself. However, be aware that changing the operator syntax has often many implications that are very difficult to fathom. Even more so, since many systems differ in some rarely used configurations. For example, the system you mentioned, SWI differs in several ways.
I'd suggest to avoid defining new operators until you have learned more about the Prolog language.
let's see what's inside X = Y:Z
?- display( X = Y:Z ).
=(_G3,:(_G1,_G2))
true.
then we have a nested structure, where functors are operators.
An operator is an atom, and the rule for atom syntax says that we have 3 kind to consider:
a sequence of any printable character enclosed in single quote
a sequence of special characters only, where a special character is one of `.=:-+*/><##~? (I hope I have found all of them, from this page you can check if I forgot someone !)
a sequence of lowercase/uppercase characters or the underscore, starting with a lowercase character
edit
A functor (shorthand for function constructor, I think, but function is misleading in Prolog context) it's the symbol that 'ties' several arguments. The number of arguments is named arity. In Prolog a term is an atomic literal (like a number, or an atom), or a recursive structure, composed of a functor and a number of arguments, each being a term itself (at least 1).
Given the appropriate declaration, i.e. op/3, unary and binary terms can be represented as expressions, like that one you show.
An example of operator, using the : special char, is ':-'
member(X,[X|_]).
member(X,[_|T]) :- member(X, T).
The O.P., said (and I quote):
Sometimes I see terms like: X = a:b or X = a-b
I can do requests like X = Y:Z and the compiler unifies Y with a and Z with b, as expected.
Now my answer: Which characters (or sequence of characters) am I allowed
to use to combine two Prolog atoms?!
The short answer is Pretty much whatever you want (provided it is an atom).
The longer answer is this:
What are seeing are infix (x infix_op b), prefix (pfx_op b) and suffix (b sfx_op ) operators. Any structure with an arity of 2 can be an infix operator. Any structure with an arity of 1 can be a prefix or suffix operator. As a result, any atom may be an operator.
Prolog is parsed via a precedence driven, recursive descent parser (written in Prolog, naturally). Operators are defined and enumerated, along with their precedence and associativity in the operator/3 predicate. Associativity has to do with how the parse tree is constructed. An expression like a - b - c could be parsed as ( a - ( b - c ) ) (right-associative), or ( ( a - b ) - c ) (left-associative).
Precedence has to do with how tightly operators bind. An expression like a + b * c binds as ( a + ( b * c ) not because of associativity, but because '*'/2 (multiplication) has higher precedence that '+'/2 (addition).
You can add, remove and change operators to your heart's content. Not that this gives you a lot of room to shoot yourself in the foot by breaking prolog's syntax.
It should be noted, however, that any operator expression can also be written via ordinary notation:
a + b * c
is exactly identical to
'+'( a , '*'(b,c) )

DPLL algorithm definition

I am having some problems understanding the DPLL algorithm and I was wondering if anyone could explain it to me because I think my understanding is incorrect.
The way I understand it is, I take some set of literals and if some every clause is true the model is true but if some clause is false then the model is false.
I recursively check the model by looking for a unit clause, if there is one I set the value for that unit clause to make it true, then update the model. Removing all clauses that are now true and remove all literals which are now false.
When there are no unit clauses left, I chose any other literal and assign values for that literal which make it true and make it false, then again remove all clauses which are now true and all literals which are now false.
DPLL requires a problem to be stated in disjunctive normal form, that is, as a set of clauses, each of which must be satisfied.
Each clause is a set of literals {l1, l2, ..., ln}, representing the disjunction of those literals (i.e., at least one literal must be true for the clause to be satisfied).
Each literal l asserts that some variable is true (x) or that it is false (~x).
If any literal is true in a clause, then the clause is satisfied.
If all literals in a clause are false, then the clause is unsatisfiable and hence the problem is unsatisfiable.
A solution is an assignment of true/false values to the variables such that every clause is satisfied. The DPLL algorithm is an optimised search for such a solution.
DPLL is essentially a depth first search that alternates between three tactics. At any stage in the search there is a partial assignment (i.e., an assignment of values to some subset of the variables) and a set of undecided clauses (i.e., those clauses that have not yet been satisfied).
(1) The first tactic is Pure Literal Elimination: if an unassigned variable x only appears in its positive form in the set of undecided clauses (i.e., the literal ~x doesn't appear anywhere) then we can just add x = true to our assignment and satisfy all the clauses containing the literal x (similarly if x only appears in its negative form, ~x, we can just add x = false to our assignment).
(2) The second tactic is Unit Propagation: if all but one of the literals in an undecided clause are false, then the remaining one must be true. If the remaining literal is x, we add x = true to our assignment; if the remaining literal is ~x, we add x = false to our assignment. This assignment can lead to further opportunities for unit propagation.
(3) The third tactic is to simply choose an unassigned variable x and branch the search: one side trying x = true, the other trying x = false.
If at any point we end up with an unsatisfiable clause then we have reached a dead end and have to backtrack.
There are all sorts of clever further optimisations, but this is the core of almost all SAT solvers.
Hope this helps.
The Davis–Putnam–Logemann–Loveland (DPLL) algorithm is a, backtracking-based search algorithm for deciding the satisfiability of propositional logic formulae in conjunctive normal form also known as satisfiability problem or SAT.
Any boolean formula can be expressed in conjunctive normal form (CNF) which means a conjunction of clauses i.e. ( … ) ^ ( … ) ^ ( … )
where a clause is a disjunction of boolean variables i.e. ( A v B v C’ v D)
an example of boolean formula expressed in CNF is
(A v B v C) ^ (C’ v D) ^ (D’ v A)
and solving the SAT problem means finding the combination of values for the variables in the formula that satisfy it like A=1, B=0, C=0, D=0
This is a NP-Complete problem. Actually it is the first problem which has been proven to be NP-Complete by Stepehn Cook and Leonid Levin
A particular type of SAT problem is the 3-SAT which is a SAT in which all clauses have three variables.
The DPLL algorithm is way to solve SAT problem (which practically depends on the hardness of the input) that recursively creates a tree of potential solution
Suppose you want to solve a 3-SAT problem like this
(A v B v C) ^ (C’ v D v B) ^ (B v A’ v C) ^ (C’ v A’ v B’)
if we enumerate the variables like A=1 B=2 C=3 D=4 and se negative numbers for negated variables like A’ = -1 then the same formula can be written in Python like this
[[1,2,3],[-3,4,2],[2,-1,3],[-3,-1,-2]]
now imagine to create a tree in which each node consists of a partial solution. In our example we also depicted a vector of the clauses satisfied by the solution
the root node is [-1,-1,-1,-1] which means no values have been yet assigned to the variables neither 0 nor 1
at each iteration:
we take the first unsatisfied clause then
if there are no more unassigned variables we can use to satisfy that clause then there can’t be valid solutions in this branch of the search tree and the algorithm shall return None
otherwise we take the first unassigned variable and set it such it satisfies the clause and start recursively from step 1. If the inner invocation of the algorithm returns None we flip the value of the variable so that it does not satisfy the clause and set the next unassigned variable in order to satisfy the clause. If all the three variables have been tried or there are no more unassigned variable for that clause it means there are no valid solutions in this branch and the algorithm shall return None
See the following example:
from the root node we choose the first variable (A) of the first clause (A v B v C) and set it such it satisfies the clause then A=1 (second node of the search tree)
the continue with the second clause and we pick the first unassigned variable (C) and set it such it satisfies the clause which means C=0 (third node on the left)
we do the same thing for the fourth clause (B v A’ v C) and set B to 1
we try to do the same thing for the last clause we realize we no longer have unassigned variables and the clause is always false. We then have to backtrack to the previous position in the search tree. We change the value we assigned to B and set B to 0. Then we look for another unassigned value that can satisfy the third clause but there are not. Then we have to backtrack again to the second node
Once there we have to flip the assignment of the first variable (C) so that it won’t satisfy the clause and set the next unassigned variable (D) in order to satisfy it (i.e. C=1 and D=1). This also satisfies the third clause which contains C.
The last clause to satisfy (C’ v A’ v B’) has one unassigned variable B which can be then set to 0 in order to satisfy the clause.
In this link http://lowcoupling.com/post/72424308422/a-simple-3-sat-solver-using-dpll you can find also the python code implementing it

Resources