% Weighted path enumeration adapted from Eyeling dijkstra.n3.
% The Eyeling source uses collect/sort built-ins for Dijkstra's queue.
% This eyelog variant enumerates simple paths and keeps the bounded frontier
% that appears in the Eyeling output for a -> f.
% The input weighted graph is quoted as ... data and projected locally,
% so the route network is not asserted as ambient edge facts.

weighted_graph(dijkstraGraph, (
  triple(a, edge, arc(b, 4)),
  triple(a, edge, arc(c, 2)),
  triple(b, edge, arc(c, 1)),
  triple(b, edge, arc(d, 5)),
  triple(c, edge, arc(d, 8)),
  triple(c, edge, arc(e, 10)),
  triple(d, edge, arc(e, 2)),
  triple(d, edge, arc(f, 6)),
  triple(e, edge, arc(f, 3))
)).

base_link(A, B, Cost) :-
  weighted_graph(dijkstraGraph, Formula),
  formula_triple(Formula, A, edge, arc(B, Cost)).

link(A, B, Cost) :- base_link(A, B, Cost).
link(B, A, Cost) :- base_link(A, B, Cost).

path(Goal, Goal, _Visited, [Goal], 0).
path(Node, Goal, Visited, [Node|Path], Cost) :-
  link(Node, Next, StepCost),
  not_member(Next, Visited),
  path(Next, Goal, [Next|Visited], Path, RestCost),
  add(StepCost, RestCost, Cost).

% Derived reverse links, mirroring the rule output in the Eyeling example.
triple([B, A], edge, Cost) :-
  base_link(A, B, Cost).

triple([a, f], path, [Path, Cost]) :-
  path(a, f, [a], Path, Cost),
  le(Cost, 16).
