PrologJ Input Output

Traditional and ISO Input-Output Models

Traditional Prolog provides limited support for text input-output through the notions of a "current input" and "current output" stream. All input operations read from the current input stream, and all output operations write to the current output stream. These streams are initially bound to the interactive console, but can be reassigned to a disk file through the use of the built-in predicates see/1 and tell/1.

The ISO standard includes the notion of an IO stream, and provides IO predicates that take a first argument which specifies the stream on which the operation is to be performed. Streams are first-class terms, and can be bound to variables (in fact, open/3, 4 do precisely this). In addition, a stream can have any number of aliases, which are ordinary atoms. When a stream must be specified as an argument to a built-in predicate, either the stream term created by open/3, 4, or an alias can be used.

For compatibility with traditional Prolog, ISO Prolog also provides versions of its IO predicates that take one less parameter, and implicitly read from a default current input stream or write to a default current output stream as the case may be. However, there are some minor differences between the mechanisms found in traditional Prolog and the backward compatibility support present in ISO Prolog, including the following:

PrologJ Support for Both Input-Output Models

PrologJ uses the same stream mechanism as ISO standard Prolog natively. As a result, all the ISO stream operations (including those not discussed above) perform as specified in the ISO standard. When the "traditional" category of built-in predicates is enabled, PrologJ also supports the traditional Prolog stream operations using the exact same predicate names and semantics as traditional Prolog. This implies the following:

Traditional Model Builtin Predicates

The normal operation of the traditional input-output predicates is as documented in sections 6.9 or 6.10 of [ Clocksin and Mellish 1994 ]. Error handling uses the same approach as for the ISO predicates. The following table summarizes the error cases for the various input-output predicates which belong to the "Traditional" category.

Traditional Prolog predicate   Error handling
display(Term) same as write_canonical/1
get0(Code) same as get_code/1
get(Code) same as get_code/1
put(Code) same as put_code/1
see(File) File is a variable: instantiation_error
File is neither a variable nor a stream term nor an atom: type_error(atom, File)
The file specified by File does not exist: existence_error(source_sink, File)
The file specified by File cannot be opened: permission_error(open, source_sink, File)
File refers to an existing output stream: permission_error(input, stream, File)
File refers to an existing binary stream: permission_error(input, binary_stream, File)
seeing(File) File is neither a variable nor an atom: type_error(atom, File)
seen none
skip(Code) Code is a variable: instantiation_error
Code is neither a variable nor an integer: type_error(integer, Code)
Code is an integer but not an in-character code: representation_error(in_character_code)
The current input stream IS is associated with a binary stream: permission_error(input, binary_stream, IS)
The current input stream IS has stream properties end_of_stream(past) and eof_action(error): permission_error(input, past_end_of_stream, IS)
Code does not occur in the stream between the current position and the end of the stream: permission_error(input, past_end_of_stream, IS)
tab(Spaces) Spaces is a variable: instantiation_error
Spaces is neither a variable nor an integer: type_error(integer, Spaces)
Spaces is a negative integer: domain_error(not_less_than_zero, Spaces)
The current output stream OS is a binary stream: permission_error(output, binary_stream, OS)
tell(File) File is a variable: instantiation_error
File is neither a variable nor a stream term nor an atom: type_error(atom, File)
The file specified by File cannot be opened: permission_error(open, source_sink, File)
File refers to an existing input stream: permission_error(output, stream, File)
File refers to an existing binary stream: permission_error(output, binary_stream, File)
telling(File) File is neither a variable nor an atom: type_error(atom, File)
told none

Clause IO Builtin Predicates

Traditional Prolog defines three predicates allowing the input and output of clauses. PrologJ makes these available when either the "Traditional" or "Clause IO" built-in predicate categories are made available. The documentation below supplements what is provided in [ Clocksin and Mellish 1994 ] sections 6.1 and 6.4.

Hybrid Builtin Predicates

As noted above, PrologJ includes a number of input-output predicates that allow the operations of traditional Prolog to be used with ISO-style streams. Each is functionally-equivalent to one of the traditional Prolog input-output predicates, but with an additional first argument that specifies a stream in the same manner as ISO input-output predicates. The following table summarizes the error handling for these predicates:

Traditional Prolog predicate   Error handling
display(Stream, Term) same as write_canonical/2
get0(Stream, Code) same as get_code/2
get(Stream, Code) same as get_code/2
put(Stream, Code) same as put_code/2
listing(Stream, Predicate) same as write/2 with regard to the Stream argument
same as listing/1 with regard to the Predicate argument
skip(Stream, Code) same as get_code/2, plus
Code is a variable: instantiation_error
Code does not occur in the stream between the current position and the end of the stream: permission_error(input, past_end_of_stream, IS)
tab(Stream, Spaces) same as same as put_code/2, plus
Spaces is a variable: instantiation_error
Spaces is neither a variable nor an integer: type_error(integer, Spaces)
Spaces is a negative integer: domain_error(not_less_than_zero, Spaces)

Added Support for read_write streams

In the ISO standard, a stream may be created for either read or write access. (The append option is a variation of write). However, it is not possible to create a stream that allows both reading and writing the same stream. PrologJ is extended to allow specifying the read_write mode when opening a stream - but only for binary streams. (It is an error to specify the mode read_write with a text stream. Hence, this mode is only usable with open/4, since streams not opened without specifying a type option are text by default.) Both binary read and write operations are allowed on such a stream. If the stream is also repositionable (which would normally be the case), it is even possible to read data that had been previously written to the same stream.

Added Valid Write-Option

In addition to allowing the three valid write-options described in the ISO standard (quoted, ignore_ops, and numbervars), the built-in predicates write_term/2 and write_term/3 also recognized one implementation-specific option:

Copyright © 2005 - Russell C. Bjork. See the file See file COPYING in the root directory for copyright information.

Valid XHTML 1.0!