I was reading up on pure prolog, including the dif/2 paper @Boris had posted some while ago and the reif library, as well as comments made by @jan, how correctness can also be achieved by ensuring instantiated variables as well as through tabling.
I find that this discussion injects uncertainty in my use of Prolog – that it is possible to have language uses that provide unexpected (incorrect – in the logic sense) results. Perhaps, i can’t always ensure that everything is instantiated, and perhaps its also too limiting, given the various techniques that make use of uninstantiated variables (difference lists perhaps, and others).
It would be great, if we as a community, could create a document for swi-prolog that gives guidance on how to use the language in a way that is correct; and that would be performant as well.
It seems that pure Prolog would only be a subset, and there are proven usage idioms, that go beyond pure Prolog, given recent developments with tabling, for example.
I’d like to know if you see value in such a collaborative effort, and how to best go about creating something. In the end it could reside in the tutorial section of the swi-prolog site.
IMHO that would be quite hard as there is no one correct way.
To put the thought into a different perspective I think of Prolog as not another programming language but a language that allows one to create various models for solving problems. While many of the models simulate a procedural process, others make use of the logic variables to give multiple answers, or generate multiple values for testing, or use constraints to solve a problem, etc. While I do use pure predicates from time to time, as I noted in another post (which I can’t find at the moment), I also view Prolog as being able to cover the gambit from fully imperative (how) to fully pure (what) and degrees of variation in between.
For more pure predicates see the info section in these StackOverflow users
While this spectrum of capabilities makes Prolog very powerful, it also makes it very hard to use correctly.
Perhaps, what is needed is a clear classification / set of profiles, with each describing a subset of language and, in particular, idiomatic use of prolog – perhaps, not unlike the utility of OWL profiles whose purpose is to organize around tractability and decidability concerns in description logic based representations.
While I see that as a noble goal, and think it would be easier to do for well defined cases such as code that is fully imperative and deterministic, or at the other end that is fully declarative and pure, it is in the middle where code can have parts of both that I would find it hard to say what is idiomatic.
Also the question of which way to solve the problem comes to my mind. If for example you are unaware of constraints or tabling, then the way you would solve the problem would not use those. But for certain problems, the use of such technology is clearly better. But then even if those technologies are are better, is there still not something better that we are unaware?
As an example when I was looking into learning whole cell simulations I learned they relied heavily on differential equations and was considering taking a course in differential equations but then in reading a book on how the simulators are built found out that they exploit the use of Runge–Kutta fourth-order method. At that point the problem for me was transformed from one of trying to learn differential equations to one of just setting the parameters of a function and calling it which as programmers we eat like candy.
I am glad you used the word toolbox because when I was writing that post in the back of my mind was the topic Bug hunting toolbox .
Note: For now this is just a random collection of items as a list. They still need to be properly formatted and have a more detailed explanation with examples, but for now having them collected in one place is better than not having them at all. As noted, anyone can edit this and even add more details and example code to this.
Is just collecting items related to what you seek and making them public possibly a part of the path to accomplishing your idea?
If so then I don’t mind adding items as I find them.
I think this is a good start and also a good way to approach it.
Bugs, are inherently connected with tests, and testing is inherently connected with a-priori expectations, which are connected to correctness, including language correctness and idiomatic use.
You can’t therefore hunt for bugs if you don’t have a clear understanding of expectations and correctness.
I think this can be expanded into sections, with each sections describing the subset of prolog in use and for which one writes tests and hunts for bugs.
A pure prolog program will have quite different bug hunting, than a procedural one. A program that relies on tabling and tnot for its language usage idioms and correctness, would again be a different animal …
Sorry, I did not mean that the bug hunting toolbox reference be taken to mean that finding bugs is related to what you are doing. The reference was to show that in trying to put together a set of ideas sometimes one has to start with no specific outline and just collect the items. Then when a pattern emerges, they can be organized.
So in a way I was asking that instead of trying to start from the top down with an outline, just collect items and from that build the outline.
I think both a top down and bottom up approach could be useful here.
You actually started outlining a bit the top-down, by describing different idiomatic application of Prolog. I think its worth expanding on.
For example, how about writing for each a short description with a few examples. E.g. how does one do pure prolog / relational programming; how does one use prolog to write procedurally (deterministically), how to apply real negation (tnot) and when – what style comes out.
There are also relevant references out there – pure prolog has been described and studied extensively; procedural programming is probably more informally passed around in discussions; tnot and real negation comes from XSB prolog and its well founded semantics implemented via tabling, etc.
A cookbook in the programming context is collection of tiny programs that each demonstrate a particular programming concept. The Cookbook Method is the process of learning a programming language by building up a repository of small programs that implement specific programming concepts.
Perhaps, a google docs shared across contributors - or even publicly editable —would be better at this early stage – so one doesn’t need to fight it out with text markup of one sort or another on a wiki.
Would you like to create a public google docs – with some creative common license notice of sort – that everyone feels comfortable contributing too – later, it could be turned into PDF or markup on the swi wiki.
Change of title? Probably. Pure Prolog is defined as side-effect free prolog without using State updates. “Correct Prolog” has no special definition, but Correctness in programming means simply bug-free, and in logic refers to the challenge of proving a process matches a model of how it should behave.
From the discussion, grossdan really wants to know what is Idiomatic Prolog. What are the accepted good ways of writing code. “The Craft of Prolog” by O’Keefe is in my opinion the starting point for that.
Thank your for your suggestion. I have the book and am reading it again and again.
I think my question addresses another, more fundamental facet, that is discussed in papers such as the indexing dif/2 paper and in Triska’s pure Prolog discussion [1, 2], where results of predicate queries are unexpected: e.g. member/2 returning true, when the tail happens not to be a list; the conditional construct -> working unexpectedly, under certain conditions (backtracking), etc.
This makes it pretty hard for a programmer to know what a call to a predicate does … and its not a bug, its the correctness definition of prolog itself.
I think that experienced prolog programmers understand these issues, and address them in different ways. Some define subsets of prolog that have simpler and clearer semantics.
I think its important to get these things down on paper – since these aren’t easily understood and appreciated.
I’m not much interested in cases where member returns true although the tail isn’t a list. member is defined over lists and a reasonable program would not try to invoke member on non-lists. Making these exceptional behaviors precise was an agenda of the failed ISO project.
I don’t know about -> working unexpectedly, unless you never learned what it does. (Aside: I have often seen my own code misbehave over backtracking when conditionals are involved, but it wasn’t the conditional misbehaving, rather I failed to account for its behavior.)
I think the issue here is analogous to “nil” results in relational databases – programmers have lived with the ambiguity of such a result for a long time - and were responsible for handing it.
More recently, languages such as F# introduced options and other (monad) constructs to clarify that and remove this burden, and area of quality concern from the programmer – through more precise language design.
I think, anything that can improve language design, and thereby make code clearer, such as attempted by pure prolog, is therefore welcome.
Naturally, as it is the case, in non-lists of member/2 – is also a question of efficiency and performance, that is traded-off with correctness. – but i think these cases have to be well understood and communicated to the developers community.