Advice for people learning Modern, Declarative Prolog from older texts

I was re-reading some Prolog code I wrote awhile back, when I was learning from older texts (ie. Covington’s Prolog Programming in Depth).

I was writing a simple web scraper for bitcoin price data, and this is what I came up with. It worked, and I realized how general a Prolog program could be.

I want to start moving all of my “scripting” tasks that I might use Perl or Python for, over to Prolog, but it seems that there are a number of new, more declarative methods that were not described in the texts available to me.

Some things I wish I knew back then:

  1. Constraints are fundamental to declarative Prolog – much more than older texts might lead one to believe. Markus Triska, for example, recommends using CLP(FD) or CLP(\mathbb{Z}) vs. Prolog built-in arithmetic (link). That is something I would not have figured out myself.

  2. DCG notation for pure input. What about pure output?

Are there any other patterns or program cliches I should know about? Is there anyone working on something like a “Prolog Cookbook” – ie. simple code samples on common tasks?

1 Like

See: Wiki Discussion: Generating Cytoscape.js graphs with SWI-Prolog
Note that the code is just proof of concept code, it still has many ways to be improved.

Also check out code using pharse/2 in the SWI-Prolog repositories on GitHub. I know most of it is for parsing but some of it is for generating.


There are many noted in
The Craft of Prolog by Richard A O`Keefe (WorldCat)

One should read all of the forum post here and in the previous places this forum was hosted. I can’t remember them all but for a while it was on Google Groups.

Check out the SWI-Prolog packages.

Personally I don’t think of Prolog as a programming language but a modelling language for problem solving. I also consider about 2/3 of what is built-in to SWI-Prolog to be models for solving problems, e.g. constraints, DCGs, tabling, → (single sided unification), is/2, EDCGs, term rewriting, etc.


Yes. It never went very far.

There is a post on this site from some months back noting how to contribute pull request to the SWI-Prolog documentation that would be the best way to add such items. I can’t find the topic but I know that @Boris did some and should be able to point the way.

1 Like

The way I understood it, that was about demonstrating how to use some of the library predicates. I did contribute a few examples, for the end result, see length/2, atom/1, string/1, and so on. Those examples are in their own repo, plweb-examples. The documentation system integrates them with the docs on the SWI-Prolog website.

Those examples were meant for a different purpose: demonstrate how a certain standard library predicate is useful, with a self-contained, simple example. This fills the void that a technical, correct documentation sometimes leaves, in terms of “but how is that really supposed to be used”. It definitely doesn’t address the question of “how do I solve a class of similar problems using idiomatic Prolog”.

(your link there is broken, btw, the correct link: https://www.metalevel.at/prolog/clpz)

In some cases this is a good approach, and it other cases it isn’t. It might depend on the person, too, I personally am sometimes not good enough to strictly follow the scripture on topics like declarative programming or pure Prolog and the like.

Constraints in particular are very useful in some situations and not so useful in others, in my opinion. I guess the best advice I can give is continue trying things out until you develop your own judgement.

4 Likes

The idea behind put input is to be able to run DCG’s over input streams without first materializing them to a list. The original implementation by Ulrich Neumerkel did this using an attributed variable at the tail of the list that reads the next fragment from the stream. Backtracking would loose this input and again forward parsing would re-read the input after a seek. This means it requires a stream that was capable of seeking, in practice typically a file. The current implementation uses some tricky stuff with non-backtrackable term manipulation to avoid the need for seeking so we can also use this in network streams.

For output that is a lot harder. You can of course collect the list until done and then write it to the stream. You gain little in that case. What you really would like is to know which part of the output list is fixed (there are no choice points anymore that may change it) such that you can already write that part to the stream. I’ve been thinking about ways to do that. It is not totally impossible but requires some nasty tricks with the garbage collector. The trick would be to have a handle to the head of the output list. Now, on GC we run the normal mark phase, disregarding this head pointer. Then the list cells that are not marked that follow the head pointer are done, so we can write them to the stream and move the head pointer to the first non-garbage cell. Maybe one day …

3 Likes

On StackOverflow is the user false and he gives out bounties on Prolog questions that should be understood. (ref)

Yes some of us know who false is and yes you should trust his answers or the answers he gives bounties on, I do.

1 Like

@EricGT : The computer scientist R.G. Dromey wrote two introductory computer science texts that remain relevant for Prolog tutorial writers:

I could see value in:

  1. initially showing declarative solutions to common problems in an intro algorithms course,
  2. then showing how imperative languages solve the problem,
  3. deriving the imperative solution from the Prolog program.

Blockquote
I see this “war” already going on for some time, who has the best Prolog collection that will attract the most people.

I have no idea where that interpretation comes from. The last thing I want is to create conflict. I appreciate all of the references and advice given in this thread.

My perspective is one who sees a lot of value in the early computer science literature that is being lost with emphasis on getting ‘programmers’ to be immediately “productive” on unimportant problems.

Blockquote
But how have “Prolog Cookbooks”, if you are not a Cook?

I have written a number of programs that are not on Github. The link to is my only public code, which is Prolog code.

My code was based on material available to me that I know now is out of date. But knowing that doesn’t provide information on how to improve.

I don’t really understand the motivation of your comment. You can’t expect people who intentionally pick up logic programming to derive things like arithmetic constraints, or the declarative if_//3, when it took some of the best computer scientists decades to figure it out.

That actual book can be found on github, but I do not post the link as I do not know if it is a legal copy.

(On other forums I participate in, it is frowned upon to post links that might infringe on rights of various parties).

My question is more general. The most recent hard copy text on Prolog programming fundamentals I have access to is the 4th edition Bratko’s Prolog Programming for AI (2012).

I checked, and there is no mention of using CLP libraries as substitutes for ISO prolog built-ins. That isn’t a criticism, but an observation. It is a great book otherwise.

In other forums (say Hacker News) it is often claimed that Prolog is not “General Purpose” when that is not the case at all.

If there were a resource that mapped a subset of the basic algorithms from the Cormen, Leiserson, Rivest, and Stein Intro to Algorithms text (done in imperative pseudocode) with ideas from Purely Functional Data Structures, (link) that would be useful for:

  1. Experienced programmers wrestling with logic programming
  2. Total newcomers to programming.

FWIW, – in Prolog terms: I’m trying to update my mental problem solving/programming database with the most Modern Prolog techniques that eliminate the use of imperative features, and map them to what I know about imperative algorithms. And when that cannot be done, describe what to do instead.

1 Like

Blockquote
Thats a big menu to cook. Maybe you need chef ramsay to help you.

No, just a bit of guidance on what might be worth reading that has been published after say 2012, or search terms that might be relevant. I’ll work out the rest myself.

Well, why perpetuate the mystery? :slight_smile: (It took me quite some time to find out!)

To add my 2 cents …

Recasting algorithms in a declarative representation, is only part of the story …

For professional programmers its also the architecture and related non-functional requirements that matter. This include performance, security, parallelism, and related tools needed to create a commercial end-to-end system.

You have to show how the Prolog can be general-purpose in this sense (and SWI-Prolog has an offering with tabling, multi-threading, etc) and/or show how Prolog can be really good for certain types of system.

Dan