Willem van Dam

ticTacToeWinner

Nu ik de eerste vier hoofdstukken van het boek heb gelezen, heb ik een programma geschreven waar Prolog de winnaar van TicTacToe kan vinden. Het programma laat een klein beetje van de functionaliteiten van Prolog zien.

Zoals eerder gezegd in mijn eerste blog bericht wil ik een AI maken voor Boter Kaas en Eieren (TicTacToe). Dit is het begin. Met dit programma ben ik met Prolog aan het oefenen. Dit programma kan namelijk niet iets voorspellen. Hij kan enkel zeggen wie er gewonnen heeft, als er iemand gewonnen heeft. Het programma ziet er als volgt uit:

winner(X):- format('Winner is ~s', X).
win(X1, X2, X3):- X1 == X2, X2 == X3, winner(X1).
winRow([X1, X2, X3|Tail]):- win(X1, X2, X3); winRow(Tail).
winCross([ 
    X1, _, X4,
    _, X2, _,
    X5, _, X3]):- win(X1, X2, X3); win(X4, X2, X5).

win(X):- winRow(X); winCross(X).

whoWins:- win([
  x, _, _,
  o, x, o,
  x, _, o
  ]).

/** <examples>

?- whoWins.
*/

Download het bestand.

De werking

Het programma heeft een structure whoWins, welke de complex structure win/1 aanroept. Deze geeft de gegeven array door aan de winRow/1 en winCross/1 complex structures. winCross/1 kijkt of ‘x’ of ‘o’ in een kruis gewonnen heeft, dus van links boven naar rechts onder of van rechts boven naar links onder.

Bij winRow/1 wordt recursie gebruikt. Aangezien de items van links naar rechts in een list zitten weten we dat steeds 1 tot 3, 4 tot 6 en 7 tot 9 rijen zijn. Door steeds de eerste drie items van de list te gebruiken en de tail weer door te geven wordt de list door drie gedeeld. Steeds bij deze drie items kijkt hij of een winnaar is in de rij, door de items door te geven aan win/3.

win/1 is de simpelste structure. Deze kijkt enkel of de drie gegeven variabelen hetzelfde zijn, als dit zo is geeft hij de variabel door aan winner/1. Deze structure print tekst waarin staat wie de winnaar is.

Opdracht

Om ook anderen te helpen met het leren van Prolog heb ik een kleine opdracht bedacht. Het programma mist nog een stukje functionaliteit. Dit is het herkennen van een rij van boven naar beneden. Dit kan op meerdere manieren worden opgelost. Download het programma hieronder waar een oplossing in is verwerkt. Succes!

Download het bestand.

Willem van Dam

alternative(Book)

Het boek, Learn Prolog Now!, is een zeer interessant boek met veel informatie. Ik geloof dat niet alle informatie voor mij is weggelegd. De stof vind ik soms wat taai namelijk. Het is duidelijk beschreven, maar het mag van mij wel wat simpeler. Kijk bijvoorbeeld naar hoofdstuk 2, Unification and Proof Search. Dit is een belangrijk hoofdstuk in het boek, omdat het je leert hoe Prolog werkt. Bij het kopje ‘The occurs check’ gaan ze in op het unification algoritme van Prolog. Ze gebruiken bij ‘The occurs check’ de volgende query:

?-  father(X)  =  X. 

Het boek gebruikt meer dan 10 alinea’s en meer dan 1200 woorden om uit te leggen dat een gemiddeld algoritme zegt dat dit niet wordt samengevoegd, omdat X niet gelijk is aan father(X). Prolog doet dit anders. Door de onderstaande regel zegt Prolog dat deze twee wel samengevoegd worden, want de linkerhand is een term en de rechterhand is een variable. Wat Prolog doet is father(X) toewijzen aan X, maar in father(X) zit een X. Nu heeft Prolog zojuist father(X) aan de X toegewezen, waardoor Prolog weet dat het eigenlijk father(father(X)) is, maar deze heeft weer een X. Prolog gaat hier steeds mee door. Hoe Prolog hier mee doorgaat of wat het precies terug geeft ligt aan de versie en de implementatie van Prolog.

If term1 is a variable and term2 is any type of term, then term1 and term2 unify, and term1 is instantiated to term2 . Similarly, if term2 is a variable and term1 is any type of term, then term1 and term2 unify, and term2 is instantiated to term1 . (So if they are both variables, they’re both instantiated to each other, and we say that they share values.)

Ik geloof dat het boek dit ook korter had kunnen doen. Hiervoor zal ik enkel de eerste vier hoofdstukken van het boek lezen. Deze geven mij, verwacht ik, de nodige basis informatie. Om Prolog in zijn werking te zien heb ik een video bekeken van Derek Banas, zie https://www.youtube.com/watch?v=qgjjlZdGet8 voor de video. De video geeft niet veel uitleg over Prolog, maar laat voor een groot gedeelte zien wat er in Prolog zit. Waar ik achter kwam is dat ik Lists nog verder moet onderzoeken.

Ik zou adviseren om het boek tot hoofdstuk 4 te lezen en dan te gaan oefenen met Prolog. Het boek geeft veel informatie, waarbij soms maar een klein gedeelte nodig is. Dit advies is ook de manier waarop ik het nu ga doen. We zullen zien of dit een handige manier was om Prolog te leren. Hier kom ik nog op terug!

Willem van Dam

learningLanguage(Willem, Prolog).

Voor de course van APP van mijn opleiding is één van de opdrachten het jezelf aanleren van een nieuwe programmeertaal. Een uitdaging en een vooruitzicht. Het leren van nieuwe technieken en deze proberen toe te passen vind ik altijd wel interessant. De programmeertaal heeft wel een aantal eisen, zoals dat het een volledig ander paradigma moet zijn. De taal die ik gekozen heb is Prolog. Deze taal is logisch. Prolog is een afkorting van “Programming with logic”. De enige talen waar ik momenteel ervaring mee heb zijn voornamelijk object georiënteerd.

Prolog is een afkorting van “Programming with logic”.

Waarom Prolog?

De keuze voor Prolog was voor mij vrij snel gemaakt. Dit alles heeft namelijk een doel. Het behalen van de opdracht. Dit doe ik door het leren van de programmeertaal, het maken van een programmeeruitdaging en dit delen door middel van deze blog. Naar andere talen heb ik ook gekeken, maar ik kon niet direct bedenken wat voor een uitdaging ik zou kunnen maken.

Bij het kennis maken van Prolog had ik direct een tweetal ideeën in mijn hoofd. Prolog is namelijk goed voor AI. Je stelt namelijk een vraag aan Prolog en deze geeft dan het antwoord. Om het antwoord te krijgen moeten wel wat regels etc. worden opgesteld, hier komen we nog op terug. De eerste potentiële uitdaging is maken van een AI voor het spel boter, kaas en eieren. Als dit niet voldoende uitdaging heeft dan zou ik een AI voor een ander spel willen maken. Een andere potentiële uitdaging is het maken van een AI die een Rubiks kubus kan oplossen, enkel weet ik niet of dit mogelijk is of te complex is.

Om te taal te leren moet kennis worden opgedaan, dat is logisch. Om dit te doen maak ik gebruik van de digitale versie van het boek ‘Learn Prolog Now!’ van Patrick Blackburn, Johan Bos, and Kristina Striegnitz. Deze is te vinden op http://www.learnprolognow.org. Momenteel heb ik hoofdstuk 1 van het boek doorgenomen en de opdrachten hiervan uitgevoerd. Ik had wat onzekerheden bij het nakijken van mijn antwoorden, dus heb ik de antwoorden van Peter Urbak gebruikt om mijzelf te controleren. Deze zijn te vinden op https://github.com/dragonwasrobot/learn-prolog-now-exercises. Alle fouten die ik bij mezelf heb ontdekt heb ik duidelijk benoemd, om zo te weten waar ik op moet letten.

Wat viel op?

Prolog is een totaal andere taal dan ik gewend ben. De syntax is volledig anders, de manier van denken moet anders en het is een enorm interessante taal. Bij de meeste talen beschrijven we regels aan de hand van vergelijkingen. Bij Prolog geven we een collectie van feiten en regels. Daarna stellen we een vraag aan Prolog en deze gaat opzoek naar een antwoord. Voor mij is dit een uitdaging om een andere manier van denken aan te leren.

happy(yolanda).
listens2Music(mia).
listens2Music(yolanda):-  happy(yolanda).
playsAirGuitar(mia):-  listens2Music(mia).
playsAirGuitar(yolanda):-  listens2Music(yolanda). 

Hierboven staat een Prolog programma. Dit zijn dus een set regels en feiten. Bij het voor het eerst zien van dit programma snapte ik niet wat er stond, totdat ik begreep dat ‘:-‘ een if statement is. De if van Prolog werkt net andersom dan de if in de meeste talen. De left hand side van de :- is de head en de right hand side van de :- is de body. Als de body waar is dan is de head waar. Het wordt leesbaar door :- te vervangen door if.

listens2Music(yolanda) if happy(yolanda).

Aan dit Prolog programma kunnen we bijvoorbeeld vragen wie er allemaal luchtgitaar spelen. Dit doen we door de volgende query uit te voeren: ‘playsAirGuitar(X)’. X is het variabel waar het antwoord aan wordt toegewezen. Variabelen worden aangegeven door woorden die beginnen met een hoofdletter of beginnen met een underscore, zoals _x.

Zoals te zien in de bovenstaande afbeelding speelt Mia luchtgitaar. Omdat er meer mensen zijn die luchtgitaar spelen kunnen we ook op next drukken. Dit zal in dit geval Yolanda zijn. Het bijzondere aan dit vind ik dat Prolog zelf kan uitzoeken wie luchtgitaar spelen.

Het laatste dat ik wil laten zien van Prolog is het omzetten van tekst naar een programma. Opdracht 1.4 van het boek is zo een opdracht. Hier worden de volgende regels gegeven:

  1. Butch is a killer.
  2. Mia and Marsellus are married.
  3. Zed is dead.
  4. Marsellus kills everyone who gives Mia a footmassage.
  5. Mia loves everyone who is a good dancer.
  6. Jules eats anything that is nutritious or tasty.

Deze regels moeten omgezet worden naar een Prolog programma, welke er dan als volgt uit ziet.

killer(butch).
married(mia,marsellus).
dead(zed).
kills(marsellus, X):- footmassage(X, mia).
loves(mia, X):- goodDancer(X).
eats(jules, X):- nutritious(X); tasty(X).

Tot nu toe vind ik Prolog een geweldige taal om te leren. Ook heb ik enorm veel zin om de rest van de taal te leren en dit te delen. Hoe het gaat uitpakken in de programmeeruitdaging zie ik nog niet voor me. Wil je deze taal ook leren? Begin met het boek Learn Prolog Now!.