Ask HN: What's Prolog like in 2024?
Hi, i am a compsci student that stumbled upon prolog and logic programming during my studies.
While i have seen the basics of vanilla prolog (atoms, predicates, cuts, lists and all that jazz) and a godawful implementation of an agent communication system that works on SICStus prolog. I would like to know more because i think that this language might be a powerhouse in per se.
Since my studies are quite basic in this regards i would like to expand my knowledge on it and kind of specialize myself both in this world and another world (ontologies :D) that i really enjoy.
What's prolog like in 2024? what are you wonderful people doing with it?
thanks from a dumbass :D
288 comments
[ 4.2 ms ] story [ 267 ms ] threadWhile I was an undergrad I was exposed to Standard ML and Prolog, both of which were/are much more about declarative "what", though they could only practically interact with the actual world by side-effects and some imposed ordering (SML's 'ref', Prolog's cut).
I am still waiting for some of the amazing stuff that was in SML to materialise in C++ and Java for example, less so anything from Prolog. For example, to search a state space I might use an off-the-shelf solver with good heuristics and an objective function written in something imperative rather than use Prolog.
But it it really is over 30Y since I touched Prolog, so life in it may be very different now.
In an introductory prolog course you will soon find that when a prolog program is written to solve some problem like 'whats-the-next-chess-move' it's actually doing a depth first (and if you use the ! cut-operator, it will stop looking for any more solutions).
But in principle, it's up to the interpreter/compiler to decide how to find solutions. In the same way that a C compiler might say "ah, you're doing tail-recursion, let me make a loop out of that", a prolog compiler might say "gee, this problem looks like it would be much more efficient to use simulated annealing to find some answers in a shorter time". That's perhaps a bit far-fetched, but a great example is Datalog which has solvers that parallelize the search. You don't write a parallel algorithm, it's just that a parallel algorithm is used to solve your problem.
A specific feature I miss in other programming approaches is that if you can find the answer to the question "is A a child of B?", the very same code is also the function to find out all of A's children, or all of B's parents. No need to explicitly code a loop, or to create the inverse function.
https://www.swi-prolog.org/FAQ/Python.md
https://www.swi-prolog.org/pldoc/doc_for?object=section(%27p...
Fuckin' A.
https://en.wikipedia.org/wiki/OPS5
>OPS5 is a rule-based or production system computer language, notable as the first such language to be used in a successful expert system, the R1/XCON system used to configure VAX computers.
>The OPS (said to be short for "Official Production System") family was developed in the late 1970s by Charles Forgy while at Carnegie Mellon University. Allen Newell's research group in artificial intelligence had been working on production systems for some time, but Forgy's implementation, based on his Rete algorithm, was especially efficient, sufficiently so that it was possible to scale up to larger problems involving hundreds or thousands of rules.
Then we discovered that our particular rule base could easily be ported into C using a sequence of nested if/thens that ran much faster, and we stopped using OPS5. It was a great tool for doing the initial development, though.
Can you describe a bit more how prolog helped you here? Thanks!
>
>Prolog is not suitable for any problem domain, although this is more readily apparent for some domains than others.
At least they are honest about it LOL
I have tried to use it in combination will LLMs unsuccessfully, partly because the domain was not specific enough. Otherwise you need a lot of real world knowledge and a large fact database.
Logic engines for first order logic in RDF/OWL also have interesting logical inference abilities, like graphdbs.
Any programming language can do "logic" and the work at MIT/CSAIL in probabilistic programming may turn out to be a better way to combine fuzzy logic and formal proofs.
Not sure this answers your question, but maybe this points towards some interesting directions.
The thing is that i think that the language itself has so much untapped potential and the world that i dived into with my studies is so vast, so full of stuff that it left me kind of dazed to be fair!
I got some papers in regards to knowledge representation (that to be fair i still have to read... exams and work got in the midst of all :/) but still it seems so... odd: when we were studying OOP in my bachelor we went over the usual examples that made you understand "this is not an imperative paradigm but there are object abstractions" while, in my studies, prolog and logic programming in general was seen as a tool of sorts for reaching an objective like "hey we have a MAS system, let's sprinkle some prolog in it for fun :D" (maybe i am exaggerating but it feels like this lol). I feel it can do much much more
Reading "The Art of Prolog" and "The Craft of Prolog" was fun for me, as was learning how the Warren Abstract Machine works.
(I am not at all a prolog expert, merely a programmer who happens to be fascinated by it, so this is all dabbling on my end but hopefully provides some stuff that's fun to learn for you as well)
https://en.wikipedia.org/wiki/James_Hendler
My Prolog programming assignment #4, a Prolog "nehcihsahA" detector (maternal uncle: a mother's brother, or any equivalent relative) seemed designed to make me hate Prolog with a passion, involving bending over backwards by defining ridiculous predicates like siblish, sibloid, relatoid, sistoid, brothoid, mothoid, and fathoid.
https://www.donhopkins.com/home/code/nehcihsaha.prolog.txt
I much more enjoyed the OPS-5 programming assignment #6, for which I made a worm simulation that hacked into Ollie North's Intimus-007s ("the ace of security paper shredders") in the White House basement, via Professor Hendler's Sun workstation dormouse, rms's account with password rms on prep, and Casper Weinberger's account on UMD's Vax 11/780 mimsy and NSA's PDP-11/70 tycho, connected via the NSA's MILNET IMP 57 at Fort Mead, then posted Ollie North's secret diary and notes it found in the paper shredder to talk.rumors via the UCB-Vax usenet gateway.
https://www.donhopkins.com/home/code/crack-ollie.ops5.txt
https://news.ycombinator.com/item?id=18376750
>At the University of Maryland, our network access was through the NSA's "secret" MILNET IMP 57 at Fort Mead. It was pretty obvious that UMD got their network access via NSA, because mimsy.umd.edu had a similar "*.57" IP address as dockmaster, tycho and coins. [...]
Your attempt at a solution definitely defines ridiculous predicates, but you should not blame that on your teacher or the language. For example, there is no way that defining "a mother's brother" would need to refer to a "same sex" predicate in any way. You took a wrong turn somewhere with your approach, but again it's neither the language nor your teacher that forced you down that path.
What I've seen in practice is that while Prolog may be good at describing a solution, its performance is often too lackluster and brittle for actual deployment: it probably fits more as a prototyping language before you do a classic implementation of the solution in a more traditional language.
So e.g. a core.logic solution can make extensive use of the jvm ecosystem.
One interesting development recently is a load of research into, reverse engineering of and emulation of the 1986 Sega AI Computer[1], which used prolog under the hood for mostly educational software. Unfortunately it does not seem there is a way to actually write some prolog for the thing today :(
[0] https://github.com/mthom/scryer-prolog
[1] https://www.smspower.org/SegaAI/Index
Ah, for a second I thought someone just found a way to make Prolog useful for something. What a terrifying thought indeed, luckily the crisis has been averted, the natural order is restored and all is well.
I would check out Markus Triska's work to have your mind blown:
https://www.metalevel.at/prolog
https://youtube.com/@thepowerofprolog
https://swi-prolog.discourse.group/t/porting-the-swi-prolog-...
He finds Scryer performs worse, which he does comment on, he also explains some tradeoffs and historic choices in SWI's design which affects its performance. I think I have seen the author of Scryer saying that's not surprising and Scryer is still building up core functionality where SWI has had 30+ years to optimise, but I don't remember where I read that.
SWI has a document explaining some strengths and weaknesses regarding performance: https://www.swi-prolog.org/pldoc/man?section=swiorother
Edit: some discussion on Scryer previously on HN: https://news.ycombinator.com/item?id=28966133
Some default settings in SWI are not ISO-compliant (for example, it uses a string type that does not exist in ISO). But these are minor things that won't usually trip you up when feeding it ISO code. You can set flags to get it to conform in the way you want. And you should set flags whenever you want your ISO Prolog programs to be portable, because the standard is very lax and leaves a lot of things implementation-defined. But it specifies the flags to get implementations into the state you want.
"Once I saw this guy on a bridge about to jump. I said, "Don't do it!" He said, "Nobody understand me." I said, "What's so special about you?"
He said, "I'm a computer guy." I said, "Me too! Desktop, tablet, console, smartphone?" He said "Desktop, mostly", I said "Me, too! Mac, Linux or Windows?" He said, "Any, I'm a programmer." I said, "Me, too! which style? OOP, Imperative, Functional, Logic, Array, Stack" He said, "Logic." I said, "Me, too! What subset? Answer Set Programming, Abductive Programming, Prolog, Datalog?" He said, "Prolog." I said, "Me, too! Conformant with the ISO/IEC 13211-1:1995 (core) standard term syntax for the period character or non-conformant extention decried by members of the ISO/IEC JTC1 SC22 WG17 working group?"
He said, "SWI Prolog 7" I said, "Die, heretic!" And I pushed him over."
- https://news.ycombinator.com/item?id=26624442
or read more seriously here:
- https://www.complang.tuwien.ac.at/ulrich/iso-prolog/SWI7_and...
> "Once I saw this guy on a bridge about to jump. I said, "Don't do it!" He said, "Nobody understand me." I said, "What's so special about you?"
He said: "I don't want to jump".
* Jumps off a bridge
With Scryer Prolog and other recent systems that implement this representation, such as Trealla Prolog, we can easily process many GBs of text with DCGs, arguably realizing the full potential of the originally intended use case of Prolog for the first time. Trealla Prolog goes even further already, and allows overhead-free processing of files, using the system-call mmap(2) to virtually map files to memory, delegating the mapping to the operating system instead of the Prolog system.
The linked benchmarks do not test these aspects at all, and in addition use a version of Scryer Prolog that was completely outdated already at the time the benchmarks were made: The benchmarks use Scryer Prolog v0.8.127, which was tagged in August 2020, more than 3 years (!) before the benchmarks were posted. The linked benchmarks thus ignore more than 3 years of development of a system that was at that time 7 years old. Newer versions of Scryer Prolog perform much better due to many improvements that have since been applied. More than 1700 commits were applied between these dates.
In the face of the 24-fold reduction of memory use that the above-mentioned efficient string representation enables, small factors of difference in speed between different systems are in my opinion barely worth mentioning at all in any direction.
And yes, in addition to this great space efficiency, the strong ISO conformance of Scryer Prolog is also a major attraction especially when using it in highly regulated areas. For example, here is a recently envisaged application of Scryer Prolog in the context of machine protection systems (MPS) of giant particle accelerators, where adherence to industry standards is of great importance for warranty reasons among others:
https://github.com/mthom/scryer-prolog/discussions/2441
As another example, a medical application of Scryer Prolog, in the highly regulated domain of oncology trial design:
https://github.com/mthom/scryer-prolog/discussions/2332
Here is an overview of syntactic ISO conformance of different Prolog systems:
https://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformi...
This is mostly a nice talking point rather than an actual thing, right? Scryer's license contains the usual all-caps NO WARRANTY and NO FITNESS FOR A PARTICULAR PURPOSE wording. Also, the links you provided describe these applications without references to warranties and standards and regulation. The users in these super-sensitive domains don't seem as sensitive about them as you claim.
This is not true. For example, quoting from page 2 of the paper that is linked to in a discussion I posted, An Executable Specification of Oncology Dose-Escalation Protocols with Prolog, available from https://arxiv.org/abs/2402.08334:
"Standards are of great importance in the medical sector and play a significant role in procurement decisions, resolution of legal disputes, warranty questions, and the preparation of teaching material. It is to be expected that the use of an ISO-standardized programming language will enable the broadest possible adoption of our approach in such a safety-critical application area. For these reasons, we are using Scryer Prolog for our application. Scryer Prolog is a modern Prolog system written in Rust that aims for strict conformance to the Prolog ISO standard and satisfies all syntactic conformity tests given in https://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformi...."
Regarding warranty guarantees of Scryer Prolog, may I suggest you contact its author if you need to negotiate arrangements that are not catered for by the only licence terms you currently have access to?
One important advantage you get from the strict syntactic conformance of Scryer Prolog is that it reliably tells you what is Prolog syntax and what is not. In this way, you can use it as a free reference system to learn what Prolog is. The conformance makes it easier to switch to other conforming systems, such as SICStus Prolog which also offers different licences and commercial support, when you need to.
> The users in these super-sensitive domains don't seem as sensitive about them as you claim.
I am at a loss at this phrasing and also about the content of this text. Apart from the facts that I did not use the wording "super-sensitive", and that the importance of standards is explicitly stated in the paper I quoted above, is there even the slightest doubt about the great importance of standards when building and operating giant particle accelerators or devising dose escalation trials in clinical oncology?
> is there even the slightest doubt about the importance of standards when building and operating giant particle accelerators
The particle accelerator application is a checker for existing JSON config files. The accelerator is already running with those files. The proposed project is in an early stage. The checker will add more assurance, which is nice. The checker's author does not talk about the importance of warranties or standards. The checker could just as well be implemented in some non-ISO dialect as long as that dialect has a reliable specification and implementation.
So yes, there is the slightest doubt.
Edit: BTW, your oncology paper heavily uses CLP(Z), which does not have an ISO standard, so your argument is... The base language must be standardized, but arbitrary nonstandard extensions are OK? Please clarify as I've probably misunderstood.
CLP(FD/Z) is a candidate for inclusion in the Prolog standard: Several Prolog systems provide it with notable commonalities in features, it fits perfectly into the existing language, and it follows the logic of the standard including its error system. It can even be implemented within Prolog, provided a few basic features are present in a Prolog system. For instance, the CLP(Z) system I provide and which is used in the paper runs with little modifications already in several different Prolog systems, including SICStus, Scryer and Trealla. CLP(FD/Z) is an admissible extension of the existing standard:
This is completely different from modifications of the standard that do not fit at all into the standard. For instance, interpreting double-quoted strings differently from what the standard prescribes is not an extension in the sense the standard defines it, but a modification of the standard.In addition, Scryer Prolog has an execution mode where all its extensions are turned off. This is called a strictly conforming mode, and is also prescribed by the standard:
In Scryer Prolog, the strictly conforming mode is the default execution mode.Regarding the other points you mention: Even though it may sound easy to say "as long as that dialect has a reliable specification and implementation", I know no such system that exists, and what I see from systems that do not adhere to the Prolog standard makes me doubt that such a thing is possible. The systems that do not follow the standard often have elementary syntactic problems, such as reading a Prolog term that they themselves emit into a different Prolog term, a recipe for disaster and unacceptable in every domain I know.
Agreed, but also minor as you can and should set the double_quotes flag, otherwise your program doesn't have portable semantics even among ISO Prolog systems.
> Even though it may sound easy to say "as long as that dialect has a reliable specification and implementation", I know no such system that exists, and what I see from systems that do not adhere to the Prolog standard makes me doubt that such a thing is possible.
Of course it is possible to program against the quirks of a given implementation. That's what you yourself are doing with your CLP libraries. As you note, your main target has different quirks from other targets.
More broadly, Scryer itself demonstrates that it's possible to program against a programming language that doesn't have an ISO standard but does have a good enough specification and an implementation that adheres to that specification.
> The systems that do not follow the standard often have elementary syntactic problems, such as reading a Prolog term that they themselves emit into a different Prolog term, a recipe for disaster and unacceptable in every domain I know.
You're painting with a very broad brush here. What implementations, and what kinds of terms? If your examples involve infix dot, that would be the kind of term nobody uses and nobody should use in modern Prolog, as you well know. Some of these syntactic problems only appear if you go looking for them. Minor syntactic annoyances will be caught in testing.
I agree that such things are bad, but they are knowable, controllable, and quite probably much less relevant in practice than you suggest.
Very very tangentially: The company I work for is very serious about its software supply chains. If we want to use external software for development, we must apply for permission. For that permission, actual programmers and lawyers trawl through the code and licenses and documentation. Scryer's license file lists one copyright holder, and there are many source files without copyright headers, and then there are many source files with copyright headers that name another copyright holder. Our lawyers would not allow us to touch such a system. If you're serious about promoting Scryer as a serious Prolog for serious use, you might want to consider cleaning this up.
In the SWI-Prolog discourse thread linked above this is pointed out to Jan Wielemaker who clarifies it was a mistake. He then repeats the benchmark comparing a newer version of Scryer to SWI and finds that Scryer has improved significantly:
Updated Scryer Prolog to 0.9.3. They made serious progress. Congrats! The queens_clpfd.pl and the sieve.pl benchmarks have been added. The ISO predicates number/1 and retractall/1 have been added. I had to made more changes to to get the code loaded. Creating a module with the programs and some support predicates somehow did not work anymore (predicates became invisible). Loading a file programs.pl from directory holding a subdirectory programs silently loaded nothing until I added the .pl suffix. The sieve bar is cut at 20, but the actual value is 359.
https://swi-prolog.discourse.group/t/porting-the-swi-prolog-...
One thing to check out: Prolog plays fairly well with Python, providing opportunities for hybrid projects.
"The Janus System: Multi-paradigm Programming in Prolog and Python"
You need to install swi prolog https://www.swi-prolog.org/download/stable and pip install janus_swi
A simple example to get started: https://www.swi-prolog.org/pldoc/doc_for?object=section(%27p...
The authors were fairly prominent Prolog researchers. It's sad Van Roy is retiring and nobody is taking this forward. AliceML, a StandardML dialect inspired by Oz is also abandonware.
The biggest source of friction I noticed when playing with PySwip was that because Prolog code was represented as strings, you avoided generating it on the fly. It would be nice to have an embedded DSL for Prolog in Python. (I am thinking something like SymPy or the Pony ORM—https://github.com/ponyorm/pony.)
Clorm (Clingo ORM) [1] makes it easy to create facts after you define simple predicate Python classes. Here's an example project of mine which uses it to set up a scheduling problem (Python -> ASP) and to present the results (ASP -> Python).
https://github.com/raceconditionrunning/relay-scheduler
Clingo (the solver) exposes its internal AST implementation through Python bindings[2], so you can build up rules or other statements from typed components instead of strings. This simplifies the translation bits of implementing an ORM or whatever kind of wrapper a developer would prefer.
[1] https://github.com/potassco/clorm [2] https://potassco.org/clingo/python-api/current/clingo/ast.ht...
Related areas like constraint programming are still very relevant.
Not only is it conceptually much simpler, it's also a "pit of success" situation as thinking in terms of relations instead of tables leads you towards normal forms by default.
Add the ability to automatically derive new facts based on rules and it just wins by a country mile. I recommend giving Soufflé a try.
I haven't worked with GraphDBs enough to comment on that.
Datalog starts by evaluating all possible combinations of facts and rules. It builds a bottom-up derivation of all possible facts:
a. First, it derives all direct parent relationships.
b. Then, it applies the ancestor rules iteratively until no new facts can be derived.
For the query ancestor(john, X):
It returns all X that satisfy the ancestor relationship with john. This includes mary, ann, and tom. The order of rules doesn't affect the result or termination. Datalog guarantees termination because it operates on a finite set of possible facts.
Prolog uses a top-down, depth-first search strategy with backtracking.
For the query ancestor(john, X):
a. It first tries to satisfy parent(john, X). This succeeds with X = mary.
b. It then backtracks and tries the second rule: It satisfies parent(john, Y) with Y = mary. Then recursively calls ancestor(mary, X).
c. This process continues, exploring the tree depth-first.
Prolog will find solutions in this order: mary, ann, tom.
The order of clauses can affect both the order of results and termination: If the recursive rule were listed first, Prolog could enter an infinite loop. Prolog doesn't guarantee termination, especially with recursive rules.
SQL is more verbose. The equivalent of the Datalog/Prolog example above is:
This is a more interesting example of how one might use Datalog on a large dataset: The equivalent Postgres example would be:Is this an issue in practice? Most languages can create programs with infinite loops, but it's easy to spot in code reviews. It's been over a decade since I encountered an infinite loop in production in the backend. Just wondering if the same is true for Prolog.
It is trivially easy to create loops of rules when describing abstract properties.
Concrete properties tend to have "levels" to them, but many human concepts are self-referential.
In this way, its possible to spot that there may be an issue now or in the future, because the presence or lack of a loop depends on the specific choice of dependencies of a concept. However spotting the potential for a loop doesn't do a lot to help remove its potential existence, or show that it is there or not there.
Prolog variables can have two states at runtime: unbound or bound. A bound variable refers to some value, while an unbound variable is a "hole" to be filled in at a later time. It's common to pass an unbound variable into some call and expect the callee to bind it to a value. This can cause problems with infinite recursion where you intend to write a call that binds some variable, but the way you've structured your program, it will not actually bind it. So the callee ends up in the same state as the caller, makes a recursive call hoping its callee will bind the variable, and down the infinite recursion you go. With experience you can definitely spot this in code review. You'll also catch it in testing, if you test properly. But it's different enough from other languages that learners struggle with it at first.
Another source of (seeming) nontermination is when you ask Prolog's backtracking search to find an answer to some query in a search space that is too large and may not contain an answer at all, or only an answer that is impracticably far away. This is also sort of Prolog-specific since in other languages you rarely write the same kind of optimistic recursive search. This is harder to spot in code review since it's really application-specific what the search space looks like. But again, you test. And when in doubt, you direct and limit the search appropriately.
As an anecdote, a long time ago for a toy project switching two rules order got the runtime to finding all solutions from ~15mn to a around the second (long time, memory fuzzy...). The difference was going into a "wrong" path and wasting a lot of time evaluating failing possibilities, vs. taking the right path and getting to the solutions very quickly.
So in practice even if Prolog is declarative to get good results you need to understand how the search is done, and organize the rules so that this search is done in the most efficient way. The runtime search is a leaky abstraction in a way ;)
It's not an issue limited to Prolog, many solvers can be helped by steering the search in the "right" way. A declarative language for constraint problem like MiniZinc provides way to pass to the solver some indication on how to best search for example.
Also, most modern Prolog support tabling, which departs from strict DFS+backtracking and can help in some cases. But here too, to get the best results may require understanding how the engine will search, including tabling.
Minor nitpick regarding an otherwise good answer: Prolog systems will warn you about "singleton variables", that is, variables with exactly one occurrence. This does catch the usual cases of this kind of error.
For me, while that kind of thing gets me once in a while it never makes it to my final commits. That's because I always test every predicate I add to a program in isolation. Hey, sometimes I even write unit tests! So my experience is that the ability to write and test your program in sizeable chunks makes up for the danger of unbound variables causing infinite loops, in practice.
Also note that some Prologs have helpful error messages that direct the user to the problem. E.g. in SWI-Prolog (in "debug" mode):
Note: _________________________[1] I remember two infinite loops in production, one in the backend, one in the frontend. That was ca. 2013 so more than 10 years ago- good estimate!
The first loop was a missing terminating condition in a for-loop in C# that brought down the company's server along with every client's deployment (it was before everyone moved all their data to the cloud, you see). There was a meeting Upstairs™ and the programming team lead returned to tell us that he had explained what happened, explained that it was nobody's fault and that there's no way to prevent infinite loops like that happening again with perfect certainty, and that Upstairs had decided that, henceforth, iteration should no longer be used and when loops are required recursion should be used instead. Obviously that was completely ignored and everyone carried on as before.
The second loop was a bona-fide recursion without a terminating condition that happened in an in-house, Jango-like, templating language, called Mango. I don't remember the details but the folks who had coded the Mango interpreter evidently did a good job because it had no problem interpreting a recursive call in a template. The programming team lead from the previous story found it in a late-afternoon session where it was just me and him in the room. I felt a little deflated but I was just a junior starting out so I guess I was excused for missing it.
One of the core problems is related to the reversible nature of Prolog. Not only are some programs reversible and some are, practically speaking, not, there are many gradations on this.
The result is that programs that look equivalent and whose tests appear equivalent may exhibit non-termination in surprising ways. This is, in my experience, the rule rather than the exception with Prolog.
That detracts from the declarative aesthetics of the program code so it upsets purists but it is very useful to those who want to actually use the language to actually write actual programs and so can avoid lots of wailing and gnashing of teeth.
In other words, Prolog is like any other programing language: if you're careful, you will not hurt yourself. Also applies to chainsaws, bathtubs, and banana peals.
[1]: https://typedb.com/ [2]: https://terminusdb.com/ [3]: http://www.fdi.ucm.es/profesor/fernan/des/ [4]: http://webdam.inria.fr/Alice/ [5]: https://github.com/evgskv/logica
It was discussed on HN https://news.ycombinator.com/item?id=33756800 and is implemented in go. There is the beginnings of a Rust implementation meanwhile.
If you are looking for datalog in the textbooks, here are some references: https://github.com/google/mangle/blob/main/docs/bibliography...
A graph DBs short intro to datalog: just like the edges of a graph could be represented as a simple table (src, target), you could consider a database tuple or a datalog or prolog fact foo(x1, ..., xN) as a "generalized edge." The nice thing about datalog is then that as one is able to express a connections in an elegant way as "foo(...X...), bar(...X...)" (a conjunction, X being a "node"), whereas in the SQL world one has to deal with a clumsy JOIN statement to express the same thing.
Aside: I write a lot more Python than Clojure, and I wish someone ported Datalevin/Datahike/persistent DataScript to Python. I'd try it as an alternative to SQLite. I suspect with thoughtful API design, an embedded Datalog could feel organic in Python. It might be easier to prototype with than SQLite. There are Datalog and miniKanren implementations for Python, but they are not designed as an on-disk database. PyCozo might be the closest thing that exists. (A sibling comment https://news.ycombinator.com/item?id=40995652 already mentions Cozo.)
https://github.com/cozodb/cozo
Has a dialect of Datalog + some vector support. Multiple storage engines for backend including SQLite, so if your concern is data stability that seems like a reasonable, proven option.
https://www.j-paine.org/dobbs/prolog_lightbulb.html
I don't publish episodes often but I have a lot of good interviewees lined up :)
In general, I would advice you to look beyond Prolog and explore Answer Set Programming, the Picat language, and the connections between logic programming and databases (SQL, RDF or otherwise). Not instead of Prolog, but in parallel. Prolog is awesome!
I particularly enjoyed the first episode, the conversation with Robert Kowalski.
Borrowing and ownership is great for building safe code, whether it's single- or multi-threaded. In C, you have a nest of pointers, and a pointer communicates nothing about the ownership of its memory. Stuff can go, and leak, and dangle, everywhere. C++ mitigated this a little with references. Then it bolted on smart pointers, mitigating it further. Without learning Rust, though, I don't think I'd be as good of a C/C++ programmer because, unlike Rust, those languages don't force you to think about where memory lives and where it's going.
The module system is also way better.
Then I could take cheap shots: `u8` is way better than `uint8_t`. Rust had slices from the beginning, to be able to refer to parts of strings in a cheap way with easy syntax, whereas only C++17 introduced the comparatively awkward `std::string_view`.
There are ways I think Rust is worse though! The easiest is that it still doesn't have a standard and will probably not see the uniquely deep and broad support of C/C++ in my lifetime. :p
https://www.swi-prolog.org/
Edit: ... and on performance vs SWI Prolog, too
[1]: https://en.wikipedia.org/wiki/ENQUIRE
[2]: https://quantumprolog.sgml.io
For instance if I wanted to express financial regulations or business rules inside a bank or other business I'd need to use math: for instance to express the conditions for reserve requirements or approving a loan.
OWL is best thought of as a set of templates for generating first-order logic rules that are decidable and also (in theory) quick to evaluate with the Tableau algorithm.
In certain domains you might tolerate tools that are imperfect, like it isn't fair to expect a SMT solver to figure out this one
where x,y,z and N are all positive integers with N>2. For that one it would try to find solutions and probably time out. For some similar problems (a different polynomial) it might give you an answer.OWL doesn't want to go there which is a big reason people say "Nein Danke!"
He did no such thing. He proved undecidable problems exist in any system powerful enough to be useful. That doesn’t make those systems useless, though.
I think they could have made a more expressive standard and something like that might have had more appeal to people but been less consistent in terms of performance.
That narrows down the already small niche where one would choose Prolog by probably a few orders.
In my opinion, this does not imply that proper lisp (and correspondingly prolog) implementations are useless, just because a simple implementation can be written in a different, "more expressive" language.
https://en.wikipedia.org/wiki/MiniKanren
There's a great book in the same series as the "Little Lisper"/"Little Schemer" books called "The Reasoned Schemer" that uses MiniKanren with Scheme.
For many, how the language faces the user, how its paradigms fit the problems at hand and the user's mode of seeing the world, that is more important.
These days, with the terabytes the petaflops and the megajoules, it might be even less relevant how the gears are turning inside the black box.
I don't think that performs like a proper Prolog engine on larger problem.
Real Prologs work by compiling to something called the WAM (Warren Abstract Machine).
I don't think I've ever seen a discussion of Resolution in functional programming textbook implementations of "Prolog". They typically just bodge some depth-first search with backtracking and unification in polish notation and call it "Prolog", or "logic programming". A bit like if I wrote a "lisp" with eval(X):- call(X), then completely ignored all that jazz about lambda calculus and concentrated on garbage collection and linked lists.
A good starting point instead, if one wishes to understand Prolog and not just dismiss it out of hand, is to try and understand Resolution, and what unification does for Resolution, and why it ended up in Prolog (and how) in the first place. I'd start, well, at the beginning:
A Machine-Oriented Logic Based on the Resolution Principle
https://www.semanticscholar.org/paper/A-Machine-Oriented-Log...
Where you can follow the progress from ground Resolution, to unification, the Resolution theorem, and all the way to the (pre-modern) Subsumption Theorem. It's a long way to Prolog from there, but that's where it all begins.
_______________
[1] Although Prolog implemented by DFS is not complete if Prolog implemented by DFS is not complete (etc).
You might also want to look at Erlang which is used in the Industry and would be helpful for your future. Joe Armstrong was originally inspired by Prolog and he conceived Erlang as Prolog-Ideas+Functional/Procedural+Concurrency+Fault-Tolerance. Hence you might find a lot of commonalities here. Here is a recent HN thread on a comparison - https://news.ycombinator.com/item?id=40521585
There is also "Erlog" (by Robert Virding, one of the co-creators of Erlang) which is described as, Erlog is a Prolog interpreter implemented in Erlang and integrated with the Erlang runtime system. It is a subset of the Prolog standard. An Erlog shell (REPL) is also included. It also says, If you want to pass data between Erlang and Prolog it is pretty easy to do so. Data types map pretty cleanly between the two languages due to the fact that Erlang evolved from Prolog. - https://github.com/rvirding/erlog
But of course, the submarine is like a cigar, not cigar like a submarine.
But apart from syntax, Erlang has quite different goals as a backend language for interruption-free telco equipment compared to Prolog.
See pdf linked here - https://news.ycombinator.com/item?id=40998632
There is a lot of historical connection to Prolog, due to the original implementation, and there are syntactic similarities and non-linear pattern matching and dynamic types and a general declarative vibe, but the actual end result of Erlang's evolution, despite the goal of "something like Prolog", is not very much like Prolog at all. Erlang is a functional language, not a logic language. Prolog is a logic language, not a functional language. General goals like in that quote can change over the decade-long development of a language.
Joe Armstrong wrote two papers The Development of Erlang (linked here https://news.ycombinator.com/item?id=40998632) and a longer A History of Erlang (pdf at https://www.labouseur.com/courses/erlang/history-of-erlang-a...). In addition to his thesis (pdf at https://erlang.org/download/armstrong_thesis_2003.pdf) they provide a fascinating study into what goes into the design of a language i.e. lots of messy experiments, shifting goals, inspiration/features from many different languages etc. until everything coalesces into a organic whole which is then validated by users. Reading the above two papers will give you a more complete picture of Prolog's influence on Erlang (in addition to others).
I think Joe Armstrong was a user here and I interacted with him waaaay way back when I first joined. He's dead now :(
But that's where the "commonalities" you mention in your OP, between Prolog and Erlang, end. Similarly, CSS and XML are declarative but that's where their "commonalities" with Prolog (and Erlang) end.
I'm insisting with this because I'm concerned that your comment promulgates a common misconception about the, like you say, "commonalities" between Prolog and Erlang. These end with syntactic similarities and misunderstanding this can cause some disappointment to people trying to go from one to the other. I've seen a similar misunderstanding arise about "commonalities" between Prolog and, e.g. Haskell - they both have weird, arcane syntax and immutable data structures, but that's all. Or, think of C and javascript: both Algol like syntax and in fact the first js compilres must have been written in C, but that's all. etc.
There is much, much more to Prolog than the declarative syntax.
I had explicitly stated above that "he conceived Erlang as Prolog-Ideas+Functional/Procedural+Concurrency+Fault-Tolerance." Here i am not making an equivalence between Prolog and Erlang but emphasizing the inspiration that Prolog provided for the design of Erlang (that is what is to be understood from all the links to the papers and comparison charts given in earlier comments). That inspiration is in the syntax of pattern matching, Atoms/Variables, Module/Export directives etc. Similarity of Syntax is very important for learning/understanding new languages since your cognitive load is decreased dramatically. A good example is C++ to Java/C# where the similarity in syntax (though the runtime object model is very different) is what was crucial to the widespread adoption of the latter. It is in this sense that Prolog to Erlang comparisons should be understood.
Your arguments of grouping/comparing widely dissimilar languages are somewhat disingenuous. A much better side-by-side comparison of languages is https://hyperpolyglot.org/ where the author has tried to group by intended functionality and historical development. I think this is a good way to do it.
What I'm saying is that this is the entirely wrong thing to focus on, i.e. syntactic similarities. Prolog is a language of the logic programming paradigm, one of the first ones. Its syntax is that of (a restriction of) the first order predicate calculus. Its programs are First Order Logic theorems. Its interpreter is an automated theorem prover. The motivation for Prolog is the ability to program a computer using the syntax and semantics of First Order Logic, to be able to prove the truth values of statements in a formal language automatically, with a computer. It has nothing to do with Erlang, a functional programming language designed to program telephony switches. Any similarity is superficial: Erlang expressions are not definite clauses; everything in a Prolog program is a definite clause, modulo punctuation. Knowing Erlang will not help you learn Prolog just because the syntax looks similar. You can forget about that right now- that's the misconception I'm trying to correct. Don't encourage people to try to understand Prolog that way because you will only cause them pain.
Take the site you link to as an example. It tries to bodge together Prolog with Erlang and Elixir in a "side-by-side reference sheet" that includes rows for "assignment" and "parallel assignment" using =/2. That's the unification predicate! Prolog does not have assignment! Just imagine the suffering of a novice programmer trying to use their knowledge of assignment, in Erlang or any language, to understand the following:
That's just setting up programming students to fail, to fail to understand, to fail to learn- and to only succeed in blaming Prolog for being a stupid, painful language that is hard to learn. Of course it's hard to learn! If you go around telling people that they can learn it more easily if they know Erlang!>> Your arguments of grouping/comparing widely dissimilar languages are somewhat disingenuous.
No, the point is that they are widely dissimilar and that you won't understand that if you just stop at the syntax. Like the site you link to, where someone clearly made an effort to memorise syntax but completely failed to understand semantics.
Semantics shmantics! The attitude I see here is the one that Peter Norvig criticises in "Teach yourself programming in 10 years": try to find a shortcut around the hard stuff so you don't have to use the brain. You don't learn anything that way.
> Knowing Erlang will not help you learn Prolog just because the syntax looks similar.
That is not what is being suggested. This is your fundamental misconception which permeates the rest of your post. The OP is already studying Prolog and is being advised to look into Erlang too in addition to that. It is not "instead of" but "in addition to" (due to the history of Erlang). Furthermore Erlog allows you to embed Prolog within Erlang giving the OP the best of both worlds.
> you won't understand that if you just stop at the syntax.
Again this is your misconception. That is not what is being suggested. Nobody in their right mind will say "stop at the syntax". But syntax is the gateway into the study of computer languages i.e. you first show the syntax and then explain its semantics. Humans learn new things using analogies/similes/metaphors/etc. Here similar syntax is a great help since it eases the cognitive load while learning new concepts. When the semantic model varies, the dissonance may not be too great and so we can better modify our mental models and understanding.
The website listing the syntax comparisons of various languages is actually pretty useful when looked at with the above viewpoint. Start with your known syntax in a language you know, see how it maps to the same/similar syntax in the language you want to study and then lookup/compare/contrast the semantics of it in both the languages. It is like a cheat-sheet while studying a proper programming language textbook.
I don't think so. In your comment above you keep saying that it's not about syntax, then immediately after you switch to explaining how it really is. Notice this for instance. I say:
>>> Knowing Erlang will not help you learn Prolog just because the syntax looks similar.
You say:
>> That is not what is being suggested.
Then you go on to say:
>> But syntax is the gateway into the study of computer languages i.e. you first show the syntax and then explain its semantics. Humans learn new things using analogies/similes/metaphors/etc. Here similar syntax is a great help since it eases the cognitive load while learning new concepts.
And:
>> Start with your known syntax in a language you know, see how it maps to the same/similar syntax in the language you want to study and then lookup/compare/contrast the semantics of it in both the languages. It is like a cheat-sheet while studying a proper programming language textbook.
So it's hard for me to see how you're not suggesting that syntax will help you learn Prolog, when you're arguing that syntax helps you learn a new language.
And what I'm saying is that knowing something about the syntax of Erlang will not help you learn anything about Prolog. I don't think you can accept that at all, but it's true and it's my experience of many years watching people, including myself, trying to learn Prolog using their knowledge of other languages, either their syntax or semantics. My experience includes working as a teaching assistant for a Prolog course during my PhD. The truth is that Prolog is not an easy language to learn because it works very differently than any other programming language and you won't be able to use your knowledge of any other programming language to learn it. If you want to learn Prolog you have to start by finding a way to set aside most of what you know about programming. That is very hard to do, and so it's very hard to learn Prolog, except at a very superficial level.
I appreciate that's not easy to accept without long time experience.
But I don't think we're getting anywhere with this conversation so I'll respectfully bow out and thank you for the patient and civil exchange of views.
To settle this once and for all; in your previous post you gave the example of assignment which actually proves my point that you can easily go from Prolog to Erlang. Why? Because the behaviour is the same in Erlang i.e. there is no assignment but only pattern-matching. You can open a Erlang shell and type in X=a, X=b and it will barf. To show it even more convincingly type in Y=1+2, Y=3 and Y=4 and it will barf only on the last line. Lhs=Rhs are pattern-matched and variables are single assignment. A person with prior exposure to Prolog already knows this and hence can easily map it to Erlang. Only people coming from imperative languages (eg. C) need to adjust their mental model of the "=" operator. When i started with Erlang years ago that was what i had to learn first but thankfully all Erlang books cover it in the introductory chapter itself. Also functions in Erlang are written as a series of clauses which are pattern-matched.
I presume you do not have experience with Erlang and so your experience with only Prolog blinds you to the similarities. I highly recommend you get a Erlang book (Joe Armstrong's book is a good one since he uses much of the terminology like "terms", "clauses" etc. from Prolog) and with the help of the cheatsheet just try out the basic syntax in the Erlang shell and see what maps to Prolog. I am quite sure that you will find it convincing.
Finally w.r.t. Prolog's computation model being based on Predicate Calculus/First-Order Logic and so the model/semantics are very important is not being denied. I myself came to Predicate Calculus from the "Program Correctness" viewpoint of Floyd/Hoare/Dijkstra and hence an quite aware of its intricacies. But for most programmers without such a background in Set theory/Relations/Logic model building takes time and so syntax is their entry point and understanding happens over a period of time with study and trial-and-error.
- no proper module nor package system in the modern sense.
- in large code bases extra-logical constructs (like cuts) are unavoidable and turn Prolog code into an untenable mess. SWI prolog has single-sided unification guards which tackle this to a degree.
- lack of static and strong types makes it harder to write robust code. At least some strong typing would have been nice. See Mercury as an example of this.
All being said, Prolog is amazing, has a place in the future of programming, and gives you a level-up understanding of programming when you get how the types in every OO program is a Prolog program itself.
Old_man_yells_at_cloud.jpg
I would go as far as to say that Prolog is more a problem solving language rather than a system building language. Package managers and module systems are for modularization of big systems. You don't need that when solving small recurrent problems. Furthermore, lack of them forces you to avoid dependencies, that most of the time would end as technical debt. IMHO.
"Any sufficiently complicated type system contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Prolog."
Using something like an embedded Prolog or miniKenran as the core of a Kubernetes operator is something I've wanted to try my hands on.
- infinite data defined by recursive predicates
- flexible data structures (think JSON but better, called complex terms) and a way to query them (called unification algorithm)
- execution strategy fine-tuned for reasoning (called resolution algorithm). You can do this with SQL but you’d have to formalize things using set operations and it’d be very very slow.
On the other hand, SQL can query plain data very very fast.
Serious question, I'd like to have something that's easy to integrate with Node.js.
"Mythical CP solver packages and OR-tools"? Lol!
Google's OR-Tools [1] has been winning golds in the MiniZinc Challenge since 2013 [2]. In 2023 it won Gold in most categories and the only Prolog to win, SICStus Prolog, took one Silver back. I'm curious where you're spending time in the community if you can word a comment like this as OR-Tools is the behemoth in this area and Prolog is the weird hacker siren call that appeals to people who certainly aren't about to publish anything novel in the space.
I say this as someone who has tinkered a lot with Prolog over the years and finds Prolog's execution model to work really well with the way I think about programming. Prolog and its hybrid solver model just isn't good enough at any one thing to make it SOTA. It's fun to tinker with, but I just don't think in 2024 it has enough to offer anyone who's not interested in the language or the WAM to make it worth exploring, especially not as an embedded constraint solver.
[1]: https://developers.google.com/optimization/
[2]: https://www.minizinc.org/challenge/
To be clear what I'd like is to be able to fire up a thread hosting a Prolog runtime and stick predicates into it and query it using an API in the host language's syntax. Instead the best I could do was munge strings together and parse result out, sort-of. And that was after a bunch of time spent trying to reverse-engineer Scryer's API.
I would love to embed a Prolog to host my application's business rules and knowledge. I could see it super useful in a game even (think of the myriad of crazy rules and interactions and special cases in a game like Dwarf Fortress...)
https://en.wikipedia.org/wiki/Fifth_Generation_Computer_Syst...
>The Fifth Generation Computer Systems (FGCS; Japanese: 第五世代コンピュータ, romanized: daigosedai konpyūta) was a 10-year initiative begun in 1982 by Japan's Ministry of International Trade and Industry (MITI) to create computers using massively parallel computing and logic programming. It aimed to create an "epoch-making computer" with supercomputer-like performance and to provide a platform for future developments in artificial intelligence. FGCS was ahead of its time, and its excessive ambitions led to commercial failure. However, on a theoretical level, the project spurred the development of concurrent logic programming.
>The term "fifth generation" was intended to convey the system as being advanced. In the history of computing hardware, there were four "generations" of computers. Computers using vacuum tubes were called the first generation; transistors and diodes, the second; integrated circuits, the third; and those using microprocessors, the fourth. Whereas previous computer generations had focused on increasing the number of logic elements in a single CPU, the fifth generation, it was widely believed at the time, would instead turn to massive numbers of CPUs to gain performance.
[...]
>Concurrent logic programming
>In 1982, during a visit to the ICOT, Ehud Shapiro invented Concurrent Prolog, a novel programming language that integrated logic programming and concurrent programming. Concurrent Prolog is a process oriented language, which embodies dataflow synchronization and guarded-command indeterminacy as its basic control mechanisms. Shapiro described the language in a Report marked as ICOT Technical Report 003,[7] which presented a Concurrent Prolog interpreter written in Prolog. Shapiro's work on Concurrent Prolog inspired a change in the direction of the FGCS from focusing on parallel implementation of Prolog to the focus on concurrent logic programming as the software foundation for the project.[3] It also inspired the concurrent logic programming language Guarded Horn Clauses (GHC) by Ueda, which was the basis of KL1, the programming language that was finally designed and implemented by the FGCS project as its core programming language.
>The FGCS project and its findings contributed greatly to the development of the concurrent logic programming field. The project produced a new generation of promising Japanese researchers.
https://www.sjsu.edu/faculty/watkins/5thgen.htm
>The Japanese Fifth Generation project was a collaborative effort of the Japanese computer industry coordinated by the Japanese Government that intended not only to update the hardware technology of computers but alleviate the problems of programming by creating AI operating systems that would ferret out what the user wanted and then do it. The Project chose to use PROLOG as the computer language for the AI programming instead of the LISP-based programming of the American AI researchers.
The Japanese National Fifth Generation Project: Introduction, survey, and evaluation:
https://stacks.stanford.edu/file/druid:kv359wz9060/kv359wz90...
>Abstract:
Projecting a great vision of intelligent systems in the service of the economy and society, the Japanese government in 1982 launched the national Fifth Generation Computer Systems (FGCS) project. The project was carried out by a central research institute, ICOT, with personnel from its memb...
http://www.call-with-current-continuation.org/fleng/fleng.ht...
--
1: https://doc.flix.dev/fixpoints.html
2: https://news.ycombinator.com/item?id=25513397
2: https://news.ycombinator.com/item?id=31448889
2: https://news.ycombinator.com/item?id=38419263
For "proper" Prolog, in 2024 it is a niche language alive in specific constraint solving applications, but not really used outside of that. I haven't seen anyone attempting at using prolog as a general purpose language since the 90'.
Datalog and logic-inspired languages tend to pop up here and there as domain-specific languages.
Rego is a recent incarnation which had good adoption for k8s and other "modern" systems. However, when trying to get people in my org to adopt it in practice, I saw engineers struggle with the paradigm when complexity grows to more than toy problems.