Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Swish: SWI Prolog Notebook (swi-prolog.org)
147 points by xfer on Oct 29, 2019 | hide | past | favorite | 53 comments


If anyone is interested in learning Prolog I can recommend two very good Prolog books: The Power of Prolog[1] and Simply Logical: Intelligent Reasoning by Example[2]. I also recommend visiting the Awesome Prolog list[3]. Worth checking also a very interesting extension of the Prolog - Probabilistic Prolog, aka ProbLog[4]. And modern ISO-compatible implementation in Rust language - Scryer Prolog[5].

[1] https://www.metalevel.at/prolog

[2] https://book.simply-logical.space/

[3] https://github.com/klaussinani/awesome-prolog

[4] https://github.com/ML-KULeuven/problog

[5] https://github.com/mthom/scryer-prolog


I didn't know about the second link. Thanks!


For an awesome video showcasing a bit of the real power of Prolog, you need to check (if you haven't already) this Strangeloop talk:

"Production Prolog" by Michael Hendricks

https://youtu.be/G_eYTctGZw8


That is an awesome talk. I'll second the recommendation.


I think I started watching this a few years ago and never finished it which is sad because you are correct that this was fascinating. Maybe I'll give Prolog another go.


Huh, is SWI Prolog having a moment?

I had always heard of Prolog as being obscure and overly academic. It's popped up a little bit recently however - the last place I heard of it in use is in the recently launched TerminusDB https://github.com/terminusdb?language=prolog


It doesn't particularly look like it's having a moment: https://trends.google.com/trends/explore/TIMESERIES/15723666...

Both Haskell and Prolog seem to run on a school-year cycle where search interest peaks a little before the end of the semester. Prolog's cycle is significantly more pronounced, suggesting the interest is indeed purely academic. Whereas Rust has been growing steadily and shows little seasonality.

I'd say it's random chance, given X million programmers and Y million articles there's always somebody who will see a lot of Z topic.

Terminus in particular seems to be an extension of work Gavin did during his postdoc, in particular the Dacura stuff mentioned here: http://aligned-project.eu/open-source-tools/. He deleted the DQS repository for some reason but there's a mirror here: https://github.com/bozicb/dacura-1.


Interesting, from Google trends, it seems that Haskell is very popular in China, compared to other regions. I wonder what can be the reason for this.


Competitive advantage.

By inflating the search results they'll encourage the competition to spend inordinate amounts of time learning cat theory and trying to get the compiler to understand their code. In the mean time they'll hack it together in Perl.

Sorry for the inappropriate about at humour, I couldn't resist.


Google is blocked in China, so I suspect that there are very few data points for Trends to draw on, as filtering the data to China, the graph seems raggedy, something like 4 searches/week. It also shows the spike in Haskell only occurred this week and says it is partial/incomplete data. So overall, probably just a data processing/extrapolation bug.

That's not to say that Haskell isn't used in China; there is a visualization group in Didi (Chinese Uber) that uses it, Haskell/FP user groups, university classes, etc. But there's no obvious reason that Haskell would have massively shot up in the past 3 days.


Consider that fact that prime-minister of Singapore knows Haskell by now

http://wadler.blogspot.com/2015/04/prime-minister-of-singapo...

He is already quite good with C++

https://arstechnica.com/information-technology/2015/05/prime...


Audrey Tang is a Tawaainese Minister (not sure of what.. computing?) and wrote one of the first Perl6 implementations using Haskell I think.


"Digital Minister in charge of Social Innovation, Open Government and Youth Engagement".


Thanks for the clarification Audrey! Quick question...do you still actively code? If so, which technologies do you use? I assume a government politician (even for a very technical role) has little time for such things, so how do you stay up to date?


I still actively code. Most of the gov tech we deploy in Taiwan is based on civic tech, re-packaged to run on sandstorm.io (CodiMD is a good example). We also rely heavily on Pol.is and Rocket.chat.

Other than that, a lot of it is just automating chores — booking my office hour appointments, maintaining sayit.pdis.nat.gov.tw (part of the radical transparency protocol visit.pdis.tw), etc.

Non-work-related projects such as moedict.tw and Hackage/CPAN modules are mostly in maintenance mode, with occasional releases based on pull requests from the community.


Thanks for the reply and best of luck in your endeavors! I've never been very good with Haskell, but I may jump into Perl6 (Raku) soon.


Prolog does have that reputation, but it's undeserved. It's incredibly fun to both learn and develop in, and it's very enlightening to learn this alternate model of computation. Prolog is awesome.


No. It is not... The CUT operator is worse than Ruby's monkey patching for debugging and maintenance reasons... Prolog without CUT is awesome, but currently there is no way to have reasonable performance without it.


You can very often rewrite uses of the cut like:

    foo(X, Y) :-
        some_condition(X),
        !,
        bar(Y, X).
    foo(X, Y) :-
        baz(X, Y).
to:

    foo(X, Y) :-
        (   some_condition(X)
        ->  bar(Y, X)
        ;   baz(X, Y) ).
and get the same performance and clearer code.

There are really very few actually useful uses of the cut in modern Prolog code. But we have no good, free, current teaching materials, so people get stuck learning the old ugly and convoluted ways.


The arrow uses a cut internally which renders it nonlogical and ruins any benefit you'd get from even writing Prolog. At that point you're just using Prolog as a quirky imperative language.

Unfortunately since it's almost impossible to model ideas without stuff like the arrow, cut, or \+ (not) operators, writing actual pure logical Prolog programs that actually do interesting things is supremely difficult.


So the arrow doesn't represent logical implication? As a non-native, I would have read that as a clause that always resolves to `baz(X, Y)` unless the implication holds (i.e., `some_condition(X)` is true). Isn't that logically consistent?


In general, using any of the mentioned predicates (->)/2, (\+)/1 or !/0 in Prolog code destroys essential properties we expect from classical logic, and therefore complicates declarative reasoning about the code to such an extent that it can be said to prevent it entirely.

For example, both versions of foo/2 that are shown above suffer from the same core deficiency: If some_condition/1 has multiple solutions, then they are cut away and not generated at all. Therefore, for the most general query,

    ?- foo(X, Y).
only a single answer, or a proper subset of all answers one would expect when reading (->)/2 as "implies", may be shown where, under a declarative reading based on first-order logic, there ought to be more.

This is problematic because if any concrete solution S is cut off due to this deficiency, we can still force the Prolog system to yield it with:

    ?- X = S, foo(X, Y).
So, we are in the situation that adding a constraint (X = S) yields a solution that is not shown when the constraint is removed. In other words, a specialized version of the predicate is more general than the original definition. This violates monotonicity, which is an essential property of classical first-order logic, and the basis for declarative debugging approaches that let us reason about the location of mistakes in Prolog predicates.

To write good declarative Prolog code that is also efficient, we first need to find and implement the mechanisms that let us express predicates like foo/2 in such a way that they are efficient while retaining their generality as logical relations.

One important building block pertaining to this concrete example was recently found with the new language construct if_/3, described in Indexing dif/2 by Ulrich Neumerkel and Stefan Kral:

https://arxiv.org/abs/1607.01590

With if_/3, we can write foo/2 as:

    foo(X, Y) :-
        if_(some_condition(X),
            bar(Y, X)
            baz(X, Y)).
The only requirement for this to work is to have a reified version of some_condition/1, in such a way that we can tell, from the implicit second argument, whether the condition holds or not, while still generating all answers for the most general query.

Some predicates are already reified in the library, so we can write for example:

    ?- X = a, if_(X = a, Y = b, Y = c).
    X = a,
    Y = b.
which succeeds without leaving choice-points, and that is good for performance. At the same time, we get both answers (X = a and also dif(X, a), i.e., X is not equal to a) on backtracking if we omit the first goal:

    ?-        if_(X = a, Y = b, Y = c).
    X = a,
    Y = b ;
    Y = c,
    dif(X, a).
Hence, the predicate retains important logical properties we expect from first-order logic, and this allows declarative reading and debugging based on these properties.

To benefit from the true power of Prolog, such constructs must become available in Prolog implementations. For example, currently, the only Prolog system that ships with if_/3 as a built-in feature is Mark Thom's Scryer Prolog, where if_/3 and related predicates are available in library(reif):

https://github.com/mthom/scryer-prolog

https://github.com/mthom/scryer-prolog/blob/master/src/prolo...

Other features that are necessary to make Prolog programs more declarative include CLP(ℤ) constraints, pure I/O, efficient implementation of partial strings as lists of characters etc., all of which are currently work in progress and as of yet only partially available in some Prolog systems. Over time, such features will become more widely available, and then they can be more easily taught and used to obtain Prolog programs that are pure and efficient.


As someone who had a prolog class last year and who really had a hard time understanding cut, this clears up a lot. Essentially, we were taught to write predicates without cut, and if they didn't yield proper results to introduce cut higher and higher up the predicate tree until they did.

I always felt that the language was more incomplete for having (needing) such an imperative construct in an otherwise entirely declarative design.


Thank you for such a complete answer! This was very enlightening.


I love pure Prolog, and I welcome new developments like the pure if_/3 discussed below. But at the same time, your position is needlessly extremist. It's perfectly fine to write a program in 90% pure Prolog and 10% in its "quirky imperative" subset. Depending on what you're doing, turning that ratio around to 20-80 can still be useful: "quirky imperative" Prolog is still the best language for matching and transforming tree-shaped data that I know of.

The ability to mix in impure features where needed is what makes Prolog practical.


The problem is, once you introduce a non-logical predicate, everything in the call stack "above" it is tainted and rendered non-logical. Since you frequently have to resort to using (\+)/1 almost as a necessity, the codebase ends up being 90% illogical and 10% logical. And at that point you step back and ask why you're even using prolog.

However: I do miss DCGs in every other language I've used. They're so useful that I've come to hate using regexes or even worse: manually parsing lists and strings.


> The problem is, once you introduce a non-logical predicate, everything in the call stack "above" it is tainted and rendered non-logical.

That's a very general statement. The non-logical behavior can be well-contained and unobservable from the outside. For example, the nice and pure if_/3 internally uses both of the non-logical predicates (->)/2 and (==)/2. Yet viewed from the outside it doesn't taint anything.

> And at that point you step back and ask why you're even using prolog.

As I wrote above, because I think even used imperatively it's a very convenient language for expressing matching and transformation of trees. And DCGs are great as well, I agree.


Very well said, exactly my opinion as well.


> nonlogical

'Logical' is a misnomer, Prolog is really a database query language. Unlike SQL it's not relational and not based on joins, it has tree walking semantics.

That said, without a decent storage/indexing system under the hood it is indeed quite pointless. Nobody wants a 'small data' tiny DB engine in 2019.


This is a good point and syncs with our approach: https://terminusdb.com/docs/woql


Prolog gives you backtracking for free and liberates you from loops and if's.


Backtracking and unification (logic variables). The latter builds on the former and is key to some of Prolog's amazing capabilities.


At the price of a couple of headaches. Most programmers need to reverse the way they were thinking about programming when learning Prolog.


Which is probably a good thing. Learning only one or two modes of thinking is severely handicapping.


SWI Prolog deserves a moment as it is amazing. Terminus uses it not because of some ideological position but as it is the best technology for the job.


I saw the TerminusDB posts on the Prolog subreddit and some of their Medium posts, but don't understand it or how they can make money.


We are pushing out documentation (worked examples etc.) as fast as we can so hopefully it will be come more understandable. In terms of making money, we'll launch a hosted platform in the near future.


Thanks! It does like look interesting. Somehow a combination of graph database and prolog? I'm trying to think what kind of customers you're looking for. Medical research? I know things like Prolog are common there for ontologies (think I said that right).


Yes - a graph database implemented in Prolog and Rust (the storage layer - better for nitty-gritty bit manipulation). We think it's a great general purpose DB with all sorts of interesting features. Cool stuff coming on the platform, so keep an eye out!


I'll meet an eye out! Thanks btw!


I have learned some prolog, and I really enjoyed it. The only problem I encountered is that I had a hard time moving to real world practical uses of the language. I enjoyed the language for the exercises I had in my learning resources, but I never found a problem I could use it for myself.


Potential use-case for you:

I prototyped (but did not fully implement, no management support) test case generation using Prolog.

In our case, it was (grossly simplified) a messaging system with a well-defined protocol running in an embedded device. When some message was sent, we anticipated a response back within some time window with some content based on what was initially sent (NB: This is only one of many potential scenarios). Let's say that some complex computation is happening on the remote end, based on the series of messages transmitted you eventually expect a response that will be the result of computation on those inputs.

You could manually calculate what that response should be, which fundamentally limits how many test cases you can generate and potentially leads to biased tests (assumptions of system behavior or design by the testers), or you can do it automatically. In our case, Prolog (or something like it) could be used to model the system and generate arbitrary test cases for us. It acts as the oracle (if you're familiar with property-based testing, this is where I was heading with my effort). You can now use Prolog to generate arbitrary input sequences with a known output (depending on the fidelity of your model to the spec) and generate test sequences for your system and compare the output.

And if your Prolog model is sufficiently developed, it can also be used for other development/testing efforts. If you get some response, what series of inputs may have produced it (this may be computationally infeasible, but maybe you know or can assume some of the inputs to constrain the search space). Or if your manual testing (throwing bodies at the problem) results in unexpected behavior, you can check what the model produces using the recorded inputs. Perhaps your system performs correctly, but the tester or user's mental model was incorrect. Or perhaps they found an actual implementation error.

A nice thing about using Prolog, vice using a second "reference" implementation in a more traditional language like C++, is that the Prolog model is often much simpler than the full system being developed, whereas (for us) a reference implementation would've been of comparable size. In our case, it could be the difference between 10k lines of code versus 100k lines of code.

The downside of this Prolog approach is performance, a C++ reference implementation may be able to run in real-time (or close enough) and could be directly substituted for the unit under test to verify other aspects of the test rig or system. Or, in a multi-system test, a reference implementation could be used in place of "real" remote systems (due to cost or other constraints).


This sounds awesome. One of the weaknesses of Test driven development always seemed to me, that ultimately a human may not be very good finding the edge cases to test. After all if he was very good then he would account for them on the code at first try. Do you have a blog post or some example code where this approach is documented. This seems genius.


I do not have a blog or demo code (this was 6 or 7 years ago now). They eventually made something like this for generating tests using a SQL database and custom logic in C#.

To get the idea (which I barely knew of at the time), look into property-based testing. I really liked this book: https://pragprog.com/book/fhproper/property-based-testing-wi...

It does a lot of the things I was thinking about but doesn’t build the whole system model like I wanted (and was tractable for our problem domain, it isn’t for all).


Seems like this would be a more comprehensible starting point: https://swish.swi-prolog.org/example/examples.swinb


When I was in college, we had an internal joke that the simplest Prolog interpreter can be easily implemented in C:

int main() { printf(“No\n”); return 0; }


Perhaps more appropriately called "Nolog."


Here's a fun one: "Compiler Tutorial" by Robert Laing https://swish.swi-prolog.org/p/Compiler1.swinb


That is awesome. It has been a very long time since I have looked at Swish. Now it looks like a very good web based IDE.

I used to use SWI Prolog a lot in the early days of the semantic web because I liked the SWI Prolog semantic web library.


site is down: 504 Gateway Time-out


coolproject('prolog-notebooks').

coolproject(X)


> coolproject('prolog-notebooks').

yes


> coolproject(X)

This rule means that everything is a cool project.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: