Finding Subdirectories

Corresponding to the above set of six predicates for matching files in a particular directory, there is another set of six for matching subdirectories. They have the forms


directory_member_of_directory([?Directory, [?Pattern, ]]?Short, ?Full)

directory_members_of_directory([?Directory, [?Pattern, ]]?Set)
They are exactly like the file_member... predicates in every way, except that they insist that the files thus located should instead be proper subdirectories of Directory. This means that not only should Full name a directory, but also Short should not be . or ... The reason for this is to allow you to easily write routines that explore an entire directory tree, as in
          explore(Directory, FullName) :-
             file_member_of_directory(Directory, _, FullName).
          explore(Directory, FullName) :-
             directory_member_of_directory(Directory, _, SubDir),
             explore(SubDir, FullName).
          
          | ?- explore(., FullName), write(FullName), nl, fail.
          

If the self (.) and parent (..) entries were not concealed from the search, this code would go into an infinite loop exploring Directory/./././././././. and so on. Note that this does not preclude using . and .. in the Directory name itself.