Here is a use case for last_sub_atom/5. Its useful to make an OS polyglott
Prolog system, at least polyglott among Unix, Windows and Mac. You
can get rid of Logtalks internal_os_path/2, which I think is a little
design flaw in my old Prolog system, which my new Prolog system tries
to avoid. One can do the following like here, maybe there are also other
agorithms based on last_sub_atom/5, but this is easiest to understand:
sys_file_parent(Path, Dir) :-
(last_sub_atom(Path, Pos1, _, _, '/') -> true; Pos1 = -1),
(last_sub_atom(Path, Pos2, _, _, '\\') -> true; Pos2 = -1),
Pos is max(Pos1, Pos2), Pos \== -1, !,
Pos3 is Pos+1,
sub_atom(Path, 0, Pos3, _, Dir).
sys_file_parent(_, '').
sys_file_name(Path, Name) :-
(last_sub_atom(Path, Pos1, _, _, '/') -> true; Pos1 = -1),
(last_sub_atom(Path, Pos2, _, _, '\\') -> true; Pos2 = -1),
Pos is max(Pos1, Pos2), Pos \== -1, !,
Pos3 is Pos+1,
atom_length(Path, Len),
Len2 is Len-Pos3,
sub_atom(Path, Pos3, Len2, _, Name).
sys_file_name(Path, Path).
Maybe regex could do the same. But can regex search backwards?
You would need a kind of greedy regex pattern, that nevertheless
has an alternative in it. And a regex library is more heavier, than some
last_sub_atom/5 which is still relative lightweight to provide, only
a variant of sub_atom/5. Here are some example runs:
?- sys_file_parent('/mnt/c/foo/bar/baz.p', X).
X = '/mnt/c/foo/bar/'.
?- sys_file_name('C:/foo/bar/baz.p', X).
X = 'baz.p'.
?- sys_file_parent('C:\\foo\\bar\\baz.p', X).
X = 'C:\\foo\\bar\\'.
?- sys_file_name('C:\\foo\\bar\\baz.p', X).
X = 'baz.p'.
Its not the same as decompose_file_name/3 from Logtalk, which is possibly
also not OS polyglott. Its not the same since it leaves the directory delemiter,
either '/'
or '\\'
at the end of the parent intact. So the reverse function
of this decomposition is simply atom_concat/3:
?- atom_concat('/mnt/c/foo/bar/', 'baz.p', X).
X = '/mnt/c/foo/bar/baz.p'.
?- atom_concat('C:\\foo\\bar\\', 'baz.p', X).
X = 'C:\\foo\\bar\\baz.p'.