
The Power of Prolog - noch
https://www.metalevel.at/prolog
======
jacquesm
One of the nicest examples of the power of prolog is that Windows NT contained
a prolog implementation to take care of network configuration, replacing the
previous codebase:

[http://www.redditmirror.cc/cache/websites/web.archive.org_84...](http://www.redditmirror.cc/cache/websites/web.archive.org_84624/web.archive.org/web/20040603192757/research.microsoft.com/research/dtg/davidhov/pap.htm)

~~~
Jtsummers
My one regret in a project at work (internal tool) was that I didn't persuade
management to let me use an embedded prolog in the application. Instead I
rewrote half of Prolog (badly) in C#.

~~~
andai
I don't get it. Isn't that the same thing but worse?

Edit: Also, Greenspun's Tenth Rule of Programming:

Any sufficiently complicated C or Fortran program contains an ad-hoc,
informally-specified, bug-ridden, slow implementation of half of Common Lisp.

~~~
Jtsummers
It was worse. That office had an aversion to anything not-Microsoft for dev
tools unless they were for the embedded systems we maintained. They also had
an aversion to any language that wasn't "industry standard", whatever that
meant (because, clearly, prolog and others do have industry standards
associated with them; here they meant commonly used and easy to hire for).

~~~
julian_1
This is a frustration of mine. At university they try to install a knowledge
of all kinds of crazy languages, before you're ready to appreciate their value
and the issues they attempt to address. The most glaring example is probably
teaching Haskell in first-year. As a working programmer, you're then corralled
into following prescriptive industry-practice - that always errs on the side
of dumbing down the choice of technologies available.

~~~
candiodari
You're being asked to be a consultant, you know. They want to pretend that if
you rewrite Prolog in C#, it'll be simpler, and that the average C# programmer
(the cheapest one they can hire) will simply understand (badly written) logic
programming solvers and be able to modify them.

Eventually you'll figure out to simply double your hourly rate and ask "do you
want a bad Haskell implementation to go with that as well ? How about SQL ?
Lisp ?"

Don't forget to terminate with "by the way here's my card" (asking them to
mention their personal referral code "ID10T") when the inevitable happens,
nobody understands that code at all when they have to modify it. And every
time they ask you to update it you increase your hourly rate 20%.

You know, management realism. You can be victimized by it, or you can make a
living out of it.

~~~
andai
I don't know, sounds like it would be pretty confusing giving so many people
the same referral code.

------
fizixer
Roughly half the 'power of prolog' comes from the 'power of logic programming'
and prolog is by far not the only logic programming language, e.g.,

\- You can do logic programming using minikanren in scheme. (you can also
extend the minikanren system if you find a feature missing).

\- Minikanren was implemented in clojure and called core.logic.

\- It was also ported to python by Matthew Rocklin I think, called logpy.

\- There is also datalog, with pydatalog it's python equivalent.

\- Also pyke. And so on.

Plus logic programming has very important (arguably necessary) extensions in
the form of constraint-logic-programming (CLP), inductive-logic-programming
(ILP), and so on.

It's a huge area.

EDIT: ILP at an advanced level starts making connections with PGMs
(probabilistic graphical models) and hence machine learning, but its a long
way to go for me (in terms of learning) before I start to make sense of all
these puzzle pieces.

EDIT 2: You can have a taste of logic programming without leaving your
favorite programming language. Just try to solve the zebra puzzle [1] (without
help if you can, esp. through any of Norvig posts or videos; they're
addictive).

[1]
[https://en.wikipedia.org/wiki/Zebra_Puzzle](https://en.wikipedia.org/wiki/Zebra_Puzzle)

EDIT 3: An "expert system" (a term from the 1980s) is largely a logic
programming system paired up with a huge database of facts (and probably some
way of growing the database by providing an entry method to non-programmer
domain experts).

EDIT 4: In other words, logic programming (along with other things like graph
search etc) is at the core of GOFAI (good old fashioned AI), the pre-machine-
learning form of AI, chess engine being a preeminent example of it.

~~~
Karrot_Kream
Not really. I use SWI Prolog for a lot of personal projects (that actually see
QPS no less) and there's a lot more to it than that. SWI gives you: good
debugging support (with trace and spy), hooks into the Prolog database (with
asserta/z and retract), optimized implementations of difference lists, online
help, and so much more. Don't even get me started on its amazing DCG support
that makes Regex feel like a Neolithic toy. Not only that but Prolog's Syntax
gives you very similar properties to lisp's homoiconicity (first class atoms,
metaprogramming, etc). Sure you can reimplement all of this in miniKanren, but
it's all there waiting for you in SWI Prolog already! There's a lot more to a
language than just its concepts.

Every time I hack in Prolog I always feel like I'm living the idea that I
"tell the computer what to do not how to do it". It's a shame that more folks
don't use it.

~~~
abhgh
Prolog was part of course that I'd taken during my Masters. I loved it then. I
would love to take a closer look when I have time ... whenever that happens
<sigh> ...

Interestingly, IBM Watson uses Prolog. [1]

[1] [https://www.cs.nmsu.edu/ALP/2011/03/natural-language-
process...](https://www.cs.nmsu.edu/ALP/2011/03/natural-language-processing-
with-prolog-in-the-ibm-watson-system/)

~~~
frik
IBM uses a special version of Prolog with a different syntax and database
access functionality. They hired a department of a university.

MS Windows (network code) contains a Prolog with C-style-syntax.

~~~
nnq
Thanks. Do you know of any other resources describing Watson's inner workings?
...cause just googling for it leads to one of the zillions of marketing
bullshit pages or whitepapers devoid of any real infos that IBM's marketing
drones have flooded the web with.

~~~
frik
Look for papers, search for Watson Prolog UIMA

------
samwalrus
I run a youtube channel called 'playing with prolog'
[https://www.youtube.com/channel/UCfWpIHmy5MEx2p9c_GJrE_g](https://www.youtube.com/channel/UCfWpIHmy5MEx2p9c_GJrE_g)

We demo little things that you can do in prolog.

Happy to take suggestions for videos :)

------
hexmiles
i have always trouble understaing prolog, lot of guide online seem to just
tackle the syntax or assume you already know a lot of logic programming, for
example the first example in the link
([https://www.metalevel.at/prolog/facets](https://www.metalevel.at/prolog/facets)):

    
    
            list_length([], 0).
            list_length([_|Ls], N) :-
                    N #> 0,
                    N #= N0 + 1,
                    list_length(Ls, N0).
    

i don't undestand it, i read the segment describing it multiple time but i
still don't get it, and is not the syntax i don't undestand how it should
work, a tried reading the next few chapter but i feel i'm missing something!
is there a "prolog for dummies" out there?

~~~
sordina
Check out
[https://en.wikipedia.org/wiki/Horn_clause](https://en.wikipedia.org/wiki/Horn_clause)

You can read this as two statements:

"The length of a list is 0, if the list is empty."

"Otherwise, if the length of a list Ls is N0, and N is N0 + 1, and N is
greater than 0, then Ls with an additional element is of length N.

~~~
na85
Good lord, does that mean it's necessary to explicitly tell the compiler the
length of an empty list? Shouldn't the list type already know its own size?

I fail to see the benefit... honestly it just seems like a waste of time.

~~~
tathougies
No. This is the standard implementation of the length/2 predicate. Like any
other language, prolog has a standard library that includes this predicate.
You'd never need to write this in practice, but this is how it would be
written in the standard library.

In general, any general purpose language worth it's salt will have substantial
portions of its standard library written in that language, and in this regard,
prolog meets the criteria for respectsbl languages

~~~
Koshkin
I guess, the point was, if _list_ is a built-in construct, the function
_length_ should be also built in. (Unless, that is, natural numbers are
defined in the standard library.)

~~~
YeGoblynQueenne
Prolog lists are predicates, like pretty much everything else in the language.
Lists have the functor '.' (the dot) and two arguments, a term and a list, so
they're defined recursively.

Frex, this is a list:

    
    
      .(a, .(b, .(c, .(d, []))))
    

'[]' is an atom that stands for the empty list.

Normally however we write lists like this:

    
    
      [a,b,c,d]
    

Which is syntactic sugar used in the vast majority of Prolog code.

The easiest way to think of it is that a list is a pattern, consisting of two
square brackets enclosing any number of terms. You can't really call functions
on it, but you can pass it as an argument to other predicates, and match it to
other patterns.

------
haddr
There is a class of problems which you can solve using Prolog with pure
pleasure.

There is one thing however: Prolog can magically hide the complexity of many
things, which is a two-sided sword. On many occasions you are hiding away the
computational complexity and wonder why the execution is so slow. This rarely
happens in imperative languages (where you are more aware of all the loops and
recursions). I guess this is why many people hate Prolog...

~~~
Karrot_Kream
> On many occasions you are hiding away the conputational complexity and
> wonder why the execution is so slow.

I disagree. Prolog is a language where it's quite easy to lose performance
because of the density of each goal (a goal is "dense" and is basically a form
of executable pseudocode), but equally easy to diagnose because of the terse
expressiveness of the language. What gets a lot of Prolog beginners is the
execution model: a lot of beginners just don't understand how the depth first
search unification algorithm really works. Playing around in the REPL should
help build that Intuition fairly quickly though.

I can post a concrete example if you want. Recently I changed an O(n^2) goal
to an O(n) one and didn't have much trouble debugging it at all. I'm on mobile
now but can post it later if you want.

~~~
carapace
I'd like to hear that story, when you get the chance. ;-)

~~~
Karrot_Kream
Sure and thanks for the wait!

To give a bit of background: I run a service for some folks that allows them
to get status messages. Some of my users wanted stats on the kinds of messages
they received. My first implementation was quick and dirty: shell scripts
which would run filters and aggregations through combinations of grep, sort,
and uniq. Eventually as more demands came in with different types of
functionality, this became unscalable, so I wrote an analysis engine in
Prolog.

Problem: Find status lines that have valid "http" links in them.

First attempt: SWI Prolog contains a goal sub_string/5 ([http://www.swi-
prolog.org/pldoc/man?predicate=sub_string/5](http://www.swi-
prolog.org/pldoc/man?predicate=sub_string/5)). The goal is invoked as:
sub_string(+String, ?Before, ?Length, ?After, ?SubString). I was storing
status messages in the Prolog database wrapped in the "status" dynamic goal,
so a status message looked like: `status("hello world")`. At a Prolog REPL, to
query for all status messages, I could match along the goal `status(X)` and
all bound instances of X would be the messages.

I created a DCG and wrapped it in a goal called `parse_http_string(String)`
which would evaluate to true if `String` was a valid HTTP string. My first
attempt was a goal like:

`status(String), sub_string(String, _, _, _, Needle),
parse_http_string(Needle) `

This is an O(n^2) query. We first bind `String` to a status message, and the
`sub_string` predicate will match _all valid substrings_ of `String` and stuff
it into `Needle`. `parse_http_string/1` will then run on `Needle` and return
true when the goal succeeds on a substring.

This was slow, but the query wasn't used very often and it worked for my
customers.

Second Attempt: I realized that all HTTP links started with the text "http".
By searching the status message for the string "http" and then starting the
substring search at the starting index at the beginning of this match, I'd
only be doing an O(n) search of substrings (because I'm only varying the end
index of `sub_string/1` rather than both the start and end index). The
modified goal looked like the following:

`status(String), sub_string(String, HttpStart, _, _, "http"),
sub_string(String, HttpStart, _, Needle), parse_http_string(Needle) `

This produced the expected O(n) algorithm, despite only adding a single line
and modifying the next line. This also made the query a lot faster, so I could
rest easier when my customers began to look for links en masse in their status
messages! (Which they did, as surely as any product you hand to users ever
scales).

~~~
gugagore
Just to clarify, it was O(n^2) for n the length of the string, not the number
of statuses. Right?

~~~
Karrot_Kream
Correct.

------
andai
For an introduction to Prolog:

Learn Prolog Now - Free Online Version
[http://www.learnprolognow.org/lpnpage.php?pageid=online](http://www.learnprolognow.org/lpnpage.php?pageid=online)

I like this one because it's beginner-friendly (and uses characters from Pulp
Fiction as examples).

\-- edit: actually, The Power of Prolog to is great, too! If anyone knows more
good resources, I'd be happy to hear about them!

------
timonoko
Never understood why natural numbers (or some set of N) is not in the search
space:

fib(X,X):- X<2.

fib(X,Y1+Y2):- fib(X-1,Y1),fib(X-2,Y2).

I tried to get answer to this kwestion in reddit, but all I got was personal
insults.

~~~
colanderman
You can do this in SWI Prolog using the between/3 predicate for the
inequality, and the is/2 predicate for the arithmetic.

~~~
thisrod
When I tried out Prolog, I was struck by the inelegance of is/2\. There has to
be something like it, because no one knows how to write an interpreter for

    
    
        arcsin(X,Y) :- sin(Y,X).
    

However, MetaPost can do that for linear expressions. You can say (in Prolog
syntax)

    
    
        midpoint(X,Y,Z) :- Z == (X+Y)/2.
        two(X) :- midpoint(0,X,1).
    

And the MetaPost interpreter will find the solution two(2).

Does anyone know of Prolog extensions that can solve linear algebra problems
like that?

~~~
colanderman
SWI-Prolog has CLP extensions to do exactly that: [http://www.swi-
prolog.org/pldoc/man?section=clp](http://www.swi-
prolog.org/pldoc/man?section=clp)

    
    
        ?- use_module(library(clpq)).
        midpoint(X, Y, Z) :- {Z =:= (X+Y)/2}.
        two(X) :- midpoint(0, X, 1).
    

does what you want.

~~~
thisrod
Thank you. It's a relief to know that I don't need to invent it.

------
skdotdan
Something I would like to be able to understand/know/study is how logic
programming languages are implemented and how their runtime looks like.

~~~
pg314
Section 4.4 in Structure and Implementation of Computer Programs [1] presents
an implementation of a Prolog-like logic programming language in Scheme. It is
very instructive to contrast it to the meta-circular evaluator of Scheme in
that same book to see the similarities and differences.

Paradigms of Artificial Programming by Norvig also contains a chapter
implementing Prolog in Common Lisp. The code can be found at [2].

[1] [https://mitpress.mit.edu/sicp/full-text/book/book-
Z-H-29.htm...](https://mitpress.mit.edu/sicp/full-text/book/book-
Z-H-29.html#%_sec_4.4)

[2] [http://norvig.com/paip/prolog.lisp](http://norvig.com/paip/prolog.lisp)

~~~
exDM69
Here [0] is a video link to SICP lecture 8A about Logic Programming, which
accompanies the section 4.4. It's an excellent lecture!

[0] [https://ocw.mit.edu/courses/electrical-engineering-and-
compu...](https://ocw.mit.edu/courses/electrical-engineering-and-computer-
science/6-001-structure-and-interpretation-of-computer-programs-
spring-2005/video-lectures/8a-logic-programming-part-1/)

------
moderation
See the Open Policy Agent [1] project that has a language and REPL called Rego
inspired by Datalog.

1\. [http://www.openpolicyagent.org/documentation/how-do-i-
write-...](http://www.openpolicyagent.org/documentation/how-do-i-write-
policies/)

------
huherto
I implemented the Wumpus World form Peter Norvig's AIMA using different
techniques. I found that Bayesian Logic was much more powerful than Logic
programming. Perhaps that explains why Prolog has flourished.

Logic programming is limited to values of true or false. 0 or 1. Bayesian
logic can deal with uncertainty values like .2 or .3. It almost seems like a
superset. It is also more intuitive IMHO.

I keep the wumpus implementation here if anyone is interested.
[https://github.com/huherto/aima3/tree/master/src/wumpus](https://github.com/huherto/aima3/tree/master/src/wumpus)

------
lacampbell
Can anyone give examples of the kinds of problems prolog is ideally suited to?
I took a course on it at university. It looked interesting but I didn't really
"get it". It might be worth another look now I have a bit more experience
under my belt. I've got a lingering feeling it would solve a certain kind of
problem very easily.

~~~
ahelwer
It's pretty much Backtracking as a language. So stuff like N Queens,
Einstein's Puzzle (the Englishman lives in the red house, the Swede in the
blue house, etc.) and so on. Any time you want to write down the rules of a
discrete system and ask questions about the properties of that system, Prolog
is a great way to do it.

One practical application: it's very easy to write the logic for a network
firewall in Prolog.

~~~
lacampbell
ah! backtracking. combinatorial optimisation would be incredibly useful for
me. if prolog is indeed backtracking as a language I definitely need to look
into it.

~~~
tom_mellior
It is indeed backtracking as a language, but you don't get optimization
entirely for free. The backtracking part only means that you can write down a
problem that has multiple solutions and get Prolog to enumerate those
solutions using its default order.

If the set of solutions is small enough, you can enumerate all of them and
pick out the best one, or have it enumerate them until you get one that is
good enough. But if you need a smarter exploration of the search space, you
will (in general) have to write that yourself.

Many implementations include an integer constraints library that will give you
functionality similar to an ILP solver, which may or may not fit your domain.

~~~
bloaf
Would it work well for algorithms like A*, or other quazi-AI problems that
crop up in games?

~~~
tom_mellior
Yes, but you shouldn't expect it to have much more magic support for this kind
of algorithms than other languages.

------
SagelyGuru
I used to teach Prolog in the GOFAI days of early 80's. It certainly was fun
and probably the quickest way how to start solving interesting search based
problems without having to write pages and pages of code. It was very good for
motivation. Also for encouraging "top-down" design.

------
camelNotation
One of my professors in college was an original creator of the Prolog
language. He made us learn Prolog so that he could teach us something we could
have just as easily done in C or Java. I strongly disliked him. For that
reason, I am filled with negative vibes when I think about Prolog.

------
pjonesdotca
A great intro to Prolog can be found here if you're not the type that learns
solely from reading.
[https://www.youtube.com/watch?v=SykxWpFwMGs](https://www.youtube.com/watch?v=SykxWpFwMGs)

------
mark_l_watson
I bookmarked this. I have been revisiting my own programming history. I used
Prolog a lot in the 1980s, partially because I was influenced by the ill-fated
Japanese 5th generation project. A few weeks ago I pulled my old Prolog code
experiments from an old repo. Prolog is a great language for some
applications, and Swi-Prolog has some great libraries and sample programs.

I also have used Common Lisp a lot since the 1980s and I am in the process of
working through a few of the classic text books, and I have it on my schedule
to update my own CL book with a second edition.

~~~
FabHK
You had version control systems in the 80s? I had cassette tapes and later 5
1/4 inch floppy disks!

~~~
mark_l_watson
I moved everything to svn, and later to git repos.

I actually had 8" floppy disks on my Xerox Lisp Machine. An unnatural size for
floppy disks!

------
norswap
If you want to exercise your Prolog-foo: [https://github.com/norswap/prolog-
dry](https://github.com/norswap/prolog-dry)

------
bschwindHN
I once wanted to solve a problem that is perfect for Prolog, but I wanted it
in Clojure. Turns out there's a great library for that! I don't think it has
the full power of Prolog (I only know of Prolog and what it does but I've
never used it), but for integer constraint programming it was a joy to work
with.

[https://github.com/aengelberg/loco](https://github.com/aengelberg/loco)

------
zodiac
I wrote some prolog for a PL class recently and had to debug some cases of
nontermination caused by the depth-first-search unification algorithm. I was
wondering why prolog (or some other logic programming language) couldn't use
breadth-first search instead, to avoid those cases, but couldn't find answers
online - could someone who knows prolog better here have an answer?

~~~
mballantyne
Other search algorithms can take up lots of memory to store progress they've
made down different paths. Having only one active state also lets you map
unification down to efficient low level cpu operations. If you have multiple
states, you either have to copy lots of data when you fork the state or you
use a persistent data structure but can't use side effects, so everything is a
bit slower.

It's a tradeoff though. I work on miniKanren, which is a logic programming
language with a complete search that doesn't hit the nontermination issues you
mention. The complete search lets us do some pretty cool stuff with program
synthesis (though we're not about to put any programmers out of business just
yet):
[https://www.youtube.com/watch?v=er_lLvkklsk](https://www.youtube.com/watch?v=er_lLvkklsk)

Note that you can implement iterative deepening depth first search on top of
prolog if you want a complete search there. Iterative deepening takes a little
more time but avoids the memory problems with breath-first. SWI has tools
built in to help there: [http://www.swi-
prolog.org/pldoc/doc_for?object=call_with_dep...](http://www.swi-
prolog.org/pldoc/doc_for?object=call_with_depth_limit/3) And I believe Ciao
implements its iterative deepening library with a meta-interpreter:
[https://ciao-lang.org/docs/ciao/id_doc.html#0](https://ciao-
lang.org/docs/ciao/id_doc.html#0)

------
nwatson
The Japanese government spent US $400 million in the '80's (a lot in those
days) to try to jump ahead of "western" computer technology via its "5th
Generation Project".
[https://news.ycombinator.com/item?id=14047780](https://news.ycombinator.com/item?id=14047780)

The basis for it all ... Prolog.

~~~
dmh2000
and it was an epic fail
[https://en.wikipedia.org/wiki/Fifth_generation_computer#Fail...](https://en.wikipedia.org/wiki/Fifth_generation_computer#Failure)

A primary problem was the choice of concurrent logic programming as the bridge
between the parallel computer architecture and the use of logic as a knowledge
representation and problem solving language for AI applications.

~~~
zmonx
Personal anecdote: I once asked a retired Japanese computer scientist why the
5th generation project had failed. He replied with:

"What do you mean 'failed'? All my colleagues who worked on this project have
become professors!" In this respect, the project was actually a smashing
success.

------
pjc50
"No."

(Disclaimer: this is a joke referencing prolog's default return when it can't
find a solution.)

------
arikrak
Question - is prolog used in the real world? I.e. are there businesses that
use prolog in production?

~~~
zmonx
Yes, there are several businesses that use Prolog in production. For example,
please see the quotes from the SICStus page, a professional Prolog system (ISO
standard compliant) with many commercial applications:

[https://www.sics.se/projects/sicstus-prolog-leading-
prolog-t...](https://www.sics.se/projects/sicstus-prolog-leading-prolog-
technology)

Here is a salient quote from the article:

"SICStus Prolog is a workhorse in the transport and logistics industries,
running systems that handle _a third of all airline tickets_ , and helping
railways to operate their trains better."

Further major commercial applications of SICStus Prolog are listed at:

[https://sicstus.sics.se/customers.html](https://sicstus.sics.se/customers.html)

These include a voice-operated procedure browser for the International Space
Station, and a dispensation order generation algorithm for biological
research.

In addition, Prolog is often used in logistics software and for scheduling,
among several other tasks for which it is very well suited.

A commercial Prolog's multi-user license easily costs _thousands_ of dollars,
so an industrial strength Prolog system is not the kind of software you
typically "just buy" as an individual. Typical customers of commercial Prolog
systems are other companies, and also universities who buy licenses for
research purposes and to teach Prolog.

------
signa11
erlang syntax is prolog inspired, not sure if that's a good thing though :)

~~~
macintux
The prologesque syntax gets a lot of grief, but I genuinely appreciate it. I
like my different paradigm languages to look different, helps me think
differently.

(but it's much closer to Algol than Lisp is, so I don't have to bend my brain
quite that hard)

------
taylorking
love(prolog).

~~~
vram22
love(prolog) :-

    
    
            love(logic_programming),
            love(elegance).

------
hota_mazi
Prolog's mathematical foundation is sound but the devil is in the details, and
very soon, you encounter two of Prolog's most glaring flaws that lead to
spaghetti code worse than what even BASIC ever produced:

\- It's dynamically typed

\- The cut operator

~~~
gmfawcett
If you like Prolog, but want static typing and no cut operator, you might
really like Mercury ([https://mercurylang.org/](https://mercurylang.org/)).

