
existing_file(++Base, ++Completions, ++Permissions, -MatchedFile)

   Finds any existing file subject to the specified conditions.

Arguments
   Base                The start of a file or path name (atom or string, possibly with a library/1 wrapper)
   Completions         Possible completions for Base (list of atomic elements)
   Permissions         Permissions (list of readable,writable,executable)
   MatchedFile         An existing file that matches the specification.

Type
   Operating System

Description
    This predicate will search for any existing files that match the
    specifications given in the first three arguments: the file starts with
    Base, which is an absolute or relative partial file name.  Possible
    completions (usually file extensions) given in Completions are appended
    to Base, in the order they are given, to give a complete name.
    If a proper file (i.e. non-directory) with this name exists, the
    ECLiPSe process's permission for this file are checked against the
    Permissions list (readable, writable, executable).  If the
    permissions match, then the filename is returned in MatchedFile.
    

    Base may have a library/1 wrapper around the name.  If this is
    used, the file is searched for in the directories specified in
    library path (including any subdirectory with the same name as
    given in the library/1 wrapper, i.e. we check for both lib/foo.eco
    and lib/foo/foo.eco).  The search order is the order in which the
    library directories appear in the library_path flag of get_flag/2,
    and for each directory, the completions are tried in the order in
    which they appear in the list Completions.

    All matching files are returned via backtracking.  If only the
    first one is required, use once/1.


    MatchedFile is the same type as Base (atom or string).  Also, if 
    Base is a relative (absolute) pathname, then so is MatchedFile.
    If Base starts with '~' or enviroment variables (specified with a
    leading '$'), these are substituted.  If the library(...) wrapper
    is used, the proper library path is substituted.

    Note that the executable permission for Windows may be approximate,
    because Windows (especially Vista) has a different system for
    dealing with execute permission.
    

    The predicates canonical_path_name/2 and existing_file/4 are intended
    as replacement for absolute_file_name/2 in previous releases. The
    functionality of completing an incomplete name and returning an
    absolute path of absolute_file_name/2 has been separated. The following
    approximately implements the old absolute_file_name/2:


    absolute_file_name(Rel, Abs) :-
	(Rel == user ->
	    Abs == user
	; get_flag(prolog_suffix, Sufs),
	  (existing_file(Rel, Sufs, [], ExtRel) -> true ; ExtRel = Rel),
	  canonical_path_name(ExtRel, Abs)
        ).




Modes and Determinism
   existing_file(++, ++, ++, -) is nondet

Fail Conditions
   MatchedFile cannot be found.

Resatisfiable
   Succeeds once for every matching file

Exceptions
     5 --- Base, Completions, Permissions not of right type.
     6 --- Base is an empty atom or string.

Examples
   
Success: 

      % Trying different file extensions, including the empty one:
      ?- existing_file("hello", [".ecl",".txt",""], [], File).
      File = "hello.txt"     More? (;) 
      No (0.00s cpu)         % assuming hello.ecl and hello do not exist

      % Looking for one of several files in the parent directory:
      ?- existing_file("../", ["a.txt","b.txt","c.txt"], [readable], File).
      File = "../a.txt"     More? (;) 
      File = "../c.txt"     More? (;) 
      No (0.00s cpu)        % assuming b.txt does not exist or is not readable

      % Looking for a precompiled library:
      ?- existing_file(library(fd), [".eco"], [readable], File).
      File = '/homes/ks15/Eclipse/lib/fd.eco'     More? (;) 
      No (0.00s cpu)

      % Looking for source files:
      ?- get_flag(prolog_suffix, Exts),
         existing_file("hello", Exts, [readable], File).
      File = "hello.ecl"     More? (;) 
      No (0.00s cpu)

      % Looking for different file names:
      [eclipse 1]: existing_file(test, [1,2,3], [], File).
      File = test1     More? (;) 
      File = test3     More? (;) 
      No (0.00s cpu)

Failure:

      [eclipse 1]:  existing_file(library(fd), [], [readable], File).
      % no Completions at all; will always fail

      [eclipse 1]:  existing_file(library(fd), [""], [readable], File).
      % no library file with just 'fd' as the name (file has a suffix)


See Also
   canonical_path_name / 2, get_flag / 2, os_file_name / 2, pathname / 4
