\input texinfo @c -*- texinfo -*-
@c %**start of header
@setfilename maria.info
@settitle Maria
@set UPDATED 23 April 2005
@set VERSION 1.3.5

@iftex
@syncodeindex fn cp
@syncodeindex vr cp
@syncodeindex tp cp
@finalout
@end iftex
@ifinfo
@synindex fn cp
@synindex vr cp
@synindex tp cp
@end ifinfo

@dircategory Formal Methods
@direntry
* Maria: (maria).          Reachability Analyzer for Algebraic System Nets
@end direntry
@c %**end of header

@ifinfo
This file documents Maria, a reachability analyzer for Algebraic System Nets.

This manual documents Maria version @value{VERSION}.
Copyright @copyright{} 1998-2000, 2002-2003, 2005
Marko M@"akel@"a.
Copyright @copyright{} 2001
Marko M@"akel@"a and
Helsinki University of Technology, Laboratory for Theoretical Computer Science.

Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries a copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).

@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
sections entitled ``Copying'' and ``GNU General Public License'' are
included exactly as in the original, and provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that the section entitled ``GNU General Public License'' and this
permission notice may be stated in a translation approved by the
copyright holder.
@end ifinfo

@titlepage
@title Maria
@subtitle Modular Reachability Analyzer for Algebraic System Nets
@subtitle @value{UPDATED}, Maria Version @value{VERSION}

@author by Marko M@"akel@"a

@page
@vskip 0pt plus 1filll
Copyright @copyright{} 1998-2000, 2002-2003, 2005 Marko M@"akel@"a.
Copyright @copyright{} 2001 Marko M@"akel@"a and
Helsinki University of Technology, Laboratory for Theoretical Computer Science.

@sp 2
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).

@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
section entitled ``GNU General Public License'' is included exactly as
in the original, and provided that the entire resulting derived work is
distributed under the terms of a permission notice identical to this
one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that the section entitled ``GNU General Public License'' and this
permission notice may be included in translations approved by the
copyright holder instead of in the original English.
@end titlepage
@page

@node Top, Introduction, (dir), (dir)

@ifinfo
This manual documents version @value{VERSION} of Maria.
@end ifinfo

@menu
* Introduction::
* Modeling::            The net description language of Maria

* Analysis::            Performing reachability analysis with Maria

* Algorithms::          Algorithms used in Maria

* Grammar::             Grammar of the Maria languages

* Graph Files::         Format of the reachability graph files

* Compiling::           Compiling Maria
* Bugs::                Reporting Bugs

* Examples::            Sample Petri Nets for Maria

* Copying::             The GNU General Public License says
                          how you can copy and share Maria

* Index::               Cross-references to the text.
@end menu

@node Introduction, Modeling, Top, Top
@unnumbered Introduction

@dfn{Maria}, or @dfn{Modular Reachability Analyzer}, is a reachability
analyzer for Algebraic System Nets.  It will generate reachability
graphs for Algebraic System Nets, detect deadlocks and check properties
expressed using temporal logic formulae.

Maria is remotely based on Prod, a reachability analyzer for
Proposition/Transition Nets developed earlier at the Laboratory for
Theoretical Computer Science.  Its data type system and expression
syntax are heavily inspired by the C programming language.  In order to
understand this manual, you should be familiar with the basic concepts
of Petri Nets and also have some knowledge in C.

Maria was written by Marko M@"akel@"a in a research project at the
Helsinki University of Technology in the Laboratory for Theoretical
Computer Science.  The project is financed by the National Technology
Agency of Finland (TEKES), Nokia Research Center, Nokia Networks, the
Helsinki Telephone Corporation and the Finnish Rail Administration.

Many of the ideas implemented in Maria were brought up in discussions
among the laboratory staff.  Ideas expressed by Dr.@: Kimmo Varpaaniemi,
Dr.@: Nisse Husberg, Keijo Heljanko and Tommi Junttila have influenced
the design.  @w{Dr.@: Varpaaniemi} sketched the first version of the
unification algorithm (@pxref{Unification}), and he helped in debugging
by stressing the analyzer with quite obscure examples.  Also Simo Blom,
who was the first one to use the analyzer for something real, reported
some bugs, which have now been fixed.

The model-checking functionality (@pxref{Model Checking}) is based on
the ideas of Keijo Heljanko and others, and the algorithms were
initially implemented by Timo Latvala.

This edition corresponds to version @value{VERSION} of Maria.

@node Modeling, Analysis, Introduction, Top
@chapter The Net Description Language
@cindex modeling
@cindex nets, composing

Petri Nets are often represented as directed bipartite graphs using a
graphical notation.  An entirely graphical notation only works for
relatively simple nets that can be represented on one sheet of paper.
We decided to use a purely textual notation, since it avoids many
problems, such as creating an optimal graphical layout for an
automatically generated Petri Net model and creating a graphical user
interface that works flawlessly on various hardware and software
platforms.

@menu
* Design Criteria::             Why the language became what it is now
* Lexical Conventions::         The format of numbers, comments etc.

* Net Constructs::
* Types::                       Defining data types
* Functions::                   Defining functions or constants
* Places::                      Declaring Petri Net places
* Transitions::                 Declaring Petri Net transitions
* Subnets::                     Declaring Petri Net modules
* Verification::                Commands for on-the-fly verification

* Data Types::                  The data type system
* Expressions::                 Expressions and formulae in the language
* Output Variables::            Non-determinism in transitions
* Scoping::                     Look-up rules for names
@end menu

@node Design Criteria, Lexical Conventions, Modeling, Modeling
@section Design Criteria

As an admirer of the programming languages C and C++, I decided to make
the net description language resemble C as closely as possible.  Users
familiar with C should feel comfortable with the way data types are
defined and expressions are written in the net description language.

In the following, we will present the grammar of the net description
language using regular expressions (@pxref{Patterns, , Patterns, flex,
The Flex Manual}) and the Extended Backus@minus{}Naur Form
(@pxref{Language and Grammar, , Languages and Context-Free Grammars,
bison, The GNU Bison Manual}).

@node Lexical Conventions, Net Constructs, Design Criteria, Modeling
@section Lexical Conventions
@cindex lexical conventions

The lexical conventions of the Maria Petri Net description language
determine how to format net descriptions in text files, including the
mechanisms for embedding explanatory comments.

@menu
* Formatting::                  How net descriptions should be formatted
* Comments::                    Writing notes for the human reader

* Lexical Tokens::
* Reserved Words::              Reserved words in the language
* Numeric Constants::           Different ways of presenting numbers
* Character Constants::         Single-character constants
* Identifiers::                 Names for variables, places, transitions etc.

* Preprocessor::                Control directives for the preprocessor
@end menu

@node Formatting, Comments, Lexical Conventions, Lexical Conventions
@subsection Formatting

The net description language is not sensitive to the presence or absence
of white space between language elements provided that all keywords and
identifiers are distinguished.  Thus the user has the same degree of
freedom that C and C++ allow in formatting code.  White space includes
these characters: space (@samp{' '}), newline (@samp{'\n'}), carriage
return (@samp{'\r'}), form feed (@samp{'\f'}), horizontal tabulator
(@samp{'\t'}) and vertical tabulator (@samp{'\v'}).

@node Comments, Lexical Tokens, Formatting, Lexical Conventions
@subsection Comments

Comments are indicated as they are in the C++ programming language.  Two
contiguous slashes (@samp{//}) indicate the start of a comment that
continues to the end of the current line.  A slash immediately followed
by an asterisk (@samp{/*}) indicates a comment that continues until the
reverse sequence (@samp{*/}) is encountered.  Comments may not be
nested, and comments are interpreted only between language elements
(e.g., not inside names enclosed in double quotes).

@node Lexical Tokens, Preprocessor, Comments, Lexical Conventions
@subsection Lexical Tokens

Lexical tokens are the atomic constituents of the language, consisting
of characters or character sequences.

@menu
* Reserved Words::              Reserved words in the language
* Numeric Constants::           Different ways of presenting numbers
* Character Constants::         Single-character constants
* Identifiers::                 Names for variables, places, transitions etc.
@end menu

@node Reserved Words, Numeric Constants, Lexical Tokens, Lexical Tokens
@subsubsection Reserved Words
@cindex reserved words

There are quite a few reserved words in the net description language:

@multitable @columnfractions .25 .25 .25 .25
@item @code{atom}
 @tab @code{cardinality}
 @tab @code{const}
 @tab @code{deadlock}
@item @code{empty}
 @tab @code{enabled}
 @tab @code{enum}
 @tab @code{equals}
@item @code{false}
 @tab @code{fatal}
 @tab @code{gate}
 @tab @code{hide}
@item @code{id}
 @tab @code{in}
 @tab @code{infinite}
 @tab @code{intersect}
@item @code{is}
 @tab @code{map}
 @tab @code{max}
 @tab @code{min}
@item @code{minus}
 @tab @code{out}
 @tab @code{place}
 @tab @code{prop}
@item @code{queue}
 @tab @code{reject}
 @tab @code{release}
 @tab @code{stack}
@item @code{strongly_fair}
 @tab @code{struct}
 @tab @code{subnet}
 @tab @code{subset}
@item @code{trans}
 @tab @code{true}
 @tab @code{typedef}
 @tab @code{undefined}
@item @code{union}
 @tab @code{until}
 @tab @code{weakly_fair}
@end multitable

@noindent
In order to use any of these words as an identifier
(@pxref{Identifiers}), you will have to enclose it in double quotation
marks (@samp{"}).

@node Numeric Constants, Character Constants, Reserved Words, Lexical Tokens
@subsubsection Numeric Constants
@cindex constants, numeric
@cindex numeric constants

Maria has three interchangeable ways of entering integer numeric
constants.  The constants can be entered using one of three different
notations: with decimal numbers (@samp{[1-9][0-9]*}), octal numbers
(@samp{0[0-7]*}) or hexadecimal numbers (@samp{0x[0-9a-fA-F]+}).  When a
numeric constant is too long to fit in the internal representation, the
lexical analyzer will detect it and issue a diagnostic message.  Decimal
numbers are always unsigned, but the hexadecimal and octal
representations are translated directly to the system-dependent internal
representation, which usually is a 32-bit word interpreted as a signed
integer using two's complement arithmetic.

@node Character Constants, Identifiers, Numeric Constants, Lexical Tokens
@subsubsection Character Constants
@cindex constants, character
@cindex character constants

Character constants are just like in the C programming language: a
single character enclosed in apostrophes (@samp{'}).  The backslash
(@samp{\}) is used for entering special characters:

@table @samp
@item \a
alert, bell (@kbd{BEL})
@item \b
backspace (@kbd{BS})
@item \t
horizontal tabulator (@kbd{HT})
@item \n
newline, line feed (@kbd{LF})
@item \v
vertical tabulator (@kbd{VT})
@item \f
form feed (@kbd{FF})
@item \r
carriage return (@kbd{CR})
@item \[0-7]@{1,3@}
octal notation
@item \x[0-9a-fA-F]@{1,2@}
hexadecimal notation
@item \@var{c}
character @var{c} (@code{@var{c} != '\n'})
@end table

@noindent
Any other characters than the apostrophe or the backslash can be entered
verbatim between the apostrophes.

Any non-special character quoted with the backslash will be entered as
such, i.e.@: the backslash will be ignored.  Thus, @samp{'\c'} is
equivalent to @samp{'c'}.  The line break character is a special case.
In order to maintain consistence with the quoted identifiers discussed
below, a backslash followed by a line break and any amount of white
space containing no line breaks will be ignored.

@node Identifiers, , Character Constants, Lexical Tokens
@subsubsection Identifiers
@cindex identifiers, syntax of

Maria uses textual names for identifying places, transitions, data
types, variables, enumeration constants and many other things.  None of
the identifiers become reserved words.  For instance, @samp{bool} may be
a type name, a place name or the name of a structure component.
Anything of the form @samp{[A-Za-z_][A-Za-z0-9_]*} that is not a
reserved word is an identifier.

Identifiers can also be enclosed in double quotation marks.  As with
single-character constants, only the backslash and the quotation mark
must be escaped with a backslash, and the backslash notation
(@pxref{Character Constants}) can be used for entering non-printable
characters.  Non-printable characters need not be escaped, though.  The
only character that is not allowed in identifiers is the @kbd{NUL}
character.

The backslash character (@samp{\}) can be used to break up long
identifiers.  A backslash followed by a line break and any amount of
white space containing no line breaks will be ignored in the input.
Also, backslashes can be used to quote the following character.  For
instance, @samp{in\ k} is equivalent to @samp{"in k"}.

In double quotes, the newline character is just as significant as any
other character.  Sometimes one wants to split a long quoted identifier
to several lines without the line breaks being significant.  This can be
achieved by putting a backslash immediately before the line break.  The
lexical analyzer will ignore the backslash, the line break and the
immediately following white space (not line break).

@node Preprocessor, , Lexical Tokens, Lexical Conventions
@subsection Preprocessor Directives
@cindex preprocessor

The language contains a subset of the directives implemented in the C
language preprocessor.  Conditional compilation and macro definitions
are not supported in the current version.

Preprocessor directives are indicated with a number sign (@samp{#})
located in the first (leftmost) column.  The number sign may be
followed by any amount of lexical comments and other white space than
newline.  The line, which must be terminated with a newline, must
contain exactly one preprocessor directive.

@menu
* Include::             Embedding other files
* Conditions::          Conditional processing
* Line::                Setting the line number counter
* Comment::             Preprocessor comment
@end menu

@node Include, Conditions, Preprocessor, Preprocessor
@subsubsection Embedding Other Files: @samp{#include}
@cindex include files
@findex #include

The @samp{#include} directive works just like in the C preprocessor,
except that the file name must be enclosed in double quotes and never in
angle brackets (@samp{<} and @samp{>}).  The string in double quotes is
interpreted as a quoted identifier (@pxref{Identifier}).

@node Conditions, Line, Include, Preprocessor
@subsubsection Conditional Processing
@cindex conditional processing
@cindex preprocessor symbols
@findex #ifdef
@findex #ifndef
@findex #else
@findex #endif
@findex #undef
@findex #define

The @samp{#ifdef}, @samp{#ifndef}, @samp{#else} and @samp{#endif}
directives work just like in the C preprocessor, expecting an argument
of the form @samp{[A-Za-z_][A-Za-z0-9_]*}.  Note that there is no
@samp{#if} directive and that the @samp{#define} directive only takes
one argument, the name of the symbol.  The preprocessor symbols are not
macros; no macro expansion will take place.

Conditional processing can be used to avoid problems with multiple
inclusions of a file or to add some parameterization to the net model.
Preprocessor symbols can also be defined on the command line.

@node Line, Comment, Conditions, Preprocessor
@subsubsection Setting the Line Number: @samp{#line}
@cindex line counter, setting
@findex #line

Code generation tools usually generate @samp{#line} directives for
excerpts that are to be embedded verbatim in the generated code.  This
allows the compiler to refer to the relevant input file of the code
generator in its diagnostic messages.

The Maria languages implement the @samp{#line} directive in order to
better support the diagnostics of automatically generated net
descriptions.  The @samp{line} keyword is followed by a numeric constant
and a character string constant indicating the line number and the file
name of the following line.

@node Comment, , Line, Preprocessor
@subsubsection Preprocessor Comment: @samp{#!}
@findex #!

The special preprocessor directive @samp{#!}, which causes the rest of
the line to be ignored, was added in order to make it possible for Maria
input files to also be executable scripts in systems having an
appropriate @code{exec} system call.

@node Net Constructs, Data Types, Lexical Conventions, Modeling
@section Constructs for Defining Nets
@cindex nets, constructs

@menu
* Types::                       Defining data types
* Functions::                   Defining functions or constants
* Places::                      Declaring Petri Net places
* Transitions::                 Declaring Petri Net transitions
* Subnets::                     Declaring Petri Net modules
* Verification::                Commands for on-the-fly verification
@end menu

@node Types, Functions, Net Constructs, Net Constructs
@subsection Type Definitions: @samp{typedef}
@cindex data types, defining
@findex typedef

In the Maria languages, only the predefined data types @samp{bool},
@samp{int}, @samp{unsigned} and @samp{char} can be used without naming
them using the grammatical construct

@example
type:   TYPEDEF typedefinition name
@end example

@noindent
inspired by C.  The built-in type names are not reserved words.
For instance, any reference to the type @samp{int} following the
definition @code{typedef int (-64..63) int;} will refer to an integer
representable with 7 bits.

For a comprehensive description of the data type system, see @ref{Data
Types}.  Here we will only present the syntax, not the semantics.

Some of the syntax for defining data types resembles the C programming
language very closely:
@example
@group
typedefinition:
        ENUM '@{' enum_item ( delim enum_item )* '@}'
        |
        STRUCT '@{' comp_list '@}'
        |
        UNION '@{' comp_list '@}'
        |
        typereference
@end group
@group
typereference:
        name
enum_item:
        name [ [ '=' ] number ]
comp_list:
        comp (delim comp)* [ delim ]
comp:
        typedefinition name
number:
        expr
delim:
        ','
        |
        ';'
@end group
@end example

The extra leaf data types include an empty @samp{struct}, often used for
denoting black tokens, and an @dfn{identifier} type used for identifying
e.g.@: processes or objects.  Note that if you intend to compile the
model (@pxref{Maria Options}), the empty @samp{struct} does not work on
all C compilers.

@example
@group
typedefinition:
        STRUCT '@{' '@}'
        |
        ID '[' number ']'
@end group
@end example

@noindent
It is a good idea to define an alias (@pxref{Functions}) for the black
token, so that its definition can be changed easily:
@example
@group
typedef struct @{@} token;
// typedef unsigned (0) token;
token token = <token;
@end group
@end example

The alert reader may have noticed that we have not introduced arrays
yet.  Arrays in Maria are not necessarily indexed by integers, but by
any type having a limited set of possible values.  One can also define a
finite-capacity buffer that uses either a queue or a stack discipline.

@example
@group
typedefinition:
        typedefinition '[' typedefinition ']'
        |
        typedefinition '[' QUEUE number ']'
        |
        typedefinition '[' STACK number ']'
@end group
@end example

Last but not least, it is possible to limit the set of possible values
for a type by defining @dfn{constraints}, unions of closed or semi-open
ranges of constant values.

@example
@group
typedefinition:
        typedefinition constraint
constraint:
        '(' range (delim range)* ')'
range:
        value
        |
        '..' value
        |
        value '..' value
        |
        value '..'
value:
        expr
@end group
@end example

@node Functions, Places, Types, Net Constructs
@subsection Function Definitions
@cindex functions, defining

Commonly used expressions can be defined as functions, which can be
viewed as macros with strictly typed parameters.  Functions are defined
in the following way:

@example
@group
function:
        typereference name ('='|'()') formula
        |
        typereference name '(' param_list ')' formula
param_list:
        [ param_list_item (delim param_list_item)* ]
param_list_item:
        typereference name
@end group
@end example

The function name and the optional parameter list are followed by a
formula that usually refers to all the function parameters.  When the
function is ``called'' (the macro is expanded), each instance of a named
parameter will be substituted with the corresponding expression passed
as an argument to the function.  Parameterless functions are practical
for defining constants.

Functions can be defined both in the global scope and in the transition
scope.  Functions defined in the declaration block of a transition will
only be accessible to that transition, and they will temporarily
override a global function definition.

@node Places, Transitions, Functions, Net Constructs
@subsection Place Definition: @samp{place}
@cindex nets, place definition
@cindex tokens
@cindex initial marking
@cindex redundant places
@findex place
@findex :@r{, initial marking}
@findex const
@cindex capacity constraint

All persistent data in Petri Nets is stored in @dfn{places} that can
contain a number of @dfn{tokens}, which in the case of Algebraic System
Nets have values.  When a place is defined, it is given a unique name,
and it is assigned a type.

@example
@group
place:
        PLACE name constraint* typedefinition
        [ CONST ] [ ':' marking_list ]
@end group
@end example

It is possible to define a @dfn{capacity constraint}, a non-negative
integer constraint (@pxref{Constraints}) that constrains the total
number of tokens the place can contain.  Note that the constraint does
not need to be of the form @samp{(0..@var{n})} for some positive integer
@var{n}; it can be e.g.@: @samp{(1)} if the place always contains
exactly one token, or @samp{(0,2,4)}.  Defining constraints has two
major advantages.  First, they help to catch errors in the model.
Second, analysis algorithms may benefit from them, and resources can be
saved when maintaining the reachability graph (@pxref{Graph Files}).

Places can be assigned an @dfn{initial marking}, a multi-set valued
expression (@pxref{Multi-Sets}) that evaluates to the collection of
tokens that will be assigned to the place in the system's initial state.
To parameterise initial markings, you may use the multi-set summation
operator.

Sometimes, it is necessary to introduce control places in the model
whose contents remains constant.  It would be unnecessary to include
such places in the representation of model states, or in the unfolding
(@pxref{Unfold}) of the model.  The keyword @samp{const} in the place
definition indicates a constant place.

When the marking of a place is a function of the marking of other
places, the place is called a @dfn{redundant place}.  Examples of such
places include counters and complement places.  It is possible to
identify such places by writing initialization expressions that make use
of the @samp{place @var{name}} operation (@pxref{Multi-Sets}).  Doing so
not only reduces disk space consumption; Maria will also check that such
invariant properties hold in all states it generates.

@node Transitions, Subnets, Places, Net Constructs
@subsection Transition Definition: @samp{trans}
@cindex nets, transition definition
@cindex transitions, firing
@cindex transitions, enabled
@cindex priority transitions
@cindex places, input
@cindex places, output
@cindex variable declarations
@cindex fairness sets
@cindex modules
@findex trans
@findex gate
@findex hide
@findex in
@findex out
@findex place
@findex :@r{, arc expressions}
@findex !@r{, transitions}
@findex strongly_fair
@findex weakly_fair
@findex enabled

The state of a Petri system is changed by @dfn{firing} transitions,
removing tokens from their @dfn{input places} and adding tokens to their
@dfn{output places}.  A transition is @dfn{enabled} if its each input
place contains at least the amount of tokens the transition is about to
remove.  Only enabled transitions may be fired.

@example
@group
transition:
        TRANS [ ':' ] name [ '!' ] trans*
trans:
        '@{' [ var_expr (delim var_expr)* [ delim ] ] '@}'
        |
        IN trans_places
        |
        OUT trans_places
        |
        GATE expr (',' expr)*
@end group
@group
        |
        HIDE expr
@end group
@group
        |
        STRONGLY_FAIR expr
        |
        WEAKLY_FAIR expr
        |
        ENABLED expr
@end group
@group
        |
        ':' [ TRANS ] name
        |
        NUMBER
@end group
@group
var_expr:
        [ HIDE ] typereference name
        |
        [ HIDE ] typereference name '!' [ '(' expr ')' ]
        |
        function
@end group
@group
trans_places:
        '@{' place_marking (';' place_marking)* '@}'
place_marking:
        [ PLACE ] name ':' marking_list
@end group
@end example

A transition definition is further divided to four different kinds of
declarations.  The @dfn{variable declaration block} is used for
declaring input and output variables and functions.  Using the block is
optional, since Maria allows implicit variable declarations.  When
declaring input variables implicitly, you may have to define the type
context (@pxref{Type Casting}).

The blocks for defining @dfn{input and output arcs} bind the
transition with places.  Last but not least, the transition may be
assigned @dfn{gate expressions}, which are additional Boolean
conditions for enabling the transition.  All gate expressions
associated with a transition must hold in order for an instance of the
transition to be enabled.

The gate expressions @samp{undefined} and @samp{fatal} (@pxref{Dynamic
Errors}) can be used for defining ``assertion'' transitions.  If a
transition having such a gate is enabled, an error is reported.  As
these transitions cannot be fired, it is not meaningful for them to
have output arcs.

In order to ease the transition instance analysis, the parser splits
all top-level logical conjunctions @samp{&&} in gate expressions.  For
this reason, gate expressions that rely on short-circuit evaluation
should be declared indivisible with the @samp{atom} keyword.

Transitions may be defined in several parts of the input file.  There
may be any number of @samp{in}, @samp{out} and @samp{gate} blocks and
variable or function definitions for a transition, and the transition
definition may span over several @samp{trans} blocks.

It is possible to define fairness sets of transition instances to
guide the on-the-fly model checker.  A transition-specific fairness
set definition consists of one of the reserved words
@samp{strongly_fair} and @samp{weakly_fair} followed by a Boolean
condition.  The condition identifies the transition instances that are
to be treated fairly.  All instances fulfilling the condition will be
treated as one unique fairness set.

The @samp{enabled} keyword allows the definition of enabledness sets
of transition instances.  If no transition instances belonging to an
enabledness set are enabled, the set will be reported at the end of
the analysis.  Use the @samp{dump} command (@pxref{Dump}) to see the
enabledness set numbers.

@xref{Fairness}, for fairness and enabledness sets comprising several
transitions.

Maria supports a form of @dfn{transition fusion}, which is a key
feature to constructing models in a modular way (See also
@pxref{Subnets}).  A transition whose name is preceded with a colon
(@samp{trans :callee}) is not an actual transition but it designates a
kind of a macro or a function body that can be substituted to other
transitions, like this: @samp{trans caller:trans callee}.  The Maria
parser would merge the definitions of @samp{trans :callee} to the
definition of @samp{trans caller}.

There is a simple priority method in the search algorithm of Maria
that works as follows.  When computing the successors of a marking,
Maria investigates the transitions in the order they were defined in
the model, from top to bottom.  Whenever a transition having a nonzero
priority class is found to be enabled, no further transitions of other
priority classes will be analyzed in the marking.

The default priority class is zero.  It is worth noting that
non-prioritized transitions that are defined before any prioritized
transitions are completely independent of other transitions in the
model.  Any non-prioritized transitions that are defined after
prioritized ones will be analyzed only if no prioritized transitions
are enabled.

The priority class can be specified by writing a non-negative integer
number after the name of the transition.  The exclamation point
@samp{!} is an alternative mechanism for providing backward
compatibility.  It assigns a nonzero priority class to the transition
from a global counter and then decrements the counter by one, so that
the next transitions marked with @samp{!} will be assigned other
priority classes.

The @samp{hide} keyword affects the output of labelled state
transition systems (@pxref{LSTS}) and the @samp{-Y} command line
option for suppressing hidden states (@pxref{Invoking Maria}).  A
transition instance is hidden (renamed to the special "tau" action) if
the hiding condition (a truth-valued expression on the transition
variables) holds.  Transition variables can be omitted from action
names by declaring them with the @samp{hide} keyword.

@node Subnets, Verification, Transitions, Net Constructs
@subsection Defining Subnets for Modular State Space Exploration
@cindex subnets
@cindex modules
@findex subnet

When a system being modelled consists of a number of loosely
synchronised processes, it is often useful to distinguish between the
internal actions of these processes and the actions that model the
communication or synchronisation of the processes.

In Maria, it is possible to define tree-like hierarchies of high-level
nets.  In the outer-level net, all transitions are @dfn{visible}, that
is, their occurrences directly corresponds to edges in the global
reachability graph (synchronisation graph).

In a subnet, defined within a @samp{subnet} block, normal transitions
model internal actions, which do not show up in the synchronisation
graph.  Synchronisation or communication of subnets is modelled with
transition fusion (@pxref{Transitions}).  When a transition in a
subnet calls a transition in its parent net, its occurrences will show
in the state space of the parent net.

When the model contains subnets, modular analysis should be applied
(command line option @samp{-R} or @samp{--modular}; @pxref{Invoking
Maria}).

@example
@group
subnet:
        SUBNET [ name ] '@{' net '@}'
@end group
@end example

@node Verification, , Subnets, Net Constructs
@subsection On-the-Fly Verification
@cindex nets, on-the-fly verification

@menu
* Assertions::          Check whether a safety property holds
* Fairness::            Specifying fairness sets of transition instances
* Propositions::        Specifying state propositions for LSTS output
@end menu

@node Assertions, Fairness, Verification, Verification
@subsubsection Verifying Safety Properties
@cindex assertions
@findex reject
@findex deadlock

The @samp{reject} and @samp{deadlock} statements are used in conjunction
with Boolean conditions on markings.  When these statements are used, the
reachability analyzer reports an error whenever
@enumerate
@item a state violating the @samp{reject} formula has been generated
@item the @samp{deadlock} formula holds
 in a marking where no transitions are enabled
@end enumerate
If the formula cannot be evaluated, the analysis will be stopped.  Thus,
commanding

@example
deadlock fatal;
@end example

@noindent
will cause the analysis to stop when a deadlock is reached.  The
following construct can be used to stop the analysis when an undesired
state is reached:

@example
reject place fork equals empty && fatal;
@end example

@noindent
An alternative mechanism for specifying undesired states is to define
``assertion'' transitions with @samp{undefined} or @samp{fatal} in
their gate expressions (@pxref{Transitions}).

@example
@group
verify:
        REJECT expr
        |
        DEADLOCK expr
@end group
@end example

@node Fairness, Propositions, Assertions, Verification
@subsubsection Defining Fairness Constraints
@cindex fairness sets
@findex strongly_fair
@findex weakly_fair
@findex enabled

It is possible to define fairness sets of transition instances to guide
the on-the-fly model checker.  Such sets may contain instances of a
single transition (@pxref{Transitions}) or of several transitions.  The
latter case is handled by identifying the transition instances that are
to be included to a set using qualifier expressions, which consist of
transition names followed by Boolean conditions for transition
variables.

A generic fairness set definition consists of one of the reserved words
@samp{strongly_fair} and @samp{weakly_fair} followed by a list of
qualifier expressions.  Each qualifier expression identifies some
transition instances that are to be treated fairly.  All instances
fulfilling a qualifier expression will be treated as one fairness set.

The @samp{enabled} keyword allows the definition of enabledness sets
of transition instances.  If no transition instances belonging to an
enabledness set are enabled, the set will be reported at the end of
the analysis.  Use the @samp{dump} command (@pxref{Dump}) to see the
enabledness set numbers.

@example
@group
fairness:
        STRONGLY_FAIR qual_expr ( ',' qual_expr )*
        |
        WEAKLY_FAIR qual_expr ( ',' qual_expr )*
        |
        ENABLED qual_expr ( ',' qual_expr )*
@end group
@group
qual_expr:
        TRANS name [ ':' expr ]
        |
        '(' qual_expr ')'
        |
@end group
@group
        '!' qual_expr
        |
        qual_expr '&&' qual_expr
        |
        qual_expr '^^' qual_expr
        |
        qual_expr '||' qual_expr
        |
        qual_expr '<=>' qual_expr
        |
        qual_expr '=>' qual_expr
@end group
@end example

Qualifier expressions may also be quantified.  The semantics of the
multi-set summation operation is that each summand is associated with a
new fairness set.  Universal and existential quantification have their
normal semantics, i.e.@: they are translated into chains of conjunctions
or disjunctions.

@example
@group
qual_expr:
        typereference name [ '(' expr ')' ] ':' qual_expr
        |
        typereference name [ '(' expr ')' ] '&&' qual_expr
        |
        typereference name [ '(' expr ')' ] '||' qual_expr
@end group
@end example

@node Propositions, , Fairness, Verification
@subsubsection Specifying State Propositions for LSTS Output
@cindex state propositions
@findex prop

The labelled state transition systems that Maria is able to output
(@pxref{LSTS}) have a notion of state propositions.  As they do not have a
natural counterpart in a high-level Petri net, a special construct has
to be used for specifying them.

@example
@group
proposition:
        PROP name ':' expr
@end group
@end example

The @samp{prop} definition does not affect anything else except the
output of labelled state transition systems and the resolution of
identifiers in the query language.  The expression must be a
truth-valued state formula.

@node Data Types, Expressions, Net Constructs, Modeling
@section Data Types
@cindex data types

In programming languages, user-defined structural data types became
popular in the 1970s with the success of C and other high-level
languages.  The original Petri Net formalism did not make use of any
data types or algebraic sorts, and its high-level variations usually
keep the data types pretty simple, often restricted to tuples of integer
numbers or enumerated data types.

In order to efficiently analyze the behavior of parallel programs
written in a high-level language, there must exist a straightforward
translation from the data types in the source formalism to the types
supported by the analyzer.  Using tuples of integers, one can emulate
simple higher-level types, such as a unidimensional array of a leaf
type, but anything beyond that is next to impossible.

The data type system in Maria holds the comparison with any high-level
programming language.  The only thing that is missing is pointers or
references, which would entirely break the locality principle of Petri
Nets.

@menu
* Types Background::    Technical background of the data type system

* Leaf Types::
* Integer::             Integer number (@samp{int} and @samp{unsigned})
* Boolean::             Truth value (@samp{bool})
* Character::           Character (@samp{char})
* Enumerated::          Enumerated integer (@samp{enum})
* Identifier::          Identifier type (@samp{id})

* Composite Types::
* Structure::           Composition of types (@samp{struct})
* Union::               One of many types (@samp{union})
* Array::               Fixed-size array
* Buffer::              Queue or stack of fixed capacity

* Constraints::         Limiting the range of a type
@end menu

@node Types Background, Leaf Types, Data Types, Data Types
@subsection Background

The Maria software stores data in two forms: as trees formed by C++
objects, which are easy to manipulate but use up much space, or as
compact bit strings.  Converting structured values to a fixed-length bit
string and vice versa requires that the number of all possible values of
a type is known and that there exists a total order among the values.

For supporting iteration through all values of a type, there are
successor and predecessor functions and functions for determining the
smallest and the largest value of a type.  These are in harmony with the
conversion functions: the numeric representation of the smallest value
of a type is 0, and its successor is 1 (unless the type only has one
value), and so on.

@node Leaf Types, Composite Types, Types Background, Data Types
@subsection Leaf Types

Data types that do not have any further structure are called @dfn{leaf
types}.  In Maria, all leaf types can be represented using a machine
word, an unsigned integer of usually 32 bits.

@menu
* Integer::             Integer number (@samp{int} and @samp{unsigned})
* Boolean::             Truth value (@samp{bool})
* Character::           Character (@samp{char})
* Enumerated::          Enumerated integer (@samp{enum})
* Identifier::          Identifier type (@samp{id})
@end menu

@node Integer, Boolean, Leaf Types, Leaf Types
@subsubsection Integer Types
@cindex data types, integer
@findex int
@findex unsigned

There are two predefined integer types: @samp{int}, a signed integer in
the range @code{INT_MIN} to @code{INT_MAX}, as defined by
@file{<limits.h>} in C, and @samp{unsigned}, an unsigned integer in the
range @code{0} to @code{UINT_MAX}.

Integer literals are numeric constants, given by the regular expressions
@samp{[1-9][0-9]*}, @samp{0[0-7]*} and @samp{0x[0-9a-fA-F]+}.  Negative
decimal numbers are formed using the @w{unary @samp{-}} operator.

The unconstrained built-in integer types have @code{INT_MAX-INT_MIN+1}
or @code{UINT_MAX+1} possible values, both usually
@tex
$2^{32}$.
@end tex
@ifnottex
@math{2^32}.
@end ifnottex
The order among the values is determined by integer arithmetics.  All
arithmetic operations in the expression evaluator are performed using
the unconstrained integer type.  Binary operators require their operands
to be either both signed or both unsigned.

@node Boolean, Character, Integer, Leaf Types
@subsubsection Boolean Type
@cindex data types, boolean
@findex bool

The Boolean type @samp{bool} is for storing truth values.  It has two
literals: @samp{false} (the smallest value) and @samp{true}.

@node Character, Enumerated, Boolean, Leaf Types
@subsubsection Character Type
@cindex data types, character
@findex char

Characters internally use the @code{unsigned char} type in C++.
Analogously with the unsigned integer type, the smallest value is
@code{0} and the largest @code{UCHAR_MAX}, and the total number
of different values is @code{UCHAR_MAX+1}, usually
@tex
$2^8$.
@end tex
@ifnottex
@math{2^8}.
@end ifnottex

@node Enumerated, Identifier, Character, Leaf Types
@subsubsection Enumerated Type
@cindex data types, enumerated
@findex enum

There are two variants of the enumerated type.  A constrained
enumerated type acts just like an integer having some named constants.
In the following we will concentrate on the unconstrained variant of
the enumerated type.

The domain of an unconstrained enumeration ranges from the smallest
enumeration constant to the largest one.  The order among the
enumeration constants is determined by their integer value.  Enumeration
constants whose value is not explicitly specified in the type definition
get their values just like in the C programming language: it is the
successor of the value given to the last declared constant.  By default,
the first constant will get the value 0.

@node Identifier, , Enumerated, Leaf Types
@subsubsection Identifier Type
@cindex data types, identifier
@findex id

In SDL, there is a data type for process identifiers.  Values of this
type can only be compared for equality and inequality, and there is an
operator for obtaining a new identifier value.  SDL assumes an unlimited
pool of distinct identifier values: the operator for obtaining a new
value will always return something that is different from all previous
values.  This is impossible for any practical system.  The identifier
type in Maria has otherwise the same properties as the one in SDL, but
one must declare the size of the identifier pool when declaring an
identifier type.

Internally, identifier values are unsigned integers ranging up to the
size of the identifier pool, exclusive.  The operator for obtaining a
new identifier value has not been implemented yet, but quantification
(@pxref{Multi-Sets}) is possible.  In the future, it is
intended to implement symmetry reductions of the state space, making use
of the properties of the identifier type.

@node Composite Types, Constraints, Leaf Types, Data Types
@subsection Composite Types

The leaf data types represented in previous section are adequate for
representing any kind of data.  Composite data types can be viewed as
syntactic sugar: by defining structural types, one can group data
items together, which can drastically simplify the notation required
for referring to the data items.

Composite types in Maria are constructed in a truly recursive way.
There are no arbitrary limits.  For example, it is entirely possible to
define a buffer of buffers containing a union of an array and a
structure.

@menu
* Structure::           Composition of types (@samp{struct})
* Union::               One of many types (@samp{union})
* Array::               Fixed-size array
* Buffer::              Queue or stack of fixed capacity
@end menu

@node Structure, Union, Composite Types, Composite Types
@subsubsection Structure
@cindex data types, structure
@findex struct

A structure type describes a sequentially allocated set of member
objects, each of which has a distinct name and possibly distinct type.
The order of structure values is determined in little-endian way: the
most significant component is stored last.  For instance, the four
values of the type @samp{struct@{bool a;bool b@}} are ordered
@samp{@{false,false@}}, @samp{@{true,false@}}, @samp{@{false,true@}} and
@samp{@{true,true@}}.

A structure type that has @math{n} members, each member @math{i} having
@tex
$c_i$
@end tex
@ifnottex
@math{c_i}
@end ifnottex
possible values, has

@tex
$$ \prod_{i=1}^n c_i $$
@end tex
@ifnottex
@math{c_1 * c_2 * ... * c_n}
@end ifnottex

@noindent
possible values.  An empty structure has only one possible value,
@samp{@{@}}.

@node Union, Array, Structure, Composite Types
@subsubsection Union
@cindex data types, union
@findex union@r{, data type}

Often there is a need to pass a parameter whose type is determined
dynamically.  The tagged union type in Maria serves exactly this
purpose.  It describes an overlapping nonempty set of member objects,
each of which have a name and a possibly distinct type.  Whenever a
union value is initialized, also the union component must be identified.

The union can be viewed as a special kind of structure of two
components: the actual value inside the union and the identifier of the
component to which the value belongs.  For instance, the values of the
type @samp{union@{bool a;struct@{@} b;@}} are ordered @samp{a=false},
@samp{a=true} and @samp{b=@{@}}.  A union type that has @math{n}
members, each member @math{i} having
@tex
$c_i$
@end tex
@ifnottex
@math{c_i}
@end ifnottex
possible values, has

@tex
$$ \sum_{i=1}^n c_i $$
@end tex
@ifnottex
@math{c_1 + c_2 + ... + c_n}
@end ifnottex

@noindent
possible values.

@node Array, Buffer, Union, Composite Types
@subsubsection Array
@cindex data types, array

An array type describes a contiguously allocated nonempty set of objects
with a particular member object, called the @dfn{element type}.  The
members (elements) of an array are accessed by indexing the array with
values of the @dfn{index type} of the array.  The number of possible
values in the index type determines the number of elements in the array.

The order of values in an array type is determined in the little-endian
manner.  The four values of the type @samp{bool[bool]} are ordered
@samp{@{false,false@}}, @samp{@{true,false@}}, @samp{@{false,true@}} and
@samp{@{true,true@}}.

An array whose element type has
@tex
$c_e$
@end tex
@ifnottex
@math{c_e}
@end ifnottex
possible values and index type
@tex
$c_i$
@end tex
@ifnottex
@math{c_i}
@end ifnottex
possible values, has
@ifnottex
@math{c_e^c_i}
@end ifnottex
@iftex

@tex
$$ {c_e}^{c_i} $$
@end tex
@noindent
@end iftex
possible values.

@node Buffer, , Array, Composite Types
@subsubsection Buffer (Queue or Stack)
@cindex data types, buffer
@findex queue
@findex stack

Communication protocols use queue-like transmission buffers heavily.
Many algorithms and the translation of procedural programming languages
to Petri Net models require stack-like buffers.  The buffer type in
Maria has a maximum size, and it has two variants, queue and stack.  A
buffer is much like an array, but it may contain a variable number of
items.

The order of values is determined in the little-endian manner.  Shorter
buffers come first.  For instance, the values of the type
@samp{bool[queue 2]} are ordered @samp{@{@}}, @samp{@{false@}},
@samp{@{true@}}, @samp{@{false,false@}}, @samp{@{true,false@}},
@samp{@{false,true@}} and @samp{@{true,true@}}.

A buffer of at most @math{n} elements whose element type has
@tex
$c_e$
@end tex
@ifnottex
@math{c_e}
@end ifnottex
possible values has

@tex
$$ \sum_{i=0}^n c_e^i = {{c_e^{n+1}-1}\over{c_e-1}} $$
@end tex
@ifnottex
@end ifnottex

@noindent
possible values.

@node Constraints, , Composite Types, Data Types
@subsection Constraints
@cindex data types, limiting with constraints
@cindex state space explosion, avoiding
@findex ..

When performing reachability analysis, it is often desirable to limit
the analysis in many ways to address the problem known as the @dfn{state
space explosion}.  One of the ways is to limit the domain of data types.
Instead of considering all 32-bit integer numbers, one may restrict the
analysis to numbers ranging from 0 to 10, for instance.

In addition to limiting the search, type constraints can act as a
valuable aid for detecting errors in system models.  The expression
evaluator will detect and report @dfn{constraint violations} whenever a
subexpression evaluates to an unconstrained value.  The successor and
predecessor functions will, however, conveniently wrap around, so that
the successor of the largest value of a type is the smallest value.

Constraints can be applied to all types whose values can be expressed
with constant literals.@footnote{The identifier type does not have any
literals, and thus it is impossible to define constraints for types
containing it.}  Not only leaf types can be constrained.  For instance,
it is possible (while not necessarily sensible) to define a type
@samp{bool(false)[queue 347](..@{false@})[int(33101)]}, a single-element
array of a buffer having two possible values: @samp{@{@{@}@}} and
@samp{@{@{false@}@}}.

The net description language parser computes unions and intersections of
value ranges while parsing constraints, which are internally stored as
unions of disjoint ranges.  In addition, it will combine adjacent
constraints and eliminate overlapping constraints.  The type
@samp{int(1..4,3,5)} is thus equivalent with the types
@samp{int(1..)(..5)} and @samp{int(1..5)}, the canonical form.

@node Expressions, Output Variables, Data Types, Modeling
@section Expressions and Formulae
@cindex expressions, overview

Expressions form the core of any language.  One of the design goals of
the Maria reachability analyzer was to make expressions as rich as
possible, to add expressive power to the language and to make the
language attractive to people who are familiar with and accustomed to
modern high-level programming languages.

Like the data type system, the expression system of Maria has been
greatly inspired by that of the programming language C.  There are no
pointer operations and no expressions with side-effects, and some
operators of our language have no direct counterpart in C.

@menu
* Literals::
* Constants::           Anything that is a constant isn't.
* Variables::           Anything that is a variable doesn't.
* Dynamic Errors::      Trapping undefined behavior

* Operators::
* Integer Arithmetic::  Basic integer arithmetic
* Successor::           The successor and predecessor functions
* Comparison::          Comparing values
* Logic::               Boolean Logic
* Selection::           The generalized if-then-else operator
* Type Casting::        Type conversions
* Atomicity::           Prohibiting formula transformations

* Structures::          Dealing with the structured type
* Unions::              Dealing with the union type
* Arrays::              Dealing with arrays
* Buffers::             Dealing with buffer contents

* Multi-Sets::          Multi-set operations
* Temporal::            Formulae of temporal logic
@end menu

@node Literals, Constants, Expressions, Expressions
@subsection Literals

When an expression is viewed as a tree, the leaves of the tree are
called @dfn{literals}.  There are three kinds of literals in Maria
expressions: constant values, variable names and the reserved words
@samp{undefined} and @samp{fatal}.  Also invocations of functions with
zero arguments, also called @dfn{nullary functions} or @dfn{named
constants}, could be viewed as literals, but they can expand to more
complex expressions or formulae.

@menu
* Constants::           Anything that is a constant isn't.
* Variables::           Anything that is a variable doesn't.
* Dynamic Errors::      Trapping undefined behavior
@end menu

@node Constants, Variables, Literals, Literals
@subsubsection Constants
@cindex constants

The constants in the Maria languages are type-specific.  The Boolean
type (types derived from the built-in @samp{bool} type) has two
constants: @samp{false} and @samp{true}.  Character types (@samp{char})
uses single character constants enclosed in single quotes
(@pxref{Lexical Tokens}), and integer types (@samp{int} and
@samp{unsigned}) use decimal, octal or hexadecimal numbers with a
notation familiar from the programming language C.

There are three unary pseudo-operators that deal with type names and
yield constant.  The number-of-values operator @samp{#} can be used to
refer to the number of possible values a type can receive.  For
instance, @samp{#bool} is equivalent to @samp{2}, unless you have
redefined the built-in type @samp{bool} to be something else.  The
operators @samp{<} and @samp{>} refer to the smallest and to the largest
value of a type, respectively.  For instance, you can use @samp{<bool}
interchangeably with @samp{false}, unless the type has been redefined.

The constants of enumerated types are written either using numbers, just
as with integer types, or using the names of the enumeration symbols.
The names do not have global scope, and in the cases when the parser
cannot determine the type from the context, you must use the type
casting operator (@pxref{Type Casting}).  If you want an enumeration
symbol to have global scope, you can define it as a nullary function or
named constant:

@example
@group
typedef enum @{ a, b, c @} enum_t;
enum_t a = is enum_t a;
reject <enum_t != a;
@end group
@end example

Constants of compound types are written using the respective expressions
for creating compound values, restricting the literals in the
expressions to constants.  The expressions will be evaluated while
parsing them and replaced with corresponding constants.  This is called
@dfn{constant folding}.

@node Variables, Dynamic Errors, Constants, Literals
@subsubsection Variables
@cindex variables

Variables make expressions behave dynamically.  In high-level Petri
Nets, variables make the arc expressions of transitions evaluate in
different ways.  Each combination of variable--value pairs (usually
referred to as @dfn{valuation}) that enables a transition is called an
enabled @dfn{instance} for the transition.@footnote{Also the terms
@dfn{binding} and @dfn{firing mode} have been used.}  Enabled transition
instances are sought in a process called @dfn{unification}
(@pxref{Unification}).  Variables cannot be explicitly assigned to in
the high-level Petri Net formalism.

Variables can be declared either explicitly e.g.@: in the declaration
blocks of transitions, or implicitly in the input arc expressions of
transitions.

@node Dynamic Errors, , Variables, Literals
@subsubsection Dynamic Errors
@cindex assertions
@cindex catching dynamic errors

The @samp{undefined} and @samp{fatal} keywords can be used to catch
dynamic errors in the model.  Both can be seen as type-less nullary
operators.  When the @samp{undefined} symbol is evaluated while
searching for enabled transition instances, the valuation built so far
will be marked as erroneous and the instance will not be fired.  The
@samp{fatal} keyword is similar, but evaluating it will cause the whole
analysis to be aborted.

These two keywords are usually used on the right-hand-side of the
if-then-else operator or of the logical @samp{&&}, @samp{||} or
@samp{=>} operators.@footnote{This relies on @dfn{short-circuit
evaluation}: if the left-hand-side of one these operators alone can
determine the result of the operation, the right-hand-side will not be
evaluated.}  To improve readability, one could define an @samp{assert()}
macro.  Unlike its counterpart in the @w{C library}, the following macro
will return a value.

@example
@group
bool assert (bool expr) expr || fatal;
place p unsigned: 42;
trans t in @{ place p: p; @}
gate assert (p == 42);
@end group
@end example

The search for enabled transition instances is an iterative process.
Because of this, expressions containing @samp{undefined} and
@samp{fatal} keywords may be evaluated before the transition instance is
complete.  If this is not desirable, the expression for catching dynamic
errors should be placed on an output arc, perhaps on the right-hand-side
of an if-then-else operator.

If you use either keyword in a gate expression as the right-hand-side of
the @samp{&&} operator, you'd better declare the expression atomic by
enclosing it with @samp{atom()}, so that the parser will not split the
gate expression into two, which would break the short-circuit evaluation
of the @samp{&&} operator.

@node Operators, Precedence, Expressions, Expressions
@subsection Operators

@menu
* Precedence::          Operator precedence
* Integer Arithmetic::  Basic integer arithmetic
* Successor::           The successor and predecessor functions
* Comparison::          Comparing values
* Logic::               Boolean Logic
* Selection::           The generalized if-then-else operator
* Type Casting::        Type conversions
* Atomicity::           Prohibiting formula transformations
@end menu

@node Precedence, Integer Arithmetic, Operators, Operators
@cindex operator precedence

The operator precedence in the Maria languages is as follows.  Each
table row forms a precedence class.
@multitable @columnfractions .20 .20 .20 .20 .20
@item @samp{?:}@*(selection)
 @tab @samp{!}@*(output)
 @tab @samp{:}@*(multi-sets)
@item @samp{until}
 @tab @samp{release}
 @tab @samp{=}
@item @samp{=>}
 @tab @samp{<=>}
@item @samp{||}
@item @samp{^^}
@item @samp{&&}
@item @samp{<>}
 @tab @samp{[]}
 @tab @samp{()}
@item @samp{|}
@item @samp{^}
@item @samp{&}
@item @samp{!=}
 @tab @samp{==}
@item @samp{>=}
 @tab @samp{<=}
 @tab @samp{<}
 @tab @samp{>}
@item @samp{<<}
 @tab @samp{>>}
@item @samp{+}
 @tab @samp{-}
@item @samp{*}
 @tab @samp{/}
 @tab @samp{%}
@item @samp{#} (binary)
 @tab @samp{is}
@item unary: @samp{~}, @samp{-}, @samp{!}
 @tab @samp{#}
 @tab @samp{<}, @samp{>}, @samp{|}, @samp{+}
 @tab @samp{*}, @samp{/}, @samp{%}
@item @samp{cardinality}
 @tab @samp{max}
 @tab @samp{min}
 @tab @samp{subset}@*(ternary)
 @tab @samp{map}
@item @samp{equals}
@item @samp{subset}
@item @samp{minus}
 @tab @samp{union}
@item @samp{intersect}
@item @samp{atom}
 @tab @samp{is} (cast)
@item @samp{.}
 @tab @samp{[}
 @tab @samp{(}
@end multitable

Some operators have several meanings.  For instance, there are two
variants of the @samp{is} operator, one that performs type conversions,
and another that determines whether a union component is active:
@example
@group
expr:
        IS typereference expr
        |
        expr IS name
@end group
@end example

@node Integer Arithmetic, Successor, Precedence, Operators
@subsubsection Integer Arithmetic
@cindex expressions, arithmetic
@findex -@r{, unary}
@findex ~@r{, unary}
@findex +
@findex -
@findex /
@findex *
@findex %
@findex &
@findex |
@findex ^
@findex <<
@findex >>

For performing integer arithmetic, the language contains all the integer
operators of C: negation (sign change, @w{unary @samp{-}}), bitwise
complementation (@w{unary @samp{~}}), basic arithmetics (@samp{+},
@samp{-}, @samp{/}, @samp{*}, @samp{%}) and bit operations (@samp{&},
@samp{|}, @samp{^}, @samp{<<}, @samp{>>}).

Actually there are two sets of integer operators: signed and unsigned
operators.  Both operands must be either signed or unsigned, and the
result is accordingly signed or unsigned.  Unsigned arithmetics is a
little faster than signed arithmetics.  Numeric constants, unsigned by
default, are automatically converted to signed integers.  For binary
integer operators, the type of the first operand determines whether the
operation is signed or unsigned.

All integer operators in Maria have been implemented in terms of the
corresponding C++ operators, but some error handling has been added.
The operators whose result can exceed the limits of the built-in
integer type will detect overflows.  These operators are negation,
addition, subtraction and multiplication.  The division and modulus
operators will check for division by zero, and the bit shifting
operators will ensure that the amount to be shifted does not exceed
the size of the integer type in bits.  Last but not least, if the
result type has a constraint, the result will be checked against it.

@node Successor, Comparison, Integer Arithmetic, Operators
@subsubsection Successor and Predecessor
@cindex expressions, successor
@cindex expressions, predecessor
@cindex successor and predecessor
@findex +@r{, unary}
@findex |@r{, unary}

The successor and the predecessor are defined for all ordered types.
All other types than the identifier type and structural types containing
an identifier component are ordered.  The successor of the largest value
of a type is the smallest value, whose predecessor in turn is the
largest value.@footnote{For discussion on the order of values in types,
see @ref{Types}.}  No errors can occur while computing the successor
(@w{unary @samp{+}}) or predecessor (@w{unary @samp{|}}).

@node Comparison, Logic, Successor, Operators
@subsubsection Comparison
@cindex expressions, comparison
@findex ==
@findex !=
@findex <
@findex <=
@findex >=
@findex >

The language contains the usual comparison operators (@samp{==},
@samp{!=}, @samp{<}, @samp{<=}, @samp{>=} and @samp{>}).  Equality and
inequality comparisons are available for all types, while other
comparisons are only available for ordered types.  The only error that
can occur in a comparison is a constraint violation, in case the result
type is constrained.@footnote{One does not need a constrained Boolean
type very often, but nevertheless it can be defined.}

@node Logic, Selection, Comparison, Operators
@subsubsection Boolean Logic
@cindex expressions, logic
@cindex expressions, short-circuit evaluation
@findex !
@findex &&
@findex ^^
@findex ||
@findex =>
@findex <=>

Boolean logic in Maria has the familiar operators from C: negation
(@w{unary @samp{!}}), conjunction (@samp{&&}) and disjunction
(@samp{||}).  There is also some syntactic sugar: implication
(@samp{a=>b} is equivalent to @samp{!a||b}), logical equivalence
(@samp{a<=>b} is equivalent to @samp{(a&&b)||!(a||b)}) and logical
exclusive or (@samp{a^^b}, equivalent to @samp{!(a<=>b)}).

Also, the language supports universal and existential quantification,
and translates them to conjunctions and disjunctions:

@example
@group
formula:
        typereference name [ '(' expr ')' ] '&&' formula
        |
        typereference name [ '(' expr ')' ] '||' formula
@end group
@end example

@noindent
For instance, the existential quantification
@example
char a (a>='a' && a<='c') || b==a
@end example
@noindent
expands to the formula @samp{b=='a'||b=='b'||b=='c'}.

In the quantified formulae, it is possible to refer to @dfn{quantified
variables}, variables indexed by a quantifier or the preceding value of
a quantifier:
@example
@group
expr:
        '.' name [ name ]
        |
        ':' name [ name ]
@end group
@end example

@noindent
For instance, if there is a declaration @samp{typedef unsigned (1..3)
index_t}, the universal quantification
@example
index_t e && (e == <index_t || :n < .n)
@end example
@noindent
is equivalent to @samp{n[1]<n[2]&&n[2]<n[3]}.

The conjunction and disjunction operators use @dfn{short-circuit
evaluation}, meaning that the expression is evaluated in depth-first
manner from left to right, and if the value of the left-hand-side
expression of an operator alone can determine the value of the
expression, no matter what the right-hand-side evaluates to, the
right-hand-side will not be evaluated.

@node Selection, Type Casting, Logic, Operators
@subsubsection Selection
@cindex if-then-else, generalized
@cindex expressions, selection
@findex ?:

The ternary @samp{?:} operator of C selects its second or third argument
based on its first argument interpreted as a truth value.  The @samp{?:}
operator in Maria is more generic.  It is not a ternary operator but
@math{n}-ary, with @math{n-1} being the number of possible values for
the type of its first argument.

Here is an example of the @samp{?:} operator for a type having three
possible values.

@example
@group
typedef int (1..3) i3_t;
place p i3_t: 1;
trans t
in @{ place p: p; @}
out @{ place p: p ? p : |p : +p; @};
@end group
@end example

@noindent
The left-hand-side of the @samp{?} on the output arc of @w{transition
@samp{t}} is the @w{variable @samp{p}}, which is of @w{type @samp{i3_t}}
and has three possible values.  When the expression has its largest
value (in this case @samp{3}), the argument immediately following the
@samp{?} will be selected.  The second largest value (@samp{2}) will
select the third argument (@samp{|p}), and the smallest value (@samp{1})
will select the last argument (@samp{+p}).

In this simple example, the marking of @w{place @samp{p}} will alternate
between @samp{1} and @samp{2} in two states.  It really should be
emphasized that it is the number of values of the type that matters, not
the number of possible (reachable) values for the left-hand-side
expression.  Selecting an initial marking @samp{3} for @w{place
@samp{p}} would yield only one state in the reachability graph.

@node Type Casting, Atomicity, Selection, Operators
@subsubsection Type Casting
@cindex data types, conversions
@findex is@r{, unary}

The type casting operator, the @w{prefix @samp{is}}, has two purposes.
First, it can be used to set the @dfn{context type} in case it cannot be
determined correctly.  The parser is pretty good at guessing the context
type, but there is one remarkable case when it cannot do so.  Comparison
expressions occur in Boolean context, but the arguments to the
comparison operator typically are of some other type.  If the argument
is an enumeration constant or a construction expression for a compound
value, the context must be set with the @samp{is} operator:

@example
@group
typedef enum @{ a, b, c @} e3_t;
place p e3_t: a;
trans t
in @{ place p: p; @}
out @{ place p: b; @}
gate p != is e3_t a;
@end group
@end example

@noindent
Boolean, integer and character literals will always be detected as such,
no matter what the context type is.

The dynamic behavior of type casting is to convert a value of one type
to an equivalent value of another type.  Type conversion is only allowed
if the two types have at least one common value.  The only error that
can occur during the conversion is a constraint violation.

Also compound values can be converted.  Two compound types are
considered compatible for the conversion if all their components are
compatible.  A union-typed value can be converted to the type of one of
its components, or vice versa.

@node Atomicity, , Type Casting, Operators
@subsubsection Atomicity
@cindex expressions, prohibiting transformations
@cindex expressions, atomicity
@findex atom

The parser may perform optimizations on expressions by converting them
to equivalent forms.  Currently transition gate expressions containing
a conjunction in the top level will be split to several gate
expressions, and it is likely that the model checker will do something
similar to temporal logic formulae.

The transformations of expressions have one disadvantage: they break
short-circuit evaluation.  If you rely on short-circuit evaluation when
writing an expression, it is a good practice to enclose the expression
with @samp{atom()}, e.g.@: @samp{atom (y==0||x/y>z)}.  Short-circuit
evaluation takes place with the operators @samp{||}, @samp{&&},
@samp{=>} and @samp{?:}.

@node Structures, Unions, Expressions, Expressions
@subsection Structures
@cindex expressions, structures
@findex .

There are two basic operators for structures: for constructing a value
of a structure type and for accessing a structure component.  Both
inherit their syntax and semantics from C.

@example
@group
expr:
        '@{' [ [ name ':' ] expr ( ',' [ name ':' ] expr )* ] '@}'
        |
        expr '.' name
@end group
@end example

In the constructor expression, the expressions for individual components
may be preceded by the name of the corresponding struct component.

Since Petri nets have no assignment statement, a special operation is
needed for modifying a structure component.

@example
@group
expr:
        expr '.' '@{' name expr '@}'
@end group
@end example

For instance, @samp{a.@{b c@}} has otherwise the same value as the
structure @samp{a}, but with the component @samp{b} equal to @samp{c}.

@node Unions, Arrays, Structures, Expressions
@subsection Unions
@cindex expressions, unions
@cindex unions, active component
@findex =
@findex is
@findex .

The union type in Maria is tagged: it is always known which component of
the union has been assigned to (or is the @dfn{active component}), and
this information can also be enquired by using the @w{infix @samp{is}}
operator.

@example
@group
expr:
        name '=' expr
        |
        expr IS name
        |
        expr '.' name
@end group
@end example

The @samp{.} operator can be used to access the value of the active
component.  If the specified component is not active, a union violation
will occur.

Structures and unions are very practical for modeling inherited classes
of object-oriented languages.  The example @w{file @file{object.pn}} in
the Maria distribution shows how a simple class structure can be
translated to Maria types and how objects can be converted between a
base class and derived classes.

@node Arrays, Buffers, Unions, Expressions
@subsection Arrays
@cindex expressions, arrays
@findex ?@r{, unary}

Array values are constructed and indexed with a syntax familiar from the
C programming language.

@example
@group
expr:
        '@{' [ expr ] ( ',' [ expr ] )* '@}'
        |
        expr '[' expr ']'
@end group
@end example

In addition, the contents of an array can be shifted by a given number
of items.  The amount to be shifted is always reduced to the modulo of
number of items in the array.  For instance, shifting an array indexed
by Boolean values by an even number of items has no effect.

@example
@group
expr:
        expr '<<' expr
        |
        expr '>>' expr
@end group
@end example

Since Petri nets have no assignment statement, a special operation is
needed for modifying an array item.

@example
@group
expr:
        expr '.' '@{' '[' expr ']' expr '@}'
@end group
@end example

For instance, @samp{a.@{[b] c@}} has otherwise the same value as the
array @samp{a}, but with the item at @samp{b} equal to @samp{c}.

@node Buffers, , Arrays, Expressions
@subsection Buffers
@cindex buffers
@cindex FIFO buffers
@cindex LIFO buffers
@cindex stacks
@cindex queues
@findex +@r{, buffer}
@findex -@r{, unary, buffer}
@findex *@r{, unary}
@findex /@r{, unary}
@findex %@r{, unary}

For ideal buffers, two operations ought to be enough: removing an item
for reading, and writing an item.  Since there is no well-defined
semantics for Petri Nets whose arc expressions have side-effects,
reading a buffer has to be split in two separate operations: peeking at
an item (@samp{*}) and removing (@samp{-}).

Some applications need to access buffers out of order.  It is possible
to specify the buffer position using an index.

@example
@group
expr:
        expr index '+' expr
        |
        '-' expr index
        |
        expr index '-' expr
        |
        '*' expr index
index:
        [ '[' expr ']' ]
@end group
@end example

The unary @samp{-} operator removes one item from a buffer.  With the
binary @samp{-} operator, it is possible to remove several successive
items.  The second operand indicates the number of items to be removed.

Many applications need to know the remaining or used buffer capacity.
That is what the unary operators @samp{%} and @samp{/} are for.  It is
also possible to construct the whole buffer contents with one
expression, just like struct and array values.

@example
@group
expr:
        '@{' [ expr ] ( ',' [ expr ] )* '@}'
        |
        '/' expr
        |
        '%' expr
@end group
@end example

@node Multi-Sets, Temporal, Expressions, Expressions
@section Operations on Multi-Sets
@cindex multi-sets
@cindex sets
@cindex marking expressions
@cindex multiplicity
@cindex quantification
@cindex expressions, multi-set valued
@findex empty
@findex place
@findex subset
@findex equals
@findex union
@findex intersect
@findex minus
@findex subset@r{, selection}
@findex cardinality
@findex max
@findex min
@findex #

The state of a Petri Net is identified by the distribution of tokens in
the places.  The contents of the places, also called @dfn{markings}, can
be represented as multi-sets, which are sets that can contain several
instances of an item, meaning that the @dfn{multiplicity} of an item in
the set may be greater than one.

Arc expressions of transitions and initialization expressions of the
model typically make use of two multi-set operations.  The simpler one,
specifying a multiplicity or a token multiplier, makes use of the binary
@samp{#} operator.

@example
@group
marking:
        '(' marking_list ')'
        |
        expr '#' marking
@end group
@end example

@noindent
For instance, @samp{347#33101} stands for 347 tokens having the value
33101, and @samp{4#(3#2,1)} is another way for expressing
@samp{12#2,4#1}, which means 12 tokens of the value 2 and four tokens of
the value 1.

The other operation, computing a multi-set sum, is called
@dfn{quantification}.

@example
@group
marking:
        typereference name [ '(' expr ')' ] ':' marking
@end group
@end example

@noindent
@iftex
This is equivalent to the formula
@tex
$$ \sum_{n\in T\land e} m $$
@end tex
where @math{n} corresponds to @samp{name}, @math{T} to
@samp{typereference}, @math{e} to @samp{expr} and @math{m} to
@samp{marking}.  Usually both @math{e} and @math{m} make use of
@math{n}.
@end iftex

The construct will iterate through all the values of the type, binding
each value to a named variable.  If the condition expression evaluates
to true when the variable is bound to a value, the marking expression
will be evaluated using that binding, and the resulting items will be
added to the quantification result.

In transition expressions, it is possible to define @dfn{quantified
variables}, variables indexed by a quantifier:

@example
@group
expr:
        '.' name [ name ]
        |
        ':' name [ name ]
@end group
@end example

@noindent
For instance, writing @samp{bool b: .a} is equivalent to writing
@samp{"a[false]", "a[true]"}.  The optional second name refers to a
quantifier variable.  It is needed in nested quantifications when
indexing a variable by something else than the innermost quantifier.

The variant with the colon indexes variables based on the predecessor of
the quantifier variable.  It is more useful in universal and existential
quantification (@pxref{Logic}).

There are two multi-set valued literals: the empty set, which is useful
in subset and equality comparisons, and the marking of a place.

In a formula, the marking of a place is a function of the current state.
In the output arc of a transition, it is defined as the multi-set of
tokens that will be removed from the place by the input arcs of the
transition instance.  Referring to the contents of a place in an input
arc or in a gate expression yields a dynamic error.

@example
@group
marking:
        EMPTY
        |
        PLACE name
@end group
@end example

Multi-sets can be compared in two ways.  Two sets are equal if both
contain the same amount of the same items.  Multi-set @math{A} is subset
of multi-set @math{B} if for each item in @math{A} there are at least as
many such items in @math{B}.

@example
@group
formula:
        marking SUBSET marking
        |
        marking EQUALS marking
@end group
@end example

Multi-sets can be combined in three ways.  The union of two multi-sets
is computed by adding the multiplicities of all items in each set
together.  The intersection is formed by computing the maximum
multiplicity of each item in both sets.  Finally, multi-sets can be
subtracted from each other.  In @math{A-B} there are only items that
have a greater multiplicity in @math{A} than in @math{B}.  The
multiplicity of each item is the difference of the multiplicities in
@math{A} and in @math{B}.

@example
@group
marking:
        marking UNION marking
        |
        marking INTERSECT marking
        |
        marking MINUS marking
@end group
@end example

As a special case of intersection, it is possible to filter multi-sets
based on conditions.  A named variable will iterate through all the
items in a multi-set, and if the condition expression is true, the item
will be included in the resulting set, with its original multiplicity.
This construct can be viewed as an intersection with a multi-set whose
items have either zero or infinite multiplicity.

@example
@group
marking:
        SUBSET name '@{' marking_list '@}' expr
@end group
@end example

@noindent
For instance, @samp{subset t @{ 3#true, 2#false @} !t} equals
@samp{2#false}.

There are two mapping operations similar to the filtering operation
described above.  One operation preserves the cardinality of a multi-set
(the number of contained items).  It transforms a multi-set of one type
to a multi-set of another type by iterating through all the items in the
source multi-set with a named variable, and by computing the items for
the target multi-set by evaluating a basic expression.

A more generic mapping iterates through a multi-set, assigning the
multiplicity and the value of each distinct item to a pair of variables,
and mapping the items by evaluating a multi-set valued expression.

@example
@group
marking:
        MAP name '@{' marking_list '@}' expr
        |
        MAP name '#' name '@{' marking_list '@}' marking
@end group
@end example

@noindent
For instance, @samp{map t @{ 3#true, 2#false @} !t} equals
@samp{3#false, 2#true}, while the expression @samp{map n#t @{ 3#true,
2#false @} (t?1#!t:n#t)} evaluates to @samp{3#false}.

Last but not least, there are operations for determining the minimum or
maximum multiplicity of the items belonging to a multi-set, or for
computing the cardinality, the sum of the multiplicities.  The minimum
multiplicity of an empty set is @code{UINT_MAX}.

@example
@group
formula:
        MAX marking
        |
        MIN marking
        |
        CARDINALITY marking
@end group
@end example

@node Temporal, , Multi-Sets, Expressions
@section Temporal Logic
@cindex temporal operators
@cindex LTL
@cindex expressions, temporal
@findex <>
@findex []
@findex ()
@findex until
@findex release
@findex !
@findex &&
@findex ^^
@findex ||
@findex =>
@findex <=>

The grammar for temporal logic is @dfn{LTL}, Linear Temporal Logic.  The
operators ``eventually'', ``henceforth'', and ``in the next state'' have
the digraph representations @samp{<>}, @samp{[]} and @samp{()},
respectively.

@example
@group
        '<>' formula
        |
        '[]' formula
        |
        '()' formula
        |
        formula UNTIL formula
        |
        formula RELEASE formula
@end group
@end example

@node Output Variables, Scoping, Expressions, Modeling
@section Non-Determinism in Transitions
@cindex non-determinism
@cindex output variables
@cindex variables, output
@cindex random behavior

Sometimes it is necessary to have non-deterministic transitions, that
is, transitions that have several possible outputs for one input.
Often such behavior is modeled by adding a @samp{const} place to the
net and binding a token from the place to the non-deterministic
transition through a bidirectional arc.  This approach may disturb
partial order reduction algorithms.

The Maria language contains a construct for declaring non-deterministic
transition variables, called @dfn{output variables}.  @footnote{With
output variables, we only mean these non-deterministic variables, not
all the variables that may occur in the output arc expressions of a
transition.}

@example
@group
expr:
        typereference [ name ] '!' [ '(' expr ')' ]
@end group
@end example

The expression will evaluate to the value of the output variable, which
will iterate through all the values of the type, or to all values for
which the condition expression is true.  The output variable can be
given a name, and doing so is recommended if the output variable is used
in several expressions or if a condition expression is used.

@example
place p bool: true;
trans t in @{ place p: p @} out @{ place p: bool! @};
@end example

The default names for unnamed output variables are @samp{:0}, @samp{:1},
and so on, a colon followed by a hexadecimal number.  Those who want to
write obfuscated net descriptions can refer to these names using the
double-quoted notation.

@node Scoping, , Output Variables, Modeling
@section Scoping of Identifiers
@cindex scoping, identifiers
@cindex name spaces
@cindex shadowing declarations

Even though Petri Nets are a very flat formalism, there is pretty much
depth in the scoping of names.  In the Petri Net level, there are three
name spaces that cannot be overridden: one for place names, one for
transition names and one for data type names.  Function names can be
overridden in the transition level.

In expressions (@pxref{Literals}), names can stand for several things.
The names will be looked up in the following order:

@enumerate
@item function parameters (in a function definition),
@item iterator variables (multi-set operations, non-determinism)
@item previously declared transition variables
@item nullary functions
@item enumeration constants (in the type context)
@item state propositions (in @samp{deadlock} and @samp{reject} formulae)
@end enumerate

@noindent
If all the look-ups fail for a name, a transition variable will be
declared, if a transition definition is being parsed and if the type
context is known.

The parser can issue warning messages about names that exist in several
name spaces.  If you know what you are doing, these warnings can safely
be ignored.

@node Analysis, Algorithms, Modeling, Top
@chapter Reachability Analysis with Maria
@cindex reachability analysis

Determining all interesting behaviors of a concurrent system is done by
computing a graph of all system states reachable from the initial state.
This process is called @dfn{reachability analysis}.  Once a (possibly
incomplete) reachability graph has been generated, it can be examined,
and one can verify temporal properties from it.

It is also possible to verify temporal properties during the generation
of the reachability graph (@pxref{Model Checking}).  This can guide the
search and speed up the analysis, but verifying another temporal
property from the system will usually require the reachability analysis
to be performed again.

@menu
* Invoking Maria::      Starting the reachability analysis
* Interrupting::        Interrupting the reachability analysis

* Maria Shell::         Examining the reachability graph interactively

* Emacs::               Editing Petri Nets with GNU Emacs
@end menu

@node Invoking Maria, Maria Shell, Analysis, Analysis
@section Invoking Maria
@cindex reachability graph, generating
@cindex command line options, @samp{maria}
@cindex invoking @file{maria}

The usual way to invoke Maria is as follows:

@example
maria -b @var{model}
@end example

Here @var{model} is the Petri Net file name, which usually ends in
@samp{.pn}.  The base name for reachability graph files (@pxref{Graph
Files}) is generated by removing the directory name part and the file
name suffix (the last part of the name starting with a period @samp{.})
from the Petri Net file name.  Three files will be generated using the
base name, with the suffixes @samp{.rgd}, @samp{.rgs}, @samp{.rga} and
@samp{.rgh}.  Thus, @samp{maria -b dining.pn} yields @file{dining.rgd},
@file{dining.rgs}, @file{dining.rga} and @file{dining.rgh}, and
@samp{maria -d test/order.pn} yields @file{order.rgd}, @file{order.rgs},
@file{order.rga} and @file{order.rgh}, in the current directory.

@menu
* Interrupting::                Interrupting the reachability analysis
* Maria Options::               All the options described in detail,
                                  in alphabetical order by short options.
* Maria Option Cross Key::      Alphabetical list of long options.
@end menu

@node Interrupting, Maria Options, Invoking Maria, Invoking Maria
@subsection Interrupting the Reachability Analysis

Maria traps the interrupt signal (@env{SIGINT}), which is usually bound
to @kbd{C-c}.  When it catches the signal, it will stop processing new
states.  After Maria has finished with the state it is currently
processing, analyzing all the enabled transition instances and
generating the successor states, it will update the reachability graph
directory and stop the analysis.

Analyzing and firing enabled transition instances in a state may take a
long time.  Be patient or issue a @env{SIGQUIT} (normally bound to
@kbd{C-\}) or a @env{SIGKILL} signal to abort the process immediately,
leaving the reachability graph files in an inconsistent state.

@node Maria Options, Maria Option Cross Key, Interrupting, Invoking Maria
@subsection Options

Maria supports both traditional single-letter options and mnemonic long
option names (if compiled with @samp{getopt_long}, @pxref{Compiling}).
Long option names are indicated with @samp{--} instead of @samp{-}.
Abbreviations for option names are allowed as long as they are unique.
When a long option takes an argument, like @samp{--include}, connect the
option name and the argument with @samp{=} or provide the argument in
the immediately following command line argument.

The options are interpreted in the order they are entered on the
command line.  In other words, the options for interpreting a model
should be specified before loading the model.  For instance,
@samp{maria -b dbm.pn -DUNUSED} does not make much sense, while
@samp{maria -DUNUSED -b dbm.pn} does.

Here is a list of options that can be used with Maria, alphabetized by
short option.  It is followed by a cross key alphabetized by long
option.

@table @samp
@item -a @var{limit}
@itemx --array-limit=@var{limit}
Limit the size of array index types to @var{limit} possible values.  A
limit of 0 disables the checks.

@item -b @var{model}
@itemx --breadth-first-search=@var{model}
Generate the reachability graph of @var{model} using breadth-first search.
Equivalent to @samp{-m @var{model} -e breadth}.

@item -C @var{directory}
@itemx --compile=@var{directory}
Generate C code in @var{directory} for evaluating expressions and for
the low-level routines of the transition instance analysis algorithm
(@pxref{Instance Analysis}).  In order for this option to work, the
program must have been compiled with support for compiled expressions
enabled (@pxref{Compiling}).  Also, the compilation script
@file{@var{progname}-cso} must be found in the search path, where
@file{@var{progname}} is the name used to invoke the analyzer.  It is a
good idea to have a look at the compilation script, and to adjust the
variable definition @env{INCLUDES}, so that the required header files
can always be found.

You may also want to adjust the variables @env{DEFINES}, @env{CC},
@env{CFLAGS}, @env{LD} and @env{LDFLAGS} either in the script or in the
environment of the reachability analyzer.  For instance, if you are
using Bourne shell or one of its descendants, prefixing the command line
for invoking Maria with @samp{DEFINES="" CFLAGS=""} disables all
compiler optimizations for the model being analyzed.  This may be useful
if the optimization algorithms of the C compiler would consume too many
resources.

Applying this option should not affect the behaviour of the model
(i.e.@: it is a bug if it does).  When this option is used, evaluation
errors are reported in a slightly different way.  The interpreter
displays the valuation and expression that caused the first error in a
state; the compiled code displays the number of errors.  For performance
reasons, the generated code does not check for overflow errors when
adding items to multi-sets.

@item -c
@itemx --no-compile
The opposite of @samp{-C}.  Evaluate all expressions in the built-in
interpreter.  This is the default behavior.

@item -D @var{symbol}
@itemx --define=@var{symbol}
Define the preprocessor symbol @var{symbol}.  @xref{Conditions}.

@item -d @var{model}
@itemx --depth-first-search=@var{model}
Generate the reachability graph of @var{model} using depth-first search.
Equivalent to @samp{-m @var{model} -e depth}.

@item -E @var{interval}
@itemx --edges=@var{interval}
When generating the reachability graph, report the size of the graph
after every @var{interval} generated edges.

@item -e @var{string}
@itemx --execute=@var{string}
Execute @var{string}.  @xref{Maria Shell}.

@item -g @var{graphfile}
@itemx --graph=@var{graphfile}
Load a previously generated reachability graph from
@file{@var{graphfile}.rgh}.

@item -H @var{h}[,@var{f}[,@var{t}]]
@itemx --hashes=@var{h}[,@var{f}[,@var{t}]]
Configure the parameters for lossy verification (@samp{-P} or
@samp{-M}).  For @samp{-P}, allocate @var{t} universal hash functions
of @var{f} elements and corresponding hash tables of @var{h} bits
each.  For @samp{-M}, allocate a @var{f} bytes for all @var{h}
elements of the hash table.  The value @var{h} (and for @samp{-P},
also the value @var{f}) will be rounded up to suitable values.

@item -?
@itemx -h
@itemx --help
Print a summary of the command-line options to Maria and exit.

@item -I @var{directory}
@itemx --include=@var{directory}
Append @var{directory} to the list of directories searched for include
files.

@item -i @var{columns}
@itemx --width=@var{columns}
Set the right margin of the output to @var{columns}.  The default is 80.

@item -j @var{processes}
@itemx --jobs=@var{processes}
When checking safety properties (options @samp{-L}, @samp{-M} and
@samp{-P}), use this many worker processes to speed up the analysis on
a multiprocessor computer.  See also @samp{-k} and @samp{-Z}.  Note
that on @w{Digital UNIX}, this option may not work properly if the
model is generating successor states too fast (especially when using
the @samp{-C} option).

@item -k @var{port}[/@var{host}]
@itemx --connect=@var{port}[/@var{host}]
Distribute safety model checking (options @samp{-L}, @samp{-M} and
@samp{-P}) in a TCP/IP network.  For the server, only @var{port} is
specified as a 16-bit unsigned integer, usually between 1024 and
65535.  For the worker processes, @var{port}/@var{host} specifies the
port and the address of the server.  See also @samp{-j}.

All processes should use the same command line options, except that on
the server, the @samp{-k} switch takes only the @var{port} argument, and
the worker processes exit after executing the @samp{breadth} or
@samp{depth} command.  To gain best performance, start the server and
one client on the fastest computer of the network.

Note that when a computer arranges machine words in the big endian byte
order, all computers must be big endian and have the same word length.
Little endian computers interoperate regardless of their word lengths.

@item -L @var{model}
@itemx --lossless=@var{model}
Load @var{model} and prepare for analysing it by constructing a set of
reachable states in disk files.  See also @samp{-M}, @samp{-P},
@samp{-j} and @samp{-k}.

@item -m @var{model}
@itemx --model=@var{model}
Load @var{model} and clear its reachability graph.  See also @samp{-b}
and @samp{-d}.

@item -M @var{model}
@itemx --md5-compacted=@var{model}
Load @var{model} and prepare for analysing it by constructing an
overapproximation of the set of reachable states in the main memory
by using a technique called @dfn{hash compaction}.  See also @samp{-P},
@samp{-L}, @samp{-j} and @samp{-k}.

@item -N @var{c}@var{regexp}
@itemx --name=@var{c}@var{regexp}
Specify the names allowed in context @var{c} as the extended regular
expression @var{regexp}; @xref{Regular Expressions, , Regular
Expressions, grep, GNU GREP Manual}.  In order for this option to work,
the program must have been compiled with the POSIX regular expression
library enabled (@pxref{Compiling}).  The context is identified by the
first character of the parameter string; the succeeding characters
constitute the regular expression that allowed names must match:
@table @samp
@item P
place name
@item T
transition name
@item t
type name
@item e
name of enumeration constant
@item c
name of struct or union component
@item f
function name
@item p
function parameter name
@item v
transition variable name
@item i
iterator variable name
@end table

@item -n @var{c}@var{regexp}
@itemx --no-name=@var{c}@var{regexp}
Specify the names not allowed in context @var{c} as the extended regular
expression @var{regexp}.

If both @samp{-N} and and @samp{-n} are specified for a context @var{c},
then the allowing match takes precedence.  For instance, to require that
all user defined type names be terminated with @samp{_t}, specify
@samp{-nt -Nt'_t$'}.  The quotes in the latter parameter are required to
remove the special meaning from @samp{$} in the command line shell you
are probably using to invoke Maria.

@item -P @var{model}
@itemx --probabilistic=@var{model}
Load @var{model} and prepare for analysing it by constructing an
overapproximation of the set of reachable states in the main memory by
using a technique called @dfn{bitstate hashing}.  See also @samp{-M},
@samp{-L}, @samp{-j} and @samp{-k}.

@item -p @var{command}
@itemx --property-translator=@var{command}
Specify the command to use for translating property automata.  The
command should read a formula from the standard input and write a
corresponding automaton description to the standard output.  The
translator @file{lbt} (available separately) is compatible with this
option.

@item -q @var{limit}
@itemx --quantification-limit=@var{limit}
Prevent quantification (multi-set sum) of types having more than
@var{limit} possible values.  A limit of 0 disables the checks.

@item -R
@itemx --modular
Explore the state space in a modular way.  @xref{Subnets}.

@item -r
@itemx --no-modular
Consider only one state space.  This is the default.

@item -t @var{limit}
@itemx --tolerance=@var{limit}
Abort the analysis when @var{limit} non-fatal errors have been
reported.  A limit of 0, the default, allows an infinite number of
errors to occur.

@item -U @var{symbol}
@itemx --undefine=@var{symbol}
Undefine the preprocessor symbol @var{symbol}.  @xref{Conditions}.

@item -u [M][@var{f}[@var{outfile}]]
@itemx --unfold=[M][@var{f}[@var{outfile}]]
Unfold the net (optionally reducing it by constructing a
@dfn{coverable marking} (@samp{M})) and write it in format @var{f} to
@var{outfile}.  If @var{outfile} is not specified, dump the unfolded
net to the standard output.  Possible formats are @samp{m} (Maria
(human-readable), default), @samp{l} (LoLA), @samp{p} (PEP), and
@samp{r} (PROD).

When the PROD output is chosen, @var{outfile} must be specified and end
in @samp{.net}.  Since PROD has no low-level input format, the
transitions in the low-level net are grouped to equivalence classes
based on the input and output arc weights.  Each equivalence class is
folded to a high-level transition.  The translation makes use of tables
that are written to a separate file.  If @var{outfile} is
@file{@var{out}.net}, the tables are written to
@file{@var{out}.src/tables.c}.

@item -V
@itemx --version
Print the version number of Maria and exit.

@item -v
@itemx --verbose
Display verbose information on different stages of the analysis.

@item -W
@itemx --warnings
Enable warnings about suspicious net constructs.  This is the default
behavior.

@item -w
@itemx --no-warnings
The opposite of @samp{-W}.  Disable all warnings.

@item -x @var{numberbase}
@itemx --radix=@var{numberbase}
Specify the number base for diagnostic output.  Allowed values for
@var{numberbase} are @samp{oct}, @samp{octal}, @samp{8}, @samp{hex},
@samp{hexadecimal}, @samp{16}, @samp{dec}, @samp{decimal} and @samp{10}.
The default is to use decimal numbers.

@item -Y
@itemx --compress-hidden
Reduce the set of reachable states by not storing the successor states
of transitions instances for which a @samp{hide} condition holds.  The
hidden successors are stored to a separate state set.  This option may
save memory (@samp{-L} or @samp{-m}) or reduce the probability that
states are omitted (@samp{-M} or @samp{-P}), and it may improve the
efficiency of parallel analysis (@samp{-j} or @samp{-k}), but it may
also considerably increase the processor time requirement.  The option
also works with liveness model checking, but there is no guarantee
that the truth values of liveness properties remain unchanged.  This
option can be combined with @samp{-Z}.

@item -y
@itemx --no-compress-hidden
The opposite of @samp{-Y}.  This is the default behavior.

@item -Z
@itemx --compress-paths
Reduce the set of reachable states by not storing intermediate states
that have at most one successor.  This option may save memory
(@samp{-L} or @samp{-m}) or reduce the probability that states are
omitted (@samp{-M} or @samp{-P}), and it may improve the efficiency of
parallel analysis (@samp{-j} or @samp{-k}), but it may also
considerably increase the processor time requirement.  The option also
works with liveness model checking, but there is no guarantee that the
truth values of liveness properties remain unchanged.  This option can
be combined with @samp{-Y}.

@item -z
@itemx --no-compress-paths
The opposite of @samp{-Z}.  This is the default behavior.
@end table

@node Maria Option Cross Key, , Maria Options, Invoking Maria
@subsection Option Cross Key

Here is a list of options, alphabetized by long option, to help you find
the corresponding short option.

@tex
\def\leaderfill{\leaders\hbox to 1em{\hss.\hss}\hfill}

{\tt
\line{ --array-limit=@var{limit} \leaderfill -a}
\line{ --breadth-first-search=@var{model} \leaderfill -b}
\line{ --compile=@var{directory} \leaderfill -C}
\line{ --compress-hidden \leaderfill -Y}
\line{ --compress-paths \leaderfill -Z}
\line{ --connect=@var{port}[/@var{host}] \leaderfill -k}
\line{ --define=@var{symbol} \leaderfill -D}
\line{ --depth-first-search=@var{model} \leaderfill -d}
\line{ --edges=@var{interval} \leaderfill -E}
\line{ --execute=@var{string} \leaderfill -e}
\line{ --graph=@var{graphfile} \leaderfill -g}
\line{ --hashes=@var{h}[,@var{f}[,@var{t}]] \leaderfill -H}
\line{ --help \leaderfill -h}
\line{ --include=@var{directory} \leaderfill -I}
\line{ --jobs=@var{processes} \leaderfill -j}
\line{ --lossless=@var{model} \leaderfill -L}
\line{ --md5-compacted=@var{model} \leaderfill -M}
\line{ --model=@var{model} \leaderfill -m}
\line{ --modular \leaderfill -R}
\line{ --name=@var{c}@var{regexp} \leaderfill -N}
\line{ --no-compile \leaderfill -c}
\line{ --no-compress-hidden \leaderfill -y}
\line{ --no-compress-paths \leaderfill -z}
\line{ --no-modular \leaderfill -r}
\line{ --no-name=@var{c}@var{regexp} \leaderfill -n}
\line{ --no-warnings \leaderfill -w}
\line{ --probabilistic=@var{model} \leaderfill -P}
\line{ --property-translator=@var{command} \leaderfill -p}
\line{ --quantification-limit=@var{limit} \leaderfill -q}
\line{ --radix=@var{numberbase} \leaderfill -x}
\line{ --tolerance=@var{limit} \leaderfill -t}
\line{ --undefine=@var{symbol} \leaderfill -U}
\line{ --unfold=[M][@var{f}[@var{outfile}]] \leaderfill -u}
\line{ --verbose \leaderfill -v}
\line{ --version \leaderfill -V}
\line{ --warnings \leaderfill -W}
\line{ --width=@var{columns} \leaderfill -i}
}
@end tex

@ifnottex
@example
--array-limit=@var{limit}                     -a @var{limit}
--breadth-first-search=@var{model}            -b @var{model}
--compile=@var{directory}                     -C @var{directory}
--compress-hidden                       -Y
--compress-paths                        -Z
--connect=@var{port}[/@var{host}]                   -k @var{port}[/@var{host}]
--define=@var{symbol}                         -D @var{symbol}
--depth-first-search=@var{model}              -d @var{model}
--edges=@var{interval}                        -E @var{interval}
--execute=@var{string}                        -e @var{string}
--graph=@var{graphfile}                       -g @var{graphfile}
--hashes=@var{h}[,@var{f}[,@var{t}]]                      -H @var{h}[,@var{f}[,@var{t}]]
--help                                  -h
--include=@var{directory}                     -I @var{directory}
--jobs=@var{processes}                        -j @var{processes}
--lossless=@var{model}                        -L @var{model}
--md5-compacted=@var{model}                   -M @var{model}
--model=@var{model}                           -m @var{model}
--modular                               -R
--name=@var{c}@var{regexp}                          -N @var{c}@var{regexp}
--no-compile                            -c
--no-compress-hidden                    -y
--no-compress-paths                     -z
--no-modular                            -r
--no-name=@var{c}@var{regexp}                       -n @var{c}@var{regexp}
--no-warnings                           -w
--probabilistic=@var{model}                   -P @var{model}
--property-translator=@var{command}           -p @var{command}
--quantification-limit=@var{limit}            -q @var{limit}
--radix=@var{numberbase}                      -x @var{numberbase}
--tolerance=@var{limit}                       -t @var{limit}
--undefine=@var{symbol}                       -U @var{symbol}
--unfold=[M][@var{f}[@var{outfile}]]                -u [M][@var{f}[@var{outfile}]]
--verbose                               -v
--version                               -V
--warnings                              -W
--width=@var{columns}                         -i @var{columns}
@end example
@end ifnottex

@node Maria Shell, Emacs, Invoking Maria, Analysis
@section The Maria Shell
@cindex reachability graph, examining

The Maria shell can be used to interactively examine the reachability
graph of a model or to check temporal properties in it.

@menu
* Line Editor::                 The command line editor
* Query Language::              The query language
* Quirks::                      Some considerations on the preprocessor
* Visual::                      Visualizing the results
@end menu

@node Line Editor, Query Language, Maria Shell, Maria Shell
@subsection The Line Editor
@cindex command line interface

The Maria shell has a command-line driven user interface.  When support
for the GNU Readline library has been enabled at compile time
(@pxref{Compiling}), using the command line is pretty comfortable.
Without Readline, you have to cope with the system's default line
editor, which certainly lacks command line history and completion
features.

When invoked, Maria will greet you with the prompt @samp{@@0$}, where
@samp{0} is the number of the current state, or @samp{$} if no model has
been loaded.  The initial state always has the number zero.  Command
lines may be split over multiple physical lines.  When there is an
unbalanced single or double quote or a multi-line (C-style) comment, or
when the line ends in a backslash @samp{\}, Maria will present the
continuation prompt @samp{@@@var{n}>}.  In case of a typing mistake,
@kbd{EOF} will tell Maria to abort reading continuation lines.

@menu
* Name Completion::             Features of the Readline library
@end menu

@node Name Completion, , Line Editor, Line Editor
@subsubsection Name Completion
@cindex Readline
@cindex completion of names
@cindex names, completion of

This is by no means a complete list of Readline features.  @xref{Command
Line Editing, , Command Line Editing, readline, GNU Readline Library},
if you are not familiar with Readline.

One of the nicest features of the Readline library is context-sensitive
completion of names.  The Maria shell completes names of data types
(immediately following the @samp{is} keyword), places (following
@samp{place}), transitions (@samp{trans}), and keywords.  Let us now
assume that you have generated the reachability graph for the dining
philosopher example (@pxref{Dining}).  The following example illustrates
how the context-sensitive completion of names works.

@example
@b{$}graph dining@kbd{RET}
@b{@@0$}pa@kbd{TAB}
@b{@@0$}pa@b{th }@@29 pl@kbd{TAB}
@b{@@0$}path @@29 pl@b{ace "}f@kbd{TAB}
@b{@@0$}path @@29 place "f@b{ork" }eq@kbd{TAB}
@b{@@0$}path @@29 place "fork" eq@b{uals }em@kbd{TAB}
@b{@@0$}path @@29 place "fork" equals em@b{pty }@kbd{RET}
@b{shortest path from condition to @@29 (2 nodes):}
@group
@b{@@74:state (}
@b{ state:}
@b{  @{3,thinking@},@{1,hungry@},@{4,hungry@},@{5,hungry@},@{2,eating@}}
@b{)}
@b{4 predecessors}
@b{1 successor}
@end group
@group
@b{transition finish->@@29}
@b{<}
@b{ p:2}
@b{>}
@end group
@group
@b{@@29:state (}
@b{ fork:}
@b{  2,3}
@b{ state:}
@b{  @{2,thinking@},@{3,thinking@},@{1,hungry@},@{4,hungry@},@{5,hungry@}}
@b{)}
@b{4 predecessors}
@b{3 successors}
@end group
@b{@@0$}exit @kbd{RET}
@end example

Unfortunately backslash-quoted names cannot be completed.  This is due
to a limitation of the Readline library, which will only call the
dequoting function if its built-in filename completion function is being
used.  This is why the keyword completer adds a double quotation mark
after keywords that are likely to be followed by a name.

@node Query Language, Quirks, Line Editor, Maria Shell
@subsection The Query Language
@cindex query language

Maria uses a script language in which statements are separated by
semicolons (@samp{;}).  @xref{Separating Statements}, for other
considerations.

There are commands for moving around in the graph and for evaluating
formulae in different graph nodes.  Maria shell commands are reserved
words only in the beginning of a statement: there is no need to quote a
place name @samp{exit}, for instance.

@menu
* Graph and Model::     Loading a reachability graph or model
* Dump::                Displaying a model
* Unfold::              Unfolding a model
* LSTS::                Exporting a Labelled State Transition System
* Dumpgraph::           Exporting a reachability graph
* Depth and Breadth::   Exhaustive reachability analysis
* Eval::                Evaluating expressions and formulae
* Show::                Displaying markings
* Hide::                Omitting places from markings
* Subnet::              Selecting the active subnet
* Succ::                Listing successor nodes
* Pred::                Listing predecessor nodes
* Go::                  Moving between nodes
* Trans::               Defining and firing an anonymous transition
* Function::            Defining functions
* Strong::              Strongly connected components
* Path::                Shortest paths
* Misc::                Miscellanous commands
* Exit::                Exiting
@end menu

@node Graph and Model, Dump, Query Language, Query Language
@subsubsection Loading a Model
@findex graph@r{, query language}
@findex model@r{, query language}

@example
@group
statement:
        GRAPH name
        |
        MODEL name
@end group
@end example

The @samp{graph} command loads a previously generated reachability
graph.  The supplied name must exclude the @samp{.rgh} suffix.

The @samp{model} command loads a Petri net model and initializes its
reachability graph.  Be careful with this command; it will delete a
previously generated reachability graph of the model, if one exists in
the current directory.

@node Dump, Unfold, Graph and Model, Query Language
@subsubsection Displaying a Model
@findex visual@r{, query language}
@findex dump@r{, query language}

@example
@group
statement:
        [ VISUAL ] DUMP
@end group
@end example

The @samp{dump} command displays the syntax tree of the current model in
the modelling language.  When the @samp{visual} prefix is present, the
Petri net will be displayed graphically (@pxref{Visual}).  This command
may be useful when trying to find out how Maria expands multi-set
summations (@pxref{Multi-Sets}) or quantifications (@pxref{Logic}).

@node Unfold, LSTS, Dump, Query Language
@subsubsection Unfolding a Model
@findex unfold@r{, query language}

@example
@group
statement:
        UNFOLD [ name ]
@end group
@end example

The @samp{unfold} command unfolds the currently loaded Petri net model.
The argument takes the same format as the command line option @samp{-u}
(@pxref{Maria Options}).

@node LSTS, Dumpgraph, Unfold, Query Language
@subsubsection Exporting a Labelled State Transition System
@findex lsts@r{, query language}

@example
@group
statement:
        LSTS [ name ]
@end group
@end example

Maria is able to export the reachability graph or parts thereof as a
labelled state transition system.  The @samp{lsts} command specifies a
file name for an LSTS.  When the command is invoked without a file name,
any currently open LSTS files are closed and the function cancelled.

The @samp{lsts} command affects exhaustive analysis (@pxref{Depth and
Breadth}), non-visual path queries (@pxref{Path}) and the representation
of counterexample paths of liveness properties (@pxref{Liveness}).

In exhaustive analysis, the command should be invoked before any states
have been explored, right after the model has been loaded.  When using
the path commands, the @samp{lsts} command should be issued right before
generating the counterexample.  These measures are necessary, because
for efficiency reasons, the @samp{lsts} command has been implemented so
that all generated states and arcs are exported to LSTS files if ones
have been opened.  The path query commands export results to LSTS if the
files are open, and close the files immediately after that.  It is
impossible to combine several query results into one exported LSTS.

The LSTS output can be controlled by hiding variables or transition
instances (@pxref{Transitions}) and by specifying state propositions
(@pxref{Propositions}).

@node Dumpgraph, Depth and Breadth, LSTS, Query Language
@subsubsection Exporting the Reachability Graph
@findex dumpgraph@r{, query language}
@findex visual@r{, query language}

@example
@group
statement:
        [ VISUAL ] DUMPGRAPH
@end group
@end example

The command @samp{dumpgraph} exports the portion of the reachability
graph that has been generated so far.  When the @samp{visual} prefix
is present, the reachability graph will be displayed graphically
(@pxref{Visual}).  @xref{Depth and Breadth}, for information on
generating the reachability graph.

@node Depth and Breadth, Eval, Dumpgraph, Query Language
@subsubsection Exhaustive Analysis
@findex breadth@r{, query language}
@findex depth@r{, query language}
@findex visual@r{, query language}

@example
@group
statement:
        BREADTH [ STATE ]
        |
        DEPTH [ STATE ]
@end group
@end example

The commands @samp{breadth} and @samp{depth} generate all states that
are reachable either from the current state or from a specified state.
This exhaustive search will only be performed if the successors of the
state have not already been generated.

@example
@group
@b{$}model "dining.pn"
@b{@@0$}breadth
@b{"dining.pn": 82 states (3..6 bytes), 265 arcs}
@end group
@end example

At the end of the search, the numbers of generated states and events are
reported.  The byte range indicates the minimum and maximum lengths of
encoded state representations.  This number is affected by modelling
techniques, such as the use of capacity constraints and invariants
(@pxref{Places}), and by not folding places unnecessarily.  For this
particular model (@pxref{Dining}), the maximum length of encoded states
can be reduced from 6 to 4 bytes by splitting the place that holds pairs
of philosophers and their states (thinking, hungry, eating) to three
places, holding a set of those philosophers that are in the state, and
by defining an invariant initialisation expression for the "thinking"
place.

The @samp{breadth} and @samp{depth} commands can be also used in
purely state-based safety verification (command-line options
@samp{-L}, @samp{-M} and @samp{-P}), without generating a reachability
graph.  If either command is given a safety LTL formula as an
argument, the model contained in the file will be verified against the
property.  When the command is preceded by a @samp{visual} keyword,
any path that violates the formula will be displayed graphically
(@pxref{Visual}).

@example
@group
statement:
        [ VISUAL ] BREADTH formula
        |
        [ VISUAL ] DEPTH formula
@end group
@end example

@node Eval, Show, Depth and Breadth, Query Language
@subsubsection Evaluating Expressions and Formulae
@cindex expressions, evaluating
@cindex model checking
@findex visual@r{, query language}
@findex eval@r{, query language}

@example
@group
statement:
        [ VISUAL ] [ EVAL ] [ STATE ] formula
@end group
@end example

Expressions and formulae can be evaluated either in the current state or
in a given state.

@example
@group
@b{@@0$}place fork
@b{fork:}
@b{ 1,2,3,4,5}
@end group
@group
@b{@@0$}eval @@4 place fork
@b{fork:}
@b{ 1,2,3,5}
@end group
@end example

When the @samp{visual} keyword is present and a temporal formula is
being evaluated, a path violating the formula is displayed graphically
(@pxref{Visual}).

@node Show, Hide, Eval, Query Language
@subsubsection Displaying Markings
@findex visual@r{, query language}
@findex show@r{, query language}

With the @samp{show} command it is possible to view the marking of a
node in the reachability graph.  When a node is not specified, the
current node will be shown.

The command can also be used to view the nodes in a strongly connected
component (@pxref{Strong}).  It is possible to specify a Boolean
condition to select a subset of the states in the strongly connected
component to be displayed.

@example
@group
statement:
        [ VISUAL ] SHOW [ STATE ]
        |
        [ VISUAL ] [ SHOW ] COMP [ expr ]
        |
        [ VISUAL ] SHOW STATE STATE ( STATE )*
@end group
@end example

When the keyword @samp{show} is followed by a sequence of at least two
state numbers, Maria displays the sequence of states in the same way as
the @samp{path} command does (@pxref{Path}).  This command is most
useful with the @samp{visual} prefix, since it can be used for
visualizing a previously reported path.

@example
@group
@b{@@0$}show @@4
@b{@@4:state (}
@b{ fork:}
@b{  1,2,3,5}
@b{ state:}
@b{  @{1,thinking@},@{2,thinking@},@{3,thinking@},@{5,thinking@},@{4,hungry@}}
@b{)}
@b{4 predecessors}
@b{5 successors}
@end group
@end example

@node Hide, Subnet, Show, Query Language
@subsubsection Excluding Places from Displayed Markings
@findex hide@r{, query language}

Petri net models often contain a large number of places whose contents
are of less significance when investigating a particular property of the
model.  The @samp{hide} command controls which places are displayed by
the @samp{show} command (@pxref{Show}) and in the graphical interface
(@pxref{Visual}).

@example
@group
statement:
        HIDE [ '!' ] [ [ PLACE ] name ( ',' [ PLACE ] name )* ]
@end group
@end example

When followed by an exclamation point, the command selects places to be
shown (instead of to be hidden).  An empty list of place names selects
all places.  Typically, one can issue the command @samp{hide} followed
by @samp{hide ! @var{placename}} for each place to be shown.

@node Subnet, Succ, Hide, Query Language
@subsubsection Selecting the Active Subnet
@findex subnet@r{, query language}
@cindex modules

When the model contains subnets (@pxref{Subnet}) and Maria has been
told to generate a reachability graph and apply modular analysis
(@pxref{Invoking Maria}), the @samp{subnet} command can be used for
navigating in the state spaces of the modules.

The @samp{subnet} command can be used for navigating in the hierarchy
tree in a similar way as the @samp{cd} command navigates in the
directory tree.  It takes a sequence of subnet identifiers separated
by slashes.  The string @samp{..} denotes the parent net.

When invoked without parameters, @samp{subnet} selects the root net,
which represents the whole system.  If the parameter string starts
with a slash, the tree is selected relative to the root net.
Otherwise, it is selected relative to the currently selected net.

Nets that have been given a name (@pxref{Subnet}) can be referred to
by that name.  All nets can be referred to by their index number in
the parent net.  The subnets are numbered starting from zero.

@example
@group
statement:
        SUBNET [ [ netid ] ( '/'+ netid )* '/'* ]
@end group
@group
netid:  '..' | name | number
@end group
@end example

@node Succ, Pred, Subnet, Query Language
@subsubsection Listing Successor Nodes
@findex visual@r{, query language}
@findex succ@r{, query language}
@cindex simulating

The @samp{succ} command lists all successors of a state, or possible
events in the state.  If no successors have been generated for the
state, they will be generated on demand.  This makes Maria suitable for
simulating or debugging a Petri Net model without generating the
complete reachability graph: to create the interesting part of the
reachability graph, one can keep listing the successors of the states he
is interested in.

The command can also be used to view the successors of a strongly
connected component (@pxref{Strong}).

@example
@group
statement:
        [ VISUAL ] SUCC [ '!' ] [ STATE ]
        |
        [ VISUAL ] SUCC COMP
@end group
@end example

When the @samp{visual} keyword is present, the successor states or
components are displayed graphically (@pxref{Visual}).

When the @samp{succ} keyword is followed by an exclamation point
(@samp{!}), Maria will follow the chain of successor states until a
state with several successors is encountered.

@example
@group
@b{@@0$}succ
@b{transition left->@@1}
@b{<}
@b{ p:1}
@b{>}
@end group
@group
@b{transition left->@@2}
@b{<}
@b{ p:2}
@b{>}
@end group
@group
@b{transition left->@@3}
@b{<}
@b{ p:3}
@b{>}
@end group
@group
@b{transition left->@@4}
@b{<}
@b{ p:4}
@b{>}
@end group
@group
@b{transition left->@@5}
@b{<}
@b{ p:5}
@b{>}
@end group
@end example

@node Pred, Go, Succ, Query Language
@subsubsection Listing Predecessor Nodes
@findex visual@r{, query language}
@findex pred@r{, query language}

The @samp{pred} command lists all the generated predecessors of a state,
or all events leading to the state.

The command can also be used to view the predecessors of a strongly
connected component (@pxref{Strong}).

@example
@group
statement:
        [ VISUAL ] PRED [ '!' ] [ STATE ]
        |
        [ VISUAL ] PRED COMP
@end group
@end example

When the @samp{visual} keyword is present, the predecessor states or
components are displayed graphically (@pxref{Visual}).

When the @samp{pred} keyword is followed by an exclamation point
(@samp{!}), Maria will follow the chain of predecessor states until a
state with several predecessors is encountered.

@example
@group
@b{@@0$}pred
@b{transition finish<-@@20}
@b{<}
@b{ p:5}
@b{>}
@end group
@group
@b{transition finish<-@@18}
@b{<}
@b{ p:4}
@b{>}
@end group
@group
@b{transition finish<-@@15}
@b{<}
@b{ p:3}
@b{>}
@end group
@group
@b{transition finish<-@@11}
@b{<}
@b{ p:2}
@b{>}
@end group
@group
@b{transition finish<-@@6}
@b{<}
@b{ p:1}
@b{>}
@end group
@end example

@node Go, Trans, Pred, Query Language
@subsubsection Moving in the Graph
@findex go@r{, query language}

Moving from a state to another is as simple as entering the state
number.  To make scripts more readable, you may also use the @samp{go}
keyword.

@example
@group
statement:
        [ GO ] STATE
@end group
@end example

@example
@group
@b{@@0$}@@4
@b{@@4$}go @@0
@b{@@0$}
@end group
@end example

@node Trans, Function, Go, Query Language
@subsubsection Anonymous Transitions
@findex trans@r{, query language}

Sometimes, when modelling a complex system, it may be useful to
specify a different initial state as a starting point for the
analysis.  For instance, one might want to slightly modify the marking
of an erroneous state to see how the analysis would proceed from
there.

In Maria, new states can be computed by entering an anonymous
transition that will be evaluated in a specified state, or in the
current state if no state is specified.  No arcs will be added to the
reachability graph.  The generated states will be displayed either
textually or graphically.

@example
@group
statement:
        [ VISUAL ] [ STATE ] TRANS atrans*
@end group
@group
atrans:
        '@{' [ avar_expr ( delim avar_expr )* [ delim ] ] '@}'
        |
        IN trans_places
        |
        OUT trans_places
        |
        GATE expr ( ',' expr )*
@end group
@group
avar_expr:
        typereference name
        |
        typereference name '!' [ '(' expr ')' ]
@end group
@end example

@example
@group
@b{@@0$}trans in @{ place fork: 1 @} out @{ place fork: 2 @}
@b{@@82:unprocessed state (}
@b{ fork:}
@b{  2#2,3,4,5}
@b{ state:}
@b{  @{1,thinking@},@{2,thinking@},@{3,thinking@},@{4,thinking@},@{5,thinking@}}
@b{)}
@b{@@0$}
@end group
@end example

@node Function, Strong, Trans, Query Language
@subsubsection Defining Functions
@cindex functions, defining
@findex function@r{, query language}

All the functions defined in the Petri Net are available in the query
tool.  It is also possible to define additional functions by using the
@samp{function} keyword.

@example
@group
statement:
        FUNCTION function
@end group
@end example

@example
@group
@b{@@0$}function bool assert (bool f) f || fatal
@b{@@0$}assert (false);
@b{<fatalExpression:}
@b{  fatal}
@b{>}
@end group
@end example

If there are many function definitions, it is advisable to write them in
a Maria command file, e.g.@: @file{dining}:

@example
@group
#!@var{/usr/local/bin/maria}
graph dining;
function bool assert (bool f) f || fatal;
@end group
@end example

@noindent
The definitions can be loaded in at least three different ways:

@example
@group
@b{$}maria dining
@b{@@0$}exit
@end group
@group
@b{$}./dining #@r{the script must be executable}
@b{@@0$}exit
@end group
@group
@b{$}maria
@b{$}#include "dining"
@end group
@end example

@node Strong, Path, Function, Query Language
@subsubsection Strongly Connected Components
@findex visual@r{, query language}
@findex strong@r{, query language}
@findex terminal@r{, query language}
@findex components@r{, query language}
@cindex strongly connected components
@cindex trivial component
@cindex terminal component

A @dfn{strongly connected component} of a directed graph (e.g.@: a
reachability graph) is a set of nodes that are reachable from each other
by following the arcs.  If the reachability graph of a model has only
one strongly connected component, it is guaranteed to be free of
deadlocks, since the initial state is reachable from all states.

A strongly connected component, or a node of a @dfn{component graph},
may be @dfn{trivial}, meaning that it contains only one node of the
underlying graph.  A @dfn{terminal component} does not have any
successors.

Maria computes the strongly connected components by starting from a
specified state (by default, the current state) and considering a
transitive closure of its generated successors in the reachability
graph.  It is possible to limit the transitive closure by specifying a
condition.  States for which the condition does not evaluate to
@samp{true} are ignored by the search algorithm.

Once the component graph has been generated, it is possible to list all
its non-trivial terminal components, or all components.  Also the
@samp{show}, @samp{succ} and @samp{prev} commands can be used to examine
the component graph.  The @samp{visual} keyword selects graphical
display (@pxref{Visual}).

@example
@group
statement:
        STRONG [ STATE ] [ expr ]
        |
        TERMINAL
        |
        [ VISUAL ] COMPONENTS
        |
@end group
@group
        [ VISUAL ] [ SHOW ] COMP [ expr ]
        |
        [ VISUAL ] ( SUCC | PRED ) COMP
@end group
@end example

@example
@group
@b{@@0$}strong
@b{dining: 82 states (3..6 bytes), 265 arcs, 2 components, 1
 terminal component}
@b{@@0$}@@@@0
@b{terminal trivial strongly connected component @@@@0: @@71}
@b{@@0$}pred @@@@0
@b{@@@@1}
@end group
@end example

Maria deploys Tarjan's algorithm for computing strongly connected
components.  The algorithm was implemented in Prod by Vesa Hirvisalo and
initially ported to Maria by Emil Falck.  His port was rewritten by
Marko M@"akel@"a to optimize memory usage.  The implementation requires
two bits for each node in the reachability graph, and one search stack
whose length is limited by the length of the longest cycle or acyclic
path in the generated reachability graph.  Everything else is managed in
disk files.

@node Path, Misc, Strong, Query Language
@subsubsection Shortest Paths
@findex visual@r{, query language}
@findex path@r{, query language}

The @samp{path} command lets one to find out the shortest path between a
specific state and a set of states.

@example
@group
statement:
        [ VISUAL ] PATH ( STATE | COMP | expr ) [ STATE ] [ ',' expr ]
        |
        [ VISUAL ] PATH STATE ( COMP | expr ) [ ',' expr ]
@end group
@end example

The command takes up to three arguments: the target state, the source
state, and an optional condition that all states on the path must
fulfill.  If the source state is omitted, the command finds out the
shortest path to the given target state.  Either the source or the
target state must be specified; the other end of the path may be
identified with a state formula or with a strongly connected component
number.

When the @samp{visual} keyword is present, the path is displayed
graphically (@pxref{Visual}).

@example
@b{@@0$}path @@6
@b{shortest path from @@0 to @@6 (3 nodes):}
@group
@b{@@0:state (}
@b{ fork:}
@b{  1,2,3,4,5}
@b{ state:}
@b{  @{1,thinking@},@{2,thinking@},@{3,thinking@},@{4,thinking@},@{5,thinking@}}
@b{)}
@b{5 predecessors}
@b{5 successors}
@end group
@group
@b{transition left->@@2}
@b{<}
@b{ p:2}
@b{>}
@end group
@group
@b{@@2:state (}
@b{ fork:}
@b{  1,3,4,5}
@b{ state:}
@b{  @{1,thinking@},@{3,thinking@},@{4,thinking@},@{5,thinking@},@{2,hungry@}}
@b{)}
@b{4 predecessors}
@b{5 successors}
@end group
@group
@b{transition left->@@6}
@b{<}
@b{ p:1}
@b{>}
@end group
@group
@b{@@6:state (}
@b{ fork:}
@b{  3,4,5}
@b{ state:}
@b{  @{3,thinking@},@{4,thinking@},@{5,thinking@},@{1,hungry@},@{2,hungry@}}
@b{)}
@b{4 predecessors}
@b{4 successors}
@end group
@end example

A third variant of the @samp{path} command finds the shortest path from
the current state to a loop.  In order to avoid an ambiguity in the
grammar, the loop must consist of at least three states.

@example
@group
statement:
        [ VISUAL ] PATH STATE STATE STATE ( STATE )* [ ',' expr ]
@end group
@end example

Maria does not check whether the given states really form a loop; it
just finds the shortest path to any of the specified states so that the
optional condition holds in all states along the path.  When the path
enters a state that is not the first (and last) state specified, the
loop is shifted.  The result is an acyclic path leading to a cycle,
resembling the shape of the number 6.

@node Misc, Exit, Path, Query Language
@subsubsection Miscellanous Commands
@findex help@r{, query language}
@findex stats@r{, query language}
@findex time@r{, query language}
@findex cd@r{, query language}
@findex translator@r{, query language}
@findex compiledir@r{, query language}
@findex log@r{, query language}
@findex prompt@r{, query language}

The @samp{help} command displays a short list of all commands.  The
@samp{stats} command displays some statistical information of the graph
being analyzed.  The @samp{time} command displays timing statistics
since the last invocation of the @samp{time} command, or since the time
when the analyzer was started.

The @samp{cd} command can be used to switch the current
directory.  Without a parameter, it tries to switch to the directory the
environment variable @env{HOME} expands to.  The @samp{translator}
command is used to specify the program for translating temporal logic
formulae into property automata.  When the command is invoked without
arguments, the verification of temporal formulae is disabled.

In order for the @samp{compiledir} command to work, Maria must have been
compiled with support for compiled expressions enabled
(@pxref{Compiling}).  This command specifies the directory that will be
used for generating executable code from the model.  Invoking the
command without arguments disables the code generator.

The @samp{log} command allows the textual output of query language
commands to be redirected to a file, or to the standard error stream
when no file name is specified to the command.

The @samp{prompt} command may be useful when Maria is executed as a
subprocess.  When the command is invoked with a non-null character
constant argument, this character will be echoed on its own line
before the command prompt is shown.  The plain @samp{prompt} command
disables this feature again.

@example
@group
        HELP
        |
@end group
@group
        STATS
        |
@end group
@group
        TIME
        |
@end group
@group
        CD [ name ]
        |
@end group
@group
        TRANSLATOR [ name ]
        |
@end group
@group
        COMPILEDIR [ name ]
        |
@end group
@group
        LOG [ name ]
	|
@end group
@group
        PROMPT [ 'c' ]
@end group
@end example

@example
@group
@b{@@0$}stats
@b{dining: 82 states (3..4 bytes), 265 arcs}
@end group
@end example

@node Exit, , Misc, Query Language
@subsubsection Exiting
@findex exit@r{, query language}

The query tool can be exited either by issuing the command @samp{exit}
or by typing the end-of-file character @kbd{EOF} at the command prompt.

@node Quirks, Visual, Query Language, Maria Shell
@subsection Some Quirks with the Query Language

Due to the way the query language and the preprocessor
(@pxref{Preprocessor}) have been implemented, there are some things that
are not obvious for the novice user.

@menu
* Separating Statements::       Why is a semicolon mandatory here?
* Conditional Processing::      Using #ifdef on the command line
@end menu

@node Separating Statements, Conditional Processing, Quirks, Quirks
@subsubsection Separating Statements

Maria uses a script language in which statements are separated by
semicolons (@samp{;}).  The separator is optional at the end of input.
In the interactive mode, every logical line is parsed separately and
semicolons are only required when issuing multiple commands on one
command line.  In script files, semicolons are mandatory between the
statements.  Consider the following example:

@example
@group
#!@var{/usr/local/bin/maria}
graph dining;
function bool eval () false;
eval;
eval
@end group
@end example

@noindent
This example will evaluate the function twice.  If the semicolon was
omitted, the function would be evaluated only once, since @samp{eval}
would be treated as a keyword in that case.

@node Conditional Processing, , Separating Statements, Quirks
@subsubsection Conditional Processing in the Editor
@cindex conditional processing, interactively

The line editor of Maria performs simple lexical analysis to find out
whether the line entered is complete.  For instance, if the line
contains an unbalanced amount of quotes, a continuation prompt will be
presented and further lines will be read until all quotes and multi-line
comments are balanced or the entry is aborted by typing @kbd{EOF} at the
beginning of a continuation line.

However, preprocessor directives for conditional processing are not
detected by the command line interpreter.  In case you want to enter
conditional statements (which must span several physical lines)
interactively, you must enter the physical lines as one logical line by
quoting all newline characters but the last one.  This can be achieved
on many systems by typing @kbd{C-v C-j}.

@node Visual, , Quirks, Maria Shell
@subsection Visualizing Graphs and Paths
@findex visual@r{, query language}

Many commands in the query language can be preceded by the @samp{visual}
keyword.  When this keyword is present, the results of the command will
be displayed in a separate visualization process.  The visual variant
often displays more information, such as edge attributes (transition
names and valuations) in displayed paths.

@menu
* GraphViz::            The interface to the graph visualizer
* Visual Caveats::      Exceptional situations in visualization
@end menu

@node GraphViz, Visual Caveats, Visual, Visual
@subsubsection GraphViz, the Graph Visualizer
@cindex GraphViz
@cindex printing

In order for this option to work, a software package for drawing graphs
called Graphviz (@uref{http://www.graphviz.org}) must be installed.  The
@file{lefty} command, belonging to the package, must be in the search
path, and the script @file{dotty.lefty} must be located either in the
default @file{lefty} search path or in a directory specified in
@env{LEFTYPATH}.  Also, the visualization script
@file{@var{progname}-vis} must be found in the search path, where
@file{@var{progname}} is the name used to invoke the analyzer.

On the Microsoft Windows platform, Maria does not invoke GraphViz as a
subprocess.  Instead, it writes the visualization data to the file
@file{maria-vis.out} in the current directory.  This file must be
slightly edited before feeding it to the @file{dotty} or @file{dot}
programs of GraphViz.

The visualization program reacts to some keyboard and mouse commands.
Pressing the left or middle mouse button while the mouse pointer is
located on a graph node requests for the successors or predecessors of
the node to be generated.  Holding down the right mouse button brings up
a menu whose contents depends on whether the mouse pointer is located
above a node, an edge or somewhere else in the graph.  There exist
keyboard short-cuts for most menu entries.

The visualization program communicates fully asynchronously with Maria
via its standard input and output.  It reads commands and graph
descriptions from standard input and writes Maria commands to standard
output.  Maria is ready to read and execute these commands whenever it
is sitting in the command prompt waiting for input.

Maria uses two commands of the visualization program.  It issues the
@samp{new();} command followed by a graph description whenever a query
language command is preprended with a @samp{visual} keyword.  This
command causes a new graph to be displayed.  The @samp{add();} command
is issued whenever a query language command is prepended with several
@samp{visual} keywords.  This command causes the visualization program
to merge the immediately following graph description with the last graph
the user has interacted with.  The visualization program always issues
query language commands prepended with @samp{visual visual}, causing the
currently displayed graph to be extended.

If you want to access the visualization commands generated by Maria, you
can rename the @file{maria-vis} script and replace it with something
like the following script:

@example
@group
#!/bin/sh
tee @var{/tmp/maria-vis.out} | exec @var{maria-vis-orig} "$@@"
@end group
@end example

In order to print a visualized graph, you can save it to a file by
selecting a command in the graphical user interface, and then input this
file to the @file{dot} command.  Alternatively, you can use a script
like the above one and extract the graph descriptions from the
intercepted log file.  As the @file{dot} command does not directly
support the @w{DIN A4} paper size, you may want to try out one of the
following command lines:

@example
dot -Gsize=11.69,8.26 -Gcenter=1 -Gmargin=0 -Grotate=90 -Tps
dot -Gsize=8.26,11.69 -Gcenter=1 -Gmargin=0 -Tps
@end example

The former line is for horizontal layouts and the latter is for vertical
layouts.  You may want to add @samp{-Grankdir=LR} to force left-to-right
layouting of the graph instead of the default top-to-bottom.  The
attributes in the graph file override the command line switches.

Both command lines act as filters, reading the graph description from
standard input and writing the Postscript code to standard output.  The
Postscript can be printed directly as such, or embedded in a document,
since it follows the Encapsulated Postscript conventions.

@node Visual Caveats, , GraphViz, Visual
@subsubsection Known Bugs in the Visualizer

Graphical user interfaces are more challenging to program than plain
textual programs.  We have avoided most of the problems by choosing an
external tool that lays out directed graphs.  The GraphViz developer
team has been very responsive and nice towards us, even though it has
limited resources.

Two bugs that may not be fixed soon concern labels in the graph.  Some
GraphViz utilities fail if labels are longer than about one thousand
characters.  You can use the @samp{hide} command (@pxref{Hide}) to
shorten node labels.  Also backslash characters in labels may be handled
incorrectly.

There are also some known bugs in Maria.  Presently, Maria identifies
paths only by state numbers.  When a path is displayed graphically,
Maria displays all transitions between each neighboring state along the
path.

This treatment of transitions may be confusing especially when
displaying counterexample paths (@pxref{Liveness}), since Maria omits
the property automaton states from the counterexample.  Effectively, it
projects the product of the reachability graph and the property
automaton on the reachability graph.  If there are several enabled
actions between two states, or if fairness constraints are present, the
presented counterexample path may contain extraneous transitions.

@node Emacs, , Maria Shell, Analysis
@section Editing Petri Nets with GNU Emacs
@cindex Emacs

We recommend that you use @w{GNU Emacs} for editing Petri Net models.
There is an Emacs major mode for editing Maria Petri Nets.  Its main
features are context-sensitive indentation and syntax highlighting.  If
you are not familiar with these features of Emacs, it is recommended
that you read the Emacs tutorial (press @kbd{C-h t}, that is, first hold
down the @kbd{Control} key, press @kbd{h}, then release @kbd{Control}
and press @kbd{t}) and learn about these features from the on-line help
system of Emacs e.g.@: with the commands @kbd{C-h i} (@kbd{M-x info})
and @kbd{C-h a} (@kbd{M-x apropos-command}).

@menu
* pn-mode::                     Installing the Petri Net mode
* Highlighting::                Syntax highlighting
* Fine-Tuning::                 Other things to customize in Emacs
@end menu

@node pn-mode, Highlighting, Emacs, Emacs
@subsection Installing the Petri Net mode
@cindex Petri Net mode
@cindex indentation
@cindex syntax highlighting

The Petri Net mode @samp{pn-mode} has been written for @w{GNU Emacs},
versions 20.3 and 21.  It does not work in version 19.34, which lacks
@samp{cc-mode} and some features of @samp{font-lock-mode} the Petri
Net mode requires.

Installing the Petri Net mode is simple.  Just add the name of the
directory containing @file{pn-mode.el} to @var{load-path} and do
@samp{(require 'pn-mode)}.  To do this, you can add e.g.@: the following
lines to your @file{.emacs} file.

@lisp
@group
(cond ((>= emacs-major-version 20)
       (let ((pn-lisp-dir (expand-file-name "@var{~/elisp}")))
         (cond ((file-readable-p pn-lisp-dir)
                (add-to-list 'load-path pn-lisp-dir))
                (require 'pn-mode)
                (setq pn-font-lock-extra-types
                      '("token" "\\sw+_t")))))))
@end group
@end lisp

In this example, we also set the variable @var{pn-font-lock-extra-types}
so that the word @samp{token} and all words ending in @samp{_t} will be
treated as type names.

@node Highlighting, Fine-Tuning, pn-mode, Emacs
@subsection Syntax Highlighting
@cindex syntax highlighting

If you are not familiar with the current syntax highlighting features of
Emacs (@samp{font-lock-mode}), you should read the documentation (using
the Info system and maybe also the @kbd{C-h f} and @kbd{C-h v}
commands).

Adding the following declarations to your @file{.emacs} file will enable
maximum degree of syntax highlighting in all Emacs modes.  You may want
to consult the documentation of the variable
@var{font-lock-maximum-decoration} if you want to limit the degree of
highlighting in some modes.

@lisp
(global-font-lock-mode t)
(setq font-lock-maximum-decoration t)
(turn-on-font-lock)
@end lisp

@node Fine-Tuning, , Highlighting, Emacs
@subsection Customizing Emacs
@cindex Emacs, customizing

One of the most frequent problems of Emacs newcomers is how to convince
Emacs to use 8-bit characters, as in the character set standardized by
@w{ISO 8859-1}, also known as the Latin-1 alphabet.  The default 7-bit
character set will suffice for editing Petri Net models.  But since this
section is about fine-tuning, here is something for your @file{.emacs}
file:

@lisp
@group
(standard-display-european t)
(set-input-mode nil nil 'dummy)
(cond ((< emacs-major-version 20)
       (require 'iso-syntax))
      (t
       (setq default-enable-multibyte-characters nil)
       (set-language-environment "Latin-1")))
@end group
@end lisp

In the following you will see some more definitions from my
@file{.emacs} file.  Feel free to use any of them.  In order for
@samp{pn-mode} to automatically register the @file{.pn} extension with
@samp{speedbar}, the latter should be loaded first.

@lisp
(setq next-line-add-newlines nil);@r{no accidentally inserted empty lines}
(setq make-backup-files nil)     ;@r{unless you like the @samp{~} files}
(setq mouse-yank-at-point t)     ;@r{for more accurate yanking (pasting)}
(setq inhibit-startup-message t) ;@r{disable the startup message}
@group
(if (null window-system)
    (menu-bar-mode -1)           ;@r{hide the menu line in text mode}
  (if (>= emacs-major-version 20)
      (speedbar-frame-mode t)))  ;@r{enable speedbar, the navigator}
@end group
(setq visible-bell t)    ;@r{do not beep---flash instead}
(line-number-mode t)     ;@r{show line numbers in the mode line}
(column-number-mode t)   ;@r{show column numbers in the mode line}
(show-paren-mode t)      ;@r{highlight matching parentheses}
(auto-compression-mode t);@r{transparently (de)compress @samp{.gz} files}
@end lisp

@node Algorithms, Grammar, Analysis, Top
@chapter Algorithms used in Maria

@menu
* Unification::                 Finding enabled transition instances
* Model Checking::              Checking temporal properties
@end menu

@node Unification, Model Checking, Algorithms, Algorithms
@section The Unification Algorithm
@cindex unification

Enabled transition instances are sought in a process called
@dfn{unification}.

@menu
* Unification Concepts::        Concepts related to unification
* Quantification::              Expanding multi-set sums
* Binding::                     Matching concrete tokens with formal ones
* Lvalues::                     Finding assignment candidates
* Instance Analysis::           The core of the unification algorithm
@end menu

@node Unification Concepts, Quantification, Unification, Unification
@subsection Concepts
@cindex concepts, unification

There are some concepts related to the unification process that may be
somewhat unclear, even though you know the basics of high level Petri
Nets.

@table @dfn
@item input arc
An arc leading from a place to a transition, labelled with a multi-set
expression evaluating to the tokens that are to be removed from the place
when the transition fires
@item output arc
An arc leading from a transition to a place, labelled with a multi-set
expression evaluating to the tokens that are to be inserted to the place
when the transition fires
@item variable
A named and strictly typed entity that may be assigned a value
@item output variable
A variable occurring only on output arcs of a transition; the value will
be picked non-deterministically at the end of the unification process
@item input variable
A variable occurring on the input arcs of a transition
@item valuation
@itemx binding
A binding of values to variables
@item expression
A formula that evaluates to a value; expressions in net descriptions do
not contain temporal logic operators or other set operations than multi-set
summing
@item arc expression
A multi-set valued expression occurring on an input or output arc
@item gate
@itemx gate expression
A condition for the valuation of the input variables; if omitted, it is
treated as identically true
@item token
an entity having a value; moved between places by the firing of transitions
@item concrete token
a token contained in a place
@item abstract token
an item of an arc expression
@item lvalue
Left-hand-side value of an assignment; a data object (in our case, an
input variable) that is assigned to
@item rvalue
Right-hand-side value of an assignment, evaluating to the value that will
be assigned to the lvalue
@end table

@node Quantification, Binding, Unification Concepts, Unification
@subsection Expanding Quantifications
@cindex quantification, expanding

Arc expressions may contain multi-set sums (@pxref{Multi-Sets}) or
universal or existential quantification with fixed or variable bounds.
They are expanded at parsing time.  Consider the following net
description:

@example
@group
place p bool: false, true;
place r bool: 2#(2#false, true);
trans t in @{
  place p: p;
  place r: bool s: (s, bool t (p): s && t);
@};
@end group
@end example

@noindent
The arc expression is expanded as follows:
@example
@group
trans t in @{
  place p: p;
  place r: false, true, (p?3:0)#false, (p?1:0)#true;
@};
@end group
@end example

@node Binding, Lvalues, Quantification, Unification
@subsection Matching Concrete and Formal Tokens
@cindex tokens, formal and concrete
@cindex assignments

The Petri Net formalism does not have the concept of assignment as known
in programming languages.  Also, expressions may not have any
side-effects.  The only way a Petri system can change its state is
through the firing of an enabled transition.

Assignments in the high level Petri Net formalism are implicit.  In
order for a high-level transition to be enabled, its variables must be
bound to suitable values.  Values for input variables will be found by
matching concrete tokens in places with abstract ones on input arc
expressions.

For each abstract token with known multiplicity, all concrete tokens in
the input place that have not been associated with other abstract tokens
will be considered.  If the tokens are compatible (given the valuation
generated so far, each component of the abstract token evaluates to the
corresponding component of the concrete token or is undefined), a
quantity of the concrete token will be associated with the abstract
token.  For instance, if the place contains @samp{3#true,2#false} and
the abstract token is @samp{2#x}, the unification algorithm will
associate 2 of the 3 @samp{true} tokens or all the @samp{false} tokens
with the abstract token.

If the abstract token contains assignment candidates (@pxref{Lvalues}),
the valuation will be extended.  Continuing our example, the variable
@samp{x} in the abstract token @samp{2#x} is an lvalue, and it can be
assigned the corresponding value of the concrete token, in this case
@samp{true} or @samp{false}.

@node Lvalues, Instance Analysis, Binding, Unification
@subsection Finding Assignment Candidates
@cindex lvalue
@cindex assignments

Assignment candidates, or left-hand-side values of assignments
(@dfn{lvalues}), are expressions that can be assigned to.  In Maria,
they are variables or array variables indexed by a known index.  Lvalues
must occur either as such (an abstract token is an lvalue) or in
components of structured expressions.

For example, the abstract token @samp{42#@{x,@{y+1,z@},+t@}} has two
lvalues, the variables @samp{x} and @samp{z}.  The abstract token
@samp{x#y} has one lvalue, @samp{y}; the token cannot be matched with a
concrete one until the value of @samp{x} is known.  The token @samp{|x}
does not have any lvalues.

@node Instance Analysis, , Lvalues, Unification
@subsection Transition Instance Analysis
@cindex transitions, instance analysis
@cindex unification stack

A preprocessor sorts the input arcs of each transition in such a way
that they can be processed in one pass.  Static analysis finds out for
each input arc the set of variables that are assigned a value based on
the token assigned to the arc expression.

Tokens are assigned to input arcs by a depth-first search algorithm.  If
no variables are unified from an arc, the arc is "constant" under the
assignment gathered so far.  In this case, the corresponding input place
is searched for the token the arc evaluates to.  Otherwise, the arc is
matched with each token in the input place, one at a time, and the
assignment is augmented in such a way that evaluating the arc expression
under the augmented (but still incomplete) assignment can yield the
token picked from the input place.

In general, the less variables there are in the arc inscriptions and the
less tokens in the input places, the faster the instance analysis can be
completed.

@node Model Checking, , Unification, Algorithms
@section Model Checking Algorithms

The on-the-fly model checker in Maria verifies properties expressed in
temporal logic by computing a product of a property automaton (which
corresponds to a formula) and the reachability graph interpreted as an
automaton.

@menu
* Safety::                      Safety properties
* Liveness::                    Liveness properties
@end menu

@node Safety, Liveness, Model Checking, Model Checking
@subsection Checking Safety Properties
@cindex model checking, safety

Safety properties can be specified with @samp{deadlock} and
@samp{reject} conditions (@pxref{Assertions}), as well as with so-called
safe LTL formulae that can be translated to automata on finite words.
Also some built-in features of the modelling language, such as capacity
constraints, marking-dependent initialization expressions, and checks
for expression evaluation errors, can be viewed as safety checking.

While exploring the reachable state space, Maria reports all violations
of safety properties and may abort the analysis in case of a fatal
violation.

Safety properties can be verified without constructing a reachability
graph; it is sufficient to construct the set of reachable states.  The
command line options @samp{-M}, @samp{-P} and @samp{-L} are more
efficient than @samp{-m}, and the search can be distributed on
multiple processors.

@node Liveness, , Safety, Model Checking
@subsection Checking Liveness Properties
@cindex model checking, liveness

Currently, the @samp{eval} command (@pxref{Eval}) supports LTL formulae
on state properties.  It is possible to examine counterexamples (paths
violating the property being verified), and the algorithm respects both
weak and strong fairness conditions.

@node Grammar, Graph Files, Algorithms, Top
@appendix The Grammar
@cindex grammar, summary

This appendix presents the grammar of the Maria languages using a
Bison-like Backus@minus{}Naur Form (@pxref{Language and Grammar, ,
Languages and Context-Free Grammars, bison, The GNU Bison Manual}) with
the following extensions inspired by regular expressions
(@pxref{Patterns, , Patterns, flex, The Flex Manual}):

@enumerate
@item Square brackets (@samp{[]}) indicate optional symbols
@item Asterisk (@samp{*}) denotes any amount repetition (0 or more instances)
@item Parentheses (@samp{()}) are used for grouping grammar symbols
@end enumerate

@menu
* Terminal Symbols::            Terminal symbols used in the grammars

* Net Grammar::                 The net description language
* Query Grammar::               The query language
* Expression Grammar::          Formulae and Expressions
@end menu

@node Terminal Symbols, Net Grammar, Grammar, Grammar
@section Terminal Symbols

By convention, terminal symbols are written in all-uppercase letters or
as character strings enclosed in single quotation marks, and
non-terminal symbols are written in all-lowercase letters.  The
non-trivial terminal symbols used in the grammar are as follows.

@table @samp
@item NUMBER
decimal (@samp{[1-9][0-9]*}), octal (@samp{0[0-7]*})
or hexadecimal (@samp{0x[0-9a-fA-F]+})
@item CHARACTER
@samp{'@var{c}'}: @ref{Character Constants}
@item STATE
number of a state in the reachability graph:
@samp{@@[1-9][0-9]*}, @samp{@@0[0-7]*} or @samp{@@0x[0-9a-fA-F]+}
@item COMP
number of a strongly connected component of (part of) the reachability graph
@samp{@@@@[1-9][0-9]*}, @samp{@@@@0[0-7]*} or @samp{@@@@0x[0-9a-fA-F]+}
@item name
@samp{[a-zA-Z_][0-9a-zA-Z_]*|"@var{c}*"}: @ref{Identifiers}
@end table

@noindent
Reserved words are not listed in the above table.  For instance, the
symbol @samp{PLACE} stands for the keyword @samp{place}.

In addition, there are a few low-level grammar rules that are almost
like terminal symbols in their nature:
@example
delim:
        ','
        |
        ';'
@end example

@node Net Grammar, Type Grammar, Terminal Symbols, Grammar
@section The Net Description Language

@example
@group
net:
        ( netcomponent ';' )*
@end group
@group
netcomponent:
        type
        |
        function
        |
        place
        |
        transition
        |
        verify
        |
        fairness
        |
        proposition
        |
        subnet
@end group
@group
subnet:
        SUBNET [ name ] '@{' net '@}'
@end group
@end example

@menu
* Type Grammar::                Data type definitions
* Constraint Grammar::          Constraints of data types
* Function Grammar::            Function definitions
* Place Grammar::               Place definitions
* Transition Grammar::          Transition definitions
* Assertion Grammar::           State properties
@end menu

@node Type Grammar, Constraint Grammar, Net Grammar, Net Grammar
@subsection Type

@example
@group
type:
        TYPEDEF typedefinition name
@end group
@group
typedefinition:
        ENUM '@{' enum_item ( delim enum_item )* '@}'
        |
        STRUCT '@{' [ comp_list ] '@}'
        |
        UNION '@{' comp_list '@}'
        |
        ID '[' number ']'
        |
        typereference
        |
        typedefinition constraint
        |
        typedefinition '[' typedefinition ']'
        |
        typedefinition '[' QUEUE number ']'
        |
        typedefinition '[' STACK number ']'
@end group
@group
typereference:
        name
@end group
@group
enum_item:
        name [ [ '=' ] number ]
@end group
@group
comp_list:
        comp ( delim comp )* [ delim ]
comp:
        typedefinition name
@end group
@group
number:
        expr
@end group
@end example

@node Constraint Grammar, Function Grammar, Type Grammar, Net Grammar
@subsubsection Constraint

@example
@group
constraint:
        '(' range ( delim range )* ')'
@end group
@group
range:
        value
        |
        '..' value
        |
        value '..' value
        |
        value '..'
@end group
@group
value:
        expr
@end group
@end example

@node Function Grammar, Place Grammar, Constraint Grammar, Net Grammar
@subsection Function

@example
@group
function:
        typereference name eq formula
        |
        typereference name '(' param_list ')' formula
@end group
@group
eq:     '=' | '()'
@end group
@group
param_list:
        [ param_list_item ( delim param_list_item )* ]
param_list_item:
        typereference name
@end group
@end example

@node Place Grammar, Transition Grammar, Function Grammar, Net Grammar
@subsection Place

@example
@group
place:
        PLACE name constraint* typedefinition
        [ CONST ] [ ':' marking_list ]
@end group
@end example

@menu
* Constraint Grammar::          @samp{constraint}
* Type Grammar::                @samp{typedefinition}
* Expression Grammar::          @samp{marking_list}
@end menu

@node Transition Grammar, Assertion Grammar, Place Grammar, Net Grammar
@subsection Transition

@example
@group
transition:
        TRANS [ ':' ] name [ '!' ] trans*
@end group
@group
trans:
        '@{' [ var_expr ( delim var_expr )* [ delim ] ] '@}'
        |
        IN trans_places
        |
        OUT trans_places
        |
        GATE expr ( ',' expr )*
@end group
@group
        |
        HIDE expr
@end group
@group
        |
        STRONGLY_FAIR expr
        |
        WEAKLY_FAIR expr
        |
        ENABLED expr
@end group
@group
        |
        ':' [ TRANS ] name
        |
        NUMBER
@end group
@group
var_expr:
        [ HIDE ] typereference name
        |
        [ HIDE ] typereference name '!' [ '(' expr ')' ]
        |
        function
@end group
@group
trans_places:
        '@{' place_marking ( ';' place_marking )* '@}'
place_marking:
        [ PLACE ] name ':' marking_list
@end group
@end example

@menu
* Type Grammar::                @samp{typedefinition}
* Function Grammar::            @samp{function}
* Expression Grammar::          @samp{expr}, @samp{marking_list}
@end menu

@node Assertion Grammar, , Transition Grammar, Net Grammar
@subsection State Properties

@example
@group
verify:
        REJECT expr
        |
        DEADLOCK expr
@end group
@group
fairness:
        STRONGLY_FAIR qual_expr ( ',' qual_expr )*
        |
        WEAKLY_FAIR qual_expr ( ',' qual_expr )*
        |
        ENABLED qual_expr ( ',' qual_expr )*
@end group
@group
proposition:
        PROP name ':' expr
@end group
@end example

@menu
* Expression Grammar::          @samp{marking_list}, @samp{formula}
@end menu

@node Query Grammar, , Grammar, Grammar
@section The Query Language
@cindex query language

Keywords of the query language are reserved words only in the beginning
of a statement.  For instance, @samp{eval eval} will try to evaluate the
symbol @samp{eval} in the current state.

@example
@group
script:
        [ statement ( ';' statement )* [ ';' ] ]
@end group
@group
statement:
        MODEL name
        |
        GRAPH name
        |
        [ VISUAL ] DUMP
        |
        UNFOLD name
        |
        LSTS [ name ]
        |
        [ VISUAL ] DUMPGRAPH
        |
        ( BREADTH | DEPTH ) [ STATE ]
        |
        [ VISUAL ] ( BREADTH | DEPTH ) formula
        |
@end group
@group
        [ VISUAL ] [ EVAL ] [ STATE ] formula
        |
        [ VISUAL ] SHOW [ STATE ]
        |
        [ VISUAL ] SHOW STATE STATE ( STATE )*
        |
        HIDE [ '!' ] [ [ PLACE ] name ( ',' [ PLACE ] name )* ]
        |
        [ VISUAL ] ( SUCC | PRED ) [ '!' ] [ STATE ]
        |
        [ GO ] STATE
        |
        [ VISUAL ] [ STATE ] TRANS atrans*
@end group
@group
atrans:
        '@{' [ avar_expr ( delim avar_expr )* [ delim ] ] '@}'
        |
        IN trans_places
        |
        OUT trans_places
        |
        GATE expr ( ',' expr )*
@end group
@group
avar_expr:
        typereference name
        |
        typereference name '!' [ '(' expr ')' ]
@end group
@group
statement:
        STRONG [ STATE ] [expr]
        |
        TERMINAL
        |
        [ VISUAL ] COMPONENTS
        |
        [ VISUAL ] ( SUCC | PRED ) COMP
        |
        [ VISUAL ] [ SHOW ] COMP [ expr ]
        |
@end group
@group
        [ VISUAL ] PATH ( STATE | COMP | expr ) [ STATE ] [ ',' expr ]
        |
        [ VISUAL ] PATH STATE ( COMP | expr ) [ ',' expr ]
        |
        [ VISUAL ] PATH STATE STATE STATE ( STATE )* [ ',' expr ]
@end group
@group
        FUNCTION function
        |
@end group
@group
        STATS
        |
@end group
        TIME
        |
@group
@end group
@group
        CD [ name ]
        |
        TRANSLATOR [ name ]
        |
        COMPILEDIR [ name ]
        |
        LOG [ name ]
        |
@end group
@group
        PROMPT [ 'c' ]
        |
@end group
@group
        HELP
        |
        EXIT
@end group
@end example

@node Expression Grammar, , Grammar, Grammar
@section Formulae and Expressions

@example
@group
expr:
        formula
@end group
@group
marking:
        formula
marking_list:
        marking ( ',' marking )*
@end group
@end example

@menu
* Literal Grammar::             Literals
* Function Call Grammar::       Function calls
* Basic Formulae Grammar::      Syntax for basic formulae
* Union Grammar::               Syntax related with unions and type casting
* Iterating Grammar::           Non-determinism and quantification
* Multi-Set Grammar::           Multi-set operations
* Temporal Grammar::            Temporal logic
@end menu

@node Literal Grammar, Function Call Grammar, Expression Grammar, Expression Grammar
@subsection Literals
@findex true
@findex false
@findex undefined
@findex fatal
@findex #@r{, unary}
@findex <@r{, unary}
@findex >@r{, unary}

@example
@group
formula:
        TRUE | FALSE
        |
        NUMBER
        |
        CHARACTER
        |
        UNDEFINED | FATAL
        |
        '#' typereference
        |
        '<' typereference | '>' typereference
        |
        name
@end group
@end example

@node Function Call Grammar, Basic Formulae Grammar, Literal Grammar, Expression Grammar
@subsection Functions

@example
@group
formula:
        name '()'
        |
        name '(' arg_list ')'
arg_list:
        [ formula ( ',' formula )* ]
@end group
@end example

@node Basic Formulae Grammar, Union Grammar, Function Call Grammar, Expression Grammar
@subsection Basic Formulae

@example
@group
formula:
        '(' formula ')'
        |
        ATOM formula
        |
@end group
@group
        formula '<' formula
        |
        formula '==' formula
        |
        formula '>' formula
        |
        formula '>=' formula
        |
        formula '!=' formula
        |
        formula '<=' formula
        |
@end group
@group
        '-' formula
        |
        formula '+' formula
        |
        formula '-' formula
        |
        formula '/' formula
        |
        formula '*' formula
        |
        formula '%' formula
        |
@end group
@group
        '|' formula | '+' formula
        |
        '*' formula
        |
        '/' formula | '%' formula
        |
        '~' formula
        |
@end group
@group
        formula '<<' formula
        |
        formula '>>' formula
        |
        formula '&' formula
        |
        formula '^' formula
        |
        formula '|' formula
        |
@end group
@group
        formula '?' formula ( ':' formula )*
        |
@end group
@group
        '@{' [ name ':' ] [ expr ] ( ',' [ name ':' ] [ expr ] )* '@}'
        |
        formula '.' name
        |
        formula '.' '@{' name expr '@}'
        |
        formula '[' formula ']'
        |
        formula '.' '@{' '[' expr ']' expr '@}'
        |
@end group
@group
        '!' formula
        |
        formula '&&' formula
        |
        formula '^^' formula
        |
        formula '||' formula
        |
        formula '<=>' formula
        |
        formula '=>' formula
@end group
@end example

@node Union Grammar, Iterating Grammar, Basic Formulae Grammar, Expression Grammar
@subsection Typecasting and Union Values

@example
@group
formula:
        IS typereference formula
        |
        name '=' formula
        |
        formula IS name
@end group
@end example

@node Iterating Grammar, Multi-Set Grammar, Union Grammar, Expression Grammar
@subsection Non-Determinism and Quantification

@example
@group
formula:
        typereference [ name ] '!' [ '(' expr ')' ]
        |
        typereference name [ '(' expr ')' ] ':' formula
        |
        typereference name [ '(' expr ')' ] '&&' formula
        |
        typereference name [ '(' expr ')' ] '||' formula
        |
        '.' name [ name ]
        |
        ':' name [ name ]
@end group
@end example

@node Multi-Set Grammar, Temporal Grammar, Iterating Grammar, Expression Grammar
@subsection Multi-Set Operations

@example
@group
formula:
        EMPTY
        |
        '(' marking_list ')'
        |
        formula '#' marking
        |
        PLACE name
        |
@end group
@group
        marking SUBSET marking
        |
        marking INTERSECT marking
        |
        marking MINUS marking
        |
        marking UNION marking
        |
        marking EQUALS marking
        |
@end group
@group
        CARDINALITY marking
        |
        MAX marking
        |
        MIN marking
        |
@end group
@group
        SUBSET name '@{' marking_list '@}' expr
        |
        MAP name '@{' marking_list '@}' expr
        |
        MAP name '#' name '@{' marking_list '@}' marking
@end group
@end example

@node Temporal Grammar, , Multi-Set Grammar, Expression Grammar
@subsection Temporal Logic

@example
@group
        '<>' formula
        |
        '[]' formula
        |
        '()' formula
        |
        formula UNTIL formula
        |
        formula RELEASE formula
@end group
@group
qual_expr:
        TRANS name [ ':' expr ]
        |
        '(' qual_expr ')'
        |
@end group
@group
        '!' qual_expr
        |
@end group
@group
        qual_expr '&&' qual_expr
        |
@end group
@group
        qual_expr '^^' qual_expr
        |
@end group
@group
        qual_expr '||' qual_expr
        |
@end group
@group
        qual_expr '<=>' qual_expr
        |
        qual_expr '=>' qual_expr
@end group
@end example

@node Graph Files, Compiling, Grammar, Top
@appendix The Graph Files
@cindex reachability graph, file format

For maximum flexibility and performance, the reachability graph is laid
out in disk files in machine dependent format.  Please refer to the
files @file{Graph/fileformats.html} and @file{Graph/Graph.C} in the
Maria source code for exact information.

Note that when Maria has been compiled for using a memory mapped file
interface (@pxref{Configuring}), the sizes of the graph files will be
rounded up to a power of two while Maria is running.  This arrangement
reduces the number of costly system calls.

@node Compiling, Examples, Graph Files, Top
@appendix Compiling Maria
@cindex compiling

@menu
* System Requirements::         What is needed for the compilation
* Configuring::                 Definitions in the @file{Makefile} files
* Installing::                  Installing Maria for system-wide use
* Debugging::                   Compiling a special version for debugging
* Bugs::                        Reporting Bugs
@end menu

@node System Requirements, Configuring, Compiling, Compiling
@section System Requirements

Special care has been taken to ensure the quality and portability of
the Maria source code.  The code should compile on any @w{ISO/IEC
14882} compliant C++ compiler.  Unfortunately the standard is fairly
new (summer 1998), and until 2001 or 2002, many C++ compilers did not
support even the subset of it that compiling Maria requires.

We use the GNU Compiler Collection (gcc) on @w{Debian GNU/Linux} as
the development platform.  GCC should be able to compile the program
also on FreeBSD, NetBSD, OpenBSD and IBM AIX systems.  Furthermore,
the code can be compiled with the native compilers of @w{Digital UNIX}
4.0 and 5.1, @w{HP-UX 11.22}, @w{Sun Solaris 8}, @w{SGI IRIX 6.2} and
@w{Apple Darwin 5.3}.

It is recommended that you install the freely available @w{gcc 2.95}
or later on your system if you have problems compiling the code.

We would like to hear success reports from people using other compilers.
Patches, even to the @file{Makefile} files, are welcome.

@node Configuring, Installing, System Requirements, Compiling
@section Editing the @file{Makefile} files
@cindex @file{Makefile}

In the top-level directory, in @file{Makefile} and in
@file{Makefile}.@var{system}, there are a couple of variable
definitions that you should check before invoking the compilation by
typing @samp{make}.  It is recommended to make @samp{reallyclean}
before re-starting the compilation after making
modifications.@footnote{If the @samp{make} command on your system does
not seem to come along with the @file{Makefile}, use @w{GNU Make}.}

@table @samp
@item HAS_READLINE
@itemx LIBREADLINE
@itemx INCREADLINE
Set @samp{HAS_READLINE=yes} if the GNU Readline library is available,
and ensure that the directories have been set up properly.  The library
is not a necessity; @xref{Line Editor}, for the features it provides.
On some systems, you may need to add @samp{-lncurses} to the list of
libraries.

@item EXPR_COMPILE
Set @samp{EXPR_COMPILE=yes} if your system supports dynamic loading of
shared libraries and if you want to enable the @samp{-C} command line
option (@pxref{Maria Options}), which will considerably speed up the
state space exploration.

@item EXTRA_DEFINES
Extra definitions for the macro preprocessor.  Set @samp{-DUSE_MMAP} in
order to enable memory mapped access to the reachability graph files on
systems that implement the POSIX.1b mmap(2) interface.  This option can
considerably speed up the analysis of models that have a relatively
small number of high-level transitions.  Please note that with this
option, 32-bit systems can only handle graph files whose total size is
less than 4 gigabytes, maybe even less than 1 gigabyte, depending on the
operating system.

@item DEBUG
Debugging flags.  Usually @samp{-DNDEBUG} for compiling the production
version and @samp{-g} for the debugging version.

@item PROF
Profiling flags.  Usually empty.

@item CXX
@itemx CC
Commands for compiling modules written in C++ and C, respectively.

@item EXTRA_LIBS
Define @samp{EXTRA_LIBS=-ldl} or similar, if you want to enable support
for compiled expressions and the dynamic loader routines are not part of
the standard libraries on your system.

@item DEFINES
Extra flags e.g.@: for enabling the usage of the POSIX regular
expression library (@samp{-DHAS_REGEX}), of the @samp{getopt_long}
function (@samp{-DHAS_GETOPT_LONG}), a GNU extension to the standard,
and of some extensions to the Standard Template Library
(@samp{-DHASH_MAP_LOC} and @samp{-DSLIST_LOC}).

@item CFLAGS
@itemx CXXFLAGS
Flags for the C and C++ compilers e.g.@: for enabling optimizations.
@end table

@node Installing, Debugging, Configuring, Compiling
@section Installing Maria
@cindex installing @file{maria}

The file @file{Makefile} in the top-level directory contains rules for
installing the @file{maria} executable and some related files on
Unix-like systems.  The installation is invoked by typing @samp{make
install installman installinfo}.  You may want to redefine some of the
following variables either in the @file{Makefile} or on the @file{make}
command line:

@table @var
@item PREFIX
The base directory where Maria should be installed.  You might want to
change this to @samp{/usr/local}.  The default is @samp{/usr}.

@item INSTALLDIR
@itemx INSTALLBIN
@itemx INSTALLDATA
The commands for creating directories, installing executable files and
installing data files.  On Apple Darwin, you will need to add the
@samp{-c} switch to the latter two commands.
@end table

@node Debugging, Bugs, Installing, Compiling
@section Compiling Maria for Debugging
@cindex debugging @file{maria}

Compiling a debugging version of Maria is simple: in @file{Makefile},
define @samp{DEBUG=-g}, and you are all set.  You could also disable
@samp{assert()} macros by defining @samp{-DNDEBUG}, but they are very
useful, since they often catch errors introduced by modifying code that
seems completely unrelated to the failed assertion at first sight.

For detecting and debugging memory management issues, you can use the
Electric Fence Library, Valgrind for GNU/Linux, the Debug Malloc Library
(@inforef{Top, , dmalloc} or @uref{http://www.dmalloc.com}) or
commercial tools such as Third Degree (@file{third}) on @w{Digital
UNIX}.

Debuggers often have problems with C++.  For us, the GNU debugger (gdb
5.0) and has worked pretty well on Debian GNU/Linux.  Version 4.18 has
problems calling virtual methods.

Defining the @samp{YYDEBUG} macro enables grammar debugging.  An
executable compiled with this macro defined will look for the
environment variable @env{DEBUG}.  When @env{DEBUG=1}, the parser will
print out more than enough information on the parsing process.  Often it
makes sense to set a conditional breakpoint on the lexical analyzer
function based on the input line number, and to enable the parser
debugging output only for a certain region of the input by setting or
clearing the status variable in the debugger.

@node Bugs, , Debugging, Compiling
@section Reporting Bugs
@cindex bugs, reporting

Every non-trivial program is likely to contain bugs.  Fatal bugs, such
as assertion failures or segmentation faults, are easiest to locate.
Our intention has been to make the parsers in Maria bullet-proof: no
matter what the input is, the program should not crash.

Sometimes a program may behave in a counter-intuitive way, doing
something else than one would except.  Such situations can be caused by
a bug, or the program might behave just as planned.  The latter case is
often fixed by rephrasing or extending the documentation.

Bug reports and suggestions are welcome at @samp{msmakela@@tcs.hut.fi}.
In the bug reports, please mention which platform you are using
(including version numbers of the operating system and the relevant
compilers and libraries) and include a stripped-down input file that is
enough for triggering the bug.  You can also compile the analyzer with
support for debugging enabled, since it can help tracking down the
error.  Please use the @samp{diff -c} format for any patches you send.

@node Examples, Copying, Compiling, Top
@appendix Examples

More examples can be found in the Maria source code, in the directory
@file{parser/test}.

@menu
* Dining::                      Dining Philosophers
* Database::                    Distributed Database
@end menu

@node Dining, Database, Examples, Examples
@section Dining Philosophers (@file{dining.pn})
@cindex dining philosophers (example)

@example
@group
#!@var{/usr/local/bin/maria}
typedef unsigned (1..5) philosopher;
typedef struct @{
  philosopher p,
  enum @{ thinking, hungry, eating @} s
@} status;
@end group
@group
place fork (0..#philosopher) philosopher: philosopher p: p;
place state (#philosopher) status: philosopher p: @{ p, thinking @};
@end group
@group
trans left
in @{ place state: @{ p, thinking @}; place fork: p; @}
out @{ place state: @{ p, hungry @}; @};
@end group
@group
trans right
in @{ place state: @{ p, hungry @}; place fork: +p; @}
out @{ place state: @{ p, eating @}; @};
@end group
@group
trans finish
in @{ place state: @{ p, eating @}; @}
out @{ place state: @{ p, thinking @}; place fork: p, +p; @};
@end group
@end example

@node Database, , Dining, Examples
@section Distributed Database Management (@file{dbm.pn})
@cindex distributed database management (example)

The parameter of the model, the number of database agents, is only
present in the data type definition.  The initial marking expression
and the arc expressions are independent of that parameter, thanks to
the multi-set sum operator.

@example
@group
typedef unsigned (1..10) db_t;
typedef struct @{
  db_t first;
  db_t second;
@} db_pair_t;
@end group

@group
place waiting (0..1) db_t;
place performing (0..#db_t-1) db_t;
place inactive (0..#db_t) db_t: (db_t d: d)
  minus (place waiting union place performing);
place exclusion (0..1) struct @{@}: (place waiting equals empty)#@{@};
@end group

@group
place sent (0..#db_t-1) db_pair_t;
place received (0..#db_t-1) db_pair_t;
place acknowledged (0..#db_t-1) db_pair_t;
@end group

@group
place unused (1+#db_pair_t-2*#db_t,#db_pair_t-#db_t) db_pair_t:
(db_pair_t p (p.first != p.second): p)
  minus (db_t t: (map s @{ place waiting @} @{s, t@}));
@end group

@group
trans update_and_send_messages
in @{
  place inactive: s;
  place exclusion: @{@};
  place unused: db_t t (t != s): @{ s, t @};
@}
out @{
  place waiting: s;
  place sent: db_t t (t != s): @{ s, t @};
@};
@end group

@group
trans receive_acknowledgements
in @{
  place waiting: s;
  place acknowledged: db_t t (t != s): @{ s, t @};
@}
out @{
  place inactive: s;
  place exclusion: @{@};
  place unused: db_t t (t != s): @{ s, t @};
@};
@end group

@group
trans receive_message
in @{
  place inactive: r;
  place sent: @{ s, r @};
@}
out @{
 place performing: r;
 place received: @{ s, r @};
@}
gate s != r;
@end group

@group
trans send_acknowledgement
in @{
  place performing: r;
  place received: @{ s, r @};
@}
out @{
  place inactive: r;
  place acknowledged: @{ s, r @};
@}
gate s != r;
@end group
@end example

@node Copying, , Examples, Top
@unnumbered GNU GENERAL PUBLIC LICENSE
@center Version 2, June 1991

@display
Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@end display

@unnumberedsec Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software---to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.

@iftex
@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end iftex
@ifinfo
@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end ifinfo

@enumerate 0
@item
This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The ``Program'', below,
refers to any such program or work, and a ``work based on the Program''
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term ``modification''.)  Each licensee is addressed as ``you''.

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

@item
You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

@item
You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

@enumerate a
@item
You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.

@item
You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.

@item
If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License.  (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
@end enumerate

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

@item
You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

@enumerate a
@item
Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,

@item
Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,

@item
Accompany it with the information you received as to the offer
to distribute corresponding source code.  (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
@end enumerate

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

@item
You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

@item
You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

@item
Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

@item
If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

@item
If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

@item
The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and ``any
later version'', you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

@item
If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

@iftex
@heading NO WARRANTY
@end iftex
@ifinfo
@center NO WARRANTY
@end ifinfo

@item
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

@item
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
@end enumerate

@iftex
@heading END OF TERMS AND CONDITIONS
@end iftex
@ifinfo
@center END OF TERMS AND CONDITIONS
@end ifinfo

@page
@unnumberedsec How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the ``copyright'' line and a pointer to where the full notice is found.

@smallexample
@var{one line to give the program's name and a brief idea of what it does.}
Copyright (C) 19@var{yy}  @var{name of author}

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
@end smallexample

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

@smallexample
Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details 
type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@end smallexample

The hypothetical commands @samp{show w} and @samp{show c} should show
the appropriate parts of the General Public License.  Of course, the
commands you use may be called something other than @samp{show w} and
@samp{show c}; they could even be mouse-clicks or menu items---whatever
suits your program.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a ``copyright disclaimer'' for the program, if
necessary.  Here is a sample; alter the names:

@smallexample
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.

@var{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
@end smallexample

This General Public License does not permit incorporating your program into
proprietary programs.  If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library.  If this is what you want to do, use the GNU Library General
Public License instead of this License.

@node Index, , , Top
@unnumbered Index

@printindex cp

@contents

@bye
Local variables:
compile-command: "makeinfo maria.texinfo && texi2dvi --pdf maria.texinfo"
End:
