Willem van Dam

Prolog het werk laten doen

De vorige uitwerking liet niet de kracht van Prolog zien. Wel hebben we verschillende technieken gebruikt die in Prolog zitten, zoals lists en recursie. Zie voor de vorige uitwerking het vorige blog bericht, ticTacToeWinner.

We kunnen ook het programma zo schrijven, zodat we Prolog het werk laten doen. Deze zegt dan of ‘x’ of ‘o’ op de gegeven positie geplaatst moet worden om te kunnen winnen. Zo kunnen we zoeken naar de plek waarme we winnen of waar we de tegenstander moeten blokeren. Om dit voor elkaar te krijgen gaan we meer de manier van Prolog gebruiken, namelijk regels en feiten.

De uitwerking

win(X, X, X).
winRow([X1, X2, X3|Tail]):- win(X1, X2, X3); winRow(Tail).
winCross([ 
    X, _, _,
    _, X, _,
    _, _, X]).
winCross([ 
    _, _, X,
    _, X, _,
    X, _, _]).
winColumn([ 
    X, _, _,
    X, _, _,
    X, _, _]).
winColumn([ 
    _, X, _,
    _, X, _,
    _, X, _]).
winColumn([ 
    _, _, X,
    _, _, X,
    _, _, X]).

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

/** <examples>

?- win([
  x, -, o,
  o, x, o,
  x, -, X
  ]).
*/

Download het bestand.

In de bovenstaande uitwerking zijn de regels en de feiten te zien van het nieuwe programma. Het is belangrijk in dit geval om geen anonieme variabelen te gebruiken bij het aanroepen van de win met de list als parameter. Als de o rechtsboven vervangen wordt door een anonieme variabel, de _, dan is de uitkomst nog steeds dat X ‘o’ en ‘x’ kan zijn.

?- win([
  x, -, _,
  o, x, o,
  x, -, X
  ]).

X = x
X = o

?- win([
  x, -, -,
  o, x, o,
  x, -, X
  ]).

X = x

Dit komt doordat Prolog ‘x’ en de ‘o’ kan samenvoegen met de anonieme variabel. Dit kan natuurlijk niet tegelijk, maar om een succes scenario te krijgen kan Prolog de anonieme variabel samenvoegen met ‘o’. Als Prolog deze variabel namelijk samenvoegt met ‘o’, dan kan ‘o’ ook worden toegewezen aan de variabel X en dan voldoet hij aan de onderstaande regel.

winColumn([ 
    _, _, X,
    _, _, X,
    _, _, X]).

Door gebruik te maken van een ‘-‘ gebeurd dit niet, omdat ‘-‘ een atom is die kan worden toegewezen aan een variabel, maar niet van waarde veranderd kan worden.

Wat kunnen we met dit programma?

Dit programma kunnen we gebruiken als voorspeller. Zie de onderstaande situatie. Hier is het de beurt van ‘o’. Deze wilt niet verliezen. We zouden Prolog iedere open plaats af kunnen laten gaan om te kijken waar ‘o’ een plaats kan innemen om te winnen en welke plaats ‘o’ kan innemen om verlies tegen te gaan.

?- win([
  x, -, -,
  o, x, o,
  -, -, X
  ]).

X = x

Nu weet ‘o’ dat als hij deze plek niet inneemt dat ‘x’ de volgende ronde kan winnen. Als het de beurt van ‘x’ zou zijn, dan zou deze nu weten dat als hij deze plaats inneemt dat hij zal winnen. Het programma kan niet zeggen wat de beste plaats zal zijn om in te nemen als er nog niemand kan winnen.