Skip to content

tell/1 and told/0 are not defined in Standard Prolog #14

@ekaf

Description

@ekaf

The current implementation of the conversion to CSV of the WordNet dbs succeeds in most Prologs, but fails with an "Attempt to write past EOF" error in Trealla.

In the ideal interpretation, the system would maintain a stack of open streams, so that when closing the current output stream, if there is a previous output stream, then the current output stream shall become the previous output stream. Otherwise, the current output stream shall become the implementation defined default.

However, the effective behaviour of the tell/told predicates varies greatly across actual Prolog systems, as exposed in this minimal reproduction:

minimal_test :-
    tell(a),      % Open file 'a' as output
    tell(b),      % Open file 'b' as output (should save a stream to 'a')
    told,         % Close 'b', should restore output to 'a'
    write(should_be_in_a),  % Best: writes to file 'a'
    told.         % Close 'a', return to default output

:- initialization(minimal_test).

Ideal Behaviour (SWI-Prolog):

· should_be_in_a → written to file 'a'
· Files 'a' and 'b' properly closed
· Stream stack correctly maintained

Actual Behaviour in GNU Prolog:

· should_be_in_a → written to screen (user_output) ✗
· No stack maintained for previous streams
· First told/0 appears to reset to default output regardless of nesting

Impact:

· Breaks portable Prolog code expecting standard behaviour
· Prevents correct implementation of nested output operations
· Code that works in some Prologs fails in others

Comparison across Prolog systems:

  1. SWI-Prolog: Ideal compliance - maintains proper stream stack
  2. Trealla Prolog: errors on backtracking across tell/told
  3. GNU Prolog: fails silently (writes to wrong destination)

Workaround:
As long as tell and told are not defined in the ISO Prolog Standard, no particular interpretation of their behaviour can be expected.
Until fixed, users requiring portable nested output operations should use open/3, current_output/1, set_output/1, and close/1 instead of tell/1 and told/0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions