% Our first program will demonstrate working with directories in Prolog.
% We'll use the SWI-Prolog's built-in predicates for file system operations.
% Helper predicate to handle errors
check_error(Error) :-
( Error == true
-> true
; throw(Error)
).
% Main predicate
main :-
% Create a new sub-directory in the current working directory
make_directory('subdir'),
% When creating temporary directories, it's good practice to clean them up afterwards
catch(
( % Create files and subdirectories
create_empty_file('subdir/file1'),
make_directory_path('subdir/parent/child'),
create_empty_file('subdir/parent/file2'),
create_empty_file('subdir/parent/file3'),
create_empty_file('subdir/parent/child/file4'),
% List directory contents
writeln('Listing subdir/parent'),
directory_files('subdir/parent', Files),
maplist(print_file_info('subdir/parent'), Files),
% Change current working directory
working_directory(_, 'subdir/parent/child'),
% List contents of current directory
writeln('Listing subdir/parent/child'),
directory_files('.', ChildFiles),
maplist(print_file_info('.'), ChildFiles),
% Change back to the original directory
working_directory(_, '../../..'),
% Visit directory recursively
writeln('Visiting subdir'),
directory_walk('subdir', visit)
),
Error,
(check_error(Error), delete_directory_and_contents('subdir'))
),
delete_directory_and_contents('subdir').
% Helper predicate to create an empty file
create_empty_file(Name) :-
open(Name, write, Stream),
close(Stream).
% Helper predicate to print file information
print_file_info(Dir, File) :-
(File \= '.' , File \= '..' ->
atomic_list_concat([Dir, '/', File], FullPath),
(exists_directory(FullPath) ->
format(' ~w true~n', [File])
;
format(' ~w false~n', [File])
)
; true).
% Predicate to visit files and directories recursively
visit(Path) :-
(exists_directory(Path) ->
format(' ~w true~n', [Path])
;
format(' ~w false~n', [Path])
).
% Predicate to walk through a directory recursively
directory_walk(Dir, Predicate) :-
directory_files(Dir, Files),
maplist(process_file(Dir, Predicate), Files).
process_file(Dir, Predicate, File) :-
(File \= '.' , File \= '..' ->
atomic_list_concat([Dir, '/', File], FullPath),
call(Predicate, FullPath),
(exists_directory(FullPath) ->
directory_walk(FullPath, Predicate)
; true)
; true).
% Helper predicate to delete a directory and its contents
delete_directory_and_contents(Dir) :-
(exists_directory(Dir) ->
directory_files(Dir, Files),
maplist(delete_file_or_dir(Dir), Files),
delete_directory(Dir)
; true).
delete_file_or_dir(Dir, File) :-
(File \= '.' , File \= '..' ->
atomic_list_concat([Dir, '/', File], FullPath),
(exists_directory(FullPath) ->
delete_directory_and_contents(FullPath)
;
delete_file(FullPath)
)
; true).