Starbeamrainbowlabs

Stardust
Blog

Learning Prolog: Lab Session #4 - Reading and Writing

The new learning prolog banner!

This week we were asked to do another 2 labs in one session - this blog post will cover lab #4, and there will be another one coming out on Thursday for lab #5.

Before we start though, I want to mention Swish. It's an online editor for Prolog that runs in the browser. It apparently doesn't support all the features that the desktop version does, but the editor itself is so much better than the desktop version. It's actually bearable! If at all possible, I'll be using it from now on.

This week's (first) lab was all about reading and writing from the console. You would have thought that this would be the first thing you'd learn as a hello world, but apparently that isn't the case. 3 weeks into the course, and we finally know enough to write our first hello world in Prolog!

Anyway, reading and writing are quite simple actually - once you've learnt rules. Here's an example:

go :-
    write('Hello, world!').

If you query go. on the above, you should get an output something like this:

?- go.
Hello, world!
true

The write/1 (write arrity 1) statement lets us write out a message to the console. Note that the string we want to output is enclosed in single quotes. This is important, because apparently some Prolog environments interpret double quotes to mean "output the ASCII character codes of the characters in this string", and not "output the characters themselves in this string". Personally I haven't found that to be the case, but it's best to be aware of it.

Writing messages to the console is neat, but not particularly useful in itself. Let's upgrade it to ask the user's name, and then say hello to them:

go :-
    write('Enter name: '), read(Name),
    write('Hello, '), write(Name), write('!'), nl.

Here's an example output:

?- go.
Enter name:
|: starbeamrainbowlabs.
Hello, starbeamrainbowlabs!
true.

When you ask Prolog go., it then asks you what your name is - and then says hello to you. There are several things to note here. Firstly, nl/0 is a special predicate that simply write a newline character to the console. Secondly, read/1 is a special predicate to read in a string from the console and drop it into the given variable.

read/1 can be rather weird when it comes to actually getting input from the user. The string the user enters must be terminated by a full stop (.), otherwise it will continue to ask for input. It must also start with a lower case letter, otherwise strange stuff starts to happen. I theorise that this is probably related to the fact that variables in Prolog start with an uppercase letter.

Thankfully, we can get around the second issue by enclosing strings in double quotes:

?- go.
Enter name:
|: 'Starbeamrainbowlabs'.
Hello, Starbeamrainbowlabs!

Much better. Let's actually use these new functions to do something (kind of) useful. Here's the first excercise:

Write a Prolog program using facts in the form month/1 that displays the month depending on the integer entered by the user, e.g. if the user enters 3 the program will display The Month is March.

Initially I was started with a program beginning like this:

month(January) :-
    % ...

But soon found that it didn't work. The solution here is to invert it, so that Prolog gets to choose which path it takes based on the input it gets. It makes sense, I suppose, considering Prolog is a language for writing artificial intelligences.

Here's some example output:

?- month(1).
January
true.
?- go.
Enter month code:
|: 4.
April
true.

In the above, we can either call query month/1 directly, or query go., which will ask us for the month code directly and call month/1 for us.

That concludes the 4th lab. I'll write up another post for lab #5, which should hopefully be out on Thursday. As an aside, I used the embed code from PasteBin in this post instead of embedding the code directly and then linking to the PasteBin. Which would you prefer? Why? Do you have another idea? Let me know in the comments!

Tag Cloud

3d account algorithms announcement archives arduino artificial intelligence assembly async audio bash batch blog bookmarklet booting c sharp c++ challenge chrome os code codepen coding conundrums coding conundrums evolved command line compiling css dailyprogrammer debugging demystification distributed computing downtime electronics email embedded systems encryption es6 features event experiment external first impressions future game github github gist graphics hardware hardware meetup holiday html html5 html5 canvas infrastructure interfaces internet io.js jabber javascript js bin labs learning library linux low level lua maintenance manjaro network networking node.js operating systems performance photos php pixelbot portable privacy programming problems project projects prolog protocol protocols pseudo 3d python reddit reference release releases resource review rust secrets security series list server software sorting source code control statistics svg technical terminal textures three thing game three.js tool tutorial tutorials twitter ubuntu university update updates upgrade version control virtualisation visual web website windows windows 10 xmpp xslt

Archive

Art by Mythdael