Warning: Singleton variables: [Alice,Ben] in prolog - prolog

I wrote a program in prolog.
parent(Amy,John).
parent(Bob,John).
parent(John,Ben).
parent(Alice,Ben).
I'm using SWI-Prolog on Ubuntu 12.04. When I insert my file in swi-prolog interpreter:
['example.pl']
I'm getting warnings:
Warning: /home/mazix/example1.pl:1:
Singleton variables: [Amy,John]
Warning: /home/mazix/example1.pl:2:
Singleton variables: [Bob,John]
Warning: /home/mazix/example1.pl:3:
Singleton variables: [John,Ben]
Warning: /home/mazix/example1.pl:4:
Singleton variables: [Alice,Ben]
% example1.pl compiled 0.00 sec, 4 clauses
true.
What do these mean? And what does the true at the bottom mean? How should I get rid of this warnings?

Identifiers starting with a capital letter are variables. If you want atoms, enclose them in single quotes:
parent('Amy', 'John').
or start them with a small letter:
parent(amy, john).
A "singleton variable" is a named variable that appears only once in its lexical scope. What this means, in practice, is that you name it, but you don't do anything useful with it, hence the compiler warning.

Ahh.. change all your names to lower case john, ben, etc.
Since they are upper case, prolog thinks they are variables. And since you didn't use those variables, it is warning you that you will hit problems later on.
The 'true' just means that it has loaded the module.. with warnings. Everything you do in prolog returns true or false.. no escape from that.

You are using uppercase names for your relations, which indicates a variable. You should get aware of the different datatypes in Prolog. Boris already gave you the hint.
Singleton variables tells you that you are not using this variable anywhere else. true at the end tells you, that there is no contradiction in your prolog rules (because there are no rules anyhow).

Related

SWI-Prolog partition predicate works differently in REPL than in programme

I imlemented quicksort using SWISH this way:
qsort([],[]).
qsort([H|T],S) :-
partition([X,O]>>compare(O,X,H),T,L,E,G),
qsort(L,A),
qsort(G,Z),
append([A,[H|E],Z],S).
main :-
length(L,22),
maplist(random(0,9),L),
qsort(L,S),
maplist(writeln,[L,S]).
It doesn't work correctly. The input and output lists are the same. However when I run this in the REPL there on the right:
length(S,22), maplist(random(0,9),S),[H|T]=S, partition([X,O]>>compare(O,X,H),T,L,E,G).
the random lists do get sorted. Whence the difference?
When the second clause for the qsort/2 predicate is compiled, there's no information on H other than it's a variable when compiling the lambda expression. Any variable occurring in the lambda expression that's not find in a local lambda parameter must be declared using the {}/1 construct. But when running your query at the top-level interpreter, by the time the lambda expression is interpreted, H is bound and thus no longer a variable (making the use of the {}/1 construct unnecessary).
Note that there are several details here at play that are out of scope of the lambda library itself: (1) is the compiler recognizing at compile time that you're calling a meta-predicate with an argument that's a lambda expression? (2) how's a top-level query interpreted? Is the full query first fully compiled or is it meta-interpreted? These details depend on the system itself.
It works when I add {H}/ in front of [X,O]>>compare(O,X,H). Might be a bug that toplevel doesn't require (but allows) it for the expected behaviour. But I'm not sure, so answers welcome from those in the know.

Prolog predicate argument descriptors [duplicate]

Looking at Prolog documentation, predicate signatures are sometimes written as following:
foo(:Bar, +Baz, -Qux, ?Mop)
What are :, +, - and ? for and how do I interpret them? Also, are these the only ones that exist or are there more of them?
Those prefix operators, in this context, represent instantiation modes, i.e. they tell you which arguments should be variables or instantiated when calling the predicate. They also tell you if an argument will be (possibly further) instantiated by the call. They can also be used to tell you that an argument is going to be meta-interpreted in some way by the predicate you're calling. Some of these instantiation modes are standard, other depend on the system. The most usual are:
- - the argument should be unbound (likely output argument)
+ - the argument should be bound (input argument)
? - the argument can be either bound or unbound
# - the argument will not be further instantiated by the call
: - the argument will be meta-interpreted in some way (often ambiguous)
0 - the argument will be interpreted as goal and called as such
N - where N is natural number; the argument will be interpreted as a closure that will be composed with N additional arguments to construct a goal that will be called
Different systems provide other or different instantiation modes. For example, for stating that an argument should be ground when calling a predicate, or for stating that an argument should be a predicate indicator or that will be interpreted as a grammar rule body. You will need to refer to the documentation of the Prolog system you're using for the details.
Mode declarations first appeared in the DECsystem-10 compiler in the end of the 1970s. The DECsystem-10 user's guide of 1978-09 being one of the first descriptions. The motivation is given 1982-11-10:
Such information enables the compiler to generate more compact code
making better use of runtime storage. The saving of runtime
storage in particular can often be very substantial. Mode
declarations also help other people to understand how your
program operates.
DECsystem-10
+ — the argument will always be a NON-variable
- — the argument will always be a variable
? — no restriction
Note that these declarations apply to each goal. Most notably, they apply to recursive goals. In this manner the following mode declaration plus its definition implies that the second argument is not a partial list. Thus, a goal member(A, [c|_]) would be not conforming. So the interface and the implementation are somewhat interdependent which can lead to quite complex cases, when unifications performed by the predicate itself have to be taken into account.
:- mode member(?, +).
member(X, [X|_]). % member(X, [X,.._]) in DEC10
member(X, [_|L]) :-
member(X, L).
In case a mode declaration is violated by a concrete goal, the declaration is either ignored, or will produce an error which at that time meant writing out an error message and failing. The DECsystem-10 interpreter always ignored the declarations.
Deep down in the 1970s, the DEC 10 User's guide thus gave rise of two interpretations to mode declarations: The first being the prescriptive one that does produce errors in case the modes are not met by a caller. The second one being entirely informal, ignoring the mode declarations at runtime. The former is used within the Prolog standard, the latter is found in the documentation of some Prolog systems.
ISO/IEC-Prolog: Template and modes subclause
The Prolog standard (ISO/IEC 13211-1:1995, 2007, 2012) uses the following format for the definition of built-in predicates. It starts with subclause .1 Description, .2 Template and modes, .3 Errors, and optionally continues with .4 Examples, .5 Bootstrapped built-in predicate(s).
8.1.2 Template and modes
A specification for both the type of arguments and which
of them shall be instantiated for the built-in predicate to
be satisfied. The cases form a mutually exclusive set....
The concretes modes are:
+ — the argument shall be instantiated.
# — like + and the argument shall remain unaltered.
- — the argument shall be a variable that will be instantiated iff the goal succeeds.
? — no mode requirement, the argument may be a variable or an instantiated.
If a predicate was called with a differing mode, an instantiation_error or uninstantiation_error is produced. If the type does not match, a type_error is produced.
In this manner the programmer can anticipate many errors simply by looking at the Template and mode subclause without reading the detailed error conditions.
Other systems
Systems that differ from ISO also differ to each other in their precise interpretation of modes. Many perform silent failure in case when a type error would be appropriate. They view mode declarations as a means to indicate cases where the predicate is expected to work with undefined meaning otherwise. Often the - is interpreted roughly as follows. Since there is no actual reference that defines the meaning, this is what I gathered informally:
- — the argument is an "output argument". Meaning that it will be unified with the resulting term after the goal has been executed. So the argument is steadfast. Often, no error is associated with such an argument.
A more modern document is here:
https://www.swi-prolog.org/pldoc/man?section=modes
There are similar annotations for meta-predicates, which should have meta_predicate directives to ensure that they get modules properly added when being called. https://www.swi-prolog.org/pldoc/doc_for?object=(meta_predicate)/1

Prolog Variable

I have a small problem when we are talking about anonymous variables. For example when we make this:
?- [_,2]=[X|Y].
Y=[2].
but my question is about the variable X. Does it have the '_'?
No, X does not "have the _". It is bound to an anonymous variable, which is never bound to anything else. This binding of X to an anonymous variable does not create any additional limitations on X - for all practical purposes, it remains unbound.
The _ variable has been introduced to let Prolog coders express in code that they do not care about a value in a particular position. One could emulate this behavior by using variables that look like UNUSED1, UNUSED2, UNUSED3 and so on instead of the _, and ignoring Prolog warnings about singleton variables:
[UNUSED123,2]=[X|Y].
Using the underscore _ is like telling Prolog that you know that the unused variable is singleton, and that it is indeed your intention.

Prolog anonymous variable

Here is what I have understood about Prolog variables.
A single underscore stands for anonymous variable, which is like a new variable each time it occurs.
A variable name starting with underscore like _W is not an anonymous variable. Or, the variable names generated inside Prolog, like _G189, is not considered anonymous:
?- append([1,2],X,Y).
X = _G189
Y = [1, 2|_G189]
Could you please help me understand?
By the way, I got the above example from some tutorials, but when I run it in SWI-Prolog version 6, I get the following:
?- append([1,2],X,Y).
Y = [1, 2|X].
Thanking you.
Variables
The anonymous variable _ is the only variable where different occurrences represent different variables. Other variables that start with _ are not anonymous. Different occurrences refer to the same variable (within the same scope). However, many Prologs like SWI will warn you should a variable not starting with an underscore occur only once:
?- [user].
a(V).
Warning: user://1:9:
Singleton variables: [V]
You have to rename that variable to _V to avoid that warning. This is a help for programmers to better spot typos in variable names. There are some more such restrictions in many systems.
a(_V,_V).
Warning: user://1:12:
Singleton-marked variables appearing more than once: [_V]
Again, this is only a warning. If you want that a variable starting with _ should occur twice (without warning), write __ instead. But better stick to more meaningful names without a starting _.
Answers
What you get from Prolog's top level loop are answers ; and in particular answer substitutions. They serve to represent solutions (that's what we are really interested in). There are several ways how answer substitutions may be represented. The tutorial you are using seems to refer to a very old version of SWI. I would say that this version is maybe 15 to 20 years old.
?- append([1,2],X,Y).
X = _G189
Y = [1, 2|_G189]
However, the answer given is not incorrect: A new auxiliary variable _G189 is introduced.
Newer versions of SWI and many other systems try to minimize the output, avoiding auxiliary variables. So
?- append([1,2],X,Y).
Y = [1, 2|X].
is just as fine. It is the answer of a "newer" version (also some 6 years old). Note that this answer tells you much more than the first one: Not only does it show you the answer substitution more compactly, but it also tells you that there is exactly this one answer (and no more). See the dot . at the end? This means: There is no more here to answer. Otherwise there would be a ; for the next answer.

warning in prolog

I wrote this predicate in prolog :
list([]).
list([X|L]) :- list(L).
it works well, but I got this warning :
**Warning: /Users/hw6.pl:2:
Singleton variables: [X]** %
what I can do to avoid it ?
The warning tells you that you have a variable used only once in that clause of the predicate list (in this case the second clause).
Why does it warns you of this ? Because it is more than often that you have misspelled the variable name. The resulting code when you misspell a variable is also a valid prolog program, so debugging would be painful if it does not warn you.
If you are not going to use that variable (X), you can use an anonymous variable instead.
To use an anonymous variable you have to use _ as the term instead of a variable name.
In your example it would be:
list([]).
list([_|L]) :- list(L).
Gusbro is exactly right. When you use a variable only once you will get a singleton variable. Your program is still syntactically correct, but prolog assumes you made a mistake typing your code. The underscore variable will always unify as true if it is given any answer.

Resources