56 lines
1.5 KiB
Perl
56 lines
1.5 KiB
Perl
|
:- use_module(library(dcg/basics)).
|
||
|
:- use_module(library(ugraphs)).
|
||
|
:- use_module(library(assoc)).
|
||
|
|
||
|
char(X, L, C0, L, C) -->
|
||
|
[X0], {X0 \= 0'\n, char_code(X, X0), C is C0 + 1}, !.
|
||
|
|
||
|
newline(L0, _, L, 0) --> "\n", {L is L0 + 1}.
|
||
|
|
||
|
empty(L, C0, L, C) --> char('.', L, C0, L, C).
|
||
|
pipe(Ds, L, C0, L, C) --> char(X, L, C0, L, C), {is_pipe(X, Ds)}.
|
||
|
start(L, C0, L, C) --> char('S', L, C0, L, C).
|
||
|
|
||
|
is_pipe('F', [down, right]).
|
||
|
is_pipe('L', [up, right]).
|
||
|
is_pipe('7', [down, left]).
|
||
|
is_pipe('J', [up, left]).
|
||
|
is_pipe('-', [left, right]).
|
||
|
is_pipe('|', [up, down]).
|
||
|
|
||
|
|
||
|
nonthing(L0, C0, L, C) --> empty(L0, C0, L, C).
|
||
|
nonthing(L0, C0, L, C) --> newline(L0, C0, L, C).
|
||
|
|
||
|
thing(s(L0, C0), L0, C0, L, C) --> start(L0, C0, L, C).
|
||
|
thing(p(P, L0, C0), L0, C0, L, C) --> pipe(P, L0, C0, L, C).
|
||
|
|
||
|
map([], L, C, L, C) --> [].
|
||
|
map(Xs, L0, C0, L, C) --> nonthing(L0, C0, L1, C1), map(Xs, L1, C1, L, C).
|
||
|
map([X|Xs], L0, C0, L, C) --> thing(X, L0, C0, L1, C1), map(Xs, L1, C1, L, C).
|
||
|
|
||
|
map(Xs) --> map(Xs, 0, 0, _, _).
|
||
|
|
||
|
insert(s(L, C), A0, A) :- put_assoc(L-C, A0, s, A).
|
||
|
insert(p(P, L, C), A0, A) :- put_assoc(L-C, A0, p(P), A).
|
||
|
|
||
|
make_assoc(Map, A) :-
|
||
|
empty_assoc(Start),
|
||
|
foldl(insert, Map, Start, A).
|
||
|
|
||
|
parse(File, A) :-
|
||
|
phrase_from_file(map(Map), File), !,
|
||
|
make_assoc(Map, A).
|
||
|
|
||
|
converse(up, down).
|
||
|
converse(down, up).
|
||
|
converse(left, right).
|
||
|
converse(right, left).
|
||
|
|
||
|
compat(p(Ds1), p(Ds2)) :- member(D1, Ds1), member(D2, Ds2), converse(D1, D2), !.
|
||
|
compat(s, p(_)).
|
||
|
compat(p(_), s).
|
||
|
|
||
|
|
||
|
% vim: set ft=prolog :
|