This library realises emulation of IF/Prolog. As with all the emulation
layers in the dialect directory, the emulation has been established on
`as needed' basis from porting programs. This implies that the emulation
is incomplete. Emumated directives, predicates and libraries are often
not 100% compatible with the IF/Prolog version.
Note that this emulation layer targets primarily IF/Prolog version 5.
Please help extending this library and submit patches to
bugs@swi-prolog.org.
- ifprolog_goal_expansion(+In, +Out)[multifile]
- goal_expansion rules to emulate IF/Prolog behaviour in
SWI-Prolog. The expansions below maintain optimization from
compilation. Defining them as predicates would loose
compilation.
- context(:Goal, Handler)
- Is mapped to
catch(Goal, Error, Recover)
is Handler is
error(_,_) => Recover
. Other cases are not covered by the
emulation.
- asserta(Head, Body) is det[private]
- assertz(Head, Body) is det[private]
- retract(Head, Body) is det[private]
- Mapped to
asserta((Head:-Body))
, etc. Note that this masks
SWI-Prolog's asserta/2, etc.
- ifprolog_term_expansion(+In, +Out)[multifile]
- term_expansion rules to emulate IF/Prolog behaviour in
SWI-Prolog.
- meta(+ListOfPI)[private]
- Mapped to module_transparent/1. Not sure whether this is
correct. It surely is not very elegant to map to a deprecated
feature. Luckily, although the module_transparent/1 API is
deprecated, the underlying functionality is still core of the
module system.
Note that if :- meta appears inside a module interface, the
predicate is also exported.
- export(+ListOfPI) is det[private]
- discontiguous +ListOfPI is det[private]
- Mapped to comma-lists
- module(+Name)[private]
- begin_module(+Name)[private]
- end_module(+Name)[private]
- These are emulated correctly, provided module/1 is the first
term of the file and the implementation is part of the same
file. Begin/end are ignored.
- pi_list_to_pi_term(+List, -CommaList) is det[private]
- push_ifprolog_library[private]
- Pushes searching for dialect/ifprolog in front of every library
directory that contains such as sub-directory.
- push_ifprolog_file_extension[private]
- Looks for .pro files before looking for .pl files if the current
dialect is
pro
. If the dialect is not active, the .pro files
are found as last resort.
- calling_context(-Context)
- Mapped to context_module/1.
- context(:Goal, +Mapping)
- IF/Prolog context/2 construct. This is the true predicate. This
is normally mapped by goal-expansion.
- bug
- - Does not deal with IF/Prolog signal mapping
- block(:Goal, +Tag, :Recovery)
- exit_block(+Tag)
- cut_block(+Tag) is semidet
- The control construct block/3 runs Goal in a block labelled Tag.
If Goal calls exit_block/1 using a matching Tag, the execution
of Goal is abandoned using exception handling and execution
continues by running Recovery. Goal can call cut_block/1. If
there is a block with matching Tag, all choice points created
since the block was started are destroyed.
- bug
- - The block control structure is implemented on top of
catch/3 and throw/1. If catch/3 is used inside Goal,
the user must ensure that either (1) the protected
goal does not call exit_block/1 or cut_block/1 or (2)
the Catcher of the catch/3 call does not unify with
a term
block(_,_)
.
- modify_mode(+PI, -OldMode, +NewMode) is det
- Switch between static and dynamic code. Fully supported, but
notably changing static to dynamic code is not allowed if the
predicate has clauses.
- debug_mode(:PI, -Old, +New)
- Old is not unified. Only New == off is mapped to disable
debugging of a predicate.
- ifprolog_debug(:Goal)
- Map IF/Prolog
debug(Goal)
@Module. This should run Goal in debug
mode. We rarely needs this type of measures in SWI-Prolog.
- debug_config(+Key, -Current, +Value)
- Ignored. Prints a message.
- float_format(-Old, +New)
- Ignored. Prints a message. Cannot be emulated. Printing floats
with a specified precision can only be done using format/2.
- program_parameters(-List:atom)
- All command-line argument, including the executable,
- user_parameters(-List:atom)
- Parameters after
--
.
- match(+Mask, +Atom) is semidet
- Same as
once(match(Mask, Atom, _Replacements))
.
- match(+Mask, +Atom, ?Replacements) is nondet
- Pattern matching. This emulation should be complete. Can be
optimized using caching of the pattern-analysis or doing the
analysis at compile-time.
- lower_upper(+Lower, -Upper) is det
- lower_upper(-Lower, +Upper) is det
- Multi-moded combination of upcase_atom/2 and downcase_atom/2.
- load(File)
- Mapped to consult. I think that the compatible version should
only load .qlf (compiled) code.
- unload(+Module) is det[private]
- Unload the named module.
- bug
- - : What to do with modules that are not associated to a
file?
- file_test(+File, +Mode)
- Mapped to access_file/2 (which understand more modes). Note that
this predicate is defined in the module
system
to allow for
direct calling.
- filepos(@Stream, -Line)
- from the IF/Prolog documentation The predicate filepos/2
determines the current line position of the specified input
stream and unifies the result with Line. The current line
position is the number of line processed + 1
- getcwd(-Dir)
- The predicate getcwd/1 unifies Dir with the full pathname of the
current working directory.
- filepos(@Stream, -Line, -Column)
- from the IF/Prolog documentation The predicate filepos/2
determines the current line position of the specified input
stream and unifies the result with Line. The current line
position is the number of line processed + 1
- assign_alias(+Alias, @Stream) is det
- writeq_atom(+Term, -Atom)
- Use writeq/1 to write Term to Atom.
- write_atom(+Term, -Atom)
- Use write/1 to write Term to Atom.
- current_error(-Stream)
- Doesn't exist in SWI-Prolog, but
user_error
is always an alias
to the current error stream.
- write_formatted_atom(-Atom, +Format, +ArgList) is det
- write_formatted(+Format, +ArgList) is det
- write_formatted(@Stream, +Format, +ArgList) is det
- Emulation of IF/Prolog formatted write. The emulation is very
incomplete. Notable asks for dealing with aligned fields, etc.
- bug
- - Not all format characters are processed
- - Incomplete processing of modifiers, fieldwidth and precision
- To be done
- - This should become goal-expansion based to process
format specifiers at compile-time.
- format_modifiers(-Flags, -FieldLength, -Precision) is det[private]
- Read the IF/Prolog format modifiers. We currently do not process
any of the modifiers! Some code seems to be using e.g. %07lx. We
assume this is the same as -07x (assuming l=left).
- get_until(+SearchChar, -Text, -EndChar) is det
- get_until(@Stream, +SearchChar, -Text, -EndChar) is det
- Read input from Stream until SearchChar. Unify EndChar with
either SearchChar or the atom
end_of_file
.
- atom_part(+Atom, +Pos, +Len, -Sub) is det
- True when Sub is part of the atom [Pos,Pos+Len). Unifies Sub
with '' if Pos or Len is out of range!?
- atom_prefix(+Atom, +Len, -Sub) is det
- Unifies Sub with the atom formed by the first Len characters in
atom.
- If Len < 1, Sub is unified with the null atom ''.
- If Len > length of Atom, Sub is unified with Atom.
- atom_suffix(+Atom, +Len, -Sub) is det
- Unifies Sub with the atom formed by the last Len characters in
atom.
- If Len < 1, Sub is unified with the null atom ''.
- If Len > length of Atom, Sub is unified with Atom.
- atom_split(+Atom, +Delimiter, ?Subatoms)
- Split Atom over Delimiter and unify the parts with Subatoms.
- if_concat_atom(+List, +Delimiter, -Atom) is det
- True when Atom is the concatenation of the lexical form of all
elements from List, using Delimiter to delimit the elements.
The behavior of this ifprolog predicate is different w.r.t.
SWI-Prolog in two respect: it supports arbitrary terms in List
rather than only atomic and it does not work in mode -,+,+.
- if_concat_atom(+List, -Atom) is det
- True when Atom is the concatenation of the lexical form of all
elements from List. Same as if_concat_atom/3 using '' as
delimiter.
- getchar(+Atom, +Pos, -Char)
- Unifies Char with the Position-th character in Atom
If Pos < 1 or Pos > length of Atom, then fail.
- parse_atom(+Atom, +StartPos, ?EndPos, ?Term, ?VarList, ?Error)
- Read from an atom.
- Arguments:
-
StartPos | - is 1-based position to start reading |
Error | - is the 1-based position of a syntax error or 0 if
there is no error. |
- index(+Atom, +String, -Position) is semidet
- True when Position is the first occurrence of String in Atom.
Position is 1-based.
- list_length(+List, ?Length) is det
- Deterministic version of length/2. Current implementation simply
calls length/2.
- for(+Start, ?Count, +End) is nondet
- Similar to between/3, but can count down if Start > End.
- prolog_version(-Version)
- Return IF/Prolog simulated version string
- proroot(-Path)
- True when Path is the installation location of the Prolog
system.
- system_name(-SystemName)
- True when SystemName identifies the operating system. Note that
this returns the SWI-Prolog
arch
flag, and not the IF/Prolog
identifiers.
- localtime(+Time, ?Year, ?Month, ?Day, ?DoW, ?DoY, ?Hour, ?Min, ?Sec)
- Break system time into its components. Deefines components:
Year | Year number | 4 digits |
Month | Month number | 1..12 |
Day | Day of month | 1..31 |
DoW | Day of week | 1..7 (Mon-Sun) |
DoY | Day in year | 1..366 |
Hour | Hours | 0..23 |
Min | Minutes | 0..59 |
Sec | Seconds | 0..59 |
Note that in IF/Prolog V4, Year is 0..99, while it is a
four-digit number in IF/Prolog V5. We emulate IF/Prolog V5.
- current_global(+Name) is semidet
- get_global(+Name, ?Value) is det
- set_global(+Name, ?Value) is det
- unset_global(+Name) is det
- IF/Prolog global variables, mapped to SWI-Prolog's nb_*
predicates.
- current_default_module(-Module) is det
- Name of the toplevel typein module.
- set_default_module(+Module) is det
- Set the default toplevel module.
- asserta_with_names(@Clause, +VarNames) is det
- assertz_with_names(@Clause, +VarNames) is det
- clause_with_names(?Head, ?Body, -VarNames) is det
- retract_with_names(?Clause, -VarNames) is det
- Predicates that manage the database while keeping track of
variable names.
- predicate_type(:PI, -Type) is det
- True when Type describes the type of PI. Note that the value
linear
seems to mean you can use clause/2 on it, which is true
for any SWI-Prolog predicate that is defined. Therefore, we use
it for any predicate that is defined.
- current_visible(@Module, @PredicateIndicator)
- FIXME check with documentation
- current_signal(?Signal, ?Mode) is nondet
- True when Mode is the current mode for handling Signal. Modes
are
on
, off
, default
, ignore
. Signals are abort
,
alarm
, interrupt
, pipe
, quit
, termination
, user_1
and user_2
.
- To be done
- - Implement
- digit(+A)
- Is the character A a digit [0-9]
- letter(+A)
- Is the character A a letter [A-Za-z]