Learning Prolog: Lab #9

The new learning prolog banner!

Sorry this post is rather late! I had multiple ACW deadlies to deal with, and I now have a nasty cold as of the time of writing :(

I had a bit of trouble with this lab - I originally lost the code that I had written due to a bug in my chromebook where it doesn't resume properly when I lift the lid...! Anyway, the main point of this lab was to practice the Prolog that we have learnt already. A lot. There were 7 problems to solve, 6 of which I have a solution for. The first two aren't very interesting, so I'll just include the code and some examples below and move on.

sbrlmember(Item, [ Head | Tail ]) :-
        Item = Head ;
        sbrlmember(Item, Tail).

lastitem([ LastItem | [] ], LastItem).
lastitem([ _ | Tail ], LastItem) :-
        lastitem(Tail, LastItem).
?- sbrlmember(Item, [ apple, orange, grape ]).
Item = apple ;
Item = orange ;
Item = grape ;
?- lastitem([ car, bus, truck, lorry, aeroplane ], Result).
Result = aeroplane .

The above contains definitions for two rules: sbrlmember and lastitem. sbrlmember works exactly like the member function that's built into Prolog, and lastitem, given a list, tells you what the last item in that list is.

The next one in the sequence is a rule that, given a list, returns the reverse of that list. Here's my solution, and an example:

listreverse([ Head | [] ], [Head]).
listreverse([ Head | Tail ], Result) :-
    listreverse(Tail, TailReversed),
    append(TailReversed, [Head], Result).
?- listreverse([windows, max, linux], Result).
Result = [linux, max, windows] .

Basically, it recurses over the tail of the list until there is just a single item left, at which point it returns the head on it's own in a list. When it comes back out of the recursion, it sticks everything back on the end of the list again in the reverse order.

The next problem we were given was to, given a pair of lists, return a third list containing all the items that appeared in both of the original lists. I decided to cheat a bit here and use an accumulator

intersection([], _, []).
intersection([ Head | Tail ], ListB, Result) :-
    member(Head, ListB),
    intersection(Tail, ListB, RecResult),
    append(RecResult, [Head], Result).
intersection([ _ | Tail ], ListB, Result) :-
    intersection(Tail, ListB, Result).

Complicated problems call for complicated solutions, so I decided to recurse over the first list and check to see if the current item is present in the second list. If so, then we add it to the result - if not, then we simply ignore it and carry on recursing. When it hits the end o fthe recursion, I start it off with an empty list, which it then adds to as it climbs its way back out of the recursion.

?- intersection([snow, rain, wind, flame], [snow, flame], Result).
Result = [flame, snow] .

The last problem I built a solution for asked for a rule that deleted the given atom (I think that's what you call them in Prolog?) from the given list.

deleteall(_, [], []).
deleteall(Item, [ Head | Tail ], [ Head | Result ]) :-
    not(Item = Head),
    deleteall(Item, Tail, Result).
deleteall(Item, [ _ | Tail ], Result) :-
    deleteall(Item, Tail, Result).
?- deleteall(snake, [ squirrel, bird, cat, snake ], Result).
Result = [squirrel, bird, cat] .

My solution copies everything in the list over to the result (rather like the intersection problem above actually), unless the next item along is equal to the item we are supposed to be ognoring, in which case we skip it. I do this by adding a condition on the rule that copies the item over to the result that it can't be the item that we were told to remove.

That's the last problem from this lab - I'll have the solutions for the 10th lab up soon.

Tag Cloud

3d 3d printing account algorithms android announcement architecture archives arduino artificial intelligence artix assembly async audio automation backups bash batch blender blog bookmarklet booting bug hunting c sharp c++ challenge chrome os cluster code codepen coding conundrums coding conundrums evolved command line compilers compiling compression containerisation css dailyprogrammer data analysis debugging demystification distributed computing dns docker documentation downtime electronics email embedded systems encryption es6 features ethics event experiment external first impressions freeside future game github github gist gitlab graphics hardware hardware meetup holiday holidays html html5 html5 canvas infrastructure interfaces internet interoperability io.js jabber jam javascript js bin labs learning library linux lora low level lua maintenance manjaro minetest network networking nibriboard node.js open source operating systems optimisation own your code pepperminty wiki performance phd photos php pixelbot portable privacy problem solving programming problems project projects prolog protocol protocols pseudo 3d python reddit redis reference release releases rendering resource review rust searching secrets security series list server software sorting source code control statistics storage svg systemquery talks technical terminal textures thoughts three thing game three.js tool tutorial tutorials twitter ubuntu university update updates upgrade version control virtual reality virtualisation visual web website windows windows 10 worldeditadditions xmpp xslt


Art by Mythdael