How to use the get/2 dictionary function?

Greetings, and while there are quite a threads from users asking about dicts already, it’d be nice to get a neat answer to this very specific question for anyone who turns up here from Google. I’m sure I can’t be the only one who’s stumped!

The documentation reads:

get (?KeyPath, +Default)

Same as get/1 , but if no match is found the function evaluates to Default. If KeyPath contains variables possible choice points are respected and the function only evaluates to Default if the pattern has no matches.

Sounds simple enough, and it’s exactly what I need for my program. But when I try and use it:

?- Dict = en_pl{cat:kot, dog:pies}, X = Dict.get(cat).
Dict = en_pl{cat:kot, dog:pies},
X = cat.

% So far, so good. But...:

?- Dict = en_pl{cat:kot, dog:pies}, X = Dict.get(fish, unknown).
ERROR: fish: No implementation for: <-unknown

% Intended result: X = unknown.

I have no idea why it is looking for <-unknown or even how I create it—what does the arrow prefix mean? Perhaps someone can explain in simple terms how to use this function (please remember, as anyone could Google this, to provide a general answer without picking at the specifics of my wording—thanks!)

You needs that latest, greatest version :slight_smile: Well, actually not really the latest, but surely the 8.3.x series.

1 Like

Thanks, Jan, that must be it! I see I’m running 8.2.4 still—time to update to the latest hotness. Now, I thought my Ubuntu had the latest version and everything (including SWI-Prolog) was up-to-date, but as I see now, I’m only running Ubuntu 20.04 (Focal Fossa) which I believe doesn’t have access to the latest SWI-Prolog from the PPA.

I’ll have to decide whether to update Ubuntu (moving off the stable release track) or build Prolog myself!

COMMENT: I’ve noticed that the term “function” has been changed to “predicate” in the thread title. While it must be really annoying for Prolog experts to see this common misapprehension time and time again, in this case I really did mean the function get/2. Functions are a concept relevant (spefically?) to dicts and are invoked by the . operator and quite possibly should really be called methods. Anyone searching for information on the predicate get/2 will be led to a now-deprecated builtin that reads from a stream. For this reason, and to aid any people searching specifically for the function get/2 (who will most likely also be wrestling with the dict library!) I’d like to revert the thread title. And thanks in advance for any further advice.

I have SWI-Prolog 8.3.27 running on Ubuntu 20.04.2 LTS.
Ubuntu is running in WSL 2 on Windows 10.

The instructions I follow are
Install SWI-Prolog development version on Ubuntu using PPA

Note: I did not need to preform the Installing on Ubuntu needs Universe checked steps.


groot@Galaxy:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.2 LTS
Release:        20.04
Codename:       focal
groot@Galaxy:~$ swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.27)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- Dict = en_pl{cat:kot, dog:pies}, X = Dict.get(fish, unknown).
Dict = en_pl{cat:kot, dog:pies},
X = unknown.
1 Like

Thanks, Eric, that was a brilliant reply—and you set me off on the right track.

I’ve realized what I’ve done—all I had to do was type the magic words
sudo apt-add-repository ppa:swi-prolog/devel
and install from there!

?- Dict=pl_en{kot:cat, pies:dog}, X = Dict.get(panda, unknown).
Dict = pl_en{kot:cat, pies:dog},
X = unknown. % as desired!

Q: Did I miss something in the web documentation that informs a predicate/function is in the dev version only?

Extra: If you’ve ended up here but you’re stuck on a pre-8.3 version, there’s an implementation of get-with-default in the other thread here.

Good question.

Not that I am aware. For those of us that use SWI-Prolog regularly and keep track of changes, we just take for granted that when something does not work to automatically upgrade to the latest dev version first.

I hardly ever touch my version of SWI-Prolog installed on Ubuntu but upgrading to the latest dev is so easy that I just do it if I think it is needed. Also I have never been bitten by a bug in dev and switching to stable would have saved me. Odds are Jan W. will have a fix for you in hours if it is a bug. :slightly_smiling_face:


Also, I think the credit and accepted solution to your problem should go to Jan W. I only confirmed his answer and gave a reference to the install instructions. Grabbing the text off the console was also really easy. :slightly_smiling_face:

Yes. The manual (and website) always run the latest development version released. As a lot of the docs are generated from the system that means it also documents that version. Ideally one would like to be able to browse back into the documentation history and have information about the last change. That is probably not that easy to setup. Maybe at some day we could consider running the stable version somewhere as well as provide a forward and backward link between the two …

edit: The output of help/1 does document your running version.

2 Likes

Also I have never been bitten by a bug in dev and switching to stable would have saved me.

Me too—I’m surprised I picked out one of the new version’s features, but on the plus side, it shows there’s enough great stuff going into SWI-Prolog continually to make it worth updating.

Odds are Jan W. will have a fix for you in hours if it is a bug. :slightly_smiling_face:

Brilliant—wish I could be such a reliable dev :anguished:. In any case, seems like a great community you have here! :smiley:

Thanks, really. I’ll have to pay attention to that in feature (and also get better at parsing error messages), In any case, I’m here to take my Prolog skills to the next level, and I suppose becoming version-conscious is an important step in that :wink:.

Thanks so much, and till next time.

Maybe put a comment with each new/modified item: “added in release x.y.z”?

(Another possibility is to preserve older versions with a separate directory level, like this: string — Common string operations — Python 3.10.0rc1 documentation – note the drop-down for selecting other versions. But this is probably a lot of work and it’s only been recently added to the Python docs.)

I once started some work trying to parse the GIT commit logs. It wasn’t too bad, but the commit logs are a bit too informal to make that work reliably. One option might be to make them conform to more formal rules.

But, as I said, the website is a mixture of static data and dynamically generated data. That gives -I think- a fair user experience at low cost.

All we can do is to run multiple servers that each server their own version. That is not extremely hard. It does require more hardware, a bit of work to make the various servers aware of each other and create version links and maintenance work to keep them alive and either kill older versions or backport security patches (fortunately rare). I fear that requires more dedicated volunteers or investors/users that consider this important enough to make it work.