# System function predicates

Arity/Prolog32 supplies predicates to perform operating system functions for managing files and directories and for accessing the system clock. You can use these predicates rather than issuing similar commands through the Arity/Prolog32 shell/1 predicate.

Arity/Prolog32 also includes predicates for performing a variety of Arity/Prolog32-related functions. For example, there are predicates which report on Arity/Prolog32 system resources, such as stack sizes, page sizes, and atom heap size. There are also a number of predicates available for dealing with error situations.

## Performing file maintenance

The predicates in this section perform routine file maintenance: deleting and renaming files, or changing the attributes of files.

delete(+Filename)

You use the delete/1 predicate to delete a file. You supply the file specification as an argument. You cannot use wildcard characters in the file specification.

rename(+Filename, +Newname)

The rename/2 predicate changes the name of a file.

For example, the following query renames the file, file.dat (which resides in the current directory) to the new name file.dat (which resides in the subdirectory, test):

?- rename('file.dat', 'test\file.dat').
yes

You cannot use rename to move files from one disk drive to another but you can use rename to move files from one directory to another on the same disk.

chmod(+Filename, ?Attributes)

The chmod/2 predicate sets or returns the attribute byte for a file. You can supply a file specification and a variable as arguments to the predicate. The Attributes argument can be either an instantiated or an uninstantiated variable. If the Attributes argument is uninstantiated, Arity/Prolog32 returns the value of the attribute byte to the variable. If the Attributes argument is instantiated, chmod/2 sets the attribute byte to the value that you specify.

The attribute values recognized and returned by chmod are given as integers and can be one of the following or any combination of the following:

0

Read, write, not a hidden file, and not a system file. This is the default. Use the 0 attribute to return a file to its original attributes.

1

Read-only. If you try to open the file for output, Arity/Prolog32 issues an error message.

2

Hidden file. The file is excluded from normal directory searches.

4

System file. The file is excluded from normal directory searches.

16

Directory. The file is a directory.

32

Archive. The file has been modified since the last backup.

You specify multiple attributes by adding the desired attribute values together. For example, the following clause changes the attributes of the file test.tst to read-only, hidden, and system:

?- chmod('test\test.tst',07).
yes

## Disks, Directories and File Names

The predicates in this section change the current disk device or directory. They create and remove directories, and they generate directory listings.

disk(?DiskName)

The disk/1 predicate sets the default disk drive to the letter you specify (a, b, c, etc.). You do not need to enclose the disk name in quotes or add a colon following the letter.

For example:
?- disk(a).
yes

This call to the disk predicate is equivalent to the command prompt directive:

C>a:

If the DiskName is an uninstantiated variable, disk returns the current disk to the variable, as in:

?- disk(X).
X = 'C'
yes

mkdir(+Path)

You use the mkdir/1 predicate to create a directory. You specify the disk drive, path, and the name of the new directory with the Path argument. The path must not exceed 63 characters.

For example, you can create a new directory called \TEST using the mkdir/1 predicate like this:

?- mkdir('\test').
yes

This Prolog goal is equivalent to the following command prompt directive:

C> mkdir \test

chdir(?Path)

The chdir/1 predicate allows you to see what directory you are currently working in or to change to another directory. You specify a backslash to move to your root directory. You supply the full root path to move to any other directory.

For example:

?- chdir('test').
yes

This is the same as the command prompt directive:

C> chdir test

rmdir(+Path)

You use the rmdir/1 predicate to remove, or delete, a directory. To remove a directory, you must first delete all of the files it contains, then change to a different directory. You cannot be in the directory you are removing.

If you specify a path, rmdir/1 removes only the last directory in the path. You cannot remove more than one directory at a time and you cannot remove the root directory. For example:

?- rmdir(test).
yes

This is the same as the command prompt directive:

C> rmdir test

directory(+Path, -Name, -Mode, -Time, -Date, -Size)

The directory/6 predicate lists the files in a directory. The information you can access in the directory includes the file name, file attributes, the time and date the file was last accessed, and the size of the file in bytes.

The Path argument selects the files you want to list. You can use the wildcard characters (? and *) in the Path argument. The Path argument must be instantiated. You supply uninstantiated variables for those parts of the directory entry that you want returned. You may supply anonymous variables for the information you do not want returned.

The Mode (file attribute) can be any of the following or a combination of the following: 1 - read only; 2 - hidden; 4 - system file excluded from normal directory searches; 16 - directory; 32 - archive.

If the size of the file is greater than 2^32-1 then the size is represented as a floating-point number. The accuracy of floating-point numbers is such that exact arithmetic may be performed.

The following example uses directory to list the files in the current directory that were last updated on October 5, 2010.

?- directory('*.*',X,_,_,date(2010,10,5),_), write(X), nl, fail.
'ARITY.LI    B'
'API.LIB'
'API.IDB'
no

pfname(+Filename, -Prefix, -Name, -Extension, -HasExtension)

The pfname/5 predicate can be used to parse a Filename. The Filename is provided as a string and the various components (Prefix,Name,Extension) are returned as strings. If the returned Extension is the empty string, then the FileName may or may not have ended with a period (.). If the Filename ended with a period, then HasExtension is returned as y, otherwise HasExtension is returned asn.

## Operating system interaction predicates

halt

halt(+Exit_code)

You use the halt/0 and halt/1 predicates to exit from the Arity/Prolog32 Interpreter or a compiled program.

For example:

?- halt.

The halt/1 predicate allows you to specify an exit code to be returned when the program is halted. This is helpful in instances when you want to perform a specific action depending on how your Prolog application exits. For example, suppose you are running your Prolog application from within a batch file, and you want a message to be displayed indicating whether the program succeeds or fails. Normally, through the use of halt/0, there is no way to return an exit code indicating success or failure. Within your application, you could have two different calls to the halt/1 predicate. One use would be executed if the program succeeded and the other would be executed if the program failed. The Exit_code is an integer. For example, to halt a program and return the exit code 3, you include the following in the program:

halt(3)

The predicates in this section are used to run operating system commands from Arity/Prolog32, terminate the application, and produce statistics on system use.

abort(+HaltCode)

The abort/1 predicate simulates a Ctrl-C entered from the keyboard and is used for exception handling. When abort is encountered, it calls the restart predicate. If there is no restart predicate and the program is interpreted, program control returns to the interpreter. If there is no restart predicate and the program is compiled, the program will use HaltCode to halt the program.

shell

shell(+Command)

The shell/0 and shell/1 predicates allow you to interact with the operating system from within the interpreter or a compiled Arity/Prolog32 program.

If you do not supply a command as an argument, you are placed at the operating system prompt. You will remain there and can execute commands until you type exit at the command prompt:

C> exit

If you do supply a command as an argument, the shell predicate executes that command and returns you to the interpreter or compiled program as soon as the command has been executed. Note that if the command takes an argument, you must supply the command as an atom or string.

lock

unlock

The lock/0 predicate adds 1 to a counting semaphore that is associated to Ctrl-Break processing. The unlock/0 predicate subtracts 1 from the counting semaphore.

When Ctrl-Break is pressed to terminate a program, the system checks whether an associated counting semaphore is set to 0. The counting semaphore simply keeps track of whether a Ctrl-Break is permitted during a specific point in program execution. If the counting semaphore is set to 0, then the Ctrl-Break is executed. If the counting semaphore is not set to 0, then the Ctrl-Break is not executed but is remembered and is executed when the counting semaphore becomes 0.

Thus, through the use of the lock/0 predicate, you can make the counting semaphore something other than 0. This is useful in instances when you have a program in which a break in the program at a particular point would have undesirable consequences. You could use the lock/0 predicate at the beginning of this segment of code to ensure that the user can not break out of the program during execution of this segment. You then include the unlock/0 predicate at the end of the code segment in order to return the counting semaphore to 0 and allow the Ctrl-Break.

Note: that each use of the lock/0 predicate should include a corresponding call to the unlock/0 predicate later in the program.

break

This goal suspends execution of an interpreter break level and re-invokes the interpreter. A break ends when the user types Ctrl-Z or endoffile. at the interpreter prompt.

## Garbage Collection

gc

The gc/0 predicate restores stack space no longer needed by the program. (gc stands for garbage collection.)

You will seldom, if ever, need to use the garbage collection facility because Arity/Prolog32 automatically restores space when it is no longer needed. For example, stack space is automatically restored when a predicate backtracks.

Garbage collection is invoked automatically if your program uses a high percentage of the global stack. You can tell if this is happening by calling the statistics predicate. If this is the case, you may want to restructure the program so that it backtracks to allow for recovery of space. If this is impractical or impossible, you may want to explicitly invoke the garbage collector with the gc predicate at convenient points in the program, such as when you are waiting for input from the user.

## Statistics

statistics(?Stat, -Struct)

The statistics/2 predicate returns information on Arity/Prolog32 system resources. You can use this predicate to return information on stack usage, database usage, and database page status.

The information returned by statistics/2 is useful for determining how an application uses system resources. You can use this information to create an environment file so that an application can make efficient use of system resources.

Arity/Prolog32 defines a number of atoms used to specify the type of information that you want statistics to return, and data structures to hold the information. If the Stat argument is unbound when statistics/2 is called then it will backtrack through all statistics results except for cache.

The following is a list of the Stat atoms and the structures statistics/2 returns.

stacks

If you specify stacks, the statistics predicate returns a structure giving the allocated sizes of the local and global stacks, as shown:

stacks(Local, Global, 0)

These sizes are the same as the sizes that are set in the environment file. The trail stack is allocated as part of the local stack and does not have a separate value.

local

global

trail

When you specify local, global, or trail, statistics returns a structure giving the current size of the specified stack and maximum size in bytes ever used by the stack.

The information for the local, global and trail statistics are returned in a structure, as shown:

size(Current,Max)

garbage

When you specify garbage, statistics returns a structure giving the number of times stack space has been recovered (this is referred to as garbage collection). It addition, it returns the number of global and the number of trail cells recovered during the most recent garbage collection.

The structure has the form:

invoked(Collect,Global,Trail)

version

When you specify version, statistics returns a structure of the form:

version(Version,Update,Revision)

The Version, Update and Revision numbers correspond to the copy of arity32.lib you linked with or that your interpreter was linked with. These values are also displayed in the heralds of the Arity/Prolog32 Compiler and Interpreter.

database

When you specify database, statistics returns a structure of the form:

database(0,MaxCachePages,CurrentCachePages,CurrentWorkspaceDatabaseName)

edb

When you specify database, statistics returns a structure of the form:

s(WorkSpaceNo,OverflowFileName,OverFlowFileSize, CacheHits,CacheMisses)

Note that the overflow statistics are dependent on the current workspace.

cache

When you specify cache, statistics returns a structure of the form:

s(MaxCachePages,CurrentCachePages,CacheHits,CacheMisses)

The predicate statistics(cache,X) has the side effect of setting CacheHits and CacheMisses to 0 after unifying the current values.

## Error Handling

Error messages can indicate syntax errors, file Input / Output errors, or runtime errors.

• Syntax errors are produced by errors in a term.
• File Input/Output errors are issued by the operating system to indicate problems in accessing a file that your program requires.
• Runtime errors can occur if the program's database or memory requirements are too large.

Syntax and file Input / Output messages can be turned on or off. The settings are specified with the atoms on and off. When these errors are turned off, you can still check the error code using an error-checking predicate.

syntaxerrors(-Old, +New)

The syntaxerrors/2 predicate turns syntax error messages on or off. You can also use syntaxerrors/2 to check the current setting of these messages. When syntax messages are on, Arity/Prolog32 displays all messages as they occur and continues to the next term. Syntax messages are turned on by default.

You can turn them off by typing:

?- syntaxerrors(_, off).
yes

When they are disabled and an error condition exists, Arity/Prolog32 posts an error code and the Input/Output predicate fails. You can check the error code with the error-checking predicate.

You can re-enable syntax error messages by typing:

?- syntaxerrors(_, on).

You can check the current setting in this way:

?- syntaxerrors(X, X).
X = on
yes

fileerrors(-Old,+New)

The fileerrors/2 predicate turns file Input/Output error messages on or off. You can also use fileerrors/2 to check the current setting of these messages. File Input/Output error messages are enabled by default. When a file error occurs, a message is displayed and Arity/Prolog32 aborts the program.

You can disable file Input/Output error messages by typing:

?- fileerrors(_, off).
yes

When disabled, no message is displayed and the goal which invokes the Input/Output operation fails. However, like syntaxerrors, Arity/Prolog32 posts the error code which you can check. The fileerrors predicate is often turned off in instances where you want your program to perform some specified action when a file can not be opened. If fileerrors is left on in this instance, a message is displayed and the program aborts. If fileerrors is turned off, the goal which attempts to open the file fails, but no message is displayed and you can write predicates to handle the failure.

To check the current fileerrors setting, type:

?- fileerrors(X, X).
X = on
yes

errcode(-OldCode, +NewCode)

The errcode/2 predicate returns the error code for the most recent error message and resets the error code to new a code provided. If syntax or file Input/Output errors are turned off and an error occurs, you would need to use this predicate to determine the cause of the error. You may specify 0 a the new error code to indicate that an error condition does not exist any longer.

## Accessing the system clock

The predicates in this section change or return the date and time of the system clock. An additional predicate is provided to determine the day of the week on which a date falls.

date(?date(Year, Month, Day))

Arity/Prolog32 defines a structure for handling dates.

All dates are expressed in the format:

date(Year, Month, Day)

The date/3 predicate takes a date structure as its argument. If the structure is uninstantiated, the predicate returns the current date. If the structure is instantiated, date/3 sets the system clock to the date you specify or will fail if the instantiated date is invalid.

For example, the first call to date, below, returns the current date (here, May 8, 2010). The second call sets the date to July 14, 2010.

?- date(X).
X = date(2010,5,8)
yes

?- date(date(2010,7,14)).
yes

time(?time(Hour, Minute, Second, Hundredth))

Arity/Prolog32 defines a structure for representing time.

The time structure has the format:

time(Hour, Minute, Second, Hundredth)

The time/1 predicate takes a time structure as its argument. If the structure is uninstantiated, time returns the current time of day. If the structure is instantiated, time sets the system clock to that value or will fail if the instantiated time is invalid.

In the following example, 11:02:40.82 is the current time:

?- time(X).
X = time(11,2,40,82)
yes

date_day(+date(Y,M,D), -WeekDay)

The date_day/2 predicate returns the day of the week for a given date. The date cannot fall before January 1, 1900 or after December 31, 2079.

The day of the week is returned as an integer between 0 and 6, where 0 is equal to Sunday and 6 is equal to Saturday.

The following example returns Saturday (6) as the weekday of January 1, 2011:

?- date_day(date(2011,1,1), X).
X = 5
yes

The following example shows how you can use date/3, date_day/2, and time/1 to display the current day of the week, date, and time. To display this information in non-numeric form, you must define two predicates, day and month, to translate the numbers returned from date_day/2 to the correct day and month names. The predicate, today, formats and displays the information.

day(0,'Sunday').
day(1,'Monday').
day(2,'Tuesday').
day(3,'Wednesday').
day(4,'Thursday').
day(5,'Friday').
day(6,'Saturday').

month(1,'January').
month(2,'February').
month(3,'March').
month(4,'April').
month(5,'May').
month(6,'June').
month(7,'July').
month(8,'August').
month(9,'September').
month(10,'October').
month(11,'November').
month(12,'December').

today :-
date(date(X,Y,Z)),
date_day(date(X,Y,Z),A),
day(A,B),
write('Today is '),
write(B), tab(1),
month(Y,C),
write(C), tab(1),
write(Z), write(','), tab(1),
write(X), nl,
write('The time is '),
time(time(H,M,_,_)),
write(H),
write(':'),
write(M).

To execute this program, you type:

?- today.
Today is Thursday April 30, 1992The time is 12:10
yes

## Including arguments in application programs

If you write your own Arity/Prolog32 applications, the command_string/1 predicate allows you to include arguments in the command line that invokes your application program. For example, suppose you have written an application program named struct which takes a single command line argument. The program is invoked by typing struct and the name of a file containing the sentences, as in the following:

C> struct file1

command_string(X)

The command_string/1 predicate returns the command line arguments as a string. It can be included in your application program to return the command line arguments so that they can be used by the application program.

For the above example, the command_string/1 predicate would return ' file1' bound to X. (Note that the leading space is included). The application can then include further instructions for processing the string so that it is useful to the application. If no argument is included in the command line, command_string/1 will return a null string.

## Accessing System Environment Variables

getEnvVar(+Variable, -Value)

If you wish to examine the current value for an environment variable, such as 'PATH', 'TEMP' or 'EDITOR', you may use the predicate getEnvVar/2. The environment value is returned as an atom. If the environment variable is not found, then getEnvVar/2 will fail.