Annotations
Topics covered in this chapter:
Annotations are meta data expressed in a Mosel source file (model or package) that are stored in the resulting BIM file after compilation. This additional information is either global or associated with public globally declared objects (including subroutines). Annotations do not have any direct impact on the model itself as they are treated like comments. Typical uses of annotations include model documentation or application configuration information.
Mosel annotations have the following format:
- a single-line annotation starts with '!@' and a name
!@doc.name This is my document title
- multi-line annotations are surrounded by '(!@' and '!)'
(!@mynote Some annotation text. Another line of text. !)
- '!@' is followed by the annotation name (identifier)
- no space between '!' and '@' characters
- space is allowed between '@' and the name
- value assignment operators are ' ' (space), ':', or '='
- no space between annotation name and operator
!@mynote contents for 'mynote' !@ another=contents of 'another' !@third: contents of 'third'
- association with symbols:
!@mynote This annotation is applied to all objects declared below public declarations val: integer !@doc.descr Explanation of 'val' !@doc.descr Text associated with 'msg' msg: string ! A standard comment !@mynote2 This annotation is ignored (no associated object) end-declarations
Annotations are organized in categories. A category groups a set of annotations and other categories (or sub-categories). For example
doc.namewill be used to select the annotation name member of the doc category. Predefined category names include mc (Mosel compiler) and doc (model documentation). Models can also define/employ new annotations and categories—these must be valid Mosel identifiers, that is, their names can only use alpha-numeric symbols and '_'.
We show some examples of the doc category in Section moseldoc: Generating model documentation below. The category mc is used to pass information to the compiler during the compilation, including the (optional) declaration of new annotations with the mc.def annotation or the definition of aliases, such as
!@mc.def descr alias doc.descr insight.descrthat redirects onto two different annotations (see section 'Annotations' of the Mosel Language Reference Manual for further detail).
Accessing annotations
Annotations can be retrieved from the model itself during its execution or before/after execution from the calling program (using the Mosel libraries). The following example annottest.mos shows how to retrieve an annotation that is defined in the same model. The subroutine getannotations is defined by mmreflect, an overloaded version (defined by mmjobs) takes an additional first argument of type Model indicating the submodel it is to be applied to instead of the model itself.
model "Using annotations" uses "mmreflect" public declarations (!@. @value.first 5 @value.second 0 @descr A scalar value !) myint: integer AnnNames: set of string !@descr Set of annotation names Ann: array(string) of string !@descr Annotation values mytxt: text !@descr Default input data file end-declarations !@descr Annotations test !@furtherinfo Simply displays all defined global or specific annotations ! Get all global annotations defined in this model: getannotations("", "", AnnNames, Ann) writeln("Global annotations:") forall(a in AnnNames) writeln(" ", a, " = ", Ann(a)) ! Get all annotations for "myint": getannotations("myint", "", AnnNames, Ann) writeln("Annotations defined for 'myint':") forall(a in AnnNames) writeln(" ", a, " = ", Ann(a)) ! Retrieve all annotations starting with 'value.' and that are ! associated to 'myint' getannotations("myint", "value.", AnnNames, Ann) writeln("'value' annotations for 'myint':") forall(a in AnnNames) writeln(" ", a, " = ", Ann(a)) end-model
Running this model produces output like the following:
Global annotations: .descr = Annotations test .furtherinfo = Simply displays all defined global or specific annotations Annotations defined for 'myint': .descr = A scalar value value.first = 5 value.second = 0 'value' annotations for 'myint': value.first = 5 value.second = 0
And here is an example how to retrieve annotations into a C program (file annotdisplay.c):
#define MAXANN 100 int main() { XPRMmodel mod; void *ref; const char *symb; /* A model object name */ const char *ann[MAXANN*2]; /* List of annotations */ int i,n; if(XPRMinit()) return 1; /* Initialize Mosel */ if((mod=XPRMloadmod("annottest.bim",NULL))==NULL) /* Load a BIM file */ return 2; /* Retrieve and display global annotations */ n=XPRMgetannotations(mod,NULL,NULL,ann,MAXANN*2); printf("Global annotations (total: %d):\n", n/2); for(i=0;i<n && i<MAXANN;i+=2) printf(" %s:%s\n",ann[i],(ann[i+1]!=NULL)?ann[i+1]:""); /* Retrieve and display all annotations associated with model objects */ printf("Annotations associated with objects:\n"); ref=NULL; while((symb=XPRMgetnextanident(mod,&ref))!=NULL) { n=XPRMgetannotations(mod,symb,NULL,ann,MAXANN*2); printf(" %s->\n",symb); for(i=0;i<n && i<MAXANN;i+=2) printf(" %s:%s\n",ann[i],(ann[i+1]!=NULL)?ann[i+1]:""); } /* Retrieve and display annotations for model object 'myint' */ n=XPRMgetannotations(mod,"myint",NULL,ann,MAXANN*2); printf("Annotations defined for 'myint' (total: %d):\n", n/2); for(i=0;i<n && i<MAXANN;i+=2) printf(" %s:%s\n",ann[i],(ann[i+1]!=NULL)?ann[i+1]:""); return 0; }
The corresponding Java code looks as follows:
public class annotdisplay { public static void main(String[] args) throws Exception { XPRM mosel; XPRMModel mod; XPRMAnnotation ann[]; // List of annotations mosel = new XPRM(); // Initialize Mosel mod = mosel.loadModel("annottest.bim"); // Load a BIM file // Retrieve and display global annotations ann=mod.getAnnotations(""); System.out.println("Global annotations (total: "+ ann.length +"):"); for(int i=0;i<ann.length;i++) System.out.println(" "+ann[i]); // Retrieve and display all annotations associated with model objects System.out.println("Annotations associated with objects:"); for(XPRMIdentifiers ids=mod.annotatedIdentifiers(); ids.hasNext();) { XPRMIdentifier id=(XPRMIdentifier)ids.next(); ann=mod.getAnnotations(id,""); System.out.println(" "+id.getName()+"->"); for(int i=0;i<ann.length;i++) System.out.println(" "+ann[i]); } // Retrieve and display annotations for model object 'myint' ann=mod.getAnnotations("myint",""); System.out.println("Annotations defined for 'myint' (total: "+ ann.length +"):"); for(int i=0;i<ann.length;i++) System.out.println(" "+ann[i]); } }
Notice that the host application only needs to load the BIM file (and not necessarily run a model) in order to be able to retrieve the annotations.
moseldoc: Generating model documentation
The Mosel compiler reserves a special treatment to annotations belonging to the doc category. This annotation category will only be included into the BIM file if the source (model or package) file is compiled with the option -D, such as
mosel comp -D mymodel.mos
To enable the -D compiler option in Xpress Workbench open the Run menu and select the entry Compiler Options, enable the Generate Doc Annotations option, and confirm with Save. When you next click the Compile button in the Workbench toolbar, the resulting BIM file will contain documentation annotations.
The tool moseldoc can be applied to the resulting BIM file to generate an XML file that is then processed into a set of HTML pages:
moseldoc mymodel ! Generates HTML and XML moseldoc -html mymodel ! HTML output only moseldoc -o mydir -html mymodel ! Specify HTML output directory moseldoc -xml mymodel ! XML output only moseldoc -ixml mymodel ! XML file for inclusion (omitting header+root) moseldoc -f mymodel ! Force output overwrite
Here are some examples of how to use the documentation annotations (example file annotdoc.mos):
- Document structure:
(!@doc. @title An example of model documentation @version 0.0.1 @date March 2015 @chapter Introduction @p This model needs to be compiled with the <tt>-D</tt> compiler option to include the documentation annotations into the BIM. The <tt>moseldoc</tt> program takes the resulting BIM file as input. !) !@doc.chapter The example !@doc.section Parameters
The resulting cover page and table of contents generated by moseldoc look as follows (the contents listing also refers to the entity and subroutine annotations shown in the following items):
- Documenting parameters:
parameters !@doc.descr Short parameter description !@doc.value v1 possible value !@doc.value v2 another possible value !@doc.info Some more explanation (longer text) MYPAR="some text" end-parameters
- Documenting entity declarations (type definitions, constants, variables):
!@doc.section Constants and variables public declarations (!@doc. @descr Short description of the constant set @info Some additional information !) S=1..10 !@doc.descr An error code constant MYERR=11 (!@doc. @descr A record type @recflddescr fld1 field description @recflddescr fld2 another field description @info Several @doc.info tags can be used for a given entity @info Entities can be referenced: <entRef>rectype</entRef> !) rectype=public record fld1:integer fld2:string end-record end-declarations
This is the HTML page generated by moseldoc from these parameter and entity annotations:
- Documenting subroutines:
!@doc.section Subroutines (!@doc. @descr A short description @param i first parameter @paramval i value1 description of value1 @paramval i value2 description of value2 @param r second parameter @err MYERR reference to an error code constant @return The return value @example Some descriptive text for the example @example [SRC] the example code is here @info Some useful information for <tt>myfunct</tt> @related <fctRef>myotherfunct</fctRef> !) public function myfunct(i:integer,r:real):boolean returned:=i>r end-function !@doc.group myfunct !@doc.info <tt>myotherfunc</tt> is an alternative to <fctRef>myfunct</fctRef> public function myotherfunc(i:integer):boolean returned:=true end-function
The HTML subroutine documentation page generated by moseldoc from these annotations is shown here:
- Relocating documentation contents:
!@doc.section A section title !@doc.relocate newlocref ... ! All doc annotations defined here will be inserted at marker 'newlocref' !@doc.relocate ... ! All subsequently defined doc annotations remain where they are !@doc.section Destination location !@doc.location newlocref
- Excluding contents from the generated documentation:
!@doc.autogen=false public declarations ... ! No automatic generation of annotations: any non-annotated entities ! defined here will not be included in the documentation end-declarations !@doc.autogen=true ... ! All subsequently defined entities will get processed ! The following procedure will not be included into the documentation !@doc.descr Ignored by the documentation !@doc.ignore public procedure hiddenproc a:=1 end-procedure !@doc.ignore public declarations ... ! All entities defined here will not be included in the documentation end-declarations
The moseldoc tool is provided in compiled form with FICO Xpress Optimization release distributions, its source and a complete example of its use (file mddoc.mos) that can be found in the subdirectory examples/mosel/Moseldoc of Xpress installations or online in the Xpress Examples Repository.
© 2001-2024 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.