What does the / slash mean in this Prolog Predicate - prolog

Would anyone be able to explain to me what the forward slash '/' means in the context of this Prolog predicate. I've tried Googling it, reviewing other questions but I can't find a definitive answer, or at least one that makes sense to me. I'm aware of what arity is but I'm not sure this is related.
move_astar([Square | Path] / G / _, [NextSquare, Square | Path] / SumG / NewH) :-
square(Square, NextSquare, Distance),
not(member(NextSquare, Path)),
SumG is G + Distance,
heuristic(NextSquare, NewH).

It has no implicit meaning, and it is not the same as arity. Prolog terms are name(Arg1, Arg2) and / can be a name. /(Arg1, Arg2).
There is a syntax sugar which allows some names to be written inline, such as *(X,Y) as X * Y and /(X,Y) as X / Y which is useful so they look like arithmetic (but NB. this does not do arithmetic). Your code is using this syntax to keep three things together:
?- write_canonical([Square | Path] / G / _).
/(/([_|_],_),_)
That is, it has no more semantic meaning than xIIPANIKIIx(X,Y) would have, it's Ls/G/H kept together.

The / has no meaning here, except for being a structure and a left associative operator. So it is unrelated to division. Sometimes people like to add such decoration to their code. It is hard to tell if this serves anything from that single clause, but think of someone who just wants to refer to the list and the two values like in:
?- start(A), move_astar(A,A).
So here it would be much more compact to ask that question than to hand over each parameter manually.
Another use would be:
?- start(A), closure(move_astar, A,B).
Using closure/2. That is, existing predicates may expect a single argument.

It's an outdated style. It's bad because:
It conveys no useful information, apart from being a weird-looking delimiter
There's a slight performance hit for Prolog having to assemble and re-assemble those slash delimiters for parsing
It's better to either:
Keep parameters individual (and therefore fast to use)
Group parameters in a reasonably-named term, or e.g. v if brevity is more appropriate than classification of the term

Related

How does = operator works in Prolog

Sorry if this is a newbie question, but recently I was trying to compare an string and I used this (not exactly :P):
some_fact('Yes').
some_fact('No').
some_rule(X):- some_fact(X), (X =:= 'Yes' -> writeln("ISS YES") ; writeln("No")).
Error: Arithmetic: `'Yes'' is not a function
After that, I Googled and saw that Strings are compared with = and \=
But if I write: X = 5 I'm assigning the value 5 to X, well I don't know if the word is assign, cause the assigment operator is is. Right?
Just in case, I don't need to fix the code, I want understand what's happening.
Thanks
I think there is a lot of confusion here and most of it would be remedied by going through a book, but let me try and clear a few things up for you right now.
'Yes' is an atom, not a string. SWI-Prolog has actual strings, but most Prolog implementations do not, they use atoms instead. The nice thing about atoms is that if they are lower case and do not contain spaces there is no need for quotes. The quotes are needed to tell Prolog "this is not a variable" and resolve the syntactic ambiguity of this and that.
Lacking strings, there is no operator for string comparison.
= is the unification operator. Unification is a big topic—not something that is easily summarized in a question, but as an approximation you can think of it as a bi-directional pattern matching. So, it will do the job for what you probably need string comparisons for, but it is the real engine of computation in Prolog and is happening behind the scenes in lots of ways.
Prolog does not have assignment. True, you can give a variable a value. But you cannot change that value later; X = X + 1 is meaningless in mathematics and it's meaningless in Prolog too. In general, you will be working recursively, so you will simply create a new variable when something like this needs to occur. It will make more sense as you get further in reading about Prolog and writing your first programs. Please check out a tutorial!
is/2 resolves arithmetic expressions. If you have X = 2+3, Prolog will reply with X = 2+3. Only X is 2+3 will cause Prolog to report X=5. Arithmetic just isn't a huge part of classic Prolog usage; these days, people will quickly suggest you check out CLPFD, which enables you to do more interesting things like 15 #= X + Y and producing bindings that add up to 15. Standard Prolog cannot "work backwards" like this. But for a complete beginner it probably suffices to say that arithmetic works differently than you expect it to, and differently than the rest of Prolog unless you use CLPFD.
=:= is an arithmetic equality operator. You use this to answer questions like 6 + 1 =:= 5 + 2. This is a really special-purpose tool that I personally have never really needed to use.

How to identify wasteful representations of Prolog terms

What is the Prolog predicate that helps to show wasteful representations of Prolog terms?
Supplement
In a aside of an earlier Prolog SO answer, IIRC by mat, it used a Prolog predicate to analyze a Prolog term and show how it was overly complicated.
Specifically for a term like
[op(add),[[number(0)],[op(add),[[number(1)],[number(1)]]]]]
it revealed that this has to many [].
I have searched my Prolog questions and looked at the answers twice and still can't find it. I also recall that it was not in SWI-Prolog but in another Prolog so instead of installing the other Prolog I was able to use the predicate with an online version of Prolog.
If you read along in the comments you will see that mat identified the post I was seeking.
What I was seeking
I have one final note on the choice of representation. Please try out the following, using for example GNU Prolog or any other conforming Prolog system:
| ?- write_canonical([op(add),[Left,Right]]).
'.'(op(add),'.'('.'(_18,'.'(_19,[])),[]))
This shows that this is a rather wasteful representation, and at the same time prevents uniform treatment of all expressions you generate, combining several disadvantages.
You can make this more compact for example using Left+Right, or make all terms uniformly available using for example op_arguments(add, [Left,Right]), op_arguments(number, [1]) etc.
Evolution of a Prolog data structure
If you don't know it already the question is related to writing a term rewriting system in Prolog that does symbolic math and I am mostly concentrating on simplification rewrites at present.
Most people only see math expressions in a natural representation
x + 0 + sin(y)
and computer programmers realize that most programming languages have to parse the math expression and convert it into an AST before using
add(add(X,0),sin(Y))
but most programming languages can not work with the AST as written above and have to create data structures See: Compiler/lexical analyzer, Compiler/syntax analyzer, Compiler/AST interpreter
Now if you have ever done more than dipped your toe in the water when learning about Prolog you will have come across Program 3.30 Derivative rules, which is included in this, but the person did not give attribution.
If you try and roll your own code to do symbolic math with Prolog you might try using is/2 but quickly find that doesn't work and then find that Prolog can read the following as compound terms
add(add(X,0),sin(Y))
This starts to work until you need to access the name of the functor and find functor/3 but then we are getting back to having to parse the input, however as noted by mat and in "The Art of Prolog" if one were to make the name of the structure accessible
op(add,(op(add,X,0),op(sin,Y)))
now one can access not only the terms of the expression but also the operator in a Prolog friendly way.
If it were not for the aside mat made the code would still be using the nested list data structure and now is being converted to use the compound terms that expose the name of the structure. I wonder if there is a common phrase to describe that, if not there should be one.
Anyway the new simpler data structure worked on the first set of test, now to see if it holds up as the project is further developed.
Try it for yourself online
Using GNU Prolog at tutorialspoint.com enter
:- initialization(main).
main :- write_canonical([op(add),[Left,Right]]).
then click Execute and look at the output
sh-4.3$ gprolog --consult file main.pg
GNU Prolog 1.4.4 (64 bits)
Compiled Aug 16 2014, 23:07:54 with gcc
By Daniel Diaz
Copyright (C) 1999-2013 Daniel Diaz
compiling /home/cg/root/main.pg for byte code...
/home/cg/root/main.pg:2: warning: singleton variables [Left,Right] for main/0
/home/cg/root/main.pg compiled, 2 lines read - 524 bytes written, 9 ms
'.'(op(add),'.'('.'(_39,'.'(_41,[])),[]))| ?-  
Clean vs. defaulty representations
From The Power of Prolog by Markus Triska
When representing data with Prolog terms, ask yourself the following question:
Can I distinguish the kind of each component from its outermost functor and arity?
If this holds, your representation is called clean. If you cannot distinguish the elements by their outermost functor and arity, your representation is called defaulty, a wordplay combining "default" and "faulty". This is because reasoning about your data will need a "default case", which is applied if everything else fails. In addition, such a representation prevents argument indexing, and is considered faulty due to this shortcoming. Always aim to avoid defaulty representations! Aim for cleaner representations instead.
Please see the last part of:
https://stackoverflow.com/a/42722823/1613573
It uses write_canonical/1 to display the canonical representation of a term.
This predicate is very useful when learning Prolog and helps to clear several misconceptions that are typical for beginners. See for example the recent question about hyphens, where it would have helped too.
Note that in SWI, the output deviates from canonical Prolog syntax in general, so I am not using SWI when explaining Prolog syntax.
You could also programmatially count how many subterms are a single-element list using something like this (not optimized);
single_element_list_subterms(Term, Index) :-
Term =.. [Functor|Args],
( Args = []
-> Index = 0
; maplist(single_element_list_subterms, Args, Indices),
sum_list(Indices, SubIndex),
( Functor = '.', Args = [_, []]
-> Index is SubIndex + 1
; Index = SubIndex
)
).
Trying it on the example compound term:
| ?- single_element_list_subterms([op(add),[[number(0)],[op(add),[[number(1)],[number(1)]]]]], Count).
Count = 7
yes
| ?-
Indicating that there are 7 subterms consisting of a single-element list. Here is the result of write_canonical:
| ?- write_canonical([op(add),[[number(0)],[op(add),[[number(1)],[number(1)]]]]]).
'.'(op(add),'.'('.'('.'(number(0),[]),'.'('.'(op(add),'.'('.'('.'(number(1),[]),'.'('.'(number(1),[]),[])),[])),[])),[]))
yes
| ?-

Predicate for removing certain terms from compound term in Prolog

I would like to write a Prolog predicate that takes in a compound term as its argument and outputs this compound term with some of the nested terms removed. For example, let's say that I have a compound term:
outer_term(level_one(level_two_a(X), level_two_b(Y)), level_one(level_two_b(Z))).
And I would like to write a predicate extract_terms/2 which would take this term and returned it without occurences of level_two_a/1.
extract_terms(Term, ExtractedTerm) :-
*** Prolog Magic ***.
Is there a built-in (or semi-built-in) way to do this in Prolog? If not, how would I go about doing this? One way that occurs to me would be to use =../2 operator to convert the Term into a list and then somehow use some built-in predicate like subtract/3 to get rid of the predicates that I want. The trouble I have is making this work with list that has nested terms as its items.
I would appreciate any ideas, thank you.
First, a general guideline:
Everything that can be expressed by pattern matching should be expressed by pattern matching.
You have asked a similar question previously, although it was a bit simpler. Still, let us consider the simpler case first: You said a possible instance of a verb phrase would be:
VP = vp(vp(verb(making), adj(quick), np2(noun(improvements))))
and you want to extract the verb. Well, the simplest approach is to use pattern matching, or more generally, unification, like this:
?- VP = vp(vp(verb(making), adj(quick), np2(noun(improvements)))),
VP = vp(vp(Verb, _, _)).
This yields:
Verb = verb(making).
Thus, we have successfully "extracted" verb(making) from such a phrase by virtue of unification.
Now to the slightly more complex task you are considering in this question: At this point, you may wonder whether you have chosen a good representation of your data. Frequent use or even the very necessity of (=..)/2 typically indicates a problem with your representation, since it may mean that you have lost track or control of the possible shapes of your data.
In this concrete case, you state as an example:
outer_term(level_one(level_two_a(X), level_two_b(Y)), level_one(level_two_b(Z))).
and you want to remove occurrences of level_two_a. You can now of course begin to mess with (=..)/2, which requires a conversion of such terms to lists, then some reasoning on these lists, and a second conversion from lists back to such structures. That's not how we want to work with our data. In addition to other drawbacks, it would preclude more general usage patterns that we expect from relations.
Instead, let us fix the data representation so that we can cleanly distinguish the different cases. For example, instead of "hardcoding" the very parameter we need to distinguish the cases inside of a functor, let us make the distinction explicit: We want to be able to distinguish, by pattern matching, level 1 from level 2.
So, the following representation suggests itself:
outer_term([level(1, [level(2, X),
level(2, Y)]),
level(1, [level(2, Z)])]).
This may need some additional attributes, such as a and b, and I leave extending this representation to represent such attributes as an easy exercise. The general idea should be clear though: We have thus achieved a uniform representation about which we can easily reason symbolically.
It is now easy to describe the relation between a (potentially nested) list of such levels and the levels without the "level 2" elements:
without_level_2(Ls0, Ls) :-
phrase(no_level_2(Ls0), Ls).
no_level_2([]) --> [].
no_level_2([L|Ls]) -->
no_level_2_(L),
no_level_2(Ls).
no_level_2_(level(2,_)) --> [].
no_level_2_(level(L,Ls0)) --> [level(L,Ls)],
{ dif(L, 2),
without_level_2(Ls0, Ls) }.
See dcg for more information about this formalism.
Sample query:
?- outer_term(Ts0),
without_level_2(Ts0, Ts).
Yielding:
Ts = [level(1, []), level(1, [])] .
Note that to truly benefit from this representation, you need to obtain it in the first place by using or generating terms of such shapes. Once you have this ensured, you can conveniently stick to pattern matching to distinguish the cases. Among the main benefits of this approach we find convenience, performance and generality. For example, we can use the DCG shown above not only to extract but also to generate terms of this form:
?- length(Ls0, _), without_level_2(Ls0, Ls).
Ls0 = Ls, Ls = [] ;
Ls0 = [level(2, _56)],
Ls = [] ;
Ls0 = Ls, Ls = [level(_130, [])],
dif(_130, 2) ;
Ls0 = [level(_150, [level(2, _164)])],
Ls = [level(_150, [])],
dif(_150, 2) .
This is truly a relation, usable in all directions. For this reason, I have avoided imperative names like "extract", "remove" etc. in the predicate name, because these always suggest a particular direction of use, not doing justice to the generality of the predicate.

Structure (Difference Lists) Prolog

This question refers to the material in chapter 3 of the book:
Programming in Prolog, Clocksin and Mellish, Ed 5
In page 72 of this book, a program using difference list is displayed:
partsOf(X,P):- partsacc(X,P,Hole) , Hole=[].
partsacc(X,[X|Hole],Hole):-basicpart(X).
partsacc(X,P,Hole):- assembly(X,Subparts), partsacclist(Subparts, P, Hole).
partsacclist([],Hole,Hole).
partsacclist([P|T], Total, Hole):- partsacc(P,Total,Hole1), partsacclist(T,Hole1,Hole).
In many tutorials online, the following format of using the "-" is used, for example::
append([ A , B , C | R1 ] – R1 , [ D , E | R2 ] – R2 , R3)
My questions are:
What is the difference between these two representations (Using - and not using it)
In which situations it is best to use each of them?
Thanks
By all means: Do not use (-)/2 or (\)/2 or any other operator to represent "difference lists". The reason is that you will often have a predicate with one list argument and an internal predicate that uses a difference list. With both having the same arity and probably also the same name, things will get confusing. Even worse, it might work for "some cases". Also, that operator will incur some cost you can avoid with two separate arguments.
Try to stick to a clean naming convention. That is S0, S1 ... S. In this manner the arguments representing the difference list will be easily visible. To better underline that those arguments belong together, some people do not use a space after the separating comma, whereas they use it for other arguments. Thus:
p(L+R, S0,S) :-
p(L, S0,S1),
p(R, S1,S).
Further, the (-)/2 has another meaning in Prolog. It is used to represent a pair Key-Value, as in keysort/2.
Any Prolog book I know suggesting an operator for difference lists comes from the 1980s.
I agree with what Boris said (+1) regarding the different representations. Moreover, this is in my opinion clearly a case where you should use DCGs instead of encoding list differences explicitly. Consider for example the following version of the code:
parts(X) --> { basicpart(X) }, [X].
parts(X) --> { assembly(X, Parts) }, assembly_(Parts).
assembly_([]) --> [].
assembly_([X|Xs]) --> parts(X), assembly_(Xs).
Usage, after defining assembly/2 and basicpart/1 exactly as in your example:
?- phrase(parts(X), Ls).
The DCG has a clear declarative and easy to read interpretation, and requires fewer arguments.
My experience in Prolog is limited, but it seems that older texts tend to use either the - or another character (for example \) to denote the list and its tail. Newer Prolog code always uses two arguments (as in your first example). For example, all built-in and library predicates in SWI-Prolog consistently use two separate arguments.
In theory, there is no difference which style you prefer. I guess it doesn't hurt to be consistent about it in your own code.
In practice, the difference is that instead of a compound term holding two lists in one single argument you have two arguments, which should be a more efficient representation.
EDIT
Make sure to also read the answer by #false.

Knowing when to use cut in prolog

I've took a course in which I learned some prolog. I couldn't figure out how / when to use cuts. Even though I get the general idea of cuts, I can't seem to use them properly.
Can anyone explain it briefly or give a good tutorial (that's not learnprolognow.org) on "cuts" that they can recommend?
TL;DR: Don't.
The cut prunes Prolog's search tree. That is, given a pure Prolog program without cut and the same program with cuts the only difference is that the program with cuts might spend less time in fruitless branches, and thus is more efficient ; might have fewer answers ; it might also terminate whereas the original program doesn't.
Sounds pretty harmless ... or even useful, doesn't it?
Well, most of the time things are more complex.
Red cuts
Cuts are often used in a way such that the program without cuts has no sensible meaning at all. Such cuts are called red cuts. In the better cases it is used to implement a crude form of non-monotonic negation. And in some other cases it is half negation, half some procedural meaning that is very difficult to understand. Not only for the reader of the program but also for its writer. In fact, often such uses unintentionally lack steadfastness. In any case: these cuts are not placed into an existing program. They are meant to be in that program right from the beginning.
For the more structured uses of such red cuts, better use once/1, (\+)/1, or (;)/2 – if-then-else like ( If -> Then ; Else ) instead. Even better, try to guard such constructs against unintended uses by issuing instantiation_errors. Or use iwhen/2 which produces instantiation errors or when/2 (offered in SWI, YAP, SICStus) which delays goals.
Green cuts
Cuts that remove useless choicepoints (and also redundant answers) are called green cuts. But beware: You cannot place them into your program simply pressing ! and some #00ff00. Most of the time you need a clean read-only guard to ensure that there is no way this cut turns #ff0000. There is also a simple way to remove some leftover choicepoints safely: call_semidet/1. Here are some related cases:
What's the SLD tree for this query?
Prolog append with cut operator
What are the optimal green cuts for successor arithmetics sum?
Implementing "last" in Prolog
Cut is not commit
Finally, let me point out that cut is not a commit-operator. It sometimes acts a bit like it, but would need lots of restrictions to be one. A commit-operator cannot be (ab)used to implement (\+)/1. A commit requires that each clause is tried independently of each other. Each clause thus needs a full guard ; it cannot rely on being tried only after some other clauses have been tried first. Also, a commit would have to occur in each clause of a predicate. The cut can occur anywhere.
A cut commits the Prolog goal being proved to the choices done.
It must be used then when the programmer knows that any alternative available must not be tried.
The most prominent use it's the implementation of negation by failure.
fact(a).
fact(b).
/* 1 */ neg(X) :- call(X), !, fail.
/* 2 */ neg(_).
Here I've (re)defined the standard negation operator, normally it's (\+)/1
?- neg(fact(c)).
true.
call(fact(c)) by rule 1 can't be proved, and the alternative rule 2 then succeeds.
?- neg(fact(a)).
false.
because fact(a) can be proved, the cut discard the alternative before failing.
?- neg(fact(X)).
false.
there exist at least an unknown X such that fact(X) succeed.
?- neg(neg(fact(X))).
true.
the double negation has the effect that variables don't get bound. This can be useful when doing meta programming, to fetch clauses without altering their 'structure'. From the operational viewpoint, it's clear (?) what's going on, but the program does lose its declarative property.
Another use, useful only in rudimentary interpreters, was to instruct the system to perform last call optimization, prefixing the recursive call with a cut. Then the system can avoid to allocate the stack space normally required to keep track of alternative point. A dummy example:
print_list([E|Es]) :- print_element(E), !, print_list(Es).
print_list([]).
edit about a tutorial: I found that 'Clause and Effect' by William Clocksin contains a detailed survey related to cut: chapter 4 'Choice and Commitment' it's fully devoted to cut pros and cons. At bottom line, mainly cons...
Before using a cut, I require that my predicates meet these two criteria:
it gives correct answers without a cut
it gives correct answers if clauses are reordered
Once my predicate behaves that way, I sometimes add a cut to trim away unwanted nondeterminism.
For example, a predicate to test whether a number is positive, negative or zero.
sign(N, positive) :-
N > 0.
sign(N, negative) :-
N < 0.
sign(N, zero) :-
N =:= 0.
Each clause stands completely independent of the others. I can reorder these clauses or remove a clause and the remaining clauses still give the expected answer. In this case, I might put a cut at the end of the positive and negative clauses just to tell the Prolog system that it won't find any more solutions by examining the other clauses.
One could write a similar predicate without cut by using -> ;, but some dislike how it looks:
sign(N, Sign) :-
( N > 0 -> Sign=positive
; N < 0 -> Sign=negative
; Sign=zero
).
Cuts all but disappeared from my code once I found the once predicate. Internally it acts like
once(X) :- X, !.
and I found it very useful for making a firm decision on how to do something before I did that something.
For example, here is my standard meta-interpreter. The maybe1/1 clause has unique functors in its arguments so once they known, then the right maybe1/1 can be selected, perfectly.
The job of finding that unique function is given to the maybe0/2 pre-processor that sets Y to a "what to do statement" about X.
Without once, this could would have to be riddled with cuts. E.g. in maybe1, there are three/two different interpretations of X/Y,and or that we need to check in a top down manner. But check it out- no cuts.
maybe(X) :-
once(maybe0(X,Y)), maybe1(Y).
maybe0(true, true).
maybe0((X,Y), (X,Y)).
maybe0((X;Y), or(L)) :- o2l((X;Y),L).
maybe0(X, calls(X)) :- calls(X).
maybe0(X/Y, fact(X/Y)) :- clause(X/_, true).
maybe0(X/Y, rule(X/Y)) :- clause(X/_,_).
maybe0(X/Y, abducible(X/Y)).
maybe0(or([H|T]), or([H|T])).
maybe0(or([]), true).
maybe1(true).
maybe1((X,Y)) :- maybe(X),maybe(Y).
maybe1((X;Y)) :- maybe(X);maybe(Y).
maybe1(abducible(X)) :- assume(X,0).
maybe1(fact(X)) :- assume(X,1), one(X).
maybe1(rule(X)) :- assume(X,2), one(clause(X,Y)), maybe(Y).
maybe1(calls(X)) :- one(clause(X,Y)), maybe(Y).
maybe1(or([H|T])) :- any(One,Rest,[H|T]), ignore(maybe(One)), maybe(or(Rest)).
Cut predicate prevents backtracking.Cut predicate is specified as an exclamation point (!). Cut prunes the search tree and shortens the path track by prolog interpreter.Semantically it always succeed.
read(a).
read(b).
color(p, red) :- red(p).
color(p,black) :- black(p),!.
color(p,unknown).
?-color(X,Y).
X = a,
Y = red;
X = b,
Y = black;
Without cut the goals shows Y=unknown after Y=black.
There are two types of cut predicate :
Green Cut : Green cut is one type of cut which had no effect on the declarative meaning. It is only use to improve efficiency as well as avoid unnecessary computation. The removal of green cut from the program does not changes the meaning of the program.
Red Cut : Red cut is one which had effect on the the declarative meaning. The removal of red cut from the program changes the meaning of the program.

Resources