Skip to content

Instantly share code, notes, and snippets.

@shawa
Last active November 20, 2017 23:10
Show Gist options
  • Save shawa/06096b299631b9b8f7a58bec56420318 to your computer and use it in GitHub Desktop.
Save shawa/06096b299631b9b8f7a58bec56420318 to your computer and use it in GitHub Desktop.
An Exposition of Facts
:- use_module(library(clpfd)). % grab some matrix functions
% Herein we present facts about boards.
% Given these facts, the user can consult Prolog for interesting
% inferences based on these facts.
% Example consultation:
%
% › swipl facts.pl
% Welcome to SWI-Prolog (threaded, 64 bits, version 7.6.1)
% SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free s
% oftware.
% Please run ?- license. for legal details.
%
% For online help and background, visit http://www.swi-prolog.
% org
% For built-in help, use ?- help(Topic). or ?- apropos(Word).
%
% Upper case variables are uninstantiated. We ask of prolog,
% "What terms will cause X to satisfy the board predicate?"
%
% And so our board is returned.
%
% ?- board(X).
% X = [[mine, 0, 0, 0], [0, 0, 0, 0], [0, mine, 0, 0], [0, 0,
% 0, 0]].
%
%
% We then ask, "given that X is a board, R is the result of shifting
% that X left. What is R?"
%
% ?- board(X), shift(X, left, R).
% X = [[mine, 0, 0, 0], [0, 0, 0, 0], [0, mine, 0, 0], [0, 0,
% 0, 0]],
% R = [[0, 0, 0, 0], [0, 0, 0, 0], [mine, 0, 0, 0], [0, 0, 0,
% 0]]
%
%
% And then...
% "X is a board, and R is the solved board. Do you know what
% R looks like, perchance?"
%
% ?- board(X), solveBoard(X, R).
% X = [[mine, 0, 0, 0], [0, 0, 0, 0], [0, mine, 0, 0], [0, 0, 0, 0]],
% R = [[mine, 1, 0, 0], [2, 2, 1, 0], [1, mine, 1, 0], [1, 1, 1, 0]]
%
board([[mine, 0, 0, 0]
,[ 0, 0, 0, 0]
,[ 0, mine, 0, 0]
,[ 0, 0, 0, 0]]).
fill(Z, [], Z).
fill(X, [_|T], Z) :-
fill([0|X], T, Z).
horizVert(right, down).
horizVert(left, up).
shift([H|Tail], up, R) :-
fill([], H, Z),
append(Tail, [Z], R).
shift(Xs, down, R) :-
reverse(Xs, T1),
shift(T1, up, T2),
reverse(T2, R).
shift(Xs, [A, B], R) :-
shift(Xs, A, T1),
shift(T1, B, R).
shift(Xs, Horiz, Ys) :-
transpose(Xs, T1),
horizVert(Horiz, Vert),
shift(T1, Vert, T2),
transpose(T2, Ys).
m_add(M1, M2, M3) :-
maplist(maplist(m_sum), M1, M2, M3).
mineToInt(mine, 1).
mineToInt(X, X).
m_sum(X,Y,Z) :-
mineToInt(X, X1),
mineToInt(Y, Y1),
Z is X1 + Y1.
solveBoard(X, R) :-
shift(X, up, T1),
shift(X, down, T2),
shift(X, left, T3),
shift(X, right, T4),
shift(X, [up, left], T5),
shift(X, [up, right], T6),
shift(X, [down, left], T7),
shift(X, [down, right], T8),
BoardPermutations = [T2, T3, T4, T5, T6, T7, T8],
foldl(m_add, BoardPermutations, T1, SolvedBoard),
mask(X, SolvedBoard, R).
mask([], _, []).
mask([H|T], [X|Xs], [R|Rtail]) :-
mask1d(H, X, R),
mask(T, Xs, Rtail).
mask1d([], [], []).
mask1d([mine|T], [_|T2] , [mine|Acc]) :- mask1d(T, T2, Acc).
mask1d([_|T], [AdjacentMines|T2], [AdjacentMines|Acc]) :- mask1d(T, T2, Acc).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment