Walk Windows directory tree. exists_directory/1 and exists_file/1 not working as expected

Created code to walk Windows directory tree but the predicates exists_directory/1 and exists_file/1 are not working as expected in that they always return false.

test_01 :-
    process_directory('C:\\Program Files\\swipl').

process_directory(Directory) :-
    format('Directory: ~w~n',[Directory]),
    directory_files(Directory,Files),
    process_files(Files).

process_files([File|Files]) :-
    process_file(File),
    process_files(Files).
process_files([]).

process_file(File) :-
    (
        File = '.',
        exists_directory(File),
        format('Directory: ~w~n',[File])
    ;
        File = '..',
        exists_directory(File),
        format('Directory: ~w~n',[File])
    ;
        exists_directory(File),
        process_directory(File)
    ;
        exists_file(File),
        format('File: ~w~n',[File])
    ;
        format('Unknown: ~w~n',[File])
    ).

Also tried using absolute_file_name/2 but couldn’t get that to work either.

Example run:

?- test_01.
Directory: C:\Program Files\swipl
Directory: .
Directory: ..
Unknown: bin
Unknown: boot
Unknown: boot64.prc
Unknown: demo
Unknown: doc
Unknown: include
Unknown: lib
Unknown: library
Unknown: LICENSE
Unknown: README.md
Unknown: swipl-win.rc
Unknown: swipl.home
Unknown: swipl.ico
Unknown: Uninstall.exe
Unknown: xpce
true .

How is a Windows directory tree walked using SWI-Prolog?

I use to pass the directory along the filename, otherwise the directory specification '.' could point to a wrong path (the current directory). So, a possible solution is:

test_01 :-
    process_directory('C:\\Program Files\\swipl').

process_directory(Directory) :-
    format('Directory: ~w~n',[Directory]),
    directory_files(Directory,Files),
    process_files(Directory,Files).

process_files(Directory, [File|Files]) :-
    process_file(Directory, File),
    process_files(Directory, Files).
process_files(_Directory, []).

process_file(Directory, File) :-
    (
        File = '.',
        directory_file_path(Directory, File, Path),
        exists_directory(Path),
        format('Directory: ~w~n',[File])
    ;
        File = '..',
        directory_file_path(Directory, File, Path),
        exists_directory(Path),
        format('Directory: ~w~n',[File])
    ;
        directory_file_path(Directory, File, Path),
        exists_directory(Path),
        process_directory(Path)
    ;
        directory_file_path(Directory, File, Path),
        exists_file(Path),
        format('File: ~w~n',[File])
    ;
        format('Unknown: ~w~n',[File])
    ).
1 Like

Hi!
Well your code works but it leaves choicepoints, so you should add cuts.

File: mkcommon.pl %last lines of output from your code 
File: quintus.pl
File: sicstus.pl
File: Xserver.pl
File: README.md
true ;   %Everything was printed correctly, but code has a choicepoint
           %If I now hit spacebar-button I get
Unknown: README.md
true ; %Hitting another spacebar
Unknown: Xserver.pl
File: README.md
true 

After inserting the ‘!’-atoms, I get


File: common.pl %last lines of output from my code
File: mkcommon.pl
File: quintus.pl
File: sicstus.pl
File: Xserver.pl
File: README.md
true.

?-  

This is your code added with cuts… well I notice that you are
using \\-atoms as a splitter in file paths

test_01 :-
    %process_directory('C:\\Program Files\\swipl').
    process_directory('C:/Program Files/swipl').

process_directory(Directory) :-
    format('Directory: ~w~n',[Directory]),
    directory_files(Directory,Files),!,  %cut inserted
    process_files(Directory,Files).

process_files(Directory, [File|Files]) :-
    process_file(Directory, File),!, %cut inserted
    process_files(Directory, Files).
process_files(_Directory, []).

process_file(Directory, File) :-
    (
        File = '.',
        directory_file_path(Directory, File, Path),
        exists_directory(Path),!,%cut inserted
        format('Directory: ~w~n',[File])
    ;
        File = '..',
        directory_file_path(Directory, File, Path),
        exists_directory(Path),!,%cut inserted
        format('Directory: ~w~n',[File])
    ;
        directory_file_path(Directory, File, Path),
        exists_directory(Path),!,%cut inserted
        process_directory(Path)
    ;
        directory_file_path(Directory, File, Path),
        exists_file(Path),!,%cut inserted
        format('File: ~w~n',[File])
    ;
        format('Unknown: ~w~n',[File])
    ).

Thanks

1 Like