Who killed Prolog?(vanemden.wordpress.com) |
Who killed Prolog?(vanemden.wordpress.com) |
I don't think Prolog is practical as a fully standalone language, though. Like SQL, it has a model that strongly skews it towards certain kinds of problems, and which makes I/O and side effects awkward. I think it would be best to have a Prolog-like language as a library (like Lua or SQLite), to embed it for rules & scripting. (Writing one is on my project TODO list. I've been reading quite a bit about Prolog implementation.)
To me, the single most interesting aspect of Prolog is computing with partial information via logic variables: variables that are constant, but don't necessarily have to be bound immediately. Conceptually, the variables always have some specific value, but you didn't know until they were bound. You can pass around structures with holes in them to use as templates in pattern matching, append lists by binding the "hole" at the end of a list to another's head ("difference lists"), etc., while still keeping the advantages of immutability. Most languages descended from Prolog (Mercury, Erlang) drop logic variables, though Oz keeps them.
Another kind of computing with partial information is constraint programming, which makes Prolog much, much less dumb. Generate-and-test is great for prototyping, but quickly shows its limits with combinatorial problems - where constraint programming excels. Most major Prolog implementations come with constraint programming extensions, and they address many of its weak points.
There's also Erlang. Erlang seems like a very modern, practical evolution of the declarative + concurrent direction that some logic programming research was going. If you remove backtracking (which makes handling concurrency far more difficult), then I/O also becomes feasible. Erlang keeps much of Prolog's declarative-ness, and adds several powerful features of its own.
http://web.archive.org/web/20030213072337/http://www.vanx.or...
Here's a (rather snarky) LtU comment by Peter Van Roy pointing to other designs improving on the WAM - http://lambda-the-ultimate.org/classic/message1618.html#1108...
> I think it would be best to have a Prolog-like language
> as a library (like Lua or SQLite), to embed it for rules
> & scripting.
You may be interested to know that there are various prolog Perl modules on CPAN, particularly AI::Prolog and Language::Prolog::Yaswi .I think designing a Prolog-like language primarily for embedding, rather than wrapping a standalone Prolog, will have an interesting effect on the design though - Lua, for example, benefits tremendously from being able to leave certain issues to C. An embedded logic language could likewise focus on what it does best.
* Somebody is probably going to pop out of the woodwork and say that my impression of Perl is based on Perl 10 years ago. They're right, as that's roughly when I switched to Python. It'd be tough to convince me to switch back, though. I'm fine with awk for "tiny Perl script" hacks, and prefer other languages for larger stuff.
I guess for C the API would need to be very different like Lua's C API, but that's life.
I'm thinking something like Lua's C API, both because I know it well and because its design does a particularly good job of bridging C and a dynamically-typed language.
When there exists a large, universal library of "common sense", of the kind people build up from years of childhood sensory experience, declarative programming will come back. But not until then.
Firstly, Prolog is it was great at the deductive, expert system type of AI, but in 90's, a new generation of AI based on statistics (firstly, fuzzy logic, and then proper statistical reasoning, particularly Bayesian approaches) appeared and showed that truth and failure just don't cut it any more.
Secondly, I don't know if anyone has done the research, but I wouldn't be surprised if Blub programmers are just better at thinking imperatively; Prolog tends to kind of warp the brain away from that, which would put off Blub programmers, but it doesn't provide the kind of killer power that makes expert programmers want to use it either.
Thirdly, Prolog is hard to optimise well, and hard to predict the performance characteristics of. In the 80's and 90's, where apps were getting written in C, this was killer.
There are attempts to reconcile the two approaches, such as Markov Logic.
http://en.wikipedia.org/wiki/Markov_logic_network
I believe Statistical Relational Learning is the more general term for this idea.
http://en.wikipedia.org/wiki/Statistical_relational_learning
As mentioned in the article, Feigenbaum's and McCorduck's book on the Japanese 5th generation project had caused quite a stir in the USA, and I think that it made it easier for me personally to get IR&D funding for anything AI-ish.
Perhaps off topic: I view Prolog as almost a scripting language because most programs I wrote in Prolog were short and solved one little problem. The only long Prolog program I every wrote was a quick one week rewrite of a 5 week IR&D project that was a prototype battlefield simulator that I wrote in Lisp. I can't imagine writing a million line system in Prolog.
Me too. I want to take this idea and run with it - it would probably work better as an embedded scripting language, like Lua or Tcl.
I'm amused at the general supposition that the FGCP was a failure. Yes, it failed to produce specific hardware that was commercially competitive, but the basic program of "applying parallelism to search and database tasks" behind it was the basis for Deep Blue, Google's web search and the infrastructure behind many a large scale system.
Elsewhere, even in AI, production-rule systems gained popularity from the 1980s as a simplified, propositional form of declarative programming, which also lent itself more naturally to state maintenance (asserting/retracting facts, and updating what changes as a result, as the core interaction loop). The focus on expert systems in the 1980s, and the development of the efficient RETE algorithm in 1983 were probably some factors in taking over an area in that in the 1970s one would've done in Prolog, or hand-coded in Lisp. Even today lots of this kind of "logic" stuff gets done in Jess or Drools, especially in business-logic, which is something of a success for declarative programming, though not for full-on logic programming.
I think a bunch of this kind of thing conspired to make Prolog not nearly as exciting even by the late 1980s as it was in the 70s. Academics moved on, and started focusing on other things. Datalog and other data-querying systems were a big focus for a while: if Prolog wasn't going to take over all programming, well, dammit, at least it was going to take over data querying, where it seemed like a clear win. That did have some impact (modern SQL cribs some features and even algorithms almost directly from Datalog), but it was more in the "influence" than "replace" sense.
Today much of the focus is on answer-set programming (http://en.wikipedia.org/wiki/Answer_set_programming), which targets neither large programs (like Prolog) nor large databases (like Datalog), but relatively small programs/databases with complex deduction and constraints (more in the style of solving combinatorial problems). That might be seen as something of a retreat, towards using logic programming for things that were more traditionally done in logic anyway, rather than as a general programming paradigm. There are some logic-programming-in-the-large descendents, like Mercury (http://en.wikipedia.org/wiki/Mercury_(programming_language)), but AFAIK their communities have always been small. It seems they're a little too hybrid to appeal to theorists, a little too academic-sounding to appeal to real-world types, live in Prolog's shadow, and lack a killer app.
One interesting angle is a very recent trend of pushing some declarative-programming ideas directly into mainstream programming languages. LINQ in C# is probably the most interesting one. It's billed as adding something like SQL into C#, but the way it's used as an actual core programming construct (not just a data-retrieval construct), which you can use to write application logic in a declarative rather than either functional or imperative style, has a very logic-programming flavor. This route is, imo, the most promising angle to get anything like logic programming used to build real, large-scale apps: the possibility that a successor to LINQ will add features that move it closer to logic programming seems much larger than the possibility that a Prolog descendent will break through.
[Note of course that the above is all my personal take. I'm a grad student using ASP and Prolog as tools in my thesis, so I clearly think they have merit, though I can also see why, when confronted with "hey we can write this all in Prolog!", the world's answer might have been, "maybe we can just take some of the cool parts of Prolog instead?" If anyone's qualified to answer the "why did Prolog die?" question definitively, it sure ain't me. But do I think that some of the above factors played a role.]
Prolog offers at lot of the same things that Lisp also does: symbolic processing, meta-programming, among others. One of the tricks of Lisp programmers is to implement Prolog in Lisp and use it for the areas it is strong. Just read "Paradigms of Artificial Intelligence" to see how this is done.
Interestingly, given the conclusions reached in the article, both Sterling and Shapiro's The Art of Prolog and Lloyd's Foundations of Logic Programming mention the Japanese fifth generation project as an example of Prolog's impending breakthrough into the mainstream.
In any case, I always thought language classifications could get a little fuzzy.
No, the original FORTRAN that the author is referring to wasn't procedural. FORTRAN II, a few years later, added subroutines to the language.
IMO the thing that killed Prolog is that there has never been a good way to do parallelization without having to massively rewite Prolog programs.
Hermenegildo, in particular, continues active research in this area and is quite visible and active in the broad programming languages community.
Also, wamcc (http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.45.1...) compiles Prolog to C.
1) write it declaratively 2) figure out that your program will take days to complete 3) add ugly procedural hacks (cuts) to make it more efficient
To an extent, you have this process in any language (write->measure->optimize) but typically not in a way that it forces you at gunpoint to rape the paradigm you're working in.
However, any "real" Prolog program that I ever saw was really using it as a slightly odd procedural language.
Once constraint propagation can't narrow things any further, it can copy the search space, use various search hueristics (such as splitting each copy of the narrowest interval in half), and see if that triggers further constraint propagation (or hits a dead end). It usually greatly reduces the amount of depth-first search. There are other ways of implementing constraints besides propagator-networks and space copying, but that's the way I understand best.
Generate-and-test is great for prototyping, but doesn't scale up to larger problems. Constraint programming fares much better.
I am not sure that I fully agree. Even without that, Prolog is very useful for many problems.
Doug Lenat was able to run a very good business (hiring about 50 people for 10+ years) running about 50% off government contracts, about 50% off sales to big companies that could use better KB management tools that his competitors had.
Cyc didn't need to change the world in order to succeed, so it didn't change the world.
That said, the fundamental trouble in NLP is the lack of common-sense knowledge. The proper word-sensing of pen in "the pig is in the pen" vs "the ink is in the pen" is a matter of semantics, not syntax. You can do Noam Chomsky stuff until you're blue in the face and it will get you nowhere... But then some stupid Markov Chain comes along that conflates syntax and semantics and beats it.
This really paid off when in a new research project, which goal is to write a sentence realizer for the same system. With nearly no modifications we could reuse the grammar, lexicon, and productive lexicon. Both the parser and the sentence realizer use the same grammar and lexicon now.
I understand that this may seem somewhat trivial, as it may seem that the lexicon and grammar are plain data. However this is not true:
- The grammar is written as a declarative manner, where goals are mostly operators that manipulate attribute-value structures. These rules are later compiled to plain Prolog terms via term expansion (DCG-like) for efficiency. - You don't want to perform some unifications immediately, even when two terms are unified. Most Prolog implementations offer blocked goals, where a goal is blocked until a variable becomes instantiated.
However, I am the first to admit that Prolog makes some classes of problems trivial (unification grammars, parsers). There are also many things that you do not want to do in Prolog, because it is a waste of time, or very inefficient. For instance, in our system the following components are implemented in C or C++:
* Finite state automata for quick lookup of subcategorization frames.
* Part-of-speech tagger for restricting the number of frames for each word before parsing.
* N-gram models that are used as a feature in fluency estimation.
* Tokenization transducer.
* Bit arrays (comparable to Bloom filters) for excluding useless paths in parsing.
Conclusion: use the right tool for the job. Unification, structure sharing, and (some) pattern matching are cheap and easy to use in (WAM) Prolog. Most other things are prohibitively expensive and clumsy in Prolog.
Alan Kay's definition, more or less: "OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I'm not aware of them."
Erlang has processes with local state communicating via messages, and can do late-binding with pattern matching and hot code loading. It just disposes of classes and other such baggage.
It's a quick-and-dirty implementation of a Prolog interpreter, but it's a great resource for prototyping. JavaScript ports very well to Lua, so you should be able to port the code in a busy afternoon.
I made a couple of suggestions to increase the speed of the interpretation, but I'm not sure Jan ever integrated them into the code. The big one was using a trace to destructively modify environments rather than recreating them on choice points; WAM and tabling would be great, but it's a non-trivial piece of work following Warren's tech report, even with the help of the (very good) tutorial.
I'm planning on doing a C VM-based implementation with tabling* . I'm not sure about coroutines, and the VM will not necessarily follow the WAM design verbatim - Peter Van Roy has several suggestions for improvements in his thesis.
* Prolog-ese for memoization
I agree that something as easy to embed from C or languages with C-embedding hooks would be nice.
I don't have a time frame for a C-embedded Prolog (I've already got several other projects I'm trying to finish), but it's high on my list.
http://yieldprolog.sourceforge.net/
"Yield Prolog lets you embed Prolog programs directly in Python, C# [1] or Javascript [2] by using the yield keyword."
Lua and SQLite are both great examples of libraries whose APIs make them straightforward to embed in other languages.
I'll check it out again, though. If nothing else, it's an example of a real compiler written in Erlang, which is interesting in itself.