Making file_search_path/2 of a forest of directories, an exercise

#1

So far, I assert file_search_path/2 manually, feeling somewhat boring. So I wrote a code for generating them below.

I think nothing interesting for most of prologers as it is so easy an exercise, but the code is fresh for me.

I used builtins prolog_load_context/2 and file_directory_name/2.

A very small thing in the code: I use [] (the empty list) for indicating
the field is void. In fact, in the example, a directory prolog does not appear in the output because alias of the directory is not necessary for this example.

Sample query for generating file_search_path/2.

:-	DirStr =
		[	(pac_root : []) -
			 [	test:test,
				:(prolog) -
					[	pac		: pac,
						misc	: misc,
						zdd		: misc,
						tmp		: tmp,
						gb		: "misc/grobner",
						other:	other
					]]],
	prolog_load_context(directory, Dir),
	file_directory_name(Dir, PacRoot),    %	assuming structure for packs
	mk_file_search_path(PacRoot, DirStr).

Output.

% ?- file_search_path(X, Y).
%@ X = other,
%@ Y = "/Users/cantor/devel/zdd/prolog/other" ;
%@ X = gb,
%@ Y = "/Users/cantor/devel/zdd/prolog/misc/grobner" ;
%@ X = tmp,
%@ Y = "/Users/cantor/devel/zdd/prolog/tmp" ;
%@ X = zdd,
%@ Y = "/Users/cantor/devel/zdd/prolog/misc" ;
%@ X = misc,
%@ Y = "/Users/cantor/devel/zdd/prolog/misc" ;
%@ X = pac,
%@ Y = "/Users/cantor/devel/zdd/prolog/pac" ;
%@ X = test,
%@ Y = "/Users/cantor/devel/zdd/test" ;
%@ X = pac_root,
%@ Y = '/Users/cantor/devel/zdd' ;

Codes of forest_to_paths/2.

mk_file_search_path(PacRoot, DirStr):-
	forest_to_paths(DirStr, Eqs),
	maplist(attach_dir_prefix(PacRoot), Eqs, Eqs0),
	maplist(assert_search_path, Eqs0).

% Remarck: [] means empty string "" to avoid "//" in paths.
attach_dir_prefix([], E, E):-!.
attach_dir_prefix(A, P = [], P = A):-!.
attach_dir_prefix(A, P = B, P = C):-
	atomics_to_string([A, /, B], C).
%
assert_search_path(A = B):-
	asserta(user:file_search_path(A, B)).

%% forest_to_paths(+X, -Y) is det.
%	X is a  directory structure with path alias
%	for sub directories in X.
%   Y is a set of pairs (A=B) such that B is the absolute
%	file name of A such that file_search_path(A, B) becomes true.

% ?- setup_aux:forest_to_paths([], X).
% ?- setup_aux:forest_to_paths([(a:b)-[]], X).
% ?- setup_aux:forest_to_paths([(a:b)-[(c:d)-[]]], X).
% ?- setup_aux:forest_to_paths([(a:b)-[(c:d)]], X).
% ?- setup_aux:forest_to_paths([(a:b)-[(c:d), (e:f)]], X).
forest_to_paths([], []).
forest_to_paths([(P:Dir)-L|Xs], Out):-!,
	forest_to_paths(L, D),
	maplist(attach_dir_prefix(Dir), D, D0),
	forest_to_paths(Xs, Ys),
	append(D0, Ys, Zs),
	(	P == [] -> Out = Zs
	; 	Out = [P = Dir| Zs]
	).
forest_to_paths([:(Dir)-L|Xs], Out):-!, forest_to_paths([([]:Dir)-L|Xs], Out).
forest_to_paths([A|Xs], Out):- forest_to_paths([A-[]|Xs], Out).