Live data from Hacker News

The Power of Prolog

metalevel.at

61–70 of 162 posts

Re: The Power of Prolog

#61
post #42

Earlier quoted context omitted.

I can confirm this impression. In my opinion, there are several reasons for this: First, many types of mistakes that are common when working with lower-level languages cannot occur at all when you use a declarative language. For example, with a logic programming language, you cannot accidentally double-free a pointer or write into unintended portions of memory. Second, when working with a high-level language, the cod…

You guys must come from another planet, because I spend 90% of my time coding in Prolog debugging my code. My code sure makes sense to me- but the interpreter frequently disagrees. Additionally, there are some constructs that are pretty damn hard to debug. For example- deeply-nested recursive loops with multiple clauses and free backtracking; you never know which clause you're in or how deep in the recursion. Well- y…

In my experience, the trick is to let go of the imperative reading since it becomes too complex in the situations you mention.

Instead, focus on declarative properties: Does your predicate (or DCG) succeed in cases it shouldn't? Then your program is too general, and you need to add constraints. Or does your predicate fail in cases it should succeed? In that case, at least one of the goals is too specific. You can use declarative debugging to find out which goals are responsible for the failure.

You can add the following definition to your program to "generalize away" a goal by simply putting a * in front:

    :- op(920,fy, *).
    *_.
For example:

    pred :-
         true,
         false.
?- pred. now fails. Why? To find out, try to locate the reason for the failure by generalizing away goals. For example:

    pred :-
         true,
         * false.
This succeeds. So the last goal was responsible for the failure.

GUPU finds such fragments automatically for you! In a very precise sense, they are explanations for the problem. I know of no other programming language that admits this approach.

Re: The Power of Prolog

#62
post #7

Very good material. Prolog (or the ideas behind it) really needs a resurgence.

It's still going strong in the industrial side of things (like SCADA). You just don't hear much about it.

I've never heard of Prolog alongside SCADA. Can you be more specific? Like in a plant or what?

Re: The Power of Prolog

#63

Earlier quoted context omitted.

Prolog has print statements you can stick anywhere. (It also has proper debuggers that allow you to go forward and backward and all that.) Also, Prolog code is often "split into digestible chunks". Even more than other languages, in fact, because it's rather hard to write nested loops or nested predicates or nested many other things. If you were ever taught Prolog, it seems that you weren't taught well. You might wan…

>> Also, Prolog code is often "split into digestible chunks". Even more than other languages, in fact, because it's rather hard to write nested loops or nested predicates or nested many other things. I find it very easy to write nested loops in Prolog: findall(A ,findall(B ,findall(D ,findall(...) ,G) ,E) ,C) To paraphrase the old saying, a good Python programmer can write Python in any language.

and correspondingly, a good Prolog programmer can write Prolog in any language.

Limerick: "Some rascal wrote Pascal in Haskell."

Re: The Power of Prolog

#64
post #61

Earlier quoted context omitted.

You guys must come from another planet, because I spend 90% of my time coding in Prolog debugging my code. My code sure makes sense to me- but the interpreter frequently disagrees. Additionally, there are some constructs that are pretty damn hard to debug. For example- deeply-nested recursive loops with multiple clauses and free backtracking; you never know which clause you're in or how deep in the recursion. Well- y…

In my experience, the trick is to let go of the imperative reading since it becomes too complex in the situations you mention. Instead, focus on declarative properties: Does your predicate (or DCG) succeed in cases it shouldn't ? Then your program is too general , and you need to add constraints . Or does your predicate fail in cases it should succeed ? In that case, at least one of the goals is too specific . You ca…

>> Instead, focus on declarative properties: Does your predicate (or DCG) succeed in cases it shouldn't? Then your program is too general, and you need to add constraints. Or does your predicate fail in cases it should succeed? In that case, at least one of the goals is too specific. You can use declarative debugging to find out which goals are responsible for the failure.

That's good advice and I realise it articulates the way I reason about why my programs fail when they do (which is all the time).

The problem is when reasoning doesn't shed any light on what's wrong. There are many such situations for me, often caused by the fact that Prolog still manages to surprise me even after many years of programming in it.

For example I recently found out that findall/3 (which I use liberally) actually copies terms with fresh variables causing subtle changes to the structure of a term that are hard to detect with the naked eye. It took me I think an hour or so of debugging my code until I realised (and accepted) what was going on and I still had to go on to the Swi mailing list and ask, just to be sure. This is not something you can reason about, unless you know the semantics of a specific predicate (in this case, findall/3) in detail.

In another recent example I was debugging code that backtracked over the combinations of a set, waiting for that one combination that caused the problem to reveal itself. It's very difficult to just reason about situations like this, when almost everything works but there is a subtle bug hiding in the wings.

Re: The Power of Prolog

#65
post #23

Earlier quoted context omitted.

I've shared this with anyone who will let me divert the conversation to Prolog. At work we have the Haskell folks, the Lispers who move everything towards Lisp, and I'm the one who moves every conversion towards Prolog, then I send the link to this. :-D

The older Lisp folks often have a Prolog integrated in their system...

[deleted]

Re: The Power of Prolog

#66
post #63

Earlier quoted context omitted.

>> Also, Prolog code is often "split into digestible chunks". Even more than other languages, in fact, because it's rather hard to write nested loops or nested predicates or nested many other things. I find it very easy to write nested loops in Prolog: findall(A ,findall(B ,findall(D ,findall(...) ,G) ,E) ,C) To paraphrase the old saying, a good Python programmer can write Python in any language.

and correspondingly, a good Prolog programmer can write Prolog in any language. Limerick: "Some rascal wrote Pascal in Haskell."

>> and correspondingly, a good Prolog programmer can write Prolog in any language.

And a really good one can even write it in Prolog.

Re: The Power of Prolog

#67
post #20

Earlier quoted context omitted.

A big problem with visual debuggers is that they are too blunt of an instrument. Often I wish to examine specific things under specific conditions and thus use conditionals to narrow down what's being explored instead of bajillion breakpoints and/or log records. Debuggers could add conditional expressions, but then they'd be re-inventing WRITE statements anyhow. As far as the nearby statement that maybe I didn't lear…

> Debuggers could add conditional expressions, but then they'd be re-inventing WRITE statements anyhow. SWI-Prolog's debugger can be invoked conditionally whenever you want from inside your running application. I've used it many times, and the code is simply: (Condition -> gtrace ; true) It's true that you could stick a write there, but you would have to think about what pieces of data you will need. Your mileage may…

>> As I said, in Prolog you cannot nest loops. You cannot nest loops.

What do you mean here? My earlier comment was jokular, but you can definitely nest loops in Prolog:

  ...
  deconstruct([L|Ls],Acc1,Bind):-
      deconstruct(L,Acc1,Acc2)
     ,deconstruct(LS,Acc2,Bind).
  ...
etc. That's a nested loop, right there.

Do you mean it in the sense that it's still the same predicate rather than a consecutive change of scopes?

Re: The Power of Prolog

#68
post #43

Earlier quoted context omitted.

Thank you, this sounds like a wonderful addition! In general, the AI chapter is what I am currently working on most. I mean not "only" on the actual content, but on the applications I want to present in this chapter. Anton Kochkov has recently motivated this chapter via a dedicated issue for AI/ML applications of Prolog, and I invite you to track its progress at: https://github.com/triska/the-power-of-prolog/issues/5

Hi Markus, thanks for your hard work on this website (also on all the Swi constraint libraries). For your machine learning section, you might want to consider discussing Metagol [1], a modern ILP system that can learn recursive theories and perform predicate invention. The core Metagol implementation is tiny and relies on a meta-interpreter (the technique is called Meta-Interpretive Learning). It is a radically diffe…

Thank you very much Stassa!

I have added Metagol to the AI chapter, please have a look.

Re: The Power of Prolog

#69
post #38

Earlier quoted context omitted.

No idea why you think functional programming can't do printf debugging. Even pure languages like Haskell have `unsafePerformIO` (or wrappers like https://hackage.haskell.org/package/base-4.11.1.0/docs/Debug... ). Also functional programming heavily encourages splitting up code into digestible chunks (they're called functions ;) )

I did not say "can't do". I essentially said "not as well". Of course "well" can be subjective, but if enough people don't like way a given language/tool does it, they will ignore it, like they have been with FP/logical programming for several decades. Somebody needs to articulate in careful unambiguous detail how and why it's "better" and "easier", not just repeatedly claim it. That writer apparently hasn't been bor…

At least some of your assumptions are wrong: no-one is ignoring FP anymore.

Re: The Power of Prolog

#70
post #12
post #9

One of my favorite languages, pity that is has had even harder time than Lisp getting mainstream acceptance.

Let's face it, procedural is just plain easier to debug because you can more easily split it into digestible and dissect-able chunks: divide-and-conquer. Perhaps functional and logical CAN readily have such features, but nobody either figured how, or have not figured out how to explain how to do dissection to normal people. (This is sometimes a criticism of SQL also, but the added WITH clause helps break up big queri…

> procedural is just plain easier to debug because you can more easily split it into digestible and dissect-able chunks: divide-and-conquer.

That's how you think and program in FP as well. Not just debugging, I mean: FP is all about divide and conquer. In fact, Wadler's seminal paper "Why Functional Programming Matters" [1] is all about what he calls modularity, i.e. splitting a problem in parts and then gluing it back together.

[1] https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.p...

Post reply on HN