It's not crazy to subscribe to the SWI-Prolog mailing list and post your questions hoping for help. I've been helped out on some REALLY ignorant questions ---embarrassing, but my ego is still intact (barely).
I don't know where this tradition of single-character identifiers came from, but it certainly makes the 5th edition of the Prolog book unnecessarily opaque, since the authors reuse the same variable name with different semantics a lot, sometimes between a code example and the prose describing it.
There are a few misprints in the 5th Ed. Ones I've found (please tell me of others you find).
The soi-disant index would be a joke if it weren't criminal negligence. The authors and editor should have their asses thoroughly kicked.
Line Editing: Sometimes the normal command-line editing you expect (repeat last command, edit the current command line...) works for me, sometimes it doesn't. Must be some sort of system preference. Anyway it *can* be made to work I'm sure.
In the meantime, a stopgap is to put test code into a file you can easily edit. Then you have to consult it but retyping the consult might be easier than editing the 'input' of the test. For instance
phrase(expr(PTree), [a , * , '(' , 3 , + , 4 , ')', - , 3 , '/' , 2],),
is one way to test the parser and evaluator from the Prolog assignment; to modify the input just edit the list of atoms.
Consulting: I have a burning fatal urge to type rules at Prolog.
For instance I got confused
and in trouble when I tried to use the "-->" operator at the
interactive level. --> indicates a rule and therefore must be
"consult"ed. So this consulting step detracts from the
interactive nature of the Prolog experience.
refer to files in single quotes. I use
to read in clauses from the file file.pl .
Don't forget the period at the end of clauses!!
Don't forget ONLY variables can start with a capital, and they MUST!!
Syntax checking. There certainly could be more helpful syntax checking
Prolog doesn't catch all sorts of easy to make errors. Like
misspelling: if you type Myop for MyOp, or (God forbid)
myop for MyOp, things just fail. You just see
for failing match. To be fair, some misspellings are caught and corrections suggested.
Other typos: the three lines below are all wrong,
and I don't think you get a lot of help from Prolog in
nailing down the problems....
pl([H|T, foo, bar).
pl([H|T]), foo, bar).
pl([H|T), foo, bar).
When things are caught, the diagnosis isn't too user-friendly (Quickie! What's wrong with line 11?)
11 ?- phrase (expr(V), [1, *, 1],).
ERROR: Syntax error: Operator expected
ERROR: phrase (expr(V), [1, *, 1],
ERROR: ** here **
ERROR: ) .
The problem is the Prolog parser got off when it saw the space after 'phrase' and blew up somewhere in your arglist looking for God knows what. Notice that the '** here **' indicator is NOT under the problem but is interpolated into the line where the parser blew up, so the location is right after '....],'. The remainder of the line is below the ** here **.
Obviously then, another Prologism is that you always have to cram the functors right up against the (...) of the arguments. So foo(bar) is OK but foo (bar) is probably an error as above.
Cute? You Douglas Adams fans may be amused.
To 'assign' a variable, you put it into a clause as an
argument to be bound by unification. There's nothing like
Ans = op(Arg1, Arg2) .
Instead, you write
op(Arg1, Arg2, Ans).
Thus a "program", or sequence of actions or subroutines, passing results along for further computation, might just look like this:
myprog(MyAnswer) :- first(3.14, FirstResult), second(FirstResult, Whatever, SecondResult), final(SecondResult,MyAnswer).
Some simple library routines don't seem to be in place for me, e.g. random/1. It may be that this is part of the clib library, which looks quite useful (supports sockets, for instance -- pre-442 students take note!).
Standard Prolog isn't great with I/O. Normal scanners and tokenizers etc aren't standard. You can copy code out of the book, and I'm sure there are libraries or packages you can find, but I've found it easier pre-tokenize input, so for input I'd use a list of atoms like [a, +, 5] rather than a string ``a+5'', say.
Tracing is, for me, often not all that helpful. It does tell you whether something is going wrong immediately or if you make a bunch of inferences before things die, and you can maybe figure out what is misbehaving. When I use ``;'' to re-satisfy for more answers, it seems that trace won't trace the re-satisfaction process. (Am I missing something?).
Warning: Predicting backtracking behavior is very mysterious. At least *my* prediction of what is going to be re-tried are mostly wrong, and wrong in ways I can't immediately explain. Best if your code does not rely on fine detail in backtracking choices.
A common warning is for ``singleton variables''. They are ones that appear only once in a clause, so can be replaced by _, or _Varname. Since they can't have their value changed, Prolog thinks you might have mistyped something. Actually, for me, often it's right!