The interactive top-level shell

Author(s): Daniel Cabeza, The Ciao Development Team.

ciaosh is the Ciao interactive top-level shell. It provides the user with an interactive programming environment with tools for incrementally building programs, debugging programs by following their executions, and modifying parts of programs without having to start again from scratch. If available, it is strongly recommended to use it with the emacs interface provided, as it greatly simplifies the operation. This chapter documents general operation in the shell itself.

Shell invocation and startup

When invoked, the shell responds with a message of identification and the prompt ?- as soon as it is ready to accept input.

When the shell is initialized it looks for a file .ciaorc in the HOME directory and makes an include of it, if it exists. This file is useful for including use_module/1 declarations for the modules one wants to be loaded by default, changing prolog flags, etc. (Note that the .ciaorc file can only contain directives, not actual code; to load some code at startup put it in a separate file and load it using e.g. a use_module/1 declaration.) If the initialization file does not exist, the default package default_for_ciaosh is included, to provide more or less what other prologs define by default. Thus, if you want to have available all builtins you had before adding the initialization file, you have to include :- use_package(default_for_ciaosh) in it. Two command-line options control the loading of the initialization file:

-f
Fast start, do not load any initialization file.

-q
Quiet, do not show banner.

-i
Force interactive even if stdin is not a pseudo-terminal.

-l File
Look for initialization file File instead of ~/.ciaorc. If it does not exist, include the default package.

-u File
Use module File on startup.

-p Prompt
Set Prompt as prompt.

-e Query
Call Query on startup.

Shell interaction

After the shell outputs the prompt, it is expecting either an internal command (see the following sections) or a query (a goal or sequence of goals). When typing in the input, which must be a valid prolog term, if the term does not end in the first line, subsequent lines are indented. For example:

?- X =
   f(a,
   b).

X = f(a,b) ? 

yes
?- 

The queries are executed by the shell as if they appeared in the user module. Thus, in addition to builtin predicates, predicates available to be executed directly are all predicates defined by loaded user files (files with no module declaration), and imported predicates from modules by the use of use_module.

The possible answers of the shell, after executing an internal command or query, are:

  • If the execution failed (or produced an error), the answer is no.

  • If the execution was successful and bindings where made (or constraints where imposed) on answer variables, then the shell outputs the values of answer variables, as a sequence of bindings (or constraints), and then prints a ? as a prompt. At this point it is expecting an input line from the user. By entering a carriage-return (RET) or any line starting with y, the query terminates and the shell answer yes. Entering a `,' the shell enters a recursive level (see below). Finally, any other answer forces the system to backtrack and look for the next solution (answering as with the first solution).

  • If the execution was successful, but no answer variable was bound or constrained, the answer is simply yes. This behavior can be changed by setting the prolog flag prompt_alternatives_no_bindings to on, so that if there are more solutions the user will be consulted as explained in the previous point (useful if the solutions produce side effects).

To allow using connection variables in queries without having to report their results, variables whose name starts with _ are not considered in answers, the rest being the answer variables. This example illustrates the previous points:

?- member(a, [b, c]).

no
?- member(a, [a, b]).

yes
?- member(X, [a|L]).

X = a ? ;

L = [X|_] ? 

yes
?- atom_codes(ciao, _C), member(L, _C).

L = 99 ? ;

L = 105 ? ;

L = 97 ? ;

L = 111 ? ;

no
?- 

Entering recursive (conjunctive) shell levels

As stated before, when the user answers with `,' after a solution is presented, the shell enters a recursive level, changing its prompt to N ?- (where N is the recursion level) and keeping the bindings or constraints of the solution (this is inspired by the LogIn language developed by H. Ait-Kaci, P. Lincoln and Roger Nasr [AKNL86]). Thus, the following queries will be executed within that context, and all variables in the lower level solutions will be reported in subsequent solutions at this level. To exit a recursive level, input an EOF character or the command up. The last solution after entering the level is repeated, to allow asking for more solutions. Use command top to exit all recursive levels and return to the top level. Example interaction:

?- directory_files('.',_Fs), member(F,_Fs).

F = 'stream_utils.po' ? ,

1 ?- file_property(F, mod_time(T)).

F = 'stream_utils.po',
T = 923497679 ? 

yes
1 ?- up.

F = 'stream_utils.po' ? ;

F = 'stream_utils.pl' ? ;

F = 'stream_utils.itf' ? ,

1 ?- file_property(F, mod_time(T)).

F = 'stream_utils.itf',
T = 923497679 ? 

yes
1 ?- ^D
F = 'stream_utils.itf' ? 

yes
?- 

Usage and interface

Documentation on exports

PREDICATEuse_module/1

Usage:use_module(Module)

Load into the top-level the module defined in Module, importing all the predicates it exports.

PREDICATEuse_module/2

Usage:use_module(Module,Imports)

Load into the top-level the module defined in Module, importing the predicates in Imports.

Usage:ensure_loaded(File)

Load into the top-level the code residing in file (or files) File, which is user (i.e. non-module) code.

PREDICATEmake_exec/2

Usage:make_exec(Files,ExecName)

Make a Ciao executable from file (or files) Files, giving it name ExecName. If ExecName is a variable, the compiler will choose a default name for the executable and will bind the variable ExecName to that name. The name is chosen as follows: if the main prolog file has no .pl extension or we are in Windows, the executable will have extension .cpx; else the executable will be named as the main prolog file without extension.

PREDICATEinclude/1

Usage:include(File)

The contents of the file File are included in the top-level shell. For the moment, it only works with some directives, which are interpreted by the shell, or with normal clauses (which are asserted).

PREDICATEuse_package/1

Usage:use_package(Package)

Include the package or packages specified in Package. Most package contents can be handled in the top level, but there are currently still some limitations.

  • The following properties should hold at call time:
    (toplevel_doc:sourcenames/1)Package is a source name or a list of source names.

PREDICATEconsult/1

Usage:consult(File)

Provided for backward compatibility. Similar to ensure_loaded/1, but ensuring each listed file is loaded in consult mode (see The interactive debugger).

PREDICATEcompile/1

Usage:compile(File)

Provided for backward compatibility. Similar to ensure_loaded/1, but ensuring each listed file is loaded in compile mode (see The interactive debugger).

PREDICATE./2

Usage:[File|Files]

Provided for backward compatibility, obsoleted by ensure_loaded/1.

PREDICATEmake_po/1

Usage:make_po(Files)

Make object (.po) files from Files. Equivalent to executing "ciaoc -c" on the files.

PREDICATEunload/1

Usage:unload(File)

Unloads dynamically loaded file File.

Usage:set_debug_mode(File)

Set the loading mode of File to consult. See The interactive debugger.

Usage:set_nodebug_mode(File)

Set the loading mode of File to compile. See The interactive debugger.

PREDICATEforce_lazy/1

Usage:force_lazy(Module)

Force module of name Module to be loaded lazily in the subsequent created executables.

  • The following properties should hold at call time:
    (basic_props:atm/1)Module is an atom.

Usage:undo_force_lazy(Module)

Disable a previous force_lazy/1 on module Module (or, if it is uninstantiated, all previous force_lazy/1).

  • Calls should, and exit will be compatible with:
    (basic_props:atm/1)Module is an atom.

Usage:dynamic_search_path(Name)

Asserting a fact to this data predicate, files using path alias Name will be treated as dynamic in the subsequent created executables.

  • The following properties should hold at call time:
    (basic_props:atm/1)Name is an atom.

PREDICATEmultifile/1

Usage:multifile Pred

Dynamically declare predicate Pred as multifile. This is useful at the top-level shell to be able to call multifile predicates of loaded files.

Documentation on internals

Is defined as follows:
sourcenames(File) :-
        sourcename(File).
sourcenames(Files) :-
        list(Files,sourcename).
See sourcename/1 in Basic file/stream handling

Usage:sourcenames(Files)

Files is a source name or a list of source names.

    Documentation on imports

    This module has the following direct dependencies: