% BEGIN LICENSE BLOCK
% Version: CMPL 1.1
%
% The contents of this file are subject to the Cisco-style Mozilla Public
% License Version 1.1 (the "License"); you may not use this file except
% in compliance with the License.  You may obtain a copy of the License
% at www.eclipse-clp.org/license.
% 
% Software distributed under the License is distributed on an "AS IS"
% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
% the License for the specific language governing rights and limitations
% under the License. 
% 
% The Original Code is  The ECLiPSe Constraint Logic Programming System. 
% The Initial Developer of the Original Code is  Cisco Systems, Inc. 
% Portions created by the Initial Developer are
% Copyright (C) 2006 Cisco Systems, Inc.  All Rights Reserved.
% 
% Contributor(s): 
% 
% END LICENSE BLOCK

:- comment(alias, "Directives").
:- comment(summary, "Directives that can only appear in compiled files").

:- tool(include / 1).
:- tool(comment / 2).

:- comment(pragma / 1, [
	summary:"Enable or disable compiler options.  Can only be used as a directive in
source files.

",
	amode:(pragma(+) is det),
	desc:html("\
   The pragma/1 directive allows to control various compiler options.  The
   effect of a pragma is local to a source file (unlike set_flag/2).
   Settings are in effect until the next pragma that overrides it or until
   the end of the file.
<PRE>
    Option     Effect
   ---------------------------------------------------------------
    debug      debuggable code, no inline compilation
    nodebug    non-debuggable code, inline compilation done
    skip       set the skipped flag for all compiled predicates
    noskip     don't (default)
    expand     do inline compilation
    noexpand   don't
    system     set the type of all compiled predicates to built_in
</PRE>
   The default for debug/nodebug depends on the global flag debug_compile.
   The default for expand/noexpand depends on the global flag goal_expansion.
   The global flags are set with set_flag/2 and tested with get_flag/2.
<P>
   Pragmas which the compiler does not recognise are silently ignored by
   the compiler, but are recorded and can be retrieved using current_pragma/1.
   Such pragmas can be atoms or structures with arbitrary arguments.
<P>
"),
	args:["Option" : "An atom."],
	exceptions:[148 : "An unknown Option was given."],
	eg:"
:- pragma(debug).
:- pragma(expand).
twice(X, Y) :-      % this is compiled into debuggable
    Y is 2*X.       % code with expanded arithmetic



",
	see_also:[compile / 1, env / 0, get_flag / 2, get_flag / 3, pred / 1, set_flag / 3, set_flag / 2, (skipped) / 1, (unskipped) / 1, current_pragma/1]]).

:- comment(comment/2,

[
summary: "Adding documentational information to ECLiPSe files.",

index: ["Literate programming"],

args: ["Type": "Comment type",
       "Information": "Information for Type"],

amode:(comment(++,+) is det),

see_also:
[icompile/1,icompile/2,eci_to_html/3,ecis_to_htmls/0,ecis_to_htmls/3],

desc: html("\
The comment/2 predicate allows documentational information to be added to
ECLiPSe modules which can then be extracted and processed automatically by
using the document tools in the document library.  Please note that any
reference to `comment' in the rest of this description means the comment
predicate, not the normal ECLiPSe comment (% and /* ... */).
<P>
Operationally, comment/2 always succeeds, so it is a no-op and is
ignored by ECLiPSe when executed. In order to be processed by the
document tools, it should appear as a directive in the program, i.e. as
<PRE>
:- comment(Type, Information).
</PRE>
A comment directive provides information on various aspects of the module
in which the comment occurs. The Type argument specifies what the aspect
is, and Information gives the information associated with that aspect. Some
restrictions should be observed to the placement of comments to allow automatic
processing to correctly process the comments. These are listed at the end.

The documentation generation tools and the tkeclipse library browser tool
make use of the comments to generate documentations for modules. They
recognise several comment types as specified by the Type argument and
extract the information accordingly.
The comments can occur in any order inside the module, and none
are compulsory; if they are missing, then the information they could have
provided is simply not used in the documentation generation. Most comment
type should only occur at most once per module unless marked *multiple* in
the following description. In the case of *multiple*, all occurrence of the
comments of the type are processed by the documentation tools. Otherwise,
only the first textual occurrence will be used.
<P>
The documentation tools recognise the following module-level comments:
<DL>
<DT><STRONG>comment(summary, String)</STRONG>
   <DD>String is a short (one line) summary of the module.

<DT><STRONG>comment(desc, Description)</STRONG>
   <DD>Description is a longer Text (see below) describing the module in more
   detail than summary.

<DT><STRONG>comment(alias, String)</STRONG>                           *once* per file
   <DD>String is used to override the module name used by the document
   processing for the comments in the file. This allows the user to
   generate groupings of comments in the documentation other than the
   module in which the comments resides.

<DT><STRONG>comment(status, String)</STRONG>
   <DD>String is a single word, describing the status of the library.
   Classification used in ECLiPSe: prototype, evolving, stable, phase_out,
   deprecated.

<DT><STRONG>comment(author, String)</STRONG>
   <DD>String is the name of author(s) of the module.

<DT><STRONG>comment(copyright, String)</STRONG>
   <DD>String is the copyright notice that the documentation library will
   generate for the documentations it produce from the comments.

<DT><STRONG>comment(date, String)</STRONG>
   <DD>This is designed for version control.  String is a time-stamp
   for the file.  With CVS version control software, the string can
   initially be set to \"&#36;Date&#36;\", which will be expanded by
   CVS into the actual date each time the file is checked in.

<DT><STRONG>comment(include, FileNames)</STRONG>                      *multiple*
   <DD>FileNames is either one file name or a list of file names. The file
   name is either a string or an atom. These are names of files in which
   additional comments for the module are located. They are only processed
   by the document library tools.

<DT><STRONG>comment(index, ListOfStrings)</STRONG>
   <DD>The strings are used by the documentation generation process to provide
   pointers in the document index to the module: each string is added to
   the index pointing at the module description. This is used to add extra
   entries in the index in addition to the ones that are automatically
   generated.
</DL>
In addition, it is possible to comment individual predicates and
structures, using comment directives of the form:
<DL>
<DT><STRONG>comment(Name/Arity, ListofProperties)</STRONG>            *once* for each Name/Arity
   <DD>Name and Arity are the specification for a predicate in the module and
   ListofProperties is a list of information for the predicate. The entries
   are described below.
   <P>
   Instead of a list of properties, the atom 'hidden' can be specified.
   This will prevent an undocumented, exported predicate from showing up
   in the generated library documentation.

<DT><STRONG>comment(struct(Name), ListofProperties)</STRONG>            *once* for each structure
   <DD>Name is the name of a structure and ListofProperties is a list
   of information for the structure.  The entries are described below
   (admissible properties are: summary, fields, desc, see_also,
   eg, index).
</DL>
In these comments, the ListOfProperties is a list of properties of the form:
<PRE>
    PropertyName: PropertyInformation
</PRE>
The properties can occur in any order in the list.
The following ones are recognized by the document tools:
<DL>
<DT><STRONG>amode: FunctorTemplate</STRONG> *multiple*
   <DD>FunctorTemplate is a structure corresponding to the functor of
   the predicate with the arguments filled in with the modes admissible
   for a call to the predicate.  The valid modes are those generally
   recognised by ECLiPSe (++, +, -, ?), with the following meaning:
   <PRE>
   	++	ground (fully instantiated, not containing variables)
   	+	instantiated (not a variable)
   	-	variable
   	?	any
   </PRE>
   The amode field can also be used to specify the determinism of a
   call with a specific mode. In this case, the format is
   <PRE>
   amode:(FunctorTemplate is Determinism)
   </PRE>
   where FunctorTemplate is as above, and Determinism is an atom specifying
   the determinism behaviour of a call with the particular mode. Determinism
   can be one of: erroneous, failure, det, semidet, multi, nondet.  Their
   meaning is as defined for the Mercury programming language and can be
   summarised as follows:
   <PRE>
                   |   Maximum number of solutions
       Can fail?   |   0               1               > 1
       ------------+------------------------------------------
       no          |   erroneous       det             multi
       yes         |   failure         semidet         nondet
   </PRE>
   The amode property can occur multiple times, each giving a
   different mode for the predicate.  The document tools
   will generate the multiple modes description in the detail
   description of the predicate, but will combine the modes by
   generalising all the amodes to produce a general template
   for the predicate in any summary description of the predicate.

<DT><STRONG>args: ListofArgs</STRONG>
   <DD>ListofArgs is a list of the argument descriptions describing the
   argument. The length of the list should correspond to the arity of the
   predicate. The argument description is of the form:
    <PRE>
      ArgName: Description
    </PRE>
   where both ArgName and Description are strings. If present, ArgName will
   be used in the mode template.

<DT><STRONG>desc: Description</STRONG>
   <DD>Description is a Text (see below) giving a long description of the
   predicate.

<DT><STRONG>eg: Description</STRONG>
    <DD>Description is a Text (see below) for examples of using the
    predicate. This is used to generate the Examples section of the
    predicate description.

<DT><STRONG>exceptions: ListofErrors</STRONG>
   <DD>ListofErrors is a list of error description of the form:
    <PRE>
      Int: Text
    </PRE>
   where Int is a error code for an error that can occur with the predicate
   and Text describes the error. This is used to generate the
   `Exceptions' section of the predicate description.

<DT><STRONG>fail_if: Text</STRONG>
   <DD>Text is a string describing the fail conditions for the predicate. It
   is used to generate the `Fail Conditions' section of the predicate
   description.

<DT><STRONG>fields: ListofFields</STRONG>	*structures only*
   <DD>ListofFields is a list of the field descriptions describing the
   structure fields. A field description is of the form:
    <PRE>
      FieldName: Description
    </PRE>
   where FieldName is an atom or string and Description is a Text.

<DT><STRONG>index: ListofStrings</STRONG>
   <DD>Each string in ListofString will be added to the index generated by the
   document tools, pointing at the predicate. This is used to add
   additional index entries for the predicate in addition to the predicate
   names that is generated automatically.

<DT><STRONG>resat: Resatisfiable</STRONG>
   <DD>Resatisfiable is either yes or no, specifying if the predicate is
   resatisfiable. This is used to generate the `Resatisfiable' section of
   the predicate description.

<DT><STRONG>see_also: ListofSpecs</STRONG>
   <DD>ListofSpecs is a list of items, referring to other predicates
   and libraries which are related to the commented predicate.  This
   is used to generate the `See Also' section of the predicate description.
   The specs can be of the form Name/Arity, LibName:Name/Arity,
   library(LibName).  Name, Arity and LibName can be uninstantiated,
   in which case links to every matching predicate or library will be
   generated.  The form link(URL,Text) can be used to insert arbitrary
   hyperlinks.

<DT><STRONG>summary: String</STRONG> *compulsory*
    <DD>String is a short (one line) summary of the predicate.

<DT><STRONG>template: String or list of strings</STRONG>
    <DD>This is normally not needed.  It is only useful to override
    the most general default template that will otherwise be
    automatically generated from the predicate name, the arguments and
    and the amode information.
</DL>
Note that only the 'summary' property is compulsory, and apart from
'amode', each property should occur at most once.
<P>
For the longer descriptions in the comments, a `Text' is allowed. 
This is either a normal ascii string or a string in a document markup
language.  In the latter case, the string must be enclosed in a
wrapper.  Currently the following are supported:
<DL>
<DT><STRONG>html(String)</STRONG>
    <DD>String is in HTML format and can contain HTML tags.
    Special characters must be written using HTML notation.
    The string must be embeddable into an HTML document,
    i.e. there should be no &lt;html&gt; .. &lt;/html&gt; and
    no headings.
<DT><STRONG>ascii_fmt(String)</STRONG>
    <DD>String is in ascii format. It will be rendered using a proportional
    font and spacing and line breaks will be lost.
<DT><STRONG>ascii(String)</STRONG>
    <DD>String is in ascii format. It can consist of multiple lines
    and will be rendered using a fixed width font with all spacing and
    line breaks being preserved.
    (To break lines without inserting a significant line break,
    precede the line break with a '\\').
<DT><STRONG>String</STRONG>
    <DD>The same as ascii_fmt(String), except in the 'eg' field
    where it is interpreted as ascii(String).
</DL>
In order to allow automatic processing, the following should be observed
with the placement of comments:
<UL>
  <LI> A comment should occur in a file.

  <LI> A comment must occur as a directive.

  <LI> A comment applies to a module, so it should occur textually inside
     a module, i.e. after any module declarations. If the program does
     not contain any module declarations, the file name (without suffix)
     is assumed to be the module.

  <LI> The file containing comments should only have a single module defined.
</UL>
Note that in addition to allowing automatic documentation generation, the
comment predicates can also be used to provide information on the module
itself when the user reads the program. Thus it can also act as comments in
the same way as the traditional comments, but in a more structured way.
"),
eg:"\

% comments for the document library
:- comment(summary, \"Automatic document generation library\").

:- comment(index, [\"Literate programming\",
                   \"automatic documentation generation\"]).

% comment for comment/2
:- comment(comment/2, [

    summary: \"Adding documentational information to ECLiPSe files.\",

    index: [\"Literate programming\"],

    args: [\"Type\": \"Comment type\",
       \"Information\": \"Information for Type\"],

    amode: comment(+,+),

    resat: no,

    fail_if: \"None. Always succeed.\",

    see_also:
	[icompile/1,icompile/2,eci_to_html/3,ecis_to_htmls/0,ecis_to_htmls/3],

    desc: html(\"\
    The comment/2 predicate allows documentational information to be added to
    .....
    \"),

    eg: \"\

    % comments for the document library
    :- comment(summary, \\\"Automatic document generation library\\\").

    ....the other examples you are seeing now
    \"

    ]).  % end of comment directive for comment/2


% other examples
:- comment(fcompile/2, [
    summary: \"Generates an object file from the ECLiPSe source File in module Module.\",
    args: [\"File\":\"Name of source file (Atom or string)\",
              \"Module\":\"Name of module (Atom)\"],
   amode: fcompile(+,+)
    ]).


:- comment(atom_string/2, [
    summary: \"Conversion between an atom and a string.\",
    args: [\"Atom\": \"Atom or variable\",
       \"String\": \"String or variable\"],
    amode:(atom_string(+,-) is det),
    amode:(atom_string(-,+) is det),
    desc: \"\\
    If Atom is instantiated, converts it to a string String.
    If String is instantiated, converts it to an atom Atom.\",

    resat: no,

    fail_if: \"\\
    Fails if the string String does not unify with the string version of the
    atom Atom.\",

    exceptions: [5: \"Atom is instantiated, but not to an atom.\",
	5: \"String is instantiated, but not to a string.\",
	4: \"Neither Atom nor String are instantiated.\"]
    ]).

"
]).  % end of comment directive


:- comment(include/1, [
     summary: "Include other files for compilation.",
     args: ["FileSpec": 
              "File name(s) (atom/string or list of atoms/strings)"
           ],
     amode:(include(+) is det),
     see_also: [compile/1],
     desc: html("\
<P>
     Include other file(s) for compilation as if the contents of those
     file(s) have been inserted in place of the directive. If more than
     one file is specified, they are included in the order in which they
     appear in the list FileSpec. 

</P><P>
     A compile/1 directive can also be used for recursive compilation.
     However, the semantics is different if the recursively compiled
     file contains any new module definition. With recursive compile, 
     those module end with the end of that file. However, with include/1, 
     the behaviour is as if the included file has appeared in place, and 
     so the new module will not end with the end of the included file.
     It is recommended that that include/1 should be used to include the
     compilation of different files in the same module, and compile/1 used
     to compile files that contain different modules.

</P><P>
     Currently, include/1 is implemented by a call to recursive compile, so
     it behaves like compile/1. This is to change in future releases. The
     documentation tools and fcompile assume that include/1 has the correct
     semantics described previously.
</P>")
]).

