Question mark, plus, minus preceding Prolog variable names - prolog

I've searched for an explanation to this but haven't found one. What do the question mark, plus sign, and minus sign that sometimes precede variable names in the description of a Prolog predicate mean?
Example:
predicate(?Variable1,+Variable2,-Variable3)

? means: This variable can be either instantiated or not. Both ways are possible.
+ means: This variable is an input to the predicate. As such it must be instantiated.
- means: This variable is an output to the predicate. It is usually non-instantiated, but may be if you want to check for a specific "return value".
Source: Chapter 4 of the SWI Prolog documentation.

+ means that Variable2 is expected to be bound (to a term, or perhaps just some variable) -- you can think of this as input to predicate/3, which the predicate won't attempt to modify in execution.
- means that Variable3 is expected to be bound by predicate/3 in it's execution -- you can think of this as output from predicate/3. This doesn't mean it can't be bound, however, particularly if you know what to expect and are checking for success, but predicate/3 is described as potentially binding (unifying) Variable3 to something.
? means that Variable1 can be either be bound (+, input) or not (-, output) - predicate/3 should deal with both cases, if it accepts either.

Related

What is the meaning of a double slash `//` after the predicate name in Prolog, appearing in the context of DCGs?

Some "predicate indicators" (this is the ISO Standard terminology for a syntactic name/arity expression denoting a predicate or functor (both of these terms are equivalent) are not content with a single slash, but actually take two. This always occurs in the context of DCGs. Examples:
syntax_error//1: "Throw the syntax error Error at the current location of the input. This predicate is designed to be called from the handler of phrase_from_file/3."
js_expression(+Expression)//: "Emit a single JSON argument."
According to the recent drafts WDTR 13211-3 (3.19) this is called a non-terminal indicator. Similar to a predicate indicator (3.131) it is used to denote one particular non-terminal.
Note that most implementations translate a non-terminal nt//n to a predicate nt/n+2. You cannot rely on the precise way of translation, though. And thus the outcome of calling a non-terminal directly by calling the corresponding predicate, that is, with the same name and two extra arguments is not defined. In particular the second additional argument has to be handled with care. A direct use might violate steadfastness, in particular when using dcg-semicontext.
What is the meaning of a double slash // after the predicate name in Prolog, appearing in the context of DCGs?
It is used by the term rewrite system of Prolog (SWI-Prolog src), but for a person it lets you know that the predicate is a DCG and has two hidden arguments added to the end of the predicate.
For example here is a very simple DCG that has 1 visible argument.
simple_dcg(X) -->
{ X is 1 + 2 }.
When the listing is seen
?- listing(simple_dcg).
simple_dcg(X, A, B) :-
X is 1+2,
B=A.
true.
the two extra hidden arguments (A, B) appear.
If you have been following my EDCG questions on SWI-Prolog forum then you know it can get much more complicated.

What do these mean in prolog?

First when I read up on different predicates on Prolog, like for example http_server, it's written like this: http_server(:Goal, +Options) what does : and + mean here? Sometimes ? is also written.
Secondly sometimes I see variables declared with an underscore before them like _Request, even though there isn't any another Request, why is that?
The +, -, : etc. sigils are called mode declarations. They describe the expected instantiation of predicate arguments, i.e., whether you are expected to call the predicate with an unbound variable, an instantiated term, etc. These are not completely standardized; here is a description of the conventions for SWI-Prolog: http://www.swi-prolog.org/pldoc/man?section=modes
As a first approximation, a + argument is an input to the predicate, you are supposed to provide a ground term. A - argument is an output of the predicate, the predicate will try to unify it with a term. A ? term may be partially instantiated at the call, and the predicate may instantiate it further. A : argument is a meta-argument, i.e., it is a goal to be called by the predicate (as in setof/3, for example).
In the example of http_server(:Goal, +Options), you are supposed to call this predicate with the first argument bound to a goal, probably a predicate name. The second argument must be instantiated, presumably to a list whose format is further described in the documentation. If you do not call this predicate like this, for example, if you pass an unbound variable as the second argument, you might get unexpected behavior or an instantiation error.
As for your second question (which would better have been separate), a variable that begins with an underscore is called an anonymous variable. Every such variable may only occur once per clause, except _ itself, which may occur several times and refers to separate variables at each occurrence.
Prolog systems usually emit a "singleton variable" warning for non-anonymous variables that occur only once, because those might be typos or a sign the programmer forgot something. You use anonymous variables to express the notion that "there must be something here (e.g., a predicate argument), but I don't care what it is". In your example, presumably you call a predicate that has a "request" argument, but in your particular use case you don't care about the request.

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: what is the - prefix in predicates / variables?

Example:
conditions([-on(a, b)]).
I have searched tirelessly but fruitlessly for the meaning of this and the + prefix. You are my last hope.
No context is provided, so I'm supposing this might come from something in documentation.
If you read the introductory material in the Prolog manual (SWI, Gnu, or whichever) they describe teh conventions. The +, -, and ? are used as a convention in documentation to indicate whether an variable is an input or an output or a variable (either). For example, from the Gnu Prolog manual:
+: the argument must be instantiated.
-: the argument must be a variable (will be instantiated if the built-in predicate succeeds).
?: the argument can be instantiated or a variable.
So, for example, atom_length/2 is described as;
atom_length(+atom, ?integer)
Which means you must provide atom (it can't be a variable) and integer can either be a variable (in which case atom_length will provide a value) or it can be instantiated (in which case atom_length will indicate whether your query is true or false)`.
You don't normally use the - or + in your code in this sense, unless you really intend to have it there as part of your term. Considering the given example, it looks like it may have been an intended part of the term:
conditions([-on(a, b)]).
The list parameter consists of a term, when spelled out fully, is -(on(a,b)) (-/1 with parameter that's on/2). The - here doesn't provide any function, it just adds structure (the structure being a term with name - and parameter on(a,b)).

Variables and how they are set and used in prolog

http://www.csupomona.edu/~jrfisher/www/prolog_tutorial/2_1.html
So on that tutorial where it has:
conflict(Coloring) :-
adjacent(X,Y),
color(X,Color,Coloring),
color(Y,Color,Coloring).
Am I understanding this correctly, that Color is a variable and is set to a value after the first call to color and then that value is used in the second call to color?
Variables in Prolog:
All variables and arguments are local in scope to the predicate in which they are declared (aka first used). Excepting of course that variables may be passed as arguments (essentially "by reference") to another predicate.
Prolog variables are only "variable" until bound (unified) with something else. At that point they cease to be variable and become one with that with which they were unified. Hence the use of the term "unification": to unify is to become one.
Backtracking, of course, undoes any unification that might have occurred, returning things to the status quo ante as it were.
The special variable _ is the "anonymous variable". Each use, even within the same clause of a predicate is independent. For instance, given the facts
letter(a).
letter(b).
letter(c).
digit(1).
digit(2).
digit(3).
the predicate:
foo :- letter(A),number(A).
fails, whilst
foo :- letter(_),number(_).
will succeed (9 times, with backtracking).
Color it's a variable, but we can't say if it will get a value (in Prolog this is called binding) from the first or the second call to color/3. All depends on the color/3 definition. But given this code it's probable that your assumption it's ok.

Resources