:- 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 :